let preGradGraphData = null;
let postGradGraphData = null;
let codeData = null;
let cppCodeData = null;
let preToPost = {};
let postToPre = {};
let pyCodeToPost = {};
let postToPyCode = {};
let postToCppCode = {};
let cppCodeToPost = {};
let lineMappings = null;
function initializeLineMappings() {
try {
const lineMappingsElement = document.getElementById('lineMappings');
if (lineMappingsElement) {
lineMappings = JSON.parse(lineMappingsElement.textContent);
preToPost = lineMappings.preToPost || {};
postToPre = lineMappings.postToPre || {};
pyCodeToPost = lineMappings.pyCodeToPost || {};
postToPyCode = lineMappings.postToPyCode || {};
cppCodeToPost = lineMappings.cppCodeToPost || {};
postToCppCode = lineMappings.postToCppCode || {};
console.log('Line mappings initialized:', {
preToPost,
postToPre,
pyCodeToPost,
postToPyCode,
cppCodeToPost,
postToCppCode
});
} else {
console.warn('No line mappings element found');
}
} catch (error) {
console.error('Error initializing line mappings:', error);
}
}
function setupEditorContent(editorId, lines) {
if (!lines) return;
const editor = document.getElementById(editorId);
if (!editor) return;
editor.innerHTML = '';
lines.forEach((line, index) => {
const lineDiv = document.createElement('div');
lineDiv.className = 'line';
const lineNumber = document.createElement('span');
lineNumber.className = 'line-number';
lineNumber.textContent = index + 1;
const lineContent = document.createElement('span');
lineContent.className = 'line-content';
lineContent.textContent = line;
const lineNum = index + 1;
let hasMatch = false;
switch (editorId) {
case 'preGradGraph':
hasMatch = preToPost[lineNum] && preToPost[lineNum].length > 0;
break;
case 'postGradGraph':
hasMatch = (postToPre[lineNum] && postToPre[lineNum].length > 0) ||
(postToPyCode[lineNum] && postToPyCode[lineNum].length > 0) ||
(postToCppCode[lineNum] && postToCppCode[lineNum].length > 0);
break;
case 'generatedCode':
hasMatch = (pyCodeToPost[lineNum] && pyCodeToPost[lineNum].length > 0) ||
(cppCodeToPost[lineNum] && cppCodeToPost[lineNum].length > 0);
break;
}
if (hasMatch) {
lineContent.classList.add('has-match');
}
lineDiv.appendChild(lineNumber);
lineDiv.appendChild(lineContent);
lineDiv.addEventListener('click', () => handleLineClick(editorId, index + 1));
lineDiv.addEventListener('mouseenter', () => handleLineHover(editorId, index + 1));
lineDiv.addEventListener('mouseleave', clearHighlights);
editor.appendChild(lineDiv);
});
}
function handleLineHover(editorId, lineNumber) {
clearHighlights();
const hoveredLine = document.querySelector(`#${editorId} .line:nth-child(${lineNumber})`);
if (hoveredLine) {
hoveredLine.classList.add('highlight');
}
highlightCorrespondingLines(editorId, lineNumber);
}
function clearHighlights() {
document.querySelectorAll('.line').forEach(line => {
line.classList.remove('highlight');
});
}
function handleLineClick(editorId, lineNumber) {
clearHighlights();
const clickedLine = document.querySelector(`#${editorId} .line:nth-child(${lineNumber})`);
if (clickedLine) {
clickedLine.classList.add('highlight');
clickedLine.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});
}
highlightCorrespondingLines(editorId, lineNumber);
}
function initializeData() {
try {
const preGradGraph = document.querySelector('#preGradGraph pre');
const postGradGraph = document.querySelector('#postGradGraph pre');
const generatedCode = document.querySelector('#generatedCode pre');
if (preGradGraph) preGradGraphData = preGradGraph.textContent.split('\n');
if (postGradGraph) postGradGraphData = postGradGraph.textContent.split('\n');
if (generatedCode) {
const content = generatedCode.textContent;
if (content.includes('AOTInductorModel::run_impl')) {
cppCodeData = content.split('\n');
codeData = null;
} else {
codeData = content.split('\n');
cppCodeData = null;
}
}
initializeLineMappings();
setupEditorContent('preGradGraph', preGradGraphData);
setupEditorContent('postGradGraph', postGradGraphData);
setupEditorContent('generatedCode', codeData || cppCodeData);
if (cppCodeData) {
const cppEditor = document.getElementById('generatedCode');
if (cppEditor) {
const targetLine = Array.from(cppEditor.querySelectorAll('.line')).find(
line => line.textContent.includes('void AOTInductorModel::run_impl(')
);
if (targetLine) {
targetLine.scrollIntoView({ behavior: 'auto', block: 'center' });
}
}
}
} catch (error) {
console.error('Error initializing data:', error);
console.error(error.stack);
}
}
window.addEventListener('DOMContentLoaded', initializeData);
function highlightCorrespondingLines(sourceEditorId, lineNumber) {
let correspondingLines = findCorrespondingLines(sourceEditorId, lineNumber);
Object.entries(correspondingLines).forEach(([editorId, lines]) => {
if (lines && editorId !== sourceEditorId) {
const lineNumbers = Array.isArray(lines) ? lines : [lines];
const middleIndex = Math.floor(lineNumbers.length / 2);
let hasScrolled = false;
lineNumbers.forEach((line, index) => {
const lineElement = document.querySelector(`#${editorId} .line:nth-child(${line})`);
if (lineElement) {
lineElement.classList.add('highlight');
if (index === middleIndex && !hasScrolled) {
lineElement.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});
hasScrolled = true;
}
}
});
}
});
}
function findCorrespondingLines(sourceEditorId, lineNumber) {
let result = {};
switch (sourceEditorId) {
case 'preGradGraph':
result.postGradGraph = preToPost[lineNumber] || [];
if (result.postGradGraph.length > 0) {
result.generatedCode = [];
for (const postLine of result.postGradGraph) {
if (codeData) {
if (postToPyCode[postLine]) {
result.generatedCode.push(...postToPyCode[postLine]);
}
} else {
if (postToCppCode[postLine]) {
result.generatedCode.push(...postToCppCode[postLine]);
}
}
}
}
break;
case 'postGradGraph':
result.preGradGraph = postToPre[lineNumber] || [];
if (codeData) {
result.generatedCode = postToPyCode[lineNumber] || [];
} else {
result.generatedCode = postToCppCode[lineNumber] || [];
}
break;
case 'generatedCode':
if (codeData) {
result.postGradGraph = pyCodeToPost[lineNumber] || [];
} else {
result.postGradGraph = cppCodeToPost[lineNumber] || [];
}
if (result.postGradGraph.length > 0) {
result.preGradGraph = [];
for (const postLine of result.postGradGraph) {
if (postToPre[postLine]) {
result.preGradGraph.push(...postToPre[postLine]);
}
}
}
break;
}
return result;
}
function setupResizablePanels() {
const container = document.querySelector('.editor-container');
const pre = document.getElementById('preGradGraph');
const post = document.getElementById('postGradGraph');
const code = document.getElementById('generatedCode');
const divider1 = document.getElementById('divider1');
const divider2 = document.getElementById('divider2');
let isDragging = false;
let dragDivider = null;
function onMouseMove(e) {
if (!isDragging || !dragDivider) return;
const containerRect = container.getBoundingClientRect();
const totalWidth = containerRect.width;
if (dragDivider === divider1) {
const newPreWidth = e.clientX - containerRect.left;
const newPostWidth = post.offsetWidth + (pre.offsetWidth - newPreWidth);
pre.style.flex = `0 0 ${newPreWidth}px`;
post.style.flex = `0 0 ${newPostWidth}px`;
} else if (dragDivider === divider2) {
const preWidth = pre.offsetWidth;
const newPostWidth = e.clientX - containerRect.left - preWidth - divider1.offsetWidth;
const newCodeWidth = totalWidth - e.clientX + containerRect.left - divider2.offsetWidth;
post.style.flex = `0 0 ${newPostWidth}px`;
code.style.flex = `0 0 ${newCodeWidth}px`;
}
}
function onMouseUp() {
isDragging = false;
dragDivider = null;
document.body.style.cursor = '';
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
[divider1, divider2].forEach(div => {
div.addEventListener('mousedown', e => {
isDragging = true;
dragDivider = div;
document.body.style.cursor = 'col-resize';
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
});
}
window.addEventListener('DOMContentLoaded', setupResizablePanels);