@industry-theme/file-city-panel 0.5.70 → 0.5.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/panels/FileCityTrailExplorerPanel/FileCityTrailExplorerPanel.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailDiffSnippetView.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailFilePath.d.ts +19 -0
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailFilePath.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailLeaderLine.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailMarkdownOverlay.d.ts +6 -0
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailMarkdownOverlay.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailSnippetView.d.ts.map +1 -1
- package/dist/panels.bundle.js +484 -181
- package/dist/panels.bundle.js.map +1 -1
- package/dist/types/FileCityTrailExplorerPanel.d.ts +20 -1
- package/dist/types/FileCityTrailExplorerPanel.d.ts.map +1 -1
- package/dist/types/Trail.d.ts +27 -8
- package/dist/types/Trail.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/panels.bundle.js
CHANGED
|
@@ -257703,7 +257703,7 @@ const TrailLeaderLine = React.forwardRef(function TrailLeaderLine2({ containerRe
|
|
|
257703
257703
|
const HEADER_BAND_OFFSET = 22;
|
|
257704
257704
|
const bx = nodeRect.left - containerRect.left;
|
|
257705
257705
|
const by = nodeRect.top - containerRect.top + HEADER_BAND_OFFSET;
|
|
257706
|
-
const ELBOW_GAP =
|
|
257706
|
+
const ELBOW_GAP = 30;
|
|
257707
257707
|
const CORNER_RADIUS = 14;
|
|
257708
257708
|
const elbowX = Math.max(
|
|
257709
257709
|
canvasLeft + 8,
|
|
@@ -257806,6 +257806,11 @@ const TrailLeaderLine = React.forwardRef(function TrailLeaderLine2({ containerRe
|
|
|
257806
257806
|
)
|
|
257807
257807
|
] });
|
|
257808
257808
|
});
|
|
257809
|
+
const CALLOUT_FADE_IN_MS = 350;
|
|
257810
|
+
const TITLE_TYPEWRITER_CPS = 28;
|
|
257811
|
+
const TITLE_TYPEWRITER_HOLD_MS = 500;
|
|
257812
|
+
const TITLE_INTER_HOLD_MS = 220;
|
|
257813
|
+
const TITLE_CARET = "▍";
|
|
257809
257814
|
const fileBasename = (path2) => {
|
|
257810
257815
|
const i = path2.lastIndexOf("/");
|
|
257811
257816
|
return i >= 0 ? path2.slice(i + 1) : path2;
|
|
@@ -257817,10 +257822,18 @@ const fileDirname = (path2) => {
|
|
|
257817
257822
|
const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
257818
257823
|
containerRef,
|
|
257819
257824
|
buildings,
|
|
257825
|
+
markerTitles,
|
|
257820
257826
|
cityCenter,
|
|
257821
257827
|
animate: animate2 = true,
|
|
257828
|
+
currentStepIndex = null,
|
|
257822
257829
|
stepMs = 1100,
|
|
257823
|
-
|
|
257830
|
+
// Dwell budget covers: fade-in (350ms) + initial hold (500ms) +
|
|
257831
|
+
// filename typewriter (~ name.length * 36ms at 28cps) + inter-hold
|
|
257832
|
+
// (220ms) + title typewriter (~ title.length * 36ms) + a digest
|
|
257833
|
+
// beat after typing finishes so the user can read the full
|
|
257834
|
+
// callout before the dot walks on. 3500ms leaves ~1.5s of digest
|
|
257835
|
+
// for typical 10-char filenames + 15-char titles.
|
|
257836
|
+
dwellMs = 3500,
|
|
257824
257837
|
endHoldMs = 2200
|
|
257825
257838
|
}, ref) {
|
|
257826
257839
|
const { theme: theme2 } = useTheme();
|
|
@@ -257828,7 +257841,9 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
257828
257841
|
const fontFamily = theme2.fonts.body;
|
|
257829
257842
|
const calloutFontSize = String(theme2.fontSizes[1] ?? 14);
|
|
257830
257843
|
const calloutFontWeight = String(theme2.fontWeights.semibold ?? 600);
|
|
257831
|
-
const
|
|
257844
|
+
const calloutBodyFontWeight = String(theme2.fontWeights.body ?? 400);
|
|
257845
|
+
const calloutLineDyPx = Math.round((theme2.fontSizes[1] ?? 14) * 1.45);
|
|
257846
|
+
const calloutLineDy = String(calloutLineDyPx);
|
|
257832
257847
|
const surfaceColor = theme2.colors.backgroundSecondary ?? "#0f1419";
|
|
257833
257848
|
const filenameColor = theme2.colors.text ?? "#f8fafc";
|
|
257834
257849
|
const dirColor = theme2.colors.textMuted ?? "#94a3b8";
|
|
@@ -257840,14 +257855,24 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
257840
257855
|
const animStartTsRef = React.useRef(
|
|
257841
257856
|
typeof performance !== "undefined" ? performance.now() : 0
|
|
257842
257857
|
);
|
|
257858
|
+
const hoverFrozenElapsedRef = React.useRef(null);
|
|
257859
|
+
const periodRef = React.useRef(0);
|
|
257843
257860
|
const buildingsRef = React.useRef(buildings);
|
|
257861
|
+
const markerTitlesRef = React.useRef(markerTitles);
|
|
257844
257862
|
const cityCenterRef = React.useRef(cityCenter);
|
|
257863
|
+
const currentStepIndexRef = React.useRef(currentStepIndex);
|
|
257845
257864
|
React.useEffect(() => {
|
|
257846
257865
|
buildingsRef.current = buildings;
|
|
257847
257866
|
}, [buildings]);
|
|
257867
|
+
React.useEffect(() => {
|
|
257868
|
+
markerTitlesRef.current = markerTitles;
|
|
257869
|
+
}, [markerTitles]);
|
|
257848
257870
|
React.useEffect(() => {
|
|
257849
257871
|
cityCenterRef.current = cityCenter;
|
|
257850
257872
|
}, [cityCenter]);
|
|
257873
|
+
React.useEffect(() => {
|
|
257874
|
+
currentStepIndexRef.current = currentStepIndex;
|
|
257875
|
+
}, [currentStepIndex]);
|
|
257851
257876
|
const hideAll = React.useCallback(() => {
|
|
257852
257877
|
const g2 = groupRef.current;
|
|
257853
257878
|
if (!g2) return;
|
|
@@ -257861,6 +257886,7 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
257861
257886
|
}, [animate2, buildings, dwellMs, stepMs, endHoldMs]);
|
|
257862
257887
|
const onCameraFrame = React.useCallback(
|
|
257863
257888
|
(camera, size) => {
|
|
257889
|
+
var _a, _b;
|
|
257864
257890
|
const targets = buildingsRef.current;
|
|
257865
257891
|
const center = cityCenterRef.current;
|
|
257866
257892
|
const container = containerRef.current;
|
|
@@ -257892,12 +257918,18 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
257892
257918
|
const N = points.length;
|
|
257893
257919
|
const slotMs = dwellMs + stepMs;
|
|
257894
257920
|
const period = N >= 2 ? (N - 1) * slotMs + dwellMs + endHoldMs : 0;
|
|
257921
|
+
periodRef.current = period;
|
|
257922
|
+
const rawFrozen = currentStepIndexRef.current;
|
|
257923
|
+
const frozenIndex = rawFrozen != null && rawFrozen >= 0 && rawFrozen < N ? rawFrozen : null;
|
|
257895
257924
|
let revealedCount = animate2 ? 0 : N;
|
|
257896
257925
|
let leadingTip = null;
|
|
257897
257926
|
let traverseFrac = null;
|
|
257898
257927
|
let dwellElapsed = 0;
|
|
257899
|
-
if (
|
|
257900
|
-
|
|
257928
|
+
if (frozenIndex != null) {
|
|
257929
|
+
revealedCount = frozenIndex + 1;
|
|
257930
|
+
dwellElapsed = CALLOUT_FADE_IN_MS;
|
|
257931
|
+
} else if (animate2 && period > 0) {
|
|
257932
|
+
const elapsed = hoverFrozenElapsedRef.current !== null ? hoverFrozenElapsedRef.current : ((typeof performance !== "undefined" ? performance.now() : Date.now()) - animStartTsRef.current) % period;
|
|
257901
257933
|
const traversalsEnd = (N - 1) * slotMs;
|
|
257902
257934
|
if (elapsed >= traversalsEnd) {
|
|
257903
257935
|
revealedCount = N;
|
|
@@ -258011,38 +258043,79 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
258011
258043
|
}
|
|
258012
258044
|
}
|
|
258013
258045
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
258014
|
-
const paintCallout = (textEl, bgEl, point2, path2, opacity) => {
|
|
258046
|
+
const paintCallout = (textEl, bgEl, point2, path2, title, opacity, nameRevealChars2, titleRevealChars2) => {
|
|
258015
258047
|
if (!textEl || !bgEl) return;
|
|
258016
258048
|
if (!point2 || !point2.visible || opacity <= 1e-3 || !path2) {
|
|
258017
258049
|
textEl.setAttribute("opacity", "0");
|
|
258018
258050
|
bgEl.setAttribute("opacity", "0");
|
|
258051
|
+
bgEl.setAttribute("pointer-events", "none");
|
|
258052
|
+
textEl.setAttribute("pointer-events", "none");
|
|
258019
258053
|
return;
|
|
258020
258054
|
}
|
|
258021
|
-
|
|
258022
|
-
|
|
258023
|
-
|
|
258055
|
+
const interactive = opacity >= 0.6;
|
|
258056
|
+
bgEl.setAttribute(
|
|
258057
|
+
"pointer-events",
|
|
258058
|
+
interactive ? "auto" : "none"
|
|
258059
|
+
);
|
|
258060
|
+
textEl.setAttribute(
|
|
258061
|
+
"pointer-events",
|
|
258062
|
+
interactive ? "auto" : "none"
|
|
258063
|
+
);
|
|
258064
|
+
while (textEl.children.length < 3) {
|
|
258024
258065
|
textEl.appendChild(document.createElementNS(SVG_NS, "tspan"));
|
|
258025
258066
|
}
|
|
258026
|
-
|
|
258027
|
-
|
|
258067
|
+
while (textEl.children.length > 3) {
|
|
258068
|
+
textEl.removeChild(textEl.lastChild);
|
|
258069
|
+
}
|
|
258070
|
+
const pathTspan = textEl.children[0];
|
|
258071
|
+
const nameTspan = textEl.children[1];
|
|
258072
|
+
const titleTspan = textEl.children[2];
|
|
258028
258073
|
const name2 = fileBasename(path2);
|
|
258029
258074
|
const dir = fileDirname(path2);
|
|
258030
|
-
const
|
|
258075
|
+
const trimmedTitle = (title == null ? void 0 : title.trim()) ?? "";
|
|
258076
|
+
const displayTitle = trimmedTitle && titleRevealChars2 !== null ? titleRevealChars2 < 0 ? "" : titleRevealChars2 >= trimmedTitle.length ? trimmedTitle : trimmedTitle.slice(0, titleRevealChars2) + TITLE_CARET : trimmedTitle;
|
|
258077
|
+
const displayName = nameRevealChars2 !== null ? nameRevealChars2 < 0 ? "" : nameRevealChars2 >= name2.length ? name2 : name2.slice(0, nameRevealChars2) + TITLE_CARET : name2;
|
|
258078
|
+
const lineCount = (dir ? 1 : 0) + 1 + (trimmedTitle ? 1 : 0);
|
|
258079
|
+
const BOTTOM_LINE_OFFSET = 24;
|
|
258080
|
+
const topLineY = point2.y - BOTTOM_LINE_OFFSET - (lineCount - 1) * calloutLineDyPx;
|
|
258031
258081
|
textEl.setAttribute("text-anchor", "middle");
|
|
258032
258082
|
textEl.setAttribute("font-family", fontFamily);
|
|
258033
258083
|
textEl.setAttribute("opacity", String(opacity));
|
|
258034
|
-
nameTspan.textContent = name2;
|
|
258035
|
-
nameTspan.setAttribute("x", String(point2.x));
|
|
258036
|
-
nameTspan.setAttribute("y", String(nameLineY));
|
|
258037
|
-
nameTspan.setAttribute("fill", filenameColor);
|
|
258038
|
-
nameTspan.setAttribute("font-size", calloutFontSize);
|
|
258039
|
-
nameTspan.setAttribute("font-weight", calloutFontWeight);
|
|
258040
258084
|
pathTspan.textContent = dir;
|
|
258085
|
+
pathTspan.setAttribute("text-anchor", "middle");
|
|
258041
258086
|
pathTspan.setAttribute("x", String(point2.x));
|
|
258042
|
-
pathTspan.setAttribute("
|
|
258043
|
-
pathTspan.
|
|
258087
|
+
pathTspan.setAttribute("y", String(topLineY));
|
|
258088
|
+
pathTspan.removeAttribute("dy");
|
|
258089
|
+
pathTspan.setAttribute("fill", color2);
|
|
258044
258090
|
pathTspan.setAttribute("font-size", calloutFontSize);
|
|
258045
258091
|
pathTspan.setAttribute("font-weight", calloutFontWeight);
|
|
258092
|
+
nameTspan.textContent = name2;
|
|
258093
|
+
nameTspan.setAttribute("text-anchor", "start");
|
|
258094
|
+
nameTspan.removeAttribute("y");
|
|
258095
|
+
nameTspan.setAttribute("dy", dir ? calloutLineDy : "0");
|
|
258096
|
+
nameTspan.setAttribute(
|
|
258097
|
+
"fill",
|
|
258098
|
+
trimmedTitle ? dirColor : filenameColor
|
|
258099
|
+
);
|
|
258100
|
+
nameTspan.setAttribute("font-size", calloutFontSize);
|
|
258101
|
+
nameTspan.setAttribute(
|
|
258102
|
+
"font-weight",
|
|
258103
|
+
trimmedTitle ? calloutBodyFontWeight : calloutFontWeight
|
|
258104
|
+
);
|
|
258105
|
+
const nameWidth = typeof nameTspan.getComputedTextLength === "function" ? nameTspan.getComputedTextLength() : 0;
|
|
258106
|
+
nameTspan.setAttribute("x", String(point2.x - nameWidth / 2));
|
|
258107
|
+
titleTspan.textContent = trimmedTitle;
|
|
258108
|
+
titleTspan.setAttribute("text-anchor", "start");
|
|
258109
|
+
titleTspan.removeAttribute("y");
|
|
258110
|
+
titleTspan.setAttribute(
|
|
258111
|
+
"dy",
|
|
258112
|
+
trimmedTitle ? calloutLineDy : "0"
|
|
258113
|
+
);
|
|
258114
|
+
titleTspan.setAttribute("fill", filenameColor);
|
|
258115
|
+
titleTspan.setAttribute("font-size", calloutFontSize);
|
|
258116
|
+
titleTspan.setAttribute("font-weight", calloutFontWeight);
|
|
258117
|
+
const titleWidth = typeof titleTspan.getComputedTextLength === "function" ? titleTspan.getComputedTextLength() : 0;
|
|
258118
|
+
titleTspan.setAttribute("x", String(point2.x - titleWidth / 2));
|
|
258046
258119
|
const bbox = textEl.getBBox();
|
|
258047
258120
|
const padX = 14;
|
|
258048
258121
|
const padY = 10;
|
|
@@ -258055,26 +258128,70 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
258055
258128
|
bgEl.setAttribute("stroke", color2);
|
|
258056
258129
|
bgEl.setAttribute("stroke-width", "1.5");
|
|
258057
258130
|
bgEl.setAttribute("opacity", String(0.94 * opacity));
|
|
258131
|
+
if (displayName !== name2) {
|
|
258132
|
+
nameTspan.textContent = displayName;
|
|
258133
|
+
}
|
|
258134
|
+
if (displayTitle !== trimmedTitle) {
|
|
258135
|
+
titleTspan.textContent = displayTitle;
|
|
258136
|
+
}
|
|
258058
258137
|
};
|
|
258059
|
-
const fadeInMs = 350;
|
|
258060
258138
|
let calloutOpacity = 0;
|
|
258061
|
-
if (
|
|
258139
|
+
if (frozenIndex != null && lastIndex >= 0) {
|
|
258140
|
+
calloutOpacity = 1;
|
|
258141
|
+
} else if (animate2 && lastIndex >= 0 && lastIndex < targets.length) {
|
|
258062
258142
|
if (traverseFrac !== null) {
|
|
258063
258143
|
const eased = traverseFrac * traverseFrac * (3 - 2 * traverseFrac);
|
|
258064
258144
|
calloutOpacity = 1 - eased;
|
|
258065
258145
|
} else {
|
|
258066
|
-
const t = Math.min(1, dwellElapsed /
|
|
258146
|
+
const t = Math.min(1, dwellElapsed / CALLOUT_FADE_IN_MS);
|
|
258067
258147
|
calloutOpacity = t * t * (3 - 2 * t);
|
|
258068
258148
|
}
|
|
258069
258149
|
} else if (!animate2 && lastIndex >= 0) {
|
|
258070
258150
|
calloutOpacity = 1;
|
|
258071
258151
|
}
|
|
258152
|
+
const activePath = lastIndex >= 0 ? targets[lastIndex].path : null;
|
|
258153
|
+
const activeName = activePath ? fileBasename(activePath) : "";
|
|
258154
|
+
const activeTitle = lastIndex >= 0 ? (((_a = markerTitlesRef.current) == null ? void 0 : _a[lastIndex]) ?? "").trim() : "";
|
|
258155
|
+
let nameRevealChars = null;
|
|
258156
|
+
let titleRevealChars = null;
|
|
258157
|
+
if (animate2 && frozenIndex == null && traverseFrac === null && lastIndex >= 0) {
|
|
258158
|
+
const charsPerMs = TITLE_TYPEWRITER_CPS / 1e3;
|
|
258159
|
+
const nameStart = CALLOUT_FADE_IN_MS + TITLE_TYPEWRITER_HOLD_MS;
|
|
258160
|
+
const nameDuration = activeName.length > 0 ? activeName.length / charsPerMs : 0;
|
|
258161
|
+
const nameDone = nameStart + nameDuration;
|
|
258162
|
+
const titleStart = nameDone + TITLE_INTER_HOLD_MS;
|
|
258163
|
+
if (activeName.length > 0) {
|
|
258164
|
+
if (dwellElapsed < nameStart) {
|
|
258165
|
+
nameRevealChars = 0;
|
|
258166
|
+
} else if (dwellElapsed < nameDone) {
|
|
258167
|
+
const typed = Math.floor(
|
|
258168
|
+
(dwellElapsed - nameStart) * charsPerMs
|
|
258169
|
+
);
|
|
258170
|
+
nameRevealChars = typed >= activeName.length ? null : Math.max(0, typed);
|
|
258171
|
+
} else {
|
|
258172
|
+
nameRevealChars = null;
|
|
258173
|
+
}
|
|
258174
|
+
}
|
|
258175
|
+
if (activeTitle.length > 0) {
|
|
258176
|
+
if (dwellElapsed < titleStart) {
|
|
258177
|
+
titleRevealChars = -1;
|
|
258178
|
+
} else {
|
|
258179
|
+
const typed = Math.floor(
|
|
258180
|
+
(dwellElapsed - titleStart) * charsPerMs
|
|
258181
|
+
);
|
|
258182
|
+
titleRevealChars = typed >= activeTitle.length ? null : Math.max(0, typed);
|
|
258183
|
+
}
|
|
258184
|
+
}
|
|
258185
|
+
}
|
|
258072
258186
|
paintCallout(
|
|
258073
258187
|
calloutTextRef.current,
|
|
258074
258188
|
calloutBgRef.current,
|
|
258075
258189
|
lastIndex >= 0 ? points[lastIndex] : null,
|
|
258076
|
-
|
|
258077
|
-
|
|
258190
|
+
activePath,
|
|
258191
|
+
lastIndex >= 0 ? ((_b = markerTitlesRef.current) == null ? void 0 : _b[lastIndex]) ?? null : null,
|
|
258192
|
+
calloutOpacity,
|
|
258193
|
+
nameRevealChars,
|
|
258194
|
+
titleRevealChars
|
|
258078
258195
|
);
|
|
258079
258196
|
g2.setAttribute("opacity", "1");
|
|
258080
258197
|
},
|
|
@@ -258089,13 +258206,28 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
258089
258206
|
fontFamily,
|
|
258090
258207
|
calloutFontSize,
|
|
258091
258208
|
calloutFontWeight,
|
|
258209
|
+
calloutBodyFontWeight,
|
|
258092
258210
|
calloutLineDy,
|
|
258211
|
+
calloutLineDyPx,
|
|
258093
258212
|
surfaceColor,
|
|
258094
258213
|
filenameColor,
|
|
258095
258214
|
dirColor
|
|
258096
258215
|
]
|
|
258097
258216
|
);
|
|
258098
258217
|
React.useImperativeHandle(ref, () => ({ onCameraFrame }), [onCameraFrame]);
|
|
258218
|
+
const handleCalloutEnter = React.useCallback(() => {
|
|
258219
|
+
if (hoverFrozenElapsedRef.current !== null) return;
|
|
258220
|
+
const period = periodRef.current;
|
|
258221
|
+
if (period <= 0) return;
|
|
258222
|
+
const now2 = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
258223
|
+
hoverFrozenElapsedRef.current = (now2 - animStartTsRef.current) % period;
|
|
258224
|
+
}, []);
|
|
258225
|
+
const handleCalloutLeave = React.useCallback(() => {
|
|
258226
|
+
if (hoverFrozenElapsedRef.current === null) return;
|
|
258227
|
+
const now2 = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
258228
|
+
animStartTsRef.current = now2 - hoverFrozenElapsedRef.current;
|
|
258229
|
+
hoverFrozenElapsedRef.current = null;
|
|
258230
|
+
}, []);
|
|
258099
258231
|
return /* @__PURE__ */ jsxs(
|
|
258100
258232
|
"svg",
|
|
258101
258233
|
{
|
|
@@ -258113,8 +258245,26 @@ const TrailFilePath = React.forwardRef(function TrailFilePath2({
|
|
|
258113
258245
|
children: [
|
|
258114
258246
|
/* @__PURE__ */ jsx("g", { ref: groupRef, opacity: 0 }),
|
|
258115
258247
|
/* @__PURE__ */ jsx("circle", { ref: leadDotRef, opacity: 0, pointerEvents: "none" }),
|
|
258116
|
-
/* @__PURE__ */ jsx(
|
|
258117
|
-
|
|
258248
|
+
/* @__PURE__ */ jsx(
|
|
258249
|
+
"rect",
|
|
258250
|
+
{
|
|
258251
|
+
ref: calloutBgRef,
|
|
258252
|
+
opacity: 0,
|
|
258253
|
+
pointerEvents: "auto",
|
|
258254
|
+
onMouseEnter: handleCalloutEnter,
|
|
258255
|
+
onMouseLeave: handleCalloutLeave
|
|
258256
|
+
}
|
|
258257
|
+
),
|
|
258258
|
+
/* @__PURE__ */ jsx(
|
|
258259
|
+
"text",
|
|
258260
|
+
{
|
|
258261
|
+
ref: calloutTextRef,
|
|
258262
|
+
opacity: 0,
|
|
258263
|
+
pointerEvents: "auto",
|
|
258264
|
+
onMouseEnter: handleCalloutEnter,
|
|
258265
|
+
onMouseLeave: handleCalloutLeave
|
|
258266
|
+
}
|
|
258267
|
+
)
|
|
258118
258268
|
]
|
|
258119
258269
|
}
|
|
258120
258270
|
);
|
|
@@ -258126,6 +258276,7 @@ const RESIZE_HANDLE_WIDTH = 6;
|
|
|
258126
258276
|
const TrailMarkdownOverlay = ({
|
|
258127
258277
|
eyebrow,
|
|
258128
258278
|
title,
|
|
258279
|
+
subtitle,
|
|
258129
258280
|
markdown: markdown2,
|
|
258130
258281
|
slideIdPrefix,
|
|
258131
258282
|
bottomOffset,
|
|
@@ -258233,7 +258384,7 @@ const TrailMarkdownOverlay = ({
|
|
|
258233
258384
|
to { transform: translateX(0); }
|
|
258234
258385
|
}
|
|
258235
258386
|
` }),
|
|
258236
|
-
eyebrow || title ? /* @__PURE__ */ jsxs(
|
|
258387
|
+
eyebrow || title || subtitle ? /* @__PURE__ */ jsxs(
|
|
258237
258388
|
"div",
|
|
258238
258389
|
{
|
|
258239
258390
|
style: {
|
|
@@ -258272,6 +258423,22 @@ const TrailMarkdownOverlay = ({
|
|
|
258272
258423
|
title,
|
|
258273
258424
|
children: title
|
|
258274
258425
|
}
|
|
258426
|
+
) : null,
|
|
258427
|
+
subtitle ? /* @__PURE__ */ jsx(
|
|
258428
|
+
"span",
|
|
258429
|
+
{
|
|
258430
|
+
style: {
|
|
258431
|
+
fontSize: theme2.fontSizes[0],
|
|
258432
|
+
color: theme2.colors.textSecondary,
|
|
258433
|
+
fontFamily: theme2.fonts.monospace,
|
|
258434
|
+
overflow: "hidden",
|
|
258435
|
+
textOverflow: "ellipsis",
|
|
258436
|
+
whiteSpace: "nowrap",
|
|
258437
|
+
marginTop: 2
|
|
258438
|
+
},
|
|
258439
|
+
title: subtitle,
|
|
258440
|
+
children: subtitle
|
|
258441
|
+
}
|
|
258275
258442
|
) : null
|
|
258276
258443
|
]
|
|
258277
258444
|
}
|
|
@@ -258675,32 +258842,15 @@ const TrailSnippetView = ({
|
|
|
258675
258842
|
if (!fileObject || !slice) {
|
|
258676
258843
|
return /* @__PURE__ */ jsx("div", { style: { padding: 16, color: theme2.colors.textSecondary }, children: "Loading…" });
|
|
258677
258844
|
}
|
|
258678
|
-
|
|
258679
|
-
|
|
258680
|
-
|
|
258681
|
-
|
|
258682
|
-
|
|
258683
|
-
|
|
258684
|
-
|
|
258685
|
-
|
|
258686
|
-
|
|
258687
|
-
color: theme2.colors.textSecondary,
|
|
258688
|
-
letterSpacing: 0.4,
|
|
258689
|
-
textTransform: "uppercase"
|
|
258690
|
-
},
|
|
258691
|
-
children: rangeLabel
|
|
258692
|
-
}
|
|
258693
|
-
),
|
|
258694
|
-
/* @__PURE__ */ jsx(
|
|
258695
|
-
File$2,
|
|
258696
|
-
{
|
|
258697
|
-
file: fileObject,
|
|
258698
|
-
options,
|
|
258699
|
-
selectedLines: slice.focusOffset != null ? { start: slice.focusOffset, end: slice.focusOffset } : void 0,
|
|
258700
|
-
style: pierreStyle$1
|
|
258701
|
-
}
|
|
258702
|
-
)
|
|
258703
|
-
] });
|
|
258845
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", minHeight: 0 }, children: /* @__PURE__ */ jsx(
|
|
258846
|
+
File$2,
|
|
258847
|
+
{
|
|
258848
|
+
file: fileObject,
|
|
258849
|
+
options,
|
|
258850
|
+
selectedLines: slice.focusOffset != null ? { start: slice.focusOffset, end: slice.focusOffset } : void 0,
|
|
258851
|
+
style: pierreStyle$1
|
|
258852
|
+
}
|
|
258853
|
+
) });
|
|
258704
258854
|
};
|
|
258705
258855
|
const buildBackgroundCSS = (color2) => `
|
|
258706
258856
|
:host {
|
|
@@ -258825,40 +258975,23 @@ const TrailDiffSnippetView = ({
|
|
|
258825
258975
|
if (!fileDiff) {
|
|
258826
258976
|
return /* @__PURE__ */ jsx("div", { style: { padding: 16, color: theme2.colors.error }, children: "Failed to compute diff" });
|
|
258827
258977
|
}
|
|
258828
|
-
|
|
258829
|
-
|
|
258830
|
-
|
|
258831
|
-
|
|
258832
|
-
{
|
|
258833
|
-
|
|
258834
|
-
|
|
258835
|
-
|
|
258836
|
-
|
|
258837
|
-
|
|
258838
|
-
|
|
258839
|
-
|
|
258840
|
-
|
|
258841
|
-
|
|
258842
|
-
}
|
|
258843
|
-
|
|
258844
|
-
|
|
258845
|
-
FileDiff$2,
|
|
258846
|
-
{
|
|
258847
|
-
fileDiff,
|
|
258848
|
-
options: { ...pierreOptionsBase, diffStyle },
|
|
258849
|
-
selectedLines: slice.focusOffset != null ? { start: slice.focusOffset, end: slice.focusOffset } : void 0,
|
|
258850
|
-
style: background ? {
|
|
258851
|
-
...pierreStyle,
|
|
258852
|
-
// Pierre derives addition/deletion/context surfaces by
|
|
258853
|
-
// `color-mix`ing from --diffs-bg, which is keyed off
|
|
258854
|
-
// --diffs-light-bg / --diffs-dark-bg. Overriding the
|
|
258855
|
-
// source variables recolors the whole palette coherently.
|
|
258856
|
-
["--diffs-light-bg"]: background,
|
|
258857
|
-
["--diffs-dark-bg"]: background
|
|
258858
|
-
} : pierreStyle
|
|
258859
|
-
}
|
|
258860
|
-
)
|
|
258861
|
-
] });
|
|
258978
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", minHeight: 0 }, children: /* @__PURE__ */ jsx(
|
|
258979
|
+
FileDiff$2,
|
|
258980
|
+
{
|
|
258981
|
+
fileDiff,
|
|
258982
|
+
options: { ...pierreOptionsBase, diffStyle },
|
|
258983
|
+
selectedLines: slice.focusOffset != null ? { start: slice.focusOffset, end: slice.focusOffset } : void 0,
|
|
258984
|
+
style: background ? {
|
|
258985
|
+
...pierreStyle,
|
|
258986
|
+
// Pierre derives addition/deletion/context surfaces by
|
|
258987
|
+
// `color-mix`ing from --diffs-bg, which is keyed off
|
|
258988
|
+
// --diffs-light-bg / --diffs-dark-bg. Overriding the
|
|
258989
|
+
// source variables recolors the whole palette coherently.
|
|
258990
|
+
["--diffs-light-bg"]: background,
|
|
258991
|
+
["--diffs-dark-bg"]: background
|
|
258992
|
+
} : pierreStyle
|
|
258993
|
+
}
|
|
258994
|
+
) });
|
|
258862
258995
|
};
|
|
258863
258996
|
const pierreOptionsBase = {
|
|
258864
258997
|
disableFileHeader: true
|
|
@@ -258867,10 +259000,11 @@ const pierreStyle = {
|
|
|
258867
259000
|
display: "block"
|
|
258868
259001
|
};
|
|
258869
259002
|
const SEQUENCE_DRAWER_HEIGHT_PCT = 45;
|
|
258870
|
-
const
|
|
259003
|
+
const SNIPPET_PANE_RIGHT_GUTTER_PX = 16;
|
|
259004
|
+
const SNIPPET_PANE_LEADER_BUFFER_PX = 60;
|
|
258871
259005
|
const PANEL_TRANSITION_MS = 280;
|
|
258872
259006
|
const THREE_D_TOGGLE_DISABLED = true;
|
|
258873
|
-
const FileCityTrailExplorerPanel = ({ context, actions }) => {
|
|
259007
|
+
const FileCityTrailExplorerPanel = ({ context, actions, defaultViewMode, defaultShowSequenceDrawer }) => {
|
|
258874
259008
|
var _a;
|
|
258875
259009
|
const tree = context.fileTree.data;
|
|
258876
259010
|
const lineCounts = ((_a = context.lineCounts.data) == null ? void 0 : _a.lineCounts) ?? null;
|
|
@@ -258926,7 +259060,9 @@ const FileCityTrailExplorerPanel = ({ context, actions }) => {
|
|
|
258926
259060
|
onSelectMarker: setSelectedMarkerId,
|
|
258927
259061
|
cityData,
|
|
258928
259062
|
hasLineCounts: lineCounts != null && Object.keys(lineCounts).length > 0,
|
|
258929
|
-
readFile: actions.readFile
|
|
259063
|
+
readFile: actions.readFile,
|
|
259064
|
+
defaultViewMode,
|
|
259065
|
+
defaultShowSequenceDrawer
|
|
258930
259066
|
}
|
|
258931
259067
|
);
|
|
258932
259068
|
};
|
|
@@ -258938,7 +259074,9 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258938
259074
|
onSelectMarker,
|
|
258939
259075
|
cityData,
|
|
258940
259076
|
hasLineCounts,
|
|
258941
|
-
readFile
|
|
259077
|
+
readFile,
|
|
259078
|
+
defaultViewMode = "city",
|
|
259079
|
+
defaultShowSequenceDrawer = true
|
|
258942
259080
|
}) => {
|
|
258943
259081
|
var _a, _b;
|
|
258944
259082
|
const { theme: theme2 } = useTheme();
|
|
@@ -258949,8 +259087,12 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258949
259087
|
return;
|
|
258950
259088
|
}, [hasLineCounts]);
|
|
258951
259089
|
const effectiveShow3D = false;
|
|
258952
|
-
const [viewMode, setViewMode] = React.useState(
|
|
258953
|
-
|
|
259090
|
+
const [viewMode, setViewMode] = React.useState(
|
|
259091
|
+
defaultViewMode
|
|
259092
|
+
);
|
|
259093
|
+
const [showSequenceDrawer, setShowSequenceDrawer] = React.useState(
|
|
259094
|
+
defaultShowSequenceDrawer
|
|
259095
|
+
);
|
|
258954
259096
|
const [drawerHeightOverridePct, setDrawerHeightOverridePct] = React.useState(null);
|
|
258955
259097
|
const [isResizingDrawer, setIsResizingDrawer] = React.useState(false);
|
|
258956
259098
|
const drawerHeightPct = !showSequenceDrawer ? 0 : drawerHeightOverridePct ?? SEQUENCE_DRAWER_HEIGHT_PCT;
|
|
@@ -258958,20 +259100,24 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258958
259100
|
if (!selectedMarkerId) return null;
|
|
258959
259101
|
return trail2.markers.find((m) => m.id === selectedMarkerId) ?? null;
|
|
258960
259102
|
}, [trail2.markers, selectedMarkerId]);
|
|
258961
|
-
const
|
|
259103
|
+
const markerByBuildingPath = React.useMemo(() => {
|
|
258962
259104
|
const map2 = /* @__PURE__ */ new Map();
|
|
259105
|
+
if (!cityData) return map2;
|
|
258963
259106
|
for (const m of markersForThisRepo) {
|
|
258964
|
-
|
|
259107
|
+
const cityPath = markerCityPath(m, trail2);
|
|
259108
|
+
if (!cityPath) continue;
|
|
259109
|
+
const b = cityData.buildings.find((cb) => cb.path === cityPath) ?? cityData.buildings.find((cb) => cb.path.endsWith(`/${cityPath}`));
|
|
259110
|
+
if (b) map2.set(b.path, m);
|
|
258965
259111
|
}
|
|
258966
259112
|
return map2;
|
|
258967
|
-
}, [markersForThisRepo]);
|
|
259113
|
+
}, [markersForThisRepo, cityData, trail2]);
|
|
258968
259114
|
const handleBuildingClick = React.useCallback(
|
|
258969
259115
|
(building) => {
|
|
258970
|
-
const marker =
|
|
259116
|
+
const marker = markerByBuildingPath.get(building.path);
|
|
258971
259117
|
if (!marker) return;
|
|
258972
259118
|
onSelectMarker(selectedMarkerId === marker.id ? null : marker.id);
|
|
258973
259119
|
},
|
|
258974
|
-
[
|
|
259120
|
+
[markerByBuildingPath, selectedMarkerId, onSelectMarker]
|
|
258975
259121
|
);
|
|
258976
259122
|
const stepperIndex = React.useMemo(() => {
|
|
258977
259123
|
if (!selectedMarkerId) return -1;
|
|
@@ -259007,37 +259153,39 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259007
259153
|
const firstMarkerByPath = /* @__PURE__ */ new Map();
|
|
259008
259154
|
const order2 = [];
|
|
259009
259155
|
for (const m of markersForThisRepo) {
|
|
259010
|
-
|
|
259011
|
-
|
|
259012
|
-
counts.
|
|
259013
|
-
|
|
259014
|
-
|
|
259015
|
-
|
|
259016
|
-
|
|
259017
|
-
|
|
259018
|
-
|
|
259019
|
-
|
|
259020
|
-
|
|
259021
|
-
|
|
259156
|
+
const cityPath = markerCityPath(m, trail2);
|
|
259157
|
+
if (!cityPath) continue;
|
|
259158
|
+
const existing = counts.get(cityPath) ?? 0;
|
|
259159
|
+
counts.set(cityPath, existing + 1);
|
|
259160
|
+
if (!firstMarkerByPath.has(cityPath)) {
|
|
259161
|
+
firstMarkerByPath.set(cityPath, m.id);
|
|
259162
|
+
order2.push(cityPath);
|
|
259163
|
+
}
|
|
259164
|
+
}
|
|
259165
|
+
const selectedCityPath = selectedMarker ? markerCityPath(selectedMarker, trail2) : null;
|
|
259166
|
+
return order2.map((cityPath) => ({
|
|
259167
|
+
sourcePath: cityPath,
|
|
259168
|
+
markerCount: counts.get(cityPath) ?? 0,
|
|
259169
|
+
isActive: selectedCityPath === cityPath,
|
|
259022
259170
|
onClick: () => {
|
|
259023
|
-
const markerId = firstMarkerByPath.get(
|
|
259171
|
+
const markerId = firstMarkerByPath.get(cityPath);
|
|
259024
259172
|
if (markerId) onSelectMarker(markerId);
|
|
259025
259173
|
},
|
|
259026
259174
|
onHoverChange: setHoveredFilePath
|
|
259027
259175
|
}));
|
|
259028
|
-
}, [markersForThisRepo, selectedMarker, onSelectMarker]);
|
|
259176
|
+
}, [markersForThisRepo, selectedMarker, onSelectMarker, trail2]);
|
|
259029
259177
|
const trailFilesHighlightLayers = React.useMemo(() => {
|
|
259030
259178
|
if (!cityData) return null;
|
|
259031
|
-
const
|
|
259032
|
-
if (
|
|
259179
|
+
const cityPaths = markersForThisRepo.map((m) => markerCityPath(m, trail2)).filter((p2) => typeof p2 === "string" && p2.length > 0);
|
|
259180
|
+
if (cityPaths.length === 0) return null;
|
|
259033
259181
|
const buildingByPath = new Map(cityData.buildings.map((b) => [b.path, b]));
|
|
259034
259182
|
const byColor = /* @__PURE__ */ new Map();
|
|
259035
259183
|
const seen = /* @__PURE__ */ new Set();
|
|
259036
|
-
for (const
|
|
259037
|
-
if (seen.has(
|
|
259038
|
-
const building = buildingByPath.get(
|
|
259184
|
+
for (const cityPath of cityPaths) {
|
|
259185
|
+
if (seen.has(cityPath)) continue;
|
|
259186
|
+
const building = buildingByPath.get(cityPath) ?? cityData.buildings.find((b) => b.path.endsWith(`/${cityPath}`));
|
|
259039
259187
|
if (!building) continue;
|
|
259040
|
-
seen.add(
|
|
259188
|
+
seen.add(cityPath);
|
|
259041
259189
|
const color2 = building.color ?? getFileColor(building.path);
|
|
259042
259190
|
if (!color2) continue;
|
|
259043
259191
|
const list2 = byColor.get(color2) ?? [];
|
|
@@ -259059,7 +259207,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259059
259207
|
renderStrategy: "fill"
|
|
259060
259208
|
}))
|
|
259061
259209
|
}));
|
|
259062
|
-
}, [markersForThisRepo, cityData]);
|
|
259210
|
+
}, [markersForThisRepo, cityData, trail2]);
|
|
259063
259211
|
const trailFilesActive = trailFilesHighlightLayers !== null && trailFilesHighlightLayers.length > 0;
|
|
259064
259212
|
const hoveredFileHighlightLayer = React.useMemo(() => {
|
|
259065
259213
|
if (!hoveredFilePath || !cityData) return null;
|
|
@@ -259084,12 +259232,49 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259084
259232
|
]
|
|
259085
259233
|
};
|
|
259086
259234
|
}, [hoveredFilePath, cityData, theme2.colors.accent]);
|
|
259235
|
+
const districtTintLayers = React.useMemo(() => {
|
|
259236
|
+
if (!cityData) return null;
|
|
259237
|
+
const repos = trail2.repos ?? [];
|
|
259238
|
+
if (repos.length <= 1) return null;
|
|
259239
|
+
const palette = ["#3b82f6", "#a855f7", "#f97316", "#10b981", "#eab308"];
|
|
259240
|
+
const layers = [];
|
|
259241
|
+
repos.forEach((repo, i) => {
|
|
259242
|
+
const prefix = `${repo.name}/`;
|
|
259243
|
+
const paths = [];
|
|
259244
|
+
for (const b of cityData.buildings) {
|
|
259245
|
+
if (b.path === repo.name || b.path.startsWith(prefix)) {
|
|
259246
|
+
paths.push(b.path);
|
|
259247
|
+
} else if (b.path.includes(`/${prefix}`)) {
|
|
259248
|
+
paths.push(b.path);
|
|
259249
|
+
}
|
|
259250
|
+
}
|
|
259251
|
+
if (paths.length === 0) return;
|
|
259252
|
+
layers.push({
|
|
259253
|
+
// The layer-system id is internal — using the PURL here is fine
|
|
259254
|
+
// (and uniquely scopes by canonical identity even if two repos
|
|
259255
|
+
// happened to share a `name`).
|
|
259256
|
+
id: `district-${repo.id}`,
|
|
259257
|
+
name: `District: ${repo.name}`,
|
|
259258
|
+
enabled: true,
|
|
259259
|
+
color: palette[i % palette.length],
|
|
259260
|
+
opacity: 0.18,
|
|
259261
|
+
priority: 10,
|
|
259262
|
+
items: paths.map((path2) => ({
|
|
259263
|
+
path: path2,
|
|
259264
|
+
type: "file",
|
|
259265
|
+
renderStrategy: "fill"
|
|
259266
|
+
}))
|
|
259267
|
+
});
|
|
259268
|
+
});
|
|
259269
|
+
return layers.length > 0 ? layers : null;
|
|
259270
|
+
}, [cityData, trail2.repos]);
|
|
259087
259271
|
const cityHighlightLayers = React.useMemo(() => {
|
|
259088
259272
|
const layers = [];
|
|
259273
|
+
if (districtTintLayers) layers.push(...districtTintLayers);
|
|
259089
259274
|
if (trailFilesHighlightLayers) layers.push(...trailFilesHighlightLayers);
|
|
259090
259275
|
if (hoveredFileHighlightLayer) layers.push(hoveredFileHighlightLayer);
|
|
259091
259276
|
return layers.length > 0 ? layers : void 0;
|
|
259092
|
-
}, [trailFilesHighlightLayers, hoveredFileHighlightLayer]);
|
|
259277
|
+
}, [districtTintLayers, trailFilesHighlightLayers, hoveredFileHighlightLayer]);
|
|
259093
259278
|
const containerRef = React.useRef(null);
|
|
259094
259279
|
const snippetPaneRef = React.useRef(null);
|
|
259095
259280
|
const leaderLineRef = React.useRef(null);
|
|
@@ -259106,10 +259291,11 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259106
259291
|
const [snippetPaneWidth, setSnippetPaneWidth] = React.useState(null);
|
|
259107
259292
|
const [containerSize, setContainerSize] = React.useState(null);
|
|
259108
259293
|
const selectedBuilding = React.useMemo(() => {
|
|
259109
|
-
if (!cityData || !
|
|
259110
|
-
const path2 = selectedMarker
|
|
259294
|
+
if (!cityData || !selectedMarker) return null;
|
|
259295
|
+
const path2 = markerCityPath(selectedMarker, trail2);
|
|
259296
|
+
if (!path2) return null;
|
|
259111
259297
|
return cityData.buildings.find((b) => b.path === path2) ?? cityData.buildings.find((b) => b.path.endsWith(`/${path2}`)) ?? null;
|
|
259112
|
-
}, [cityData, selectedMarker]);
|
|
259298
|
+
}, [cityData, selectedMarker, trail2]);
|
|
259113
259299
|
const cityCenter = React.useMemo(() => {
|
|
259114
259300
|
if (!cityData) return null;
|
|
259115
259301
|
return {
|
|
@@ -259117,17 +259303,42 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259117
259303
|
z: (cityData.bounds.minZ + cityData.bounds.maxZ) / 2
|
|
259118
259304
|
};
|
|
259119
259305
|
}, [cityData]);
|
|
259120
|
-
const trailPathBuildings = React.useMemo(() => {
|
|
259121
|
-
|
|
259122
|
-
|
|
259123
|
-
|
|
259306
|
+
const { trailPathBuildings, trailPathTitles, trailPathMarkerIds } = React.useMemo(() => {
|
|
259307
|
+
var _a2;
|
|
259308
|
+
if (!cityData || markersForThisRepo.length === 0) {
|
|
259309
|
+
return {
|
|
259310
|
+
trailPathBuildings: [],
|
|
259311
|
+
trailPathTitles: [],
|
|
259312
|
+
trailPathMarkerIds: []
|
|
259313
|
+
};
|
|
259314
|
+
}
|
|
259315
|
+
const buildingByPath = new Map(
|
|
259316
|
+
cityData.buildings.map((b) => [b.path, b])
|
|
259317
|
+
);
|
|
259318
|
+
const buildings = [];
|
|
259319
|
+
const titles = [];
|
|
259320
|
+
const markerIds = [];
|
|
259124
259321
|
for (const m of markersForThisRepo) {
|
|
259125
|
-
|
|
259126
|
-
|
|
259127
|
-
|
|
259322
|
+
const cityPath = markerCityPath(m, trail2);
|
|
259323
|
+
if (!cityPath) continue;
|
|
259324
|
+
const b = buildingByPath.get(cityPath) ?? cityData.buildings.find((cb) => cb.path.endsWith(`/${cityPath}`));
|
|
259325
|
+
if (b) {
|
|
259326
|
+
buildings.push(b);
|
|
259327
|
+
titles.push(((_a2 = m.label) == null ? void 0 : _a2.trim()) || null);
|
|
259328
|
+
markerIds.push(m.id);
|
|
259329
|
+
}
|
|
259128
259330
|
}
|
|
259129
|
-
return
|
|
259130
|
-
|
|
259331
|
+
return {
|
|
259332
|
+
trailPathBuildings: buildings,
|
|
259333
|
+
trailPathTitles: titles,
|
|
259334
|
+
trailPathMarkerIds: markerIds
|
|
259335
|
+
};
|
|
259336
|
+
}, [cityData, markersForThisRepo, trail2]);
|
|
259337
|
+
const trailPathCurrentStepIndex = React.useMemo(() => {
|
|
259338
|
+
if (!selectedMarkerId) return null;
|
|
259339
|
+
const idx = trailPathMarkerIds.indexOf(selectedMarkerId);
|
|
259340
|
+
return idx >= 0 ? idx : null;
|
|
259341
|
+
}, [selectedMarkerId, trailPathMarkerIds]);
|
|
259131
259342
|
const onCameraFrame = React.useCallback(
|
|
259132
259343
|
(camera, size) => {
|
|
259133
259344
|
var _a2, _b2;
|
|
@@ -259172,13 +259383,18 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259172
259383
|
return () => observer.disconnect();
|
|
259173
259384
|
}, [snippetPaneEl]);
|
|
259174
259385
|
const overlayMarkdown = ((_a = selectedMarker == null ? void 0 : selectedMarker.description) == null ? void 0 : _a.trim()) ? {
|
|
259175
|
-
eyebrow:
|
|
259386
|
+
eyebrow: null,
|
|
259176
259387
|
title: selectedMarker.label ?? selectedMarker.id,
|
|
259388
|
+
// File path under the title — the panel header already names
|
|
259389
|
+
// the trail, so swapping the "Marker" eyebrow for the marker's
|
|
259390
|
+
// sourcePath gives the user the more useful piece of context.
|
|
259391
|
+
subtitle: selectedMarker.sourcePath ?? null,
|
|
259177
259392
|
markdown: selectedMarker.description,
|
|
259178
259393
|
slideIdPrefix: `trail-${trail2.id}-marker-${selectedMarker.id}`
|
|
259179
259394
|
} : ((_b = trail2.summary) == null ? void 0 : _b.trim()) ? {
|
|
259180
259395
|
eyebrow: null,
|
|
259181
259396
|
title: null,
|
|
259397
|
+
subtitle: null,
|
|
259182
259398
|
markdown: trail2.summary,
|
|
259183
259399
|
slideIdPrefix: `trail-${trail2.id}-summary`
|
|
259184
259400
|
} : null;
|
|
@@ -259262,6 +259478,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259262
259478
|
{
|
|
259263
259479
|
trail: trail2,
|
|
259264
259480
|
markerCount: markersForThisRepo.length,
|
|
259481
|
+
activeMarkerIndex: stepperIndex,
|
|
259265
259482
|
show3D: effectiveShow3D,
|
|
259266
259483
|
onToggle3D: () => setShow3D((v) => !v),
|
|
259267
259484
|
hideToggle: THREE_D_TOGGLE_DISABLED,
|
|
@@ -259274,13 +259491,16 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259274
259491
|
// Drawer-open is the default start state, so it no longer
|
|
259275
259492
|
// counts as "non-idle". Exit is offered only when the user
|
|
259276
259493
|
// has drilled into something the start view doesn't show.
|
|
259277
|
-
|
|
259494
|
+
// The "idle" view-mode is the host-supplied default — when
|
|
259495
|
+
// the host opens the panel in 'doc', staying in 'doc' is
|
|
259496
|
+
// idle and switching to 'city' is the non-idle drill-in.
|
|
259497
|
+
selectedMarkerId != null || snippetExpanded || viewMode !== defaultViewMode
|
|
259278
259498
|
),
|
|
259279
259499
|
onExitTrail: () => {
|
|
259280
259500
|
onSelectMarker(null);
|
|
259281
259501
|
setDrawerHeightOverridePct(null);
|
|
259282
259502
|
setSnippetExpanded(false);
|
|
259283
|
-
setViewMode(
|
|
259503
|
+
setViewMode(defaultViewMode);
|
|
259284
259504
|
},
|
|
259285
259505
|
viewMode,
|
|
259286
259506
|
onSetViewMode: setViewMode
|
|
@@ -259312,7 +259532,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259312
259532
|
cityData,
|
|
259313
259533
|
width: "100%",
|
|
259314
259534
|
height: "100%",
|
|
259315
|
-
selectedPath:
|
|
259535
|
+
selectedPath: selectedMarker ? markerCityPath(selectedMarker, trail2) : null,
|
|
259316
259536
|
onBuildingClick: handleBuildingClick,
|
|
259317
259537
|
onCameraFrame,
|
|
259318
259538
|
showControls: false,
|
|
@@ -259329,6 +259549,8 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259329
259549
|
ref: filePathRef,
|
|
259330
259550
|
containerRef,
|
|
259331
259551
|
buildings: trailPathBuildings,
|
|
259552
|
+
markerTitles: trailPathTitles,
|
|
259553
|
+
currentStepIndex: trailPathCurrentStepIndex,
|
|
259332
259554
|
cityCenter
|
|
259333
259555
|
}
|
|
259334
259556
|
),
|
|
@@ -259347,6 +259569,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259347
259569
|
{
|
|
259348
259570
|
eyebrow: overlayMarkdown.eyebrow,
|
|
259349
259571
|
title: overlayMarkdown.title,
|
|
259572
|
+
subtitle: overlayMarkdown.subtitle,
|
|
259350
259573
|
markdown: overlayMarkdown.markdown,
|
|
259351
259574
|
slideIdPrefix: overlayMarkdown.slideIdPrefix,
|
|
259352
259575
|
bottomOffset: `${drawerHeightPct}%`,
|
|
@@ -259388,7 +259611,8 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259388
259611
|
drawerHeightPct,
|
|
259389
259612
|
disableBottomTransition: isResizingDrawer,
|
|
259390
259613
|
expanded: snippetExpanded,
|
|
259391
|
-
onToggleExpanded: () => setSnippetExpanded((v) => !v)
|
|
259614
|
+
onToggleExpanded: () => setSnippetExpanded((v) => !v),
|
|
259615
|
+
markdownOverlayWidth
|
|
259392
259616
|
}
|
|
259393
259617
|
) : null
|
|
259394
259618
|
]
|
|
@@ -259555,7 +259779,8 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259555
259779
|
drawerHeightPct,
|
|
259556
259780
|
disableBottomTransition,
|
|
259557
259781
|
expanded,
|
|
259558
|
-
onToggleExpanded
|
|
259782
|
+
onToggleExpanded,
|
|
259783
|
+
markdownOverlayWidth
|
|
259559
259784
|
}, ref) {
|
|
259560
259785
|
const { theme: theme2 } = useTheme();
|
|
259561
259786
|
if (!marker.sourcePath) {
|
|
@@ -259569,6 +259794,7 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259569
259794
|
disableBottomTransition,
|
|
259570
259795
|
expanded,
|
|
259571
259796
|
onToggleExpanded,
|
|
259797
|
+
markdownOverlayWidth,
|
|
259572
259798
|
children: /* @__PURE__ */ jsx(
|
|
259573
259799
|
"div",
|
|
259574
259800
|
{
|
|
@@ -259594,6 +259820,7 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259594
259820
|
disableBottomTransition,
|
|
259595
259821
|
expanded,
|
|
259596
259822
|
onToggleExpanded,
|
|
259823
|
+
markdownOverlayWidth,
|
|
259597
259824
|
children: snippet2.kind === "slice" ? /* @__PURE__ */ jsx(
|
|
259598
259825
|
TrailSnippetView,
|
|
259599
259826
|
{
|
|
@@ -259635,10 +259862,12 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259635
259862
|
drawerHeightPct,
|
|
259636
259863
|
disableBottomTransition,
|
|
259637
259864
|
expanded,
|
|
259638
|
-
onToggleExpanded
|
|
259865
|
+
onToggleExpanded,
|
|
259866
|
+
markdownOverlayWidth
|
|
259639
259867
|
}, ref) {
|
|
259640
259868
|
const { theme: theme2 } = useTheme();
|
|
259641
259869
|
const [widthPx, setWidthPx] = React.useState(null);
|
|
259870
|
+
const defaultLeftInset = (markdownOverlayWidth ?? 0) + SNIPPET_PANE_LEADER_BUFFER_PX;
|
|
259642
259871
|
const [isResizing, setIsResizing] = React.useState(false);
|
|
259643
259872
|
const innerRef = React.useRef(null);
|
|
259644
259873
|
const setInnerRef = React.useCallback(
|
|
@@ -259677,7 +259906,7 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259677
259906
|
const parentWidth = (parent == null ? void 0 : parent.clientWidth) ?? window.innerWidth;
|
|
259678
259907
|
const maxWidth = Math.max(
|
|
259679
259908
|
SNIPPET_PANE_MIN_WIDTH_PX,
|
|
259680
|
-
parentWidth -
|
|
259909
|
+
parentWidth - defaultLeftInset - SNIPPET_PANE_RIGHT_GUTTER_PX
|
|
259681
259910
|
);
|
|
259682
259911
|
const dx = e.clientX - drag2.startX;
|
|
259683
259912
|
const next2 = Math.min(
|
|
@@ -259686,7 +259915,7 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259686
259915
|
);
|
|
259687
259916
|
setWidthPx(next2);
|
|
259688
259917
|
},
|
|
259689
|
-
[]
|
|
259918
|
+
[defaultLeftInset]
|
|
259690
259919
|
);
|
|
259691
259920
|
const handleResizePointerUp = React.useCallback(
|
|
259692
259921
|
(e) => {
|
|
@@ -259706,9 +259935,15 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259706
259935
|
style: {
|
|
259707
259936
|
position: "absolute",
|
|
259708
259937
|
top: 16,
|
|
259709
|
-
right:
|
|
259938
|
+
right: SNIPPET_PANE_RIGHT_GUTTER_PX,
|
|
259710
259939
|
bottom: expanded ? `calc(${drawerHeightPct}% + 16px)` : "50%",
|
|
259711
|
-
|
|
259940
|
+
// Auto-fill the right column when the user hasn't dragged an
|
|
259941
|
+
// explicit width: anchor to the markdown overlay's right edge
|
|
259942
|
+
// (plus a leader-line buffer) and the city container's right
|
|
259943
|
+
// gutter. Once `widthPx` is set, switch to an explicit width
|
|
259944
|
+
// and let `right` keep the right anchor.
|
|
259945
|
+
left: widthPx == null ? defaultLeftInset : void 0,
|
|
259946
|
+
width: widthPx ?? void 0,
|
|
259712
259947
|
minWidth: SNIPPET_PANE_MIN_WIDTH_PX,
|
|
259713
259948
|
backgroundColor: theme2.colors.background,
|
|
259714
259949
|
border: `1px solid ${theme2.colors.border}`,
|
|
@@ -259771,33 +260006,77 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259771
260006
|
flexShrink: 0
|
|
259772
260007
|
},
|
|
259773
260008
|
children: [
|
|
259774
|
-
/* @__PURE__ */
|
|
259775
|
-
|
|
259776
|
-
|
|
259777
|
-
|
|
259778
|
-
|
|
259779
|
-
|
|
259780
|
-
|
|
259781
|
-
|
|
259782
|
-
|
|
259783
|
-
|
|
259784
|
-
|
|
259785
|
-
|
|
259786
|
-
|
|
259787
|
-
|
|
259788
|
-
|
|
259789
|
-
|
|
259790
|
-
|
|
259791
|
-
|
|
259792
|
-
|
|
259793
|
-
|
|
259794
|
-
|
|
259795
|
-
|
|
259796
|
-
|
|
259797
|
-
|
|
259798
|
-
|
|
259799
|
-
|
|
259800
|
-
|
|
260009
|
+
/* @__PURE__ */ jsx("div", { style: { minWidth: 0, flex: 1 }, children: (() => {
|
|
260010
|
+
const path2 = marker.sourcePath ?? "";
|
|
260011
|
+
const slashIdx = path2.lastIndexOf("/");
|
|
260012
|
+
const filename = slashIdx >= 0 ? path2.slice(slashIdx + 1) : path2;
|
|
260013
|
+
const directory = slashIdx >= 0 ? path2.slice(0, slashIdx + 1) : null;
|
|
260014
|
+
const snippet2 = marker.snippet;
|
|
260015
|
+
const rangeLabel = snippet2 ? snippet2.startLine === snippet2.endLine ? `${snippet2.startLine}` : `${snippet2.startLine}–${snippet2.endLine}` : null;
|
|
260016
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
260017
|
+
/* @__PURE__ */ jsxs(
|
|
260018
|
+
"div",
|
|
260019
|
+
{
|
|
260020
|
+
style: {
|
|
260021
|
+
display: "flex",
|
|
260022
|
+
alignItems: "baseline",
|
|
260023
|
+
gap: 8,
|
|
260024
|
+
minWidth: 0
|
|
260025
|
+
},
|
|
260026
|
+
children: [
|
|
260027
|
+
/* @__PURE__ */ jsx(
|
|
260028
|
+
"div",
|
|
260029
|
+
{
|
|
260030
|
+
style: {
|
|
260031
|
+
fontFamily: theme2.fonts.monospace,
|
|
260032
|
+
fontSize: theme2.fontSizes[1],
|
|
260033
|
+
fontWeight: theme2.fontWeights.semibold,
|
|
260034
|
+
color: theme2.colors.text,
|
|
260035
|
+
overflow: "hidden",
|
|
260036
|
+
textOverflow: "ellipsis",
|
|
260037
|
+
whiteSpace: "nowrap",
|
|
260038
|
+
minWidth: 0,
|
|
260039
|
+
flexShrink: 1
|
|
260040
|
+
},
|
|
260041
|
+
title: path2 || void 0,
|
|
260042
|
+
children: filename || marker.id
|
|
260043
|
+
}
|
|
260044
|
+
),
|
|
260045
|
+
rangeLabel ? /* @__PURE__ */ jsx(
|
|
260046
|
+
"div",
|
|
260047
|
+
{
|
|
260048
|
+
style: {
|
|
260049
|
+
fontFamily: theme2.fonts.monospace,
|
|
260050
|
+
fontSize: theme2.fontSizes[0],
|
|
260051
|
+
color: theme2.colors.textSecondary,
|
|
260052
|
+
letterSpacing: 0.4,
|
|
260053
|
+
textTransform: "uppercase",
|
|
260054
|
+
flexShrink: 0
|
|
260055
|
+
},
|
|
260056
|
+
children: rangeLabel
|
|
260057
|
+
}
|
|
260058
|
+
) : null
|
|
260059
|
+
]
|
|
260060
|
+
}
|
|
260061
|
+
),
|
|
260062
|
+
directory ? /* @__PURE__ */ jsx(
|
|
260063
|
+
"div",
|
|
260064
|
+
{
|
|
260065
|
+
style: {
|
|
260066
|
+
fontSize: theme2.fontSizes[0],
|
|
260067
|
+
color: theme2.colors.textSecondary,
|
|
260068
|
+
fontFamily: theme2.fonts.monospace,
|
|
260069
|
+
marginTop: 2,
|
|
260070
|
+
overflow: "hidden",
|
|
260071
|
+
textOverflow: "ellipsis",
|
|
260072
|
+
whiteSpace: "nowrap"
|
|
260073
|
+
},
|
|
260074
|
+
title: directory,
|
|
260075
|
+
children: directory
|
|
260076
|
+
}
|
|
260077
|
+
) : null
|
|
260078
|
+
] });
|
|
260079
|
+
})() }),
|
|
259801
260080
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, flexShrink: 0 }, children: [
|
|
259802
260081
|
/* @__PURE__ */ jsx(
|
|
259803
260082
|
"button",
|
|
@@ -260094,6 +260373,7 @@ const TrailDocumentCard = ({
|
|
|
260094
260373
|
const TrailHeader = ({
|
|
260095
260374
|
trail: trail2,
|
|
260096
260375
|
markerCount,
|
|
260376
|
+
activeMarkerIndex,
|
|
260097
260377
|
show3D,
|
|
260098
260378
|
onToggle3D,
|
|
260099
260379
|
hideToggle = false,
|
|
@@ -260173,20 +260453,34 @@ const TrailHeader = ({
|
|
|
260173
260453
|
children: trail2.title
|
|
260174
260454
|
}
|
|
260175
260455
|
),
|
|
260176
|
-
/* @__PURE__ */
|
|
260456
|
+
/* @__PURE__ */ jsx(
|
|
260177
260457
|
"div",
|
|
260178
260458
|
{
|
|
260459
|
+
"aria-label": `${markerCount} marker${markerCount === 1 ? "" : "s"} in this repo`,
|
|
260179
260460
|
style: {
|
|
260180
|
-
|
|
260181
|
-
|
|
260182
|
-
|
|
260461
|
+
display: "flex",
|
|
260462
|
+
alignItems: "center",
|
|
260463
|
+
height: theme2.fontSizes[0]
|
|
260183
260464
|
},
|
|
260184
|
-
children:
|
|
260185
|
-
|
|
260186
|
-
|
|
260187
|
-
|
|
260188
|
-
|
|
260189
|
-
|
|
260465
|
+
children: Array.from({ length: markerCount }).map((_, i) => {
|
|
260466
|
+
const isActive = i === activeMarkerIndex;
|
|
260467
|
+
return /* @__PURE__ */ jsx(
|
|
260468
|
+
"span",
|
|
260469
|
+
{
|
|
260470
|
+
style: {
|
|
260471
|
+
width: 6,
|
|
260472
|
+
height: 6,
|
|
260473
|
+
borderRadius: "50%",
|
|
260474
|
+
background: isActive ? theme2.colors.accent : theme2.colors.textSecondary,
|
|
260475
|
+
// Group dots in fives for at-a-glance countability — a
|
|
260476
|
+
// wider gap before every 5th index (after the first)
|
|
260477
|
+
// creates visual columns of 5 like tally marks.
|
|
260478
|
+
marginLeft: i === 0 ? 0 : i % 5 === 0 ? 11 : 5
|
|
260479
|
+
}
|
|
260480
|
+
},
|
|
260481
|
+
i
|
|
260482
|
+
);
|
|
260483
|
+
})
|
|
260190
260484
|
}
|
|
260191
260485
|
)
|
|
260192
260486
|
]
|
|
@@ -260341,6 +260635,15 @@ function filterMarkersForRepo(trail2, repository) {
|
|
|
260341
260635
|
}
|
|
260342
260636
|
return trail2.markers.filter((m) => m.repo === repository.id);
|
|
260343
260637
|
}
|
|
260638
|
+
function markerCityPath(marker, trail2) {
|
|
260639
|
+
if (!marker.sourcePath) return null;
|
|
260640
|
+
const repos = trail2.repos ?? [];
|
|
260641
|
+
if (repos.length <= 1) return marker.sourcePath;
|
|
260642
|
+
if (!marker.repo) return null;
|
|
260643
|
+
const repo = repos.find((r2) => r2.id === marker.repo);
|
|
260644
|
+
if (!repo) return null;
|
|
260645
|
+
return `${repo.name}/${marker.sourcePath}`;
|
|
260646
|
+
}
|
|
260344
260647
|
const focusBuildingTool = {
|
|
260345
260648
|
name: "focus_building",
|
|
260346
260649
|
description: "Focuses the camera on a specific file (building) in the file city visualization",
|