@elaraai/east-ui-components 1.0.12 → 1.0.14
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/collections/schematic/camera.d.ts +175 -0
- package/dist/collections/schematic/camera.d.ts.map +1 -0
- package/dist/collections/schematic/index.d.ts +2 -0
- package/dist/collections/schematic/index.d.ts.map +1 -1
- package/dist/collections/schematic/paint.d.ts +174 -0
- package/dist/collections/schematic/paint.d.ts.map +1 -0
- package/dist/collections/schematic/theme.d.ts +9 -0
- package/dist/collections/schematic/theme.d.ts.map +1 -0
- package/dist/index.cjs +1030 -247
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1030 -247
- package/dist/index.js.map +1 -1
- package/dist/theme/global-css.d.ts.map +1 -1
- package/dist/theme/slot-recipes/schematic.d.ts +1 -1
- package/dist/theme/slot-recipes/schematic.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1187,8 +1187,13 @@ const globalCss = react.defineGlobalStyles({
|
|
|
1187
1187
|
},
|
|
1188
1188
|
/* ─── Drag & drop stages (drag-drop-visuals) ─────────────────────────
|
|
1189
1189
|
* The DragLayerProvider drives these via data attributes; surfaces get
|
|
1190
|
-
* the treatment for free by registering cells/sinks.
|
|
1191
|
-
|
|
1190
|
+
* the treatment for free by registering cells/sinks.
|
|
1191
|
+
*
|
|
1192
|
+
* Scoped `:not([data-scope])` so it dims only our own drag origins —
|
|
1193
|
+
* Ark/Zag widgets (Slider, etc.) set `data-dragging` on themselves for
|
|
1194
|
+
* their own drag state and carry a `data-scope`; without this exclusion
|
|
1195
|
+
* a slider goes to 40% opacity while its thumb is dragged. */
|
|
1196
|
+
"[data-dragging]:not([data-scope])": {
|
|
1192
1197
|
opacity: "0.4"
|
|
1193
1198
|
},
|
|
1194
1199
|
"[data-drag-ghost]": {
|
|
@@ -3008,9 +3013,13 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3008
3013
|
"root",
|
|
3009
3014
|
"canvas",
|
|
3010
3015
|
"grid",
|
|
3016
|
+
"cardLayer",
|
|
3011
3017
|
"underlay",
|
|
3012
3018
|
"zone",
|
|
3013
3019
|
"zoneLabel",
|
|
3020
|
+
"zoneShapes",
|
|
3021
|
+
"zoneShapeLabel",
|
|
3022
|
+
"footprints",
|
|
3014
3023
|
"item",
|
|
3015
3024
|
"itemHead",
|
|
3016
3025
|
"itemIcon",
|
|
@@ -3082,6 +3091,15 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3082
3091
|
linear-gradient(to right, color-mix(in oklch, {colors.border.subtle} 22%, transparent) 1px, transparent 1px),
|
|
3083
3092
|
linear-gradient(to bottom, color-mix(in oklch, {colors.border.subtle} 22%, transparent) 1px, transparent 1px)`
|
|
3084
3093
|
},
|
|
3094
|
+
/* Holds the live `--cam-ppu` / `--cam-tx` / `--cam-ty` custom
|
|
3095
|
+
* properties (written by applyCamera each frame). Transparent and
|
|
3096
|
+
* click-through; each card re-enables its own pointer events so the
|
|
3097
|
+
* full-cover layer never swallows canvas clicks (issue #57). */
|
|
3098
|
+
cardLayer: {
|
|
3099
|
+
position: "absolute",
|
|
3100
|
+
inset: "0",
|
|
3101
|
+
pointerEvents: "none"
|
|
3102
|
+
},
|
|
3085
3103
|
/* Links draw in pixel space; tone → token mapping lives here so
|
|
3086
3104
|
* data only ever names a tone. */
|
|
3087
3105
|
underlay: {
|
|
@@ -3140,6 +3158,91 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3140
3158
|
paddingX: "{spacing.1}",
|
|
3141
3159
|
whiteSpace: "nowrap"
|
|
3142
3160
|
},
|
|
3161
|
+
/* Shaped zones (polyline / polygon) stroke in SVG so curves and
|
|
3162
|
+
* diagonals aren't confined to a div bounding box. Tone → token
|
|
3163
|
+
* mapping mirrors `underlay`; data only ever names a tone. These
|
|
3164
|
+
* are annotations like the rect zones — no pointer events. */
|
|
3165
|
+
zoneShapes: {
|
|
3166
|
+
position: "absolute",
|
|
3167
|
+
inset: "0",
|
|
3168
|
+
pointerEvents: "none",
|
|
3169
|
+
overflow: "visible",
|
|
3170
|
+
"& g[data-tone=brand]": { "--schematic-tone": "{colors.brand.600}" },
|
|
3171
|
+
"& g[data-tone=ink]": { "--schematic-tone": "{colors.fg}" },
|
|
3172
|
+
"& g[data-tone=muted]": { "--schematic-tone": "{colors.border.strong}" },
|
|
3173
|
+
"& g[data-tone=success]": { "--schematic-tone": "{colors.status.ok}" },
|
|
3174
|
+
"& g[data-tone=warning]": { "--schematic-tone": "{colors.status.warn}" },
|
|
3175
|
+
"& g[data-tone=danger]": { "--schematic-tone": "{colors.status.bad}" },
|
|
3176
|
+
"& path": {
|
|
3177
|
+
stroke: "var(--schematic-tone)",
|
|
3178
|
+
fill: "none",
|
|
3179
|
+
strokeLinejoin: "round"
|
|
3180
|
+
},
|
|
3181
|
+
/* Polygon outline echoes the dashed outline-rect zone. */
|
|
3182
|
+
"& path[data-shape=polygon]": {
|
|
3183
|
+
strokeWidth: "1px",
|
|
3184
|
+
strokeDasharray: "4 3"
|
|
3185
|
+
},
|
|
3186
|
+
/* Polyline is a run / road: a thin centre-line, or a soft band
|
|
3187
|
+
* when a world-space width is set inline. */
|
|
3188
|
+
"& path[data-shape=polyline]": {
|
|
3189
|
+
strokeWidth: "1.5px",
|
|
3190
|
+
strokeLinecap: "round",
|
|
3191
|
+
opacity: "0.55"
|
|
3192
|
+
}
|
|
3193
|
+
},
|
|
3194
|
+
/* Standalone eyebrow for a shaped zone — same look as `zoneLabel`
|
|
3195
|
+
* but positioned at the bbox top-left via inline coords. */
|
|
3196
|
+
zoneShapeLabel: {
|
|
3197
|
+
position: "absolute",
|
|
3198
|
+
transform: "translateY(-50%)",
|
|
3199
|
+
marginLeft: "{spacing.2}",
|
|
3200
|
+
fontFamily: "mono",
|
|
3201
|
+
fontSize: "9px",
|
|
3202
|
+
fontWeight: "600",
|
|
3203
|
+
letterSpacing: "0.14em",
|
|
3204
|
+
lineHeight: "normal",
|
|
3205
|
+
textTransform: "uppercase",
|
|
3206
|
+
color: "fg.muted",
|
|
3207
|
+
background: "bg.panel",
|
|
3208
|
+
paddingX: "{spacing.1}",
|
|
3209
|
+
whiteSpace: "nowrap",
|
|
3210
|
+
pointerEvents: "none"
|
|
3211
|
+
},
|
|
3212
|
+
/* Item footprints — the true shape body at close zoom (semantic
|
|
3213
|
+
* zoom). The path is clickable (selects the item); the card still
|
|
3214
|
+
* renders at the anchor, so no item info is lost. */
|
|
3215
|
+
footprints: {
|
|
3216
|
+
position: "absolute",
|
|
3217
|
+
inset: "0",
|
|
3218
|
+
pointerEvents: "none",
|
|
3219
|
+
overflow: "visible",
|
|
3220
|
+
"& g[data-tone=success]": { "--schematic-tone": "{colors.status.ok}" },
|
|
3221
|
+
"& g[data-tone=warning]": { "--schematic-tone": "{colors.status.warn}" },
|
|
3222
|
+
"& g[data-tone=danger]": { "--schematic-tone": "{colors.status.bad}" },
|
|
3223
|
+
"& g[data-tone=info]": { "--schematic-tone": "{colors.brand.500}" },
|
|
3224
|
+
"& g[data-tone=neutral]": { "--schematic-tone": "{colors.fg.muted}" },
|
|
3225
|
+
"& path": {
|
|
3226
|
+
stroke: "var(--schematic-tone)",
|
|
3227
|
+
strokeWidth: "1.5px",
|
|
3228
|
+
strokeLinejoin: "round",
|
|
3229
|
+
fill: "color-mix(in oklch, var(--schematic-tone) 12%, transparent)",
|
|
3230
|
+
cursor: "pointer",
|
|
3231
|
+
pointerEvents: "visiblePainted",
|
|
3232
|
+
transition: "fill {durations.fast}"
|
|
3233
|
+
},
|
|
3234
|
+
"& path[data-shape=polyline]": {
|
|
3235
|
+
fill: "none",
|
|
3236
|
+
strokeLinecap: "round"
|
|
3237
|
+
},
|
|
3238
|
+
"& g:hover path": {
|
|
3239
|
+
fill: "color-mix(in oklch, var(--schematic-tone) 20%, transparent)"
|
|
3240
|
+
},
|
|
3241
|
+
"& g[data-selected] path": {
|
|
3242
|
+
strokeWidth: "2.5px",
|
|
3243
|
+
fill: "color-mix(in oklch, var(--schematic-tone) 24%, transparent)"
|
|
3244
|
+
}
|
|
3245
|
+
},
|
|
3143
3246
|
/* LOD tiers — constant screen-size markers over scaled geometry.
|
|
3144
3247
|
* Items are the content layer: the darkest marks on the canvas at
|
|
3145
3248
|
* every tier. */
|
|
@@ -3193,6 +3296,7 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3193
3296
|
item: {
|
|
3194
3297
|
position: "absolute",
|
|
3195
3298
|
transform: "translate(-50%, -50%)",
|
|
3299
|
+
pointerEvents: "auto",
|
|
3196
3300
|
display: "flex",
|
|
3197
3301
|
flexDirection: "column",
|
|
3198
3302
|
gap: "2px",
|
|
@@ -3388,14 +3492,24 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3388
3492
|
minHeight: "0",
|
|
3389
3493
|
overflowY: "auto",
|
|
3390
3494
|
paddingBottom: "{spacing.2}",
|
|
3391
|
-
lineHeight: "1.7"
|
|
3392
|
-
|
|
3495
|
+
lineHeight: "1.7",
|
|
3496
|
+
// Row height shared by the sticky zone headers (their stacked `top`
|
|
3497
|
+
// offset is a multiple of this) so an ancestor chain pins flush.
|
|
3498
|
+
"--nav-row-h": "22px"
|
|
3499
|
+
},
|
|
3500
|
+
/* Zone headers pin to the top of the scroll area like a tree view: each
|
|
3501
|
+
* depth level sticks at `top = depth × --nav-row-h` (set inline), so the
|
|
3502
|
+
* area (and its ancestors) stays visible while you scroll its items.
|
|
3503
|
+
* The opaque surface + z-index occlude the items scrolling underneath. */
|
|
3393
3504
|
navZone: {
|
|
3394
3505
|
display: "flex",
|
|
3395
3506
|
alignItems: "center",
|
|
3396
3507
|
gap: "{spacing.1}",
|
|
3397
|
-
|
|
3398
|
-
paddingRight: "{spacing.3}"
|
|
3508
|
+
height: "var(--nav-row-h)",
|
|
3509
|
+
paddingRight: "{spacing.3}",
|
|
3510
|
+
position: "sticky",
|
|
3511
|
+
background: "bg.surface",
|
|
3512
|
+
zIndex: "1"
|
|
3399
3513
|
},
|
|
3400
3514
|
navCaret: {
|
|
3401
3515
|
background: "transparent",
|
|
@@ -3442,6 +3556,9 @@ const schematicSlotRecipe = react.defineSlotRecipe({
|
|
|
3442
3556
|
border: "none",
|
|
3443
3557
|
paddingY: "2px",
|
|
3444
3558
|
paddingRight: "{spacing.3}",
|
|
3559
|
+
// Keep the auto-scroll-to-selected item clear of the pinned zone
|
|
3560
|
+
// headers (up to two ancestor levels).
|
|
3561
|
+
scrollMarginTop: "calc(var(--nav-row-h) * 2)",
|
|
3445
3562
|
fontFamily: "mono",
|
|
3446
3563
|
fontSize: "11px",
|
|
3447
3564
|
letterSpacing: "0.06em",
|
|
@@ -9439,7 +9556,7 @@ function transformForCss(_ref2) {
|
|
|
9439
9556
|
return val;
|
|
9440
9557
|
}
|
|
9441
9558
|
var baseStyles = ":root, :host {\n --fa-font-solid: normal 900 1em/1 'Font Awesome 7 Free';\n --fa-font-regular: normal 400 1em/1 'Font Awesome 7 Free';\n --fa-font-light: normal 300 1em/1 'Font Awesome 7 Pro';\n --fa-font-thin: normal 100 1em/1 'Font Awesome 7 Pro';\n --fa-font-duotone: normal 900 1em/1 'Font Awesome 7 Duotone';\n --fa-font-duotone-regular: normal 400 1em/1 'Font Awesome 7 Duotone';\n --fa-font-duotone-light: normal 300 1em/1 'Font Awesome 7 Duotone';\n --fa-font-duotone-thin: normal 100 1em/1 'Font Awesome 7 Duotone';\n --fa-font-brands: normal 400 1em/1 'Font Awesome 7 Brands';\n --fa-font-sharp-solid: normal 900 1em/1 'Font Awesome 7 Sharp';\n --fa-font-sharp-regular: normal 400 1em/1 'Font Awesome 7 Sharp';\n --fa-font-sharp-light: normal 300 1em/1 'Font Awesome 7 Sharp';\n --fa-font-sharp-thin: normal 100 1em/1 'Font Awesome 7 Sharp';\n --fa-font-sharp-duotone-solid: normal 900 1em/1 'Font Awesome 7 Sharp Duotone';\n --fa-font-sharp-duotone-regular: normal 400 1em/1 'Font Awesome 7 Sharp Duotone';\n --fa-font-sharp-duotone-light: normal 300 1em/1 'Font Awesome 7 Sharp Duotone';\n --fa-font-sharp-duotone-thin: normal 100 1em/1 'Font Awesome 7 Sharp Duotone';\n --fa-font-slab-regular: normal 400 1em/1 'Font Awesome 7 Slab';\n --fa-font-slab-press-regular: normal 400 1em/1 'Font Awesome 7 Slab Press';\n --fa-font-whiteboard-semibold: normal 600 1em/1 'Font Awesome 7 Whiteboard';\n --fa-font-thumbprint-light: normal 300 1em/1 'Font Awesome 7 Thumbprint';\n --fa-font-notdog-solid: normal 900 1em/1 'Font Awesome 7 Notdog';\n --fa-font-notdog-duo-solid: normal 900 1em/1 'Font Awesome 7 Notdog Duo';\n --fa-font-etch-solid: normal 900 1em/1 'Font Awesome 7 Etch';\n --fa-font-graphite-thin: normal 100 1em/1 'Font Awesome 7 Graphite';\n --fa-font-jelly-regular: normal 400 1em/1 'Font Awesome 7 Jelly';\n --fa-font-jelly-fill-regular: normal 400 1em/1 'Font Awesome 7 Jelly Fill';\n --fa-font-jelly-duo-regular: normal 400 1em/1 'Font Awesome 7 Jelly Duo';\n --fa-font-chisel-regular: normal 400 1em/1 'Font Awesome 7 Chisel';\n --fa-font-utility-semibold: normal 600 1em/1 'Font Awesome 7 Utility';\n --fa-font-utility-duo-semibold: normal 600 1em/1 'Font Awesome 7 Utility Duo';\n --fa-font-utility-fill-semibold: normal 600 1em/1 'Font Awesome 7 Utility Fill';\n}\n\n.svg-inline--fa {\n box-sizing: content-box;\n display: var(--fa-display, inline-block);\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n width: var(--fa-width, 1.25em);\n}\n.svg-inline--fa.fa-2xs {\n vertical-align: 0.1em;\n}\n.svg-inline--fa.fa-xs {\n vertical-align: 0em;\n}\n.svg-inline--fa.fa-sm {\n vertical-align: -0.0714285714em;\n}\n.svg-inline--fa.fa-lg {\n vertical-align: -0.2em;\n}\n.svg-inline--fa.fa-xl {\n vertical-align: -0.25em;\n}\n.svg-inline--fa.fa-2xl {\n vertical-align: -0.3125em;\n}\n.svg-inline--fa.fa-pull-left,\n.svg-inline--fa .fa-pull-start {\n float: inline-start;\n margin-inline-end: var(--fa-pull-margin, 0.3em);\n}\n.svg-inline--fa.fa-pull-right,\n.svg-inline--fa .fa-pull-end {\n float: inline-end;\n margin-inline-start: var(--fa-pull-margin, 0.3em);\n}\n.svg-inline--fa.fa-li {\n width: var(--fa-li-width, 2em);\n inset-inline-start: calc(-1 * var(--fa-li-width, 2em));\n inset-block-start: 0.25em; /* syncing vertical alignment with Web Font rendering */\n}\n\n.fa-layers-counter, .fa-layers-text {\n display: inline-block;\n position: absolute;\n text-align: center;\n}\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -0.125em;\n width: var(--fa-width, 1.25em);\n}\n.fa-layers .svg-inline--fa {\n inset: 0;\n margin: auto;\n position: absolute;\n transform-origin: center center;\n}\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n transform-origin: center center;\n}\n\n.fa-layers-counter {\n background-color: var(--fa-counter-background-color, #ff253a);\n border-radius: var(--fa-counter-border-radius, 1em);\n box-sizing: border-box;\n color: var(--fa-inverse, #fff);\n line-height: var(--fa-counter-line-height, 1);\n max-width: var(--fa-counter-max-width, 5em);\n min-width: var(--fa-counter-min-width, 1.5em);\n overflow: hidden;\n padding: var(--fa-counter-padding, 0.25em 0.5em);\n right: var(--fa-right, 0);\n text-overflow: ellipsis;\n top: var(--fa-top, 0);\n transform: scale(var(--fa-counter-scale, 0.25));\n transform-origin: top right;\n}\n\n.fa-layers-bottom-right {\n bottom: var(--fa-bottom, 0);\n right: var(--fa-right, 0);\n top: auto;\n transform: scale(var(--fa-layers-scale, 0.25));\n transform-origin: bottom right;\n}\n\n.fa-layers-bottom-left {\n bottom: var(--fa-bottom, 0);\n left: var(--fa-left, 0);\n right: auto;\n top: auto;\n transform: scale(var(--fa-layers-scale, 0.25));\n transform-origin: bottom left;\n}\n\n.fa-layers-top-right {\n top: var(--fa-top, 0);\n right: var(--fa-right, 0);\n transform: scale(var(--fa-layers-scale, 0.25));\n transform-origin: top right;\n}\n\n.fa-layers-top-left {\n left: var(--fa-left, 0);\n right: auto;\n top: var(--fa-top, 0);\n transform: scale(var(--fa-layers-scale, 0.25));\n transform-origin: top left;\n}\n\n.fa-1x {\n font-size: 1em;\n}\n\n.fa-2x {\n font-size: 2em;\n}\n\n.fa-3x {\n font-size: 3em;\n}\n\n.fa-4x {\n font-size: 4em;\n}\n\n.fa-5x {\n font-size: 5em;\n}\n\n.fa-6x {\n font-size: 6em;\n}\n\n.fa-7x {\n font-size: 7em;\n}\n\n.fa-8x {\n font-size: 8em;\n}\n\n.fa-9x {\n font-size: 9em;\n}\n\n.fa-10x {\n font-size: 10em;\n}\n\n.fa-2xs {\n font-size: calc(10 / 16 * 1em); /* converts a 10px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 10 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 10 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-xs {\n font-size: calc(12 / 16 * 1em); /* converts a 12px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 12 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 12 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-sm {\n font-size: calc(14 / 16 * 1em); /* converts a 14px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 14 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 14 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-lg {\n font-size: calc(20 / 16 * 1em); /* converts a 20px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 20 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 20 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-xl {\n font-size: calc(24 / 16 * 1em); /* converts a 24px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 24 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 24 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-2xl {\n font-size: calc(32 / 16 * 1em); /* converts a 32px size into an em-based value that's relative to the scale's 16px base */\n line-height: calc(1 / 32 * 1em); /* sets the line-height of the icon back to that of it's parent */\n vertical-align: calc((6 / 32 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */\n}\n\n.fa-width-auto {\n --fa-width: auto;\n}\n\n.fa-fw,\n.fa-width-fixed {\n --fa-width: 1.25em;\n}\n\n.fa-ul {\n list-style-type: none;\n margin-inline-start: var(--fa-li-margin, 2.5em);\n padding-inline-start: 0;\n}\n.fa-ul > li {\n position: relative;\n}\n\n.fa-li {\n inset-inline-start: calc(-1 * var(--fa-li-width, 2em));\n position: absolute;\n text-align: center;\n width: var(--fa-li-width, 2em);\n line-height: inherit;\n}\n\n/* Heads Up: Bordered Icons will not be supported in the future!\n - This feature will be deprecated in the next major release of Font Awesome (v8)!\n - You may continue to use it in this version *v7), but it will not be supported in Font Awesome v8.\n*/\n/* Notes:\n* --@{v.$css-prefix}-border-width = 1/16 by default (to render as ~1px based on a 16px default font-size)\n* --@{v.$css-prefix}-border-padding =\n ** 3/16 for vertical padding (to give ~2px of vertical whitespace around an icon considering it's vertical alignment)\n ** 4/16 for horizontal padding (to give ~4px of horizontal whitespace around an icon)\n*/\n.fa-border {\n border-color: var(--fa-border-color, #eee);\n border-radius: var(--fa-border-radius, 0.1em);\n border-style: var(--fa-border-style, solid);\n border-width: var(--fa-border-width, 0.0625em);\n box-sizing: var(--fa-border-box-sizing, content-box);\n padding: var(--fa-border-padding, 0.1875em 0.25em);\n}\n\n.fa-pull-left,\n.fa-pull-start {\n float: inline-start;\n margin-inline-end: var(--fa-pull-margin, 0.3em);\n}\n\n.fa-pull-right,\n.fa-pull-end {\n float: inline-end;\n margin-inline-start: var(--fa-pull-margin, 0.3em);\n}\n\n.fa-beat {\n animation-name: fa-beat;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\n}\n\n.fa-bounce {\n animation-name: fa-bounce;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\n}\n\n.fa-fade {\n animation-name: fa-fade;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n}\n\n.fa-beat-fade {\n animation-name: fa-beat-fade;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n}\n\n.fa-flip {\n animation-name: fa-flip;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, ease-in-out);\n}\n\n.fa-shake {\n animation-name: fa-shake;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, linear);\n}\n\n.fa-spin {\n animation-name: fa-spin;\n animation-delay: var(--fa-animation-delay, 0s);\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 2s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, linear);\n}\n\n.fa-spin-reverse {\n --fa-animation-direction: reverse;\n}\n\n.fa-pulse,\n.fa-spin-pulse {\n animation-name: fa-spin;\n animation-direction: var(--fa-animation-direction, normal);\n animation-duration: var(--fa-animation-duration, 1s);\n animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n animation-timing-function: var(--fa-animation-timing, steps(8));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fa-beat,\n .fa-bounce,\n .fa-fade,\n .fa-beat-fade,\n .fa-flip,\n .fa-pulse,\n .fa-shake,\n .fa-spin,\n .fa-spin-pulse {\n animation: none !important;\n transition: none !important;\n }\n}\n@keyframes fa-beat {\n 0%, 90% {\n transform: scale(1);\n }\n 45% {\n transform: scale(var(--fa-beat-scale, 1.25));\n }\n}\n@keyframes fa-bounce {\n 0% {\n transform: scale(1, 1) translateY(0);\n }\n 10% {\n transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n }\n 30% {\n transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n }\n 50% {\n transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n }\n 57% {\n transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n }\n 64% {\n transform: scale(1, 1) translateY(0);\n }\n 100% {\n transform: scale(1, 1) translateY(0);\n }\n}\n@keyframes fa-fade {\n 50% {\n opacity: var(--fa-fade-opacity, 0.4);\n }\n}\n@keyframes fa-beat-fade {\n 0%, 100% {\n opacity: var(--fa-beat-fade-opacity, 0.4);\n transform: scale(1);\n }\n 50% {\n opacity: 1;\n transform: scale(var(--fa-beat-fade-scale, 1.125));\n }\n}\n@keyframes fa-flip {\n 50% {\n transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n }\n}\n@keyframes fa-shake {\n 0% {\n transform: rotate(-15deg);\n }\n 4% {\n transform: rotate(15deg);\n }\n 8%, 24% {\n transform: rotate(-18deg);\n }\n 12%, 28% {\n transform: rotate(18deg);\n }\n 16% {\n transform: rotate(-22deg);\n }\n 20% {\n transform: rotate(22deg);\n }\n 32% {\n transform: rotate(-12deg);\n }\n 36% {\n transform: rotate(12deg);\n }\n 40%, 100% {\n transform: rotate(0deg);\n }\n}\n@keyframes fa-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.fa-rotate-90 {\n transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n transform: scale(1, -1);\n}\n\n.fa-flip-both,\n.fa-flip-horizontal.fa-flip-vertical {\n transform: scale(-1, -1);\n}\n\n.fa-rotate-by {\n transform: rotate(var(--fa-rotate-angle, 0));\n}\n\n.svg-inline--fa .fa-primary {\n fill: var(--fa-primary-color, currentColor);\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa .fa-secondary {\n fill: var(--fa-secondary-color, currentColor);\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n fill: black;\n}\n\n.svg-inline--fa.fa-inverse {\n fill: var(--fa-inverse, #fff);\n}\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n line-height: 2em;\n position: relative;\n vertical-align: middle;\n width: 2.5em;\n}\n\n.fa-inverse {\n color: var(--fa-inverse, #fff);\n}\n\n.svg-inline--fa.fa-stack-1x {\n --fa-width: 1.25em;\n height: 1em;\n width: var(--fa-width);\n}\n.svg-inline--fa.fa-stack-2x {\n --fa-width: 2.5em;\n height: 2em;\n width: var(--fa-width);\n}\n\n.fa-stack-1x,\n.fa-stack-2x {\n inset: 0;\n margin: auto;\n position: absolute;\n z-index: var(--fa-stack-z-index, auto);\n}";
|
|
9442
|
-
function css() {
|
|
9559
|
+
function css$1() {
|
|
9443
9560
|
var dcp = DEFAULT_CSS_PREFIX;
|
|
9444
9561
|
var drc = DEFAULT_REPLACEMENT_CLASS;
|
|
9445
9562
|
var fp = config.cssPrefix;
|
|
@@ -9456,7 +9573,7 @@ function css() {
|
|
|
9456
9573
|
var _cssInserted = false;
|
|
9457
9574
|
function ensureCss() {
|
|
9458
9575
|
if (config.autoAddCss && !_cssInserted) {
|
|
9459
|
-
insertCss(css());
|
|
9576
|
+
insertCss(css$1());
|
|
9460
9577
|
_cssInserted = true;
|
|
9461
9578
|
}
|
|
9462
9579
|
}
|
|
@@ -9464,7 +9581,7 @@ var InjectCSS = {
|
|
|
9464
9581
|
mixout: function mixout() {
|
|
9465
9582
|
return {
|
|
9466
9583
|
dom: {
|
|
9467
|
-
css,
|
|
9584
|
+
css: css$1,
|
|
9468
9585
|
insertCss: ensureCss
|
|
9469
9586
|
}
|
|
9470
9587
|
};
|
|
@@ -61532,23 +61649,123 @@ function multiSelect(arr, left, right, n2, compare) {
|
|
|
61532
61649
|
stack.push(left, mid, mid, right);
|
|
61533
61650
|
}
|
|
61534
61651
|
}
|
|
61535
|
-
library$1.add(icons$2);
|
|
61536
|
-
const schematicEqual = east.equalFor(internal.Schematic.Types.Schematic);
|
|
61537
61652
|
const IDENTITY = { zoom: 1, tx: 0, ty: 0 };
|
|
61538
|
-
|
|
61539
|
-
|
|
61540
|
-
const LOD_LABEL_PPU = 16;
|
|
61541
|
-
const MINIMAP_AUTO = 25;
|
|
61542
|
-
function statusTone(status) {
|
|
61543
|
-
return status.type === "some" ? status.value.type : void 0;
|
|
61653
|
+
function project(x2, y2, cam) {
|
|
61654
|
+
return { sx: x2 * cam.ppu + cam.tx, sy: y2 * cam.ppu + cam.ty };
|
|
61544
61655
|
}
|
|
61545
|
-
function
|
|
61546
|
-
|
|
61547
|
-
|
|
61548
|
-
|
|
61549
|
-
|
|
61656
|
+
function cardTranslateCss(x2, y2) {
|
|
61657
|
+
return `translate(calc(var(--cam-ppu) * ${x2} * 1px + var(--cam-tx)), calc(var(--cam-ppu) * ${y2} * 1px + var(--cam-ty)))`;
|
|
61658
|
+
}
|
|
61659
|
+
function cardWidthCss(width) {
|
|
61660
|
+
return `calc(var(--cam-ppu) * ${width} * 1px)`;
|
|
61661
|
+
}
|
|
61662
|
+
function viewportWorldBbox(cam, width, height) {
|
|
61663
|
+
return {
|
|
61664
|
+
minX: -cam.tx / cam.ppu,
|
|
61665
|
+
minY: -cam.ty / cam.ppu,
|
|
61666
|
+
maxX: (width - cam.tx) / cam.ppu,
|
|
61667
|
+
maxY: (height - cam.ty) / cam.ppu
|
|
61668
|
+
};
|
|
61669
|
+
}
|
|
61670
|
+
function bboxOverlaps(a2, b2) {
|
|
61671
|
+
return a2.maxX >= b2.minX && a2.minX <= b2.maxX && a2.maxY >= b2.minY && a2.minY <= b2.maxY;
|
|
61672
|
+
}
|
|
61673
|
+
function pointsBbox(pts) {
|
|
61674
|
+
if (pts.length === 0) return null;
|
|
61675
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
61676
|
+
for (const p2 of pts) {
|
|
61677
|
+
if (p2.x < minX) minX = p2.x;
|
|
61678
|
+
if (p2.y < minY) minY = p2.y;
|
|
61679
|
+
if (p2.x > maxX) maxX = p2.x;
|
|
61680
|
+
if (p2.y > maxY) maxY = p2.y;
|
|
61681
|
+
}
|
|
61682
|
+
return { minX, minY, maxX, maxY };
|
|
61683
|
+
}
|
|
61684
|
+
function zoomAbout(prev, factor, px, py, min2, max2) {
|
|
61685
|
+
const zoom = Math.max(min2, Math.min(max2, prev.zoom * factor));
|
|
61686
|
+
if (zoom === 1) return IDENTITY;
|
|
61687
|
+
const k2 = zoom / prev.zoom;
|
|
61688
|
+
return { zoom, tx: px - k2 * (px - prev.tx), ty: py - k2 * (py - prev.ty) };
|
|
61689
|
+
}
|
|
61690
|
+
function nextMode(mode, event) {
|
|
61691
|
+
switch (event) {
|
|
61692
|
+
case "pointerDown":
|
|
61693
|
+
return "panning";
|
|
61694
|
+
case "wheel":
|
|
61695
|
+
return "wheeling";
|
|
61696
|
+
case "zoom":
|
|
61697
|
+
return "wheeling";
|
|
61698
|
+
case "flyStart":
|
|
61699
|
+
return "flying";
|
|
61700
|
+
case "pointerUp":
|
|
61701
|
+
return mode === "panning" ? "idle" : mode;
|
|
61702
|
+
case "flyEnd":
|
|
61703
|
+
return mode === "flying" ? "idle" : mode;
|
|
61704
|
+
case "cancel":
|
|
61705
|
+
return "idle";
|
|
61706
|
+
}
|
|
61707
|
+
}
|
|
61708
|
+
function cancelsFly(mode, event) {
|
|
61709
|
+
return mode === "flying" && (event === "pointerDown" || event === "wheel" || event === "zoom" || event === "cancel");
|
|
61710
|
+
}
|
|
61711
|
+
function makeRafCoalescer(schedule, cancel) {
|
|
61712
|
+
let handle2 = null;
|
|
61713
|
+
return {
|
|
61714
|
+
request(run) {
|
|
61715
|
+
if (handle2 !== null) return;
|
|
61716
|
+
handle2 = schedule(() => {
|
|
61717
|
+
handle2 = null;
|
|
61718
|
+
run();
|
|
61719
|
+
});
|
|
61720
|
+
},
|
|
61721
|
+
cancel() {
|
|
61722
|
+
if (handle2 !== null) {
|
|
61723
|
+
cancel(handle2);
|
|
61724
|
+
handle2 = null;
|
|
61725
|
+
}
|
|
61726
|
+
}
|
|
61727
|
+
};
|
|
61728
|
+
}
|
|
61729
|
+
const css = (c2, a2 = 1) => a2 >= 1 ? `rgb(${c2[0]},${c2[1]},${c2[2]})` : `rgba(${c2[0]},${c2[1]},${c2[2]},${a2})`;
|
|
61730
|
+
function toneRGB(p2, tone, kind) {
|
|
61731
|
+
switch (tone) {
|
|
61732
|
+
case "brand":
|
|
61733
|
+
return p2.brand600;
|
|
61734
|
+
case "ink":
|
|
61735
|
+
return p2.fg;
|
|
61736
|
+
case "muted":
|
|
61737
|
+
return kind === "zone" ? p2.borderStrong : p2.fgMuted;
|
|
61738
|
+
case "success":
|
|
61739
|
+
return p2.statusOk;
|
|
61740
|
+
case "warning":
|
|
61741
|
+
return p2.statusWarn;
|
|
61742
|
+
case "danger":
|
|
61743
|
+
return p2.statusBad;
|
|
61744
|
+
default:
|
|
61745
|
+
return p2.fgMuted;
|
|
61746
|
+
}
|
|
61747
|
+
}
|
|
61748
|
+
function statusRGB(p2, status) {
|
|
61749
|
+
switch (status) {
|
|
61750
|
+
case "success":
|
|
61751
|
+
return p2.statusOk;
|
|
61752
|
+
case "warning":
|
|
61753
|
+
return p2.statusWarn;
|
|
61754
|
+
case "danger":
|
|
61755
|
+
return p2.statusBad;
|
|
61756
|
+
case "info":
|
|
61757
|
+
return p2.brand500;
|
|
61758
|
+
default:
|
|
61759
|
+
return p2.fgMuted;
|
|
61550
61760
|
}
|
|
61551
|
-
|
|
61761
|
+
}
|
|
61762
|
+
function statusTone$1(status) {
|
|
61763
|
+
return status.type === "some" ? status.value.type : void 0;
|
|
61764
|
+
}
|
|
61765
|
+
function resolveTint(p2, color2, tone, fallback) {
|
|
61766
|
+
if (color2 !== void 0) return color2;
|
|
61767
|
+
if (tone !== void 0) return css(toneRGB(p2, tone, "link"));
|
|
61768
|
+
return css(fallback);
|
|
61552
61769
|
}
|
|
61553
61770
|
function orthogonalize(points) {
|
|
61554
61771
|
const out = [];
|
|
@@ -61561,26 +61778,410 @@ function orthogonalize(points) {
|
|
|
61561
61778
|
}
|
|
61562
61779
|
return out;
|
|
61563
61780
|
}
|
|
61564
|
-
function
|
|
61565
|
-
if (pts.length === 0) return
|
|
61566
|
-
|
|
61781
|
+
function traceRounded(ctx, pts, radius) {
|
|
61782
|
+
if (pts.length === 0) return;
|
|
61783
|
+
ctx.moveTo(pts[0].x, pts[0].y);
|
|
61567
61784
|
for (let i2 = 1; i2 < pts.length - 1; i2++) {
|
|
61568
61785
|
const p2 = pts[i2], a2 = pts[i2 - 1], b2 = pts[i2 + 1];
|
|
61569
61786
|
const inLen = Math.hypot(p2.x - a2.x, p2.y - a2.y);
|
|
61570
61787
|
const outLen = Math.hypot(b2.x - p2.x, b2.y - p2.y);
|
|
61571
61788
|
const r2 = Math.min(radius, inLen / 2, outLen / 2);
|
|
61572
61789
|
if (r2 < 0.5) {
|
|
61573
|
-
|
|
61790
|
+
ctx.lineTo(p2.x, p2.y);
|
|
61574
61791
|
continue;
|
|
61575
61792
|
}
|
|
61576
61793
|
const inU = { x: (p2.x - a2.x) / inLen, y: (p2.y - a2.y) / inLen };
|
|
61577
|
-
|
|
61578
|
-
|
|
61579
|
-
d2 += ` Q ${p2.x} ${p2.y} ${p2.x + outU.x * r2} ${p2.y + outU.y * r2}`;
|
|
61794
|
+
ctx.lineTo(p2.x - inU.x * r2, p2.y - inU.y * r2);
|
|
61795
|
+
ctx.quadraticCurveTo(p2.x, p2.y, p2.x + (b2.x - p2.x) / outLen * r2, p2.y + (b2.y - p2.y) / outLen * r2);
|
|
61580
61796
|
}
|
|
61581
61797
|
const last = pts[pts.length - 1];
|
|
61582
|
-
if (pts.length > 1)
|
|
61583
|
-
|
|
61798
|
+
if (pts.length > 1) ctx.lineTo(last.x, last.y);
|
|
61799
|
+
}
|
|
61800
|
+
function arcFromBulge(p1, p2, bulge) {
|
|
61801
|
+
const dx = p2.x - p1.x, dy = p2.y - p1.y;
|
|
61802
|
+
const chord = Math.hypot(dx, dy);
|
|
61803
|
+
if (Math.abs(bulge) < 1e-4 || chord < 1e-9) return null;
|
|
61804
|
+
const theta = 4 * Math.atan(bulge);
|
|
61805
|
+
const radius = Math.abs(chord / (2 * Math.sin(theta / 2)));
|
|
61806
|
+
const mx = (p1.x + p2.x) / 2, my = (p1.y + p2.y) / 2;
|
|
61807
|
+
const d2 = chord / 2 / Math.tan(theta / 2);
|
|
61808
|
+
const cx2 = mx - dy / chord * d2, cy = my + dx / chord * d2;
|
|
61809
|
+
if (!Number.isFinite(radius) || !Number.isFinite(d2) || !Number.isFinite(cx2) || !Number.isFinite(cy)) return null;
|
|
61810
|
+
return {
|
|
61811
|
+
cx: cx2,
|
|
61812
|
+
cy,
|
|
61813
|
+
radius,
|
|
61814
|
+
startAngle: Math.atan2(p1.y - cy, p1.x - cx2),
|
|
61815
|
+
endAngle: Math.atan2(p2.y - cy, p2.x - cx2),
|
|
61816
|
+
anticlockwise: theta < 0
|
|
61817
|
+
};
|
|
61818
|
+
}
|
|
61819
|
+
function traceBulge(ctx, p1, p2, bulge) {
|
|
61820
|
+
const arc = arcFromBulge(p1, p2, bulge);
|
|
61821
|
+
if (arc === null) {
|
|
61822
|
+
ctx.lineTo(p2.x, p2.y);
|
|
61823
|
+
return;
|
|
61824
|
+
}
|
|
61825
|
+
ctx.arc(arc.cx, arc.cy, arc.radius, arc.startAngle, arc.endAngle, arc.anticlockwise);
|
|
61826
|
+
}
|
|
61827
|
+
function traceVertices(ctx, pts, closed) {
|
|
61828
|
+
if (pts.length === 0) return;
|
|
61829
|
+
ctx.moveTo(pts[0].x, pts[0].y);
|
|
61830
|
+
for (let i2 = 1; i2 < pts.length; i2++) traceBulge(ctx, pts[i2 - 1], pts[i2], pts[i2 - 1].bulge);
|
|
61831
|
+
if (closed) {
|
|
61832
|
+
const last = pts[pts.length - 1];
|
|
61833
|
+
traceBulge(ctx, last, pts[0], last.bulge);
|
|
61834
|
+
ctx.closePath();
|
|
61835
|
+
}
|
|
61836
|
+
}
|
|
61837
|
+
const MARKER_LABEL_FONT = '600 10px ui-monospace, "SF Mono", Menlo, monospace';
|
|
61838
|
+
const MARKER_DOT_RADIUS = 5;
|
|
61839
|
+
const MARKER_DOT_HIT_RADIUS = 10;
|
|
61840
|
+
const MARKER_PIN_PAD_X = 6, MARKER_PIN_DOT_W = 7, MARKER_PIN_GAP = 4, MARKER_PIN_H = 16;
|
|
61841
|
+
function markerHitbox(item, tier, cam, measure) {
|
|
61842
|
+
const { sx, sy } = project(item.x, item.y, cam);
|
|
61843
|
+
if (tier === "dot") return { kind: "circle", cx: sx, cy: sy, r: MARKER_DOT_HIT_RADIUS };
|
|
61844
|
+
const tw = measure(item.label);
|
|
61845
|
+
const w2 = MARKER_PIN_PAD_X + MARKER_PIN_DOT_W + MARKER_PIN_GAP + tw + MARKER_PIN_PAD_X;
|
|
61846
|
+
return { kind: "rect", left: sx - w2 / 2, top: sy - MARKER_PIN_H / 2, w: w2, h: MARKER_PIN_H };
|
|
61847
|
+
}
|
|
61848
|
+
function markerHit(box, sx, sy) {
|
|
61849
|
+
return box.kind === "circle" ? Math.hypot(sx - box.cx, sy - box.cy) <= box.r : sx >= box.left && sx <= box.left + box.w && sy >= box.top && sy <= box.top + box.h;
|
|
61850
|
+
}
|
|
61851
|
+
function hatchSpacing(rawSpacing) {
|
|
61852
|
+
return Number.isFinite(rawSpacing) ? Math.max(1, rawSpacing) : 1;
|
|
61853
|
+
}
|
|
61854
|
+
function hatchSweepBounds(x2, y2, w2, h2, width, height, dx, dy, diag, spacing) {
|
|
61855
|
+
const nx = -dy, ny = dx;
|
|
61856
|
+
if (Math.abs(nx) <= 1e-6) return { oStart: -diag, oEnd: diag };
|
|
61857
|
+
const cx0 = Math.max(x2, 0), cy0 = Math.max(y2, 0);
|
|
61858
|
+
const cx1 = Math.min(x2 + w2, width), cy1 = Math.min(y2 + h2, height);
|
|
61859
|
+
const cs = [cx0 * nx + cy0 * ny, cx1 * nx + cy0 * ny, cx0 * nx + cy1 * ny, cx1 * nx + cy1 * ny];
|
|
61860
|
+
const oOfC = (c2) => (c2 - x2 * nx - (y2 - diag * dy) * ny) / nx;
|
|
61861
|
+
const oA = oOfC(Math.min(...cs)), oB = oOfC(Math.max(...cs));
|
|
61862
|
+
return {
|
|
61863
|
+
oStart: Math.max(-diag, -diag + Math.floor((Math.min(oA, oB) + diag) / spacing) * spacing - spacing),
|
|
61864
|
+
oEnd: Math.min(diag, Math.max(oA, oB) + spacing)
|
|
61865
|
+
};
|
|
61866
|
+
}
|
|
61867
|
+
function zoneWorldBbox(zone, geom) {
|
|
61868
|
+
const bb = { minX: zone.x, minY: zone.y, maxX: zone.x + zone.width, maxY: zone.y + zone.height };
|
|
61869
|
+
if (geom !== void 0 && geom.type === "circle") {
|
|
61870
|
+
const cx2 = zone.x + zone.width / 2, cy = zone.y + zone.height / 2, r2 = geom.value.radius;
|
|
61871
|
+
bb.minX = Math.min(bb.minX, cx2 - r2);
|
|
61872
|
+
bb.minY = Math.min(bb.minY, cy - r2);
|
|
61873
|
+
bb.maxX = Math.max(bb.maxX, cx2 + r2);
|
|
61874
|
+
bb.maxY = Math.max(bb.maxY, cy + r2);
|
|
61875
|
+
} else if (geom !== void 0 && geom.type !== "rect") {
|
|
61876
|
+
const g2 = pointsBbox(geom.value.vertices);
|
|
61877
|
+
if (g2 !== null) {
|
|
61878
|
+
bb.minX = Math.min(bb.minX, g2.minX);
|
|
61879
|
+
bb.minY = Math.min(bb.minY, g2.minY);
|
|
61880
|
+
bb.maxX = Math.max(bb.maxX, g2.maxX);
|
|
61881
|
+
bb.maxY = Math.max(bb.maxY, g2.maxY);
|
|
61882
|
+
}
|
|
61883
|
+
}
|
|
61884
|
+
return bb;
|
|
61885
|
+
}
|
|
61886
|
+
function paintSchematic(input) {
|
|
61887
|
+
var _a2, _b, _c, _d;
|
|
61888
|
+
const { ctx, value, cam, width, height, visibleItems, tiers, selected, centers, palette: p2 } = input;
|
|
61889
|
+
const wx = (x2) => x2 * cam.ppu + cam.tx;
|
|
61890
|
+
const wy = (y2) => y2 * cam.ppu + cam.ty;
|
|
61891
|
+
const ppu = cam.ppu;
|
|
61892
|
+
const viewBbox = viewportWorldBbox(cam, width, height);
|
|
61893
|
+
ctx.save();
|
|
61894
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
61895
|
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
61896
|
+
ctx.restore();
|
|
61897
|
+
ctx.lineJoin = "round";
|
|
61898
|
+
for (const zone of value.zones) {
|
|
61899
|
+
const geom = getSomeorUndefined(zone.geometry);
|
|
61900
|
+
if (!bboxOverlaps(zoneWorldBbox(zone, geom), viewBbox)) continue;
|
|
61901
|
+
const pattern = zone.pattern;
|
|
61902
|
+
const patternTone = (pattern.value.tone.type === "some" ? pattern.value.tone.value.type : void 0) ?? "muted";
|
|
61903
|
+
const tint = resolveTint(p2, getSomeorUndefined(zone.color), (_a2 = getSomeorUndefined(zone.tone)) == null ? void 0 : _a2.type, toneRGB(p2, patternTone, "zone"));
|
|
61904
|
+
const zbg = getSomeorUndefined(zone.bg);
|
|
61905
|
+
const zFillAlpha = getSomeorUndefined(zone.fillOpacity) ?? 0.15;
|
|
61906
|
+
const zWeight = getSomeorUndefined(zone.weight);
|
|
61907
|
+
const x2 = wx(zone.x), y2 = wy(zone.y), w2 = zone.width * ppu, h2 = zone.height * ppu;
|
|
61908
|
+
const fillShape = () => {
|
|
61909
|
+
if (zbg === void 0) return;
|
|
61910
|
+
ctx.save();
|
|
61911
|
+
ctx.globalAlpha = zFillAlpha;
|
|
61912
|
+
ctx.fillStyle = zbg;
|
|
61913
|
+
ctx.fill();
|
|
61914
|
+
ctx.restore();
|
|
61915
|
+
};
|
|
61916
|
+
if (geom !== void 0 && geom.type !== "rect") {
|
|
61917
|
+
if (geom.type === "circle") {
|
|
61918
|
+
ctx.beginPath();
|
|
61919
|
+
ctx.arc(x2 + w2 / 2, y2 + h2 / 2, geom.value.radius * ppu, 0, Math.PI * 2);
|
|
61920
|
+
fillShape();
|
|
61921
|
+
ctx.setLineDash([4, 3]);
|
|
61922
|
+
ctx.lineWidth = zWeight ?? 1;
|
|
61923
|
+
ctx.strokeStyle = tint;
|
|
61924
|
+
ctx.stroke();
|
|
61925
|
+
ctx.setLineDash([]);
|
|
61926
|
+
} else {
|
|
61927
|
+
const pts = geom.value.vertices.map((q) => ({ x: wx(q.x), y: wy(q.y), bulge: q.bulge }));
|
|
61928
|
+
if (pts.length > 0) {
|
|
61929
|
+
ctx.beginPath();
|
|
61930
|
+
if (geom.type === "polygon") {
|
|
61931
|
+
traceVertices(ctx, pts, true);
|
|
61932
|
+
fillShape();
|
|
61933
|
+
ctx.setLineDash([4, 3]);
|
|
61934
|
+
ctx.lineWidth = zWeight ?? 1;
|
|
61935
|
+
ctx.strokeStyle = tint;
|
|
61936
|
+
ctx.stroke();
|
|
61937
|
+
ctx.setLineDash([]);
|
|
61938
|
+
} else {
|
|
61939
|
+
traceVertices(ctx, pts, false);
|
|
61940
|
+
const band2 = geom.value.width.type === "some" ? geom.value.width.value * ppu : void 0;
|
|
61941
|
+
ctx.setLineDash([]);
|
|
61942
|
+
ctx.lineCap = "round";
|
|
61943
|
+
ctx.lineWidth = zWeight ?? band2 ?? 1.5;
|
|
61944
|
+
ctx.save();
|
|
61945
|
+
ctx.globalAlpha = 0.55;
|
|
61946
|
+
ctx.strokeStyle = tint;
|
|
61947
|
+
ctx.stroke();
|
|
61948
|
+
ctx.restore();
|
|
61949
|
+
ctx.lineCap = "butt";
|
|
61950
|
+
}
|
|
61951
|
+
}
|
|
61952
|
+
}
|
|
61953
|
+
} else if (pattern.type === "hatch") {
|
|
61954
|
+
const spacing = hatchSpacing(getSomeorUndefined(pattern.value.spacing) ?? 8);
|
|
61955
|
+
const angle = (getSomeorUndefined(pattern.value.angle) ?? 45) * Math.PI / 180;
|
|
61956
|
+
ctx.save();
|
|
61957
|
+
ctx.beginPath();
|
|
61958
|
+
ctx.rect(x2, y2, w2, h2);
|
|
61959
|
+
ctx.clip();
|
|
61960
|
+
if (zbg !== void 0) {
|
|
61961
|
+
ctx.save();
|
|
61962
|
+
ctx.globalAlpha = zFillAlpha;
|
|
61963
|
+
ctx.fillStyle = zbg;
|
|
61964
|
+
ctx.fillRect(x2, y2, w2, h2);
|
|
61965
|
+
ctx.restore();
|
|
61966
|
+
}
|
|
61967
|
+
ctx.globalAlpha = 0.3;
|
|
61968
|
+
ctx.strokeStyle = tint;
|
|
61969
|
+
ctx.lineWidth = zWeight ?? 1;
|
|
61970
|
+
const dx = Math.cos(angle), dy = Math.sin(angle);
|
|
61971
|
+
const diag = Math.hypot(w2, h2);
|
|
61972
|
+
const { oStart, oEnd } = hatchSweepBounds(x2, y2, w2, h2, width, height, dx, dy, diag, spacing);
|
|
61973
|
+
ctx.beginPath();
|
|
61974
|
+
for (let o2 = oStart; o2 < oEnd; o2 += spacing) {
|
|
61975
|
+
ctx.moveTo(x2 + o2, y2 - diag * dy);
|
|
61976
|
+
ctx.lineTo(x2 + o2 + dx * 2 * diag, y2 - diag * dy + dy * 2 * diag);
|
|
61977
|
+
}
|
|
61978
|
+
ctx.stroke();
|
|
61979
|
+
ctx.restore();
|
|
61980
|
+
} else {
|
|
61981
|
+
if (zbg !== void 0) {
|
|
61982
|
+
ctx.save();
|
|
61983
|
+
ctx.globalAlpha = zFillAlpha;
|
|
61984
|
+
ctx.fillStyle = zbg;
|
|
61985
|
+
ctx.fillRect(x2, y2, w2, h2);
|
|
61986
|
+
ctx.restore();
|
|
61987
|
+
}
|
|
61988
|
+
ctx.setLineDash([5, 4]);
|
|
61989
|
+
ctx.lineWidth = zWeight ?? 1;
|
|
61990
|
+
ctx.strokeStyle = tint;
|
|
61991
|
+
ctx.strokeRect(x2, y2, w2, h2);
|
|
61992
|
+
ctx.setLineDash([]);
|
|
61993
|
+
}
|
|
61994
|
+
if (w2 >= zone.label.length * 6.2 + 24) {
|
|
61995
|
+
ctx.font = '600 9px ui-monospace, "SF Mono", Menlo, monospace';
|
|
61996
|
+
const label = zone.label.toUpperCase();
|
|
61997
|
+
const tw = ctx.measureText(label).width;
|
|
61998
|
+
ctx.fillStyle = css(p2.bgPanel);
|
|
61999
|
+
ctx.fillRect(x2 + 6, y2 - 7, tw + 6, 12);
|
|
62000
|
+
ctx.fillStyle = css(p2.fgMuted);
|
|
62001
|
+
ctx.textBaseline = "middle";
|
|
62002
|
+
ctx.fillText(label, x2 + 9, y2);
|
|
62003
|
+
}
|
|
62004
|
+
}
|
|
62005
|
+
for (const link2 of value.links) {
|
|
62006
|
+
const from = centers.get(link2.from), to = centers.get(link2.to);
|
|
62007
|
+
if (!from || !to) continue;
|
|
62008
|
+
const linkBbox = pointsBbox([from, ...link2.via, to]);
|
|
62009
|
+
if (linkBbox !== null && !bboxOverlaps(linkBbox, viewBbox)) continue;
|
|
62010
|
+
const anchors = [from, ...link2.via, to].map((q) => ({ x: wx(q.x), y: wy(q.y) }));
|
|
62011
|
+
const corner = link2.route.type === "orthogonal" ? link2.route.value.corner.type === "some" ? link2.route.value.corner.value : 8 : 0;
|
|
62012
|
+
const pts = link2.route.type === "orthogonal" ? orthogonalize(anchors) : anchors;
|
|
62013
|
+
const style = link2.style;
|
|
62014
|
+
const tone = (style.value.tone.type === "some" ? style.value.tone.value.type : void 0) ?? (style.type === "solid" ? "brand" : "muted");
|
|
62015
|
+
const weight = style.value.weight.type === "some" ? style.value.weight.value : style.type === "solid" ? 2.5 : 1.5;
|
|
62016
|
+
const color2 = toneRGB(p2, tone, "link");
|
|
62017
|
+
ctx.lineCap = "round";
|
|
62018
|
+
ctx.strokeStyle = css(color2);
|
|
62019
|
+
ctx.lineWidth = weight;
|
|
62020
|
+
ctx.setLineDash(style.type === "dashed" ? [6, 5] : []);
|
|
62021
|
+
ctx.beginPath();
|
|
62022
|
+
traceRounded(ctx, pts, corner);
|
|
62023
|
+
ctx.stroke();
|
|
62024
|
+
ctx.setLineDash([]);
|
|
62025
|
+
ctx.fillStyle = css(color2);
|
|
62026
|
+
for (const end3 of [anchors[0], anchors[anchors.length - 1]]) {
|
|
62027
|
+
ctx.beginPath();
|
|
62028
|
+
ctx.arc(end3.x, end3.y, weight + 1.5, 0, Math.PI * 2);
|
|
62029
|
+
ctx.fill();
|
|
62030
|
+
}
|
|
62031
|
+
ctx.lineCap = "butt";
|
|
62032
|
+
}
|
|
62033
|
+
for (const item of visibleItems) {
|
|
62034
|
+
const footprint = getSomeorUndefined(item.footprint);
|
|
62035
|
+
if (footprint === void 0 || footprint.type === "rect") continue;
|
|
62036
|
+
if ((tiers.get(item.key) ?? "dot") !== "card") continue;
|
|
62037
|
+
const isSel = selected === item.key;
|
|
62038
|
+
const tint = resolveTint(p2, getSomeorUndefined(item.color), (_b = getSomeorUndefined(item.tone)) == null ? void 0 : _b.type, statusRGB(p2, statusTone$1(item.status)));
|
|
62039
|
+
const ibg = getSomeorUndefined(item.bg);
|
|
62040
|
+
const fillAlpha = getSomeorUndefined(item.fillOpacity) ?? (isSel ? 0.24 : 0.12);
|
|
62041
|
+
const stroke = getSomeorUndefined(item.weight) ?? (isSel ? 2.5 : 1.5);
|
|
62042
|
+
const fillShape = () => {
|
|
62043
|
+
ctx.save();
|
|
62044
|
+
ctx.globalAlpha = fillAlpha;
|
|
62045
|
+
ctx.fillStyle = ibg ?? tint;
|
|
62046
|
+
ctx.fill();
|
|
62047
|
+
ctx.restore();
|
|
62048
|
+
};
|
|
62049
|
+
if (footprint.type === "circle") {
|
|
62050
|
+
ctx.beginPath();
|
|
62051
|
+
ctx.arc(wx(item.x), wy(item.y), footprint.value.radius * ppu, 0, Math.PI * 2);
|
|
62052
|
+
fillShape();
|
|
62053
|
+
ctx.lineWidth = stroke;
|
|
62054
|
+
ctx.strokeStyle = tint;
|
|
62055
|
+
ctx.stroke();
|
|
62056
|
+
continue;
|
|
62057
|
+
}
|
|
62058
|
+
const pts = footprint.value.vertices.map((q) => ({ x: wx(q.x), y: wy(q.y), bulge: q.bulge }));
|
|
62059
|
+
if (pts.length === 0) continue;
|
|
62060
|
+
ctx.beginPath();
|
|
62061
|
+
if (footprint.type === "polygon") {
|
|
62062
|
+
traceVertices(ctx, pts, true);
|
|
62063
|
+
fillShape();
|
|
62064
|
+
ctx.lineWidth = stroke;
|
|
62065
|
+
} else {
|
|
62066
|
+
traceVertices(ctx, pts, false);
|
|
62067
|
+
const band2 = footprint.value.width.type === "some" ? footprint.value.width.value * ppu : void 0;
|
|
62068
|
+
ctx.lineCap = "round";
|
|
62069
|
+
ctx.lineWidth = getSomeorUndefined(item.weight) ?? band2 ?? (isSel ? 2.5 : 1.5);
|
|
62070
|
+
}
|
|
62071
|
+
ctx.strokeStyle = tint;
|
|
62072
|
+
ctx.stroke();
|
|
62073
|
+
ctx.lineCap = "butt";
|
|
62074
|
+
}
|
|
62075
|
+
for (const item of visibleItems) {
|
|
62076
|
+
const tier = tiers.get(item.key) ?? "dot";
|
|
62077
|
+
if (tier === "card") continue;
|
|
62078
|
+
const tint = resolveTint(p2, getSomeorUndefined(item.color), (_c = getSomeorUndefined(item.tone)) == null ? void 0 : _c.type, statusRGB(p2, statusTone$1(item.status)));
|
|
62079
|
+
const isSel = selected === item.key;
|
|
62080
|
+
const x2 = wx(item.x), y2 = wy(item.y);
|
|
62081
|
+
if (tier === "dot") {
|
|
62082
|
+
ctx.beginPath();
|
|
62083
|
+
ctx.arc(x2, y2, MARKER_DOT_RADIUS, 0, Math.PI * 2);
|
|
62084
|
+
ctx.fillStyle = tint;
|
|
62085
|
+
ctx.fill();
|
|
62086
|
+
ctx.lineWidth = 1.5;
|
|
62087
|
+
ctx.strokeStyle = css(p2.white);
|
|
62088
|
+
ctx.stroke();
|
|
62089
|
+
if (isSel) {
|
|
62090
|
+
ctx.beginPath();
|
|
62091
|
+
ctx.arc(x2, y2, 7.5, 0, Math.PI * 2);
|
|
62092
|
+
ctx.lineWidth = 2;
|
|
62093
|
+
ctx.strokeStyle = css(p2.fg);
|
|
62094
|
+
ctx.stroke();
|
|
62095
|
+
}
|
|
62096
|
+
continue;
|
|
62097
|
+
}
|
|
62098
|
+
ctx.font = MARKER_LABEL_FONT;
|
|
62099
|
+
const box = markerHitbox(item, "label", cam, (t4) => ctx.measureText(t4).width);
|
|
62100
|
+
if (box.kind !== "rect") continue;
|
|
62101
|
+
const { left, top, w: w2, h: h2 } = box;
|
|
62102
|
+
ctx.beginPath();
|
|
62103
|
+
(_d = ctx.roundRect) == null ? void 0 : _d.call(ctx, left, top, w2, h2, h2 / 2);
|
|
62104
|
+
if (!ctx.roundRect) ctx.rect(left, top, w2, h2);
|
|
62105
|
+
ctx.fillStyle = css(p2.bgSurface);
|
|
62106
|
+
ctx.fill();
|
|
62107
|
+
ctx.lineWidth = 1;
|
|
62108
|
+
ctx.strokeStyle = isSel ? css(p2.fg) : css(p2.borderStrong);
|
|
62109
|
+
ctx.stroke();
|
|
62110
|
+
ctx.beginPath();
|
|
62111
|
+
ctx.arc(left + MARKER_PIN_PAD_X + MARKER_PIN_DOT_W / 2, y2, MARKER_PIN_DOT_W / 2, 0, Math.PI * 2);
|
|
62112
|
+
ctx.fillStyle = tint;
|
|
62113
|
+
ctx.fill();
|
|
62114
|
+
ctx.fillStyle = css(p2.fg);
|
|
62115
|
+
ctx.textBaseline = "middle";
|
|
62116
|
+
ctx.fillText(item.label, left + MARKER_PIN_PAD_X + MARKER_PIN_DOT_W + MARKER_PIN_GAP, y2);
|
|
62117
|
+
}
|
|
62118
|
+
}
|
|
62119
|
+
const TOKENS = {
|
|
62120
|
+
brand600: "brand.600",
|
|
62121
|
+
brand500: "brand.500",
|
|
62122
|
+
fg: "fg",
|
|
62123
|
+
fgMuted: "fg.muted",
|
|
62124
|
+
fgSubtle: "fg.subtle",
|
|
62125
|
+
borderStrong: "border.strong",
|
|
62126
|
+
borderSubtle: "border.subtle",
|
|
62127
|
+
bgSurface: "bg.surface",
|
|
62128
|
+
bgPanel: "bg.panel",
|
|
62129
|
+
statusOk: "status.ok",
|
|
62130
|
+
statusWarn: "status.warn",
|
|
62131
|
+
statusBad: "status.bad",
|
|
62132
|
+
white: "white"
|
|
62133
|
+
};
|
|
62134
|
+
const KEYS = Object.keys(TOKENS);
|
|
62135
|
+
function parseRGB(s2) {
|
|
62136
|
+
const m2 = s2.match(/[\d.]+/g);
|
|
62137
|
+
if (m2 === null || m2.length < 3) return [0, 0, 0];
|
|
62138
|
+
return [Math.round(+m2[0]), Math.round(+m2[1]), Math.round(+m2[2])];
|
|
62139
|
+
}
|
|
62140
|
+
const SchematicPaletteProbe = React.memo(function SchematicPaletteProbe2({ onResolve }) {
|
|
62141
|
+
const ref = React.useRef(null);
|
|
62142
|
+
React.useLayoutEffect(() => {
|
|
62143
|
+
const read = () => {
|
|
62144
|
+
const el = ref.current;
|
|
62145
|
+
if (el === null) return;
|
|
62146
|
+
const kids = el.children;
|
|
62147
|
+
const palette = {};
|
|
62148
|
+
KEYS.forEach((k2, i2) => {
|
|
62149
|
+
const child = kids[i2];
|
|
62150
|
+
if (child !== void 0) palette[k2] = parseRGB(getComputedStyle(child).color);
|
|
62151
|
+
});
|
|
62152
|
+
onResolve(palette);
|
|
62153
|
+
};
|
|
62154
|
+
read();
|
|
62155
|
+
const obs = new MutationObserver(read);
|
|
62156
|
+
obs.observe(document.documentElement, { attributes: true, attributeFilter: ["class", "data-theme", "style"] });
|
|
62157
|
+
return () => obs.disconnect();
|
|
62158
|
+
}, [onResolve]);
|
|
62159
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { ref, "aria-hidden": "true", css: { position: "absolute", width: "0", height: "0", overflow: "hidden", pointerEvents: "none" }, children: KEYS.map((k2) => /* @__PURE__ */ jsxRuntime.jsx(react.Box, { color: TOKENS[k2] }, k2)) });
|
|
62160
|
+
});
|
|
62161
|
+
library$1.add(icons$2);
|
|
62162
|
+
const schematicEqual = east.equalFor(internal.Schematic.Types.Schematic);
|
|
62163
|
+
const MAX_ZOOM = 40;
|
|
62164
|
+
const LOD_CARD_PPU = 30;
|
|
62165
|
+
const LOD_LABEL_PPU = 16;
|
|
62166
|
+
const MINIMAP_AUTO = 25;
|
|
62167
|
+
function statusTone(status) {
|
|
62168
|
+
return status.type === "some" ? status.value.type : void 0;
|
|
62169
|
+
}
|
|
62170
|
+
function niceScaleLength(ppu, targetPx) {
|
|
62171
|
+
const target = targetPx / ppu;
|
|
62172
|
+
const pow2 = Math.pow(10, Math.floor(Math.log10(target)));
|
|
62173
|
+
for (const m2 of [5, 2, 1]) {
|
|
62174
|
+
if (m2 * pow2 <= target) return m2 * pow2;
|
|
62175
|
+
}
|
|
62176
|
+
return pow2;
|
|
62177
|
+
}
|
|
62178
|
+
function pointInPolygon(x2, y2, pts) {
|
|
62179
|
+
let inside = false;
|
|
62180
|
+
for (let i2 = 0, j2 = pts.length - 1; i2 < pts.length; j2 = i2++) {
|
|
62181
|
+
const xi = pts[i2].x, yi = pts[i2].y, xj = pts[j2].x, yj = pts[j2].y;
|
|
62182
|
+
if (yi > y2 !== yj > y2 && x2 < (xj - xi) * (y2 - yi) / (yj - yi) + xi) inside = !inside;
|
|
62183
|
+
}
|
|
62184
|
+
return inside;
|
|
61584
62185
|
}
|
|
61585
62186
|
function buildNavTree(zones, items) {
|
|
61586
62187
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -61663,7 +62264,7 @@ function declutterTiers(items, tree, baseLod, ppu, selected) {
|
|
|
61663
62264
|
if (selected !== null && tiers.has(selected)) tiers.set(selected, baseLod);
|
|
61664
62265
|
return tiers;
|
|
61665
62266
|
}
|
|
61666
|
-
const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value }) {
|
|
62267
|
+
const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value, storageKey }) {
|
|
61667
62268
|
const styles2 = react.useSlotRecipe({ key: "schematic" })();
|
|
61668
62269
|
const { width: W2, height: H } = value.extent;
|
|
61669
62270
|
const onSelectFn = React.useMemo(() => getSomeorUndefined(value.onSelect), [value.onSelect]);
|
|
@@ -61671,13 +62272,19 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61671
62272
|
const showGrid = getSomeorUndefined(value.grid) ?? true;
|
|
61672
62273
|
const showNavigator = getSomeorUndefined(value.navigator) ?? value.zones.length > 0;
|
|
61673
62274
|
const showMinimap = getSomeorUndefined(value.minimap) ?? value.items.length >= MINIMAP_AUTO;
|
|
62275
|
+
const fixedHeight = getSomeorUndefined(value.height);
|
|
61674
62276
|
const [selected, setSelected] = React.useState(null);
|
|
61675
|
-
const [view, setView] = React.useState(IDENTITY);
|
|
61676
62277
|
const [query, setQuery] = React.useState("");
|
|
61677
62278
|
const [openZone, setOpenZone] = React.useState(null);
|
|
61678
|
-
const
|
|
62279
|
+
const { state: persisted, setState: setPersisted } = usePersistedState(storageKey, { navCollapsed: false });
|
|
62280
|
+
const navCollapsed = persisted.navCollapsed;
|
|
62281
|
+
const setNavCollapsed = React.useCallback((next) => setPersisted((prev) => ({ ...prev, navCollapsed: next })), [setPersisted]);
|
|
62282
|
+
const [palette, setPalette] = React.useState(null);
|
|
61679
62283
|
const navTreeRef = React.useRef(null);
|
|
61680
62284
|
const canvasRef = React.useRef(null);
|
|
62285
|
+
const drawRef = React.useRef(null);
|
|
62286
|
+
const cardLayerRef = React.useRef(null);
|
|
62287
|
+
const gridRef = React.useRef(null);
|
|
61681
62288
|
const [size, setSize] = React.useState(null);
|
|
61682
62289
|
React.useLayoutEffect(() => {
|
|
61683
62290
|
const el = canvasRef.current;
|
|
@@ -61688,10 +62295,30 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61688
62295
|
ro.observe(el);
|
|
61689
62296
|
return () => ro.disconnect();
|
|
61690
62297
|
}, []);
|
|
62298
|
+
const [dpr, setDpr] = React.useState(() => typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1);
|
|
62299
|
+
React.useEffect(() => {
|
|
62300
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
62301
|
+
let cleanup = () => {
|
|
62302
|
+
};
|
|
62303
|
+
const subscribe2 = () => {
|
|
62304
|
+
const mql = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
62305
|
+
const onChange2 = () => {
|
|
62306
|
+
cleanup();
|
|
62307
|
+
setDpr(window.devicePixelRatio || 1);
|
|
62308
|
+
subscribe2();
|
|
62309
|
+
};
|
|
62310
|
+
mql.addEventListener("change", onChange2);
|
|
62311
|
+
cleanup = () => mql.removeEventListener("change", onChange2);
|
|
62312
|
+
};
|
|
62313
|
+
subscribe2();
|
|
62314
|
+
return () => cleanup();
|
|
62315
|
+
}, []);
|
|
62316
|
+
const cameraRef = React.useRef(IDENTITY);
|
|
62317
|
+
const modeRef = React.useRef("idle");
|
|
62318
|
+
const animRef = React.useRef(null);
|
|
62319
|
+
const [cameraSnapshot, setCameraSnapshot] = React.useState(IDENTITY);
|
|
61691
62320
|
const fit = size !== null ? Math.min(size.w / W2, size.h / H) : 0;
|
|
61692
|
-
const ppu = fit *
|
|
61693
|
-
const wx = (x2) => x2 * ppu + view.tx;
|
|
61694
|
-
const wy = (y2) => y2 * ppu + view.ty;
|
|
62321
|
+
const ppu = fit * cameraSnapshot.zoom;
|
|
61695
62322
|
const centers = React.useMemo(() => {
|
|
61696
62323
|
const out = /* @__PURE__ */ new Map();
|
|
61697
62324
|
for (const item of value.items) out.set(item.key, { x: item.x, y: item.y });
|
|
@@ -61701,19 +62328,35 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61701
62328
|
const tree = new RBush();
|
|
61702
62329
|
tree.load(value.items.map((item) => {
|
|
61703
62330
|
const hw = (getSomeorUndefined(item.width) ?? 0) / 2 + 2.4;
|
|
61704
|
-
|
|
62331
|
+
let minX = item.x - hw, minY = item.y - 2, maxX = item.x + hw, maxY = item.y + 2;
|
|
62332
|
+
const fp = getSomeorUndefined(item.footprint);
|
|
62333
|
+
if (fp !== void 0 && fp.type === "circle") {
|
|
62334
|
+
const r2 = fp.value.radius;
|
|
62335
|
+
minX = Math.min(minX, item.x - r2);
|
|
62336
|
+
minY = Math.min(minY, item.y - r2);
|
|
62337
|
+
maxX = Math.max(maxX, item.x + r2);
|
|
62338
|
+
maxY = Math.max(maxY, item.y + r2);
|
|
62339
|
+
} else if (fp !== void 0 && fp.type !== "rect") {
|
|
62340
|
+
for (const v2 of fp.value.vertices) {
|
|
62341
|
+
minX = Math.min(minX, v2.x);
|
|
62342
|
+
minY = Math.min(minY, v2.y);
|
|
62343
|
+
maxX = Math.max(maxX, v2.x);
|
|
62344
|
+
maxY = Math.max(maxY, v2.y);
|
|
62345
|
+
}
|
|
62346
|
+
}
|
|
62347
|
+
return { minX, minY, maxX, maxY, item };
|
|
61705
62348
|
}));
|
|
61706
62349
|
return tree;
|
|
61707
62350
|
}, [value.items]);
|
|
61708
62351
|
const visibleItems = React.useMemo(() => {
|
|
61709
62352
|
if (size === null || ppu === 0) return [];
|
|
61710
62353
|
return index2.search({
|
|
61711
|
-
minX: -
|
|
61712
|
-
minY: -
|
|
61713
|
-
maxX: (size.w -
|
|
61714
|
-
maxY: (size.h -
|
|
62354
|
+
minX: -cameraSnapshot.tx / ppu,
|
|
62355
|
+
minY: -cameraSnapshot.ty / ppu,
|
|
62356
|
+
maxX: (size.w - cameraSnapshot.tx) / ppu,
|
|
62357
|
+
maxY: (size.h - cameraSnapshot.ty) / ppu
|
|
61715
62358
|
}).map((b2) => b2.item);
|
|
61716
|
-
}, [index2, size, ppu,
|
|
62359
|
+
}, [index2, size, ppu, cameraSnapshot]);
|
|
61717
62360
|
const nav = React.useMemo(() => buildNavTree(value.zones, value.items), [value.zones, value.items]);
|
|
61718
62361
|
const zoneDisplay = React.useMemo(() => {
|
|
61719
62362
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -61739,39 +62382,194 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61739
62382
|
const indexOf = new Map(ordered.map((item, i2) => [item.key, i2]));
|
|
61740
62383
|
return { ordered, indexOf };
|
|
61741
62384
|
}, [nav]);
|
|
61742
|
-
const
|
|
61743
|
-
|
|
61744
|
-
|
|
62385
|
+
const [currentZone, setCurrentZone] = React.useState(void 0);
|
|
62386
|
+
React.useEffect(() => {
|
|
62387
|
+
const SPY_ENTER = 0.3, SPY_STAY = 0.18, SPY_MARGIN = 0.15;
|
|
62388
|
+
if (size === null || ppu === 0 || cameraSnapshot.zoom <= 1.05) {
|
|
62389
|
+
setCurrentZone(void 0);
|
|
62390
|
+
return;
|
|
62391
|
+
}
|
|
62392
|
+
const vx0 = -cameraSnapshot.tx / ppu, vy0 = -cameraSnapshot.ty / ppu;
|
|
62393
|
+
const vx1 = (size.w - cameraSnapshot.tx) / ppu, vy1 = (size.h - cameraSnapshot.ty) / ppu;
|
|
62394
|
+
const viewArea = (vx1 - vx0) * (vy1 - vy0);
|
|
62395
|
+
const scoreOf = (z) => {
|
|
62396
|
+
const ix = Math.max(0, Math.min(vx1, z.x + z.width) - Math.max(vx0, z.x));
|
|
62397
|
+
const iy = Math.max(0, Math.min(vy1, z.y + z.height) - Math.max(vy0, z.y));
|
|
62398
|
+
return ix * iy / Math.min(viewArea, z.width * z.height);
|
|
62399
|
+
};
|
|
62400
|
+
let best;
|
|
62401
|
+
let bestScore = 0;
|
|
62402
|
+
for (const z of value.zones) {
|
|
62403
|
+
const score = scoreOf(z);
|
|
62404
|
+
if (score > bestScore) {
|
|
62405
|
+
best = z.key;
|
|
62406
|
+
bestScore = score;
|
|
62407
|
+
}
|
|
62408
|
+
}
|
|
62409
|
+
setCurrentZone((prev) => {
|
|
62410
|
+
if (prev !== void 0) {
|
|
62411
|
+
const holder = value.zones.find((z) => z.key === prev);
|
|
62412
|
+
const holderScore = holder !== void 0 ? scoreOf(holder) : 0;
|
|
62413
|
+
if (holderScore >= SPY_STAY && (best === prev || bestScore < holderScore + SPY_MARGIN)) return prev;
|
|
62414
|
+
}
|
|
62415
|
+
return bestScore >= SPY_ENTER ? best : void 0;
|
|
62416
|
+
});
|
|
62417
|
+
}, [size, ppu, cameraSnapshot, value.zones]);
|
|
62418
|
+
const lod = ppu >= LOD_CARD_PPU ? "card" : ppu >= LOD_LABEL_PPU ? "label" : "dot";
|
|
62419
|
+
const centerTree = React.useMemo(() => buildCenterTree(visibleItems), [visibleItems]);
|
|
62420
|
+
const tiers = React.useMemo(() => declutterTiers(visibleItems, centerTree, lod, ppu, selected), [visibleItems, centerTree, lod, ppu, selected]);
|
|
62421
|
+
const lowerQuery = query.trim().toLowerCase();
|
|
62422
|
+
const searchHits = React.useMemo(() => lowerQuery === "" ? [] : value.items.filter((i2) => i2.key.toLowerCase().includes(lowerQuery) || i2.label.toLowerCase().includes(lowerQuery)).slice(0, 12), [lowerQuery, value.items]);
|
|
62423
|
+
const scaleLen = ppu > 0 ? niceScaleLength(ppu, 100) : 0;
|
|
62424
|
+
const valueRef = React.useRef(value);
|
|
62425
|
+
valueRef.current = value;
|
|
62426
|
+
const sizeRef = React.useRef(size);
|
|
62427
|
+
sizeRef.current = size;
|
|
62428
|
+
const fitRef = React.useRef(fit);
|
|
62429
|
+
fitRef.current = fit;
|
|
62430
|
+
const dprRef = React.useRef(dpr);
|
|
62431
|
+
dprRef.current = dpr;
|
|
62432
|
+
const paletteRef = React.useRef(palette);
|
|
62433
|
+
paletteRef.current = palette;
|
|
62434
|
+
const visibleItemsRef = React.useRef(visibleItems);
|
|
62435
|
+
visibleItemsRef.current = visibleItems;
|
|
62436
|
+
const tiersRef = React.useRef(tiers);
|
|
62437
|
+
tiersRef.current = tiers;
|
|
62438
|
+
const selectedRef = React.useRef(selected);
|
|
62439
|
+
selectedRef.current = selected;
|
|
62440
|
+
const centersRef = React.useRef(centers);
|
|
62441
|
+
centersRef.current = centers;
|
|
62442
|
+
const openZoneRef = React.useRef(openZone);
|
|
62443
|
+
openZoneRef.current = openZone;
|
|
62444
|
+
const lastPaintRef = React.useRef(null);
|
|
62445
|
+
const applyCamera = React.useCallback(() => {
|
|
62446
|
+
const sz = sizeRef.current;
|
|
62447
|
+
if (sz === null) return;
|
|
62448
|
+
const cam = cameraRef.current;
|
|
62449
|
+
const ppuLive = fitRef.current * cam.zoom;
|
|
62450
|
+
const dprLive = dprRef.current;
|
|
62451
|
+
const layer = cardLayerRef.current;
|
|
62452
|
+
if (layer !== null) {
|
|
62453
|
+
layer.style.setProperty("--cam-ppu", String(ppuLive));
|
|
62454
|
+
layer.style.setProperty("--cam-tx", `${cam.tx}px`);
|
|
62455
|
+
layer.style.setProperty("--cam-ty", `${cam.ty}px`);
|
|
62456
|
+
}
|
|
62457
|
+
const grid = gridRef.current;
|
|
62458
|
+
if (grid !== null) {
|
|
62459
|
+
const len = ppuLive > 0 ? niceScaleLength(ppuLive, 100) : 0;
|
|
62460
|
+
if (len > 0) {
|
|
62461
|
+
const major = len * ppuLive, minor = major / 5;
|
|
62462
|
+
grid.style.backgroundSize = `${major}px ${major}px, ${major}px ${major}px, ${minor}px ${minor}px, ${minor}px ${minor}px`;
|
|
62463
|
+
grid.style.backgroundPosition = `${cam.tx}px 0, 0 ${cam.ty}px, ${cam.tx}px 0, 0 ${cam.ty}px`;
|
|
62464
|
+
}
|
|
62465
|
+
}
|
|
62466
|
+
const canvas = drawRef.current, pal = paletteRef.current;
|
|
62467
|
+
if (canvas === null || pal === null) return;
|
|
62468
|
+
const last = lastPaintRef.current;
|
|
62469
|
+
if (last !== null && last.zoom === cam.zoom && last.tx === cam.tx && last.ty === cam.ty && last.vis === visibleItemsRef.current && last.tiers === tiersRef.current && last.sel === selectedRef.current && last.pal === pal && last.w === sz.w && last.h === sz.h && last.dpr === dprLive && last.val === valueRef.current) return;
|
|
62470
|
+
lastPaintRef.current = {
|
|
62471
|
+
zoom: cam.zoom,
|
|
62472
|
+
tx: cam.tx,
|
|
62473
|
+
ty: cam.ty,
|
|
62474
|
+
vis: visibleItemsRef.current,
|
|
62475
|
+
tiers: tiersRef.current,
|
|
62476
|
+
sel: selectedRef.current,
|
|
62477
|
+
pal,
|
|
62478
|
+
w: sz.w,
|
|
62479
|
+
h: sz.h,
|
|
62480
|
+
dpr: dprLive,
|
|
62481
|
+
val: valueRef.current
|
|
62482
|
+
};
|
|
62483
|
+
const bw = Math.round(sz.w * dprLive), bh = Math.round(sz.h * dprLive);
|
|
62484
|
+
if (canvas.width !== bw || canvas.height !== bh) {
|
|
62485
|
+
canvas.width = bw;
|
|
62486
|
+
canvas.height = bh;
|
|
62487
|
+
}
|
|
62488
|
+
const ctx = canvas.getContext("2d");
|
|
62489
|
+
if (ctx === null) return;
|
|
62490
|
+
ctx.setTransform(dprLive, 0, 0, dprLive, 0, 0);
|
|
62491
|
+
paintSchematic({
|
|
62492
|
+
ctx,
|
|
62493
|
+
value: valueRef.current,
|
|
62494
|
+
cam: { ppu: ppuLive, tx: cam.tx, ty: cam.ty },
|
|
62495
|
+
width: sz.w,
|
|
62496
|
+
height: sz.h,
|
|
62497
|
+
visibleItems: visibleItemsRef.current,
|
|
62498
|
+
tiers: tiersRef.current,
|
|
62499
|
+
selected: selectedRef.current,
|
|
62500
|
+
centers: centersRef.current,
|
|
62501
|
+
palette: pal
|
|
62502
|
+
});
|
|
62503
|
+
}, []);
|
|
62504
|
+
const coalescerRef = React.useRef(null);
|
|
62505
|
+
if (coalescerRef.current === null && typeof requestAnimationFrame !== "undefined") {
|
|
62506
|
+
coalescerRef.current = makeRafCoalescer(requestAnimationFrame, cancelAnimationFrame);
|
|
62507
|
+
}
|
|
62508
|
+
const requestRender = React.useCallback(() => {
|
|
62509
|
+
const run = () => {
|
|
62510
|
+
applyCamera();
|
|
62511
|
+
const cam = cameraRef.current;
|
|
62512
|
+
setCameraSnapshot((prev) => prev.zoom === cam.zoom && prev.tx === cam.tx && prev.ty === cam.ty ? prev : { zoom: cam.zoom, tx: cam.tx, ty: cam.ty });
|
|
62513
|
+
};
|
|
62514
|
+
const cz = coalescerRef.current;
|
|
62515
|
+
if (cz !== null) cz.request(run);
|
|
62516
|
+
else run();
|
|
62517
|
+
}, [applyCamera]);
|
|
62518
|
+
const cancelFlyRaf = React.useCallback(() => {
|
|
62519
|
+
if (animRef.current !== null) {
|
|
62520
|
+
cancelAnimationFrame(animRef.current);
|
|
62521
|
+
animRef.current = null;
|
|
62522
|
+
}
|
|
62523
|
+
}, []);
|
|
62524
|
+
const transition = React.useCallback((event) => {
|
|
62525
|
+
if (cancelsFly(modeRef.current, event)) cancelFlyRaf();
|
|
62526
|
+
modeRef.current = nextMode(modeRef.current, event);
|
|
62527
|
+
}, [cancelFlyRaf]);
|
|
61745
62528
|
const flyTo = React.useCallback((rect) => {
|
|
61746
|
-
if (
|
|
62529
|
+
if (sizeRef.current === null || fitRef.current === 0) return;
|
|
61747
62530
|
const pad2 = 1.18;
|
|
61748
|
-
const
|
|
61749
|
-
|
|
61750
|
-
|
|
61751
|
-
|
|
61752
|
-
|
|
62531
|
+
const frame = () => {
|
|
62532
|
+
const sz = sizeRef.current, ft = fitRef.current;
|
|
62533
|
+
if (sz === null || ft === 0) return null;
|
|
62534
|
+
const zoom = Math.min(MAX_ZOOM, Math.min(sz.w / (rect.w * pad2 * ft), sz.h / (rect.h * pad2 * ft)));
|
|
62535
|
+
return {
|
|
62536
|
+
zoom,
|
|
62537
|
+
tx: sz.w / 2 - (rect.x + rect.w / 2) * ft * zoom,
|
|
62538
|
+
ty: sz.h / 2 - (rect.y + rect.h / 2) * ft * zoom
|
|
62539
|
+
};
|
|
61753
62540
|
};
|
|
61754
|
-
const from =
|
|
62541
|
+
const from = { ...cameraRef.current };
|
|
61755
62542
|
const start = performance.now();
|
|
61756
62543
|
if (animRef.current !== null) cancelAnimationFrame(animRef.current);
|
|
62544
|
+
transition("flyStart");
|
|
61757
62545
|
const step = (now) => {
|
|
61758
62546
|
const t4 = Math.min(1, (now - start) / 350);
|
|
61759
62547
|
const e3 = 1 - Math.pow(1 - t4, 3);
|
|
61760
|
-
|
|
61761
|
-
|
|
61762
|
-
|
|
61763
|
-
|
|
61764
|
-
|
|
61765
|
-
|
|
62548
|
+
const target = frame();
|
|
62549
|
+
if (target !== null) {
|
|
62550
|
+
cameraRef.current = {
|
|
62551
|
+
zoom: from.zoom + (target.zoom - from.zoom) * e3,
|
|
62552
|
+
tx: from.tx + (target.tx - from.tx) * e3,
|
|
62553
|
+
ty: from.ty + (target.ty - from.ty) * e3
|
|
62554
|
+
};
|
|
62555
|
+
applyCamera();
|
|
62556
|
+
const cam = cameraRef.current;
|
|
62557
|
+
setCameraSnapshot({ zoom: cam.zoom, tx: cam.tx, ty: cam.ty });
|
|
62558
|
+
}
|
|
62559
|
+
if (t4 < 1) {
|
|
62560
|
+
animRef.current = requestAnimationFrame(step);
|
|
62561
|
+
} else {
|
|
62562
|
+
animRef.current = null;
|
|
62563
|
+
transition("flyEnd");
|
|
62564
|
+
}
|
|
61766
62565
|
};
|
|
61767
62566
|
animRef.current = requestAnimationFrame(step);
|
|
61768
|
-
}, [
|
|
61769
|
-
React.
|
|
61770
|
-
if (animRef.current !== null) cancelAnimationFrame(animRef.current);
|
|
61771
|
-
}, []);
|
|
62567
|
+
}, [applyCamera, transition]);
|
|
62568
|
+
const zoneOverrideRef = React.useRef(null);
|
|
61772
62569
|
const flyToItem = React.useCallback((item) => {
|
|
61773
62570
|
flyTo({ x: item.x - 4, y: item.y - 3, w: 8, h: 6 });
|
|
61774
62571
|
setSelected(item.key);
|
|
62572
|
+
zoneOverrideRef.current = null;
|
|
61775
62573
|
setOpenZone(nav.zoneOf.get(item.key) ?? null);
|
|
61776
62574
|
if (onSelectFn) queueMicrotask(() => onSelectFn(item.key));
|
|
61777
62575
|
}, [flyTo, nav.zoneOf, onSelectFn]);
|
|
@@ -61783,6 +62581,7 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61783
62581
|
}, [itemOrder, selected, flyToItem]);
|
|
61784
62582
|
const flyToZone = React.useCallback((zone) => {
|
|
61785
62583
|
flyTo({ x: zone.x, y: zone.y, w: zone.width, h: zone.height });
|
|
62584
|
+
zoneOverrideRef.current = null;
|
|
61786
62585
|
setOpenZone(zone.key);
|
|
61787
62586
|
}, [flyTo]);
|
|
61788
62587
|
React.useEffect(() => {
|
|
@@ -61792,85 +62591,144 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61792
62591
|
e3.preventDefault();
|
|
61793
62592
|
const rect = el.getBoundingClientRect();
|
|
61794
62593
|
const px = e3.clientX - rect.left, py = e3.clientY - rect.top;
|
|
61795
|
-
|
|
61796
|
-
|
|
61797
|
-
|
|
61798
|
-
const next = { zoom, tx: px - k2 * (px - prev.tx), ty: py - k2 * (py - prev.ty) };
|
|
61799
|
-
return zoom === 1 ? IDENTITY : next;
|
|
61800
|
-
});
|
|
62594
|
+
transition("wheel");
|
|
62595
|
+
cameraRef.current = zoomAbout(cameraRef.current, Math.exp(-e3.deltaY * 15e-4), px, py, 1, MAX_ZOOM);
|
|
62596
|
+
requestRender();
|
|
61801
62597
|
};
|
|
61802
62598
|
el.addEventListener("wheel", onWheel, { passive: false });
|
|
61803
62599
|
return () => el.removeEventListener("wheel", onWheel);
|
|
61804
|
-
}, []);
|
|
62600
|
+
}, [transition, requestRender]);
|
|
61805
62601
|
const panRef = React.useRef(null);
|
|
62602
|
+
const movedRef = React.useRef(false);
|
|
62603
|
+
const pickAt = React.useCallback((host, clientX, clientY) => {
|
|
62604
|
+
var _a2, _b, _c;
|
|
62605
|
+
const sz = sizeRef.current;
|
|
62606
|
+
if (sz === null) return false;
|
|
62607
|
+
const cam = cameraRef.current;
|
|
62608
|
+
const ppuLive = fitRef.current * cam.zoom;
|
|
62609
|
+
if (ppuLive === 0) return false;
|
|
62610
|
+
const rect = host.getBoundingClientRect();
|
|
62611
|
+
const sx = clientX - rect.left, sy = clientY - rect.top;
|
|
62612
|
+
const wxp = (sx - cam.tx) / ppuLive, wyp = (sy - cam.ty) / ppuLive;
|
|
62613
|
+
const select = (key) => {
|
|
62614
|
+
setSelected(key);
|
|
62615
|
+
if (onSelectFn) queueMicrotask(() => onSelectFn(key));
|
|
62616
|
+
};
|
|
62617
|
+
for (const it of visibleItems) {
|
|
62618
|
+
if ((tiers.get(it.key) ?? lod) !== "card") continue;
|
|
62619
|
+
const fp = getSomeorUndefined(it.footprint);
|
|
62620
|
+
if (fp === void 0 || fp.type === "rect") continue;
|
|
62621
|
+
const hit = fp.type === "circle" ? Math.hypot(wxp - it.x, wyp - it.y) <= fp.value.radius : pointInPolygon(wxp, wyp, fp.value.vertices);
|
|
62622
|
+
if (hit) {
|
|
62623
|
+
select(it.key);
|
|
62624
|
+
return true;
|
|
62625
|
+
}
|
|
62626
|
+
}
|
|
62627
|
+
if (typeof document !== "undefined") {
|
|
62628
|
+
const cardKey = (_b = (_a2 = document.elementFromPoint(clientX, clientY)) == null ? void 0 : _a2.closest("[data-card-key]")) == null ? void 0 : _b.getAttribute("data-card-key");
|
|
62629
|
+
if (cardKey !== null && cardKey !== void 0) {
|
|
62630
|
+
select(cardKey);
|
|
62631
|
+
return true;
|
|
62632
|
+
}
|
|
62633
|
+
}
|
|
62634
|
+
const ctx = ((_c = drawRef.current) == null ? void 0 : _c.getContext("2d")) ?? null;
|
|
62635
|
+
if (ctx !== null) {
|
|
62636
|
+
ctx.save();
|
|
62637
|
+
ctx.font = MARKER_LABEL_FONT;
|
|
62638
|
+
}
|
|
62639
|
+
const camScreen = { ppu: ppuLive, tx: cam.tx, ty: cam.ty };
|
|
62640
|
+
let best = null, bestD = Infinity;
|
|
62641
|
+
for (const it of visibleItems) {
|
|
62642
|
+
const tier = tiers.get(it.key) ?? lod;
|
|
62643
|
+
if (tier === "card") continue;
|
|
62644
|
+
const box = markerHitbox(it, tier, camScreen, (t4) => ctx !== null ? ctx.measureText(t4).width : t4.length * 6);
|
|
62645
|
+
if (!markerHit(box, sx, sy)) continue;
|
|
62646
|
+
const d2 = Math.hypot(it.x * ppuLive + cam.tx - sx, it.y * ppuLive + cam.ty - sy);
|
|
62647
|
+
if (d2 < bestD) {
|
|
62648
|
+
best = it;
|
|
62649
|
+
bestD = d2;
|
|
62650
|
+
}
|
|
62651
|
+
}
|
|
62652
|
+
if (ctx !== null) ctx.restore();
|
|
62653
|
+
if (best !== null) {
|
|
62654
|
+
flyToItem(best);
|
|
62655
|
+
return true;
|
|
62656
|
+
}
|
|
62657
|
+
return false;
|
|
62658
|
+
}, [tiers, lod, visibleItems, onSelectFn, flyToItem]);
|
|
61806
62659
|
const onCanvasPointerDown = React.useCallback((e3) => {
|
|
61807
62660
|
if (e3.button !== 0) return;
|
|
61808
62661
|
if (e3.target.closest("button") !== null) return;
|
|
61809
|
-
|
|
62662
|
+
transition("pointerDown");
|
|
62663
|
+
panRef.current = { x: e3.clientX, y: e3.clientY, tx: cameraRef.current.tx, ty: cameraRef.current.ty };
|
|
62664
|
+
movedRef.current = false;
|
|
61810
62665
|
e3.currentTarget.setPointerCapture(e3.pointerId);
|
|
61811
|
-
}, []);
|
|
62666
|
+
}, [transition]);
|
|
61812
62667
|
const onCanvasPointerMove = React.useCallback((e3) => {
|
|
61813
62668
|
const pan = panRef.current;
|
|
61814
62669
|
if (!pan) return;
|
|
61815
|
-
|
|
61816
|
-
|
|
61817
|
-
|
|
62670
|
+
if (Math.abs(e3.clientX - pan.x) > 4 || Math.abs(e3.clientY - pan.y) > 4) movedRef.current = true;
|
|
62671
|
+
cameraRef.current = { ...cameraRef.current, tx: pan.tx + e3.clientX - pan.x, ty: pan.ty + e3.clientY - pan.y };
|
|
62672
|
+
requestRender();
|
|
62673
|
+
}, [requestRender]);
|
|
62674
|
+
const endPan = React.useCallback(() => {
|
|
62675
|
+
if (panRef.current === null) return false;
|
|
61818
62676
|
panRef.current = null;
|
|
61819
|
-
|
|
61820
|
-
|
|
62677
|
+
transition("pointerUp");
|
|
62678
|
+
return true;
|
|
62679
|
+
}, [transition]);
|
|
62680
|
+
const onCanvasPointerUp = React.useCallback((e3) => {
|
|
62681
|
+
const wasPress = endPan();
|
|
62682
|
+
if (!wasPress || movedRef.current) return;
|
|
62683
|
+
if (!pickAt(e3.currentTarget, e3.clientX, e3.clientY)) setSelected(null);
|
|
62684
|
+
}, [endPan, pickAt]);
|
|
62685
|
+
const onCanvasPointerCancel = React.useCallback(() => {
|
|
62686
|
+
movedRef.current = false;
|
|
62687
|
+
endPan();
|
|
62688
|
+
}, [endPan]);
|
|
62689
|
+
const resetView = React.useCallback(() => {
|
|
62690
|
+
transition("cancel");
|
|
62691
|
+
cameraRef.current = IDENTITY;
|
|
62692
|
+
requestRender();
|
|
62693
|
+
}, [transition, requestRender]);
|
|
61821
62694
|
const zoomBy = React.useCallback((factor) => {
|
|
61822
|
-
|
|
61823
|
-
|
|
61824
|
-
|
|
61825
|
-
|
|
61826
|
-
|
|
61827
|
-
|
|
61828
|
-
|
|
61829
|
-
|
|
61830
|
-
|
|
61831
|
-
|
|
61832
|
-
const
|
|
61833
|
-
|
|
61834
|
-
|
|
61835
|
-
|
|
61836
|
-
}
|
|
61837
|
-
|
|
61838
|
-
|
|
61839
|
-
|
|
61840
|
-
|
|
61841
|
-
|
|
61842
|
-
|
|
61843
|
-
|
|
61844
|
-
|
|
61845
|
-
|
|
61846
|
-
|
|
61847
|
-
for (const z of value.zones) {
|
|
61848
|
-
const score = scoreOf(z);
|
|
61849
|
-
if (score > bestScore) {
|
|
61850
|
-
best = z.key;
|
|
61851
|
-
bestScore = score;
|
|
61852
|
-
}
|
|
61853
|
-
}
|
|
61854
|
-
setCurrentZone((prev) => {
|
|
61855
|
-
if (prev !== void 0) {
|
|
61856
|
-
const holder = value.zones.find((z) => z.key === prev);
|
|
61857
|
-
const holderScore = holder !== void 0 ? scoreOf(holder) : 0;
|
|
61858
|
-
if (holderScore >= SPY_STAY && (best === prev || bestScore < holderScore + SPY_MARGIN)) return prev;
|
|
61859
|
-
}
|
|
61860
|
-
return bestScore >= SPY_ENTER ? best : void 0;
|
|
61861
|
-
});
|
|
61862
|
-
}, [size, ppu, view, value.zones]);
|
|
61863
|
-
const lod = ppu >= LOD_CARD_PPU ? "card" : ppu >= LOD_LABEL_PPU ? "label" : "dot";
|
|
61864
|
-
const centerTree = React.useMemo(() => buildCenterTree(visibleItems), [visibleItems]);
|
|
61865
|
-
const tiers = React.useMemo(() => declutterTiers(visibleItems, centerTree, lod, ppu, selected), [visibleItems, centerTree, lod, ppu, selected]);
|
|
61866
|
-
const lowerQuery = query.trim().toLowerCase();
|
|
61867
|
-
const searchHits = React.useMemo(() => lowerQuery === "" ? [] : value.items.filter((i2) => i2.key.toLowerCase().includes(lowerQuery) || i2.label.toLowerCase().includes(lowerQuery)).slice(0, 12), [lowerQuery, value.items]);
|
|
61868
|
-
const scaleLen = ppu > 0 ? niceScaleLength(ppu, 100) : 0;
|
|
62695
|
+
const sz = sizeRef.current;
|
|
62696
|
+
if (sz === null) return;
|
|
62697
|
+
transition("zoom");
|
|
62698
|
+
cameraRef.current = zoomAbout(cameraRef.current, factor, sz.w / 2, sz.h / 2, 1, MAX_ZOOM);
|
|
62699
|
+
requestRender();
|
|
62700
|
+
}, [transition, requestRender]);
|
|
62701
|
+
const minimapDragRef = React.useRef(false);
|
|
62702
|
+
const minimapJump = React.useCallback((el, clientX, clientY) => {
|
|
62703
|
+
const sz = sizeRef.current;
|
|
62704
|
+
if (sz === null) return;
|
|
62705
|
+
const rect = el.getBoundingClientRect();
|
|
62706
|
+
const cx2 = (clientX - rect.left) / rect.width * W2;
|
|
62707
|
+
const cy = (clientY - rect.top) / rect.height * H;
|
|
62708
|
+
const cam = cameraRef.current;
|
|
62709
|
+
cameraRef.current = { ...cam, tx: sz.w / 2 - cx2 * fitRef.current * cam.zoom, ty: sz.h / 2 - cy * fitRef.current * cam.zoom };
|
|
62710
|
+
requestRender();
|
|
62711
|
+
}, [W2, H, requestRender]);
|
|
62712
|
+
React.useEffect(() => () => {
|
|
62713
|
+
var _a2;
|
|
62714
|
+
(_a2 = coalescerRef.current) == null ? void 0 : _a2.cancel();
|
|
62715
|
+
if (animRef.current !== null) cancelAnimationFrame(animRef.current);
|
|
62716
|
+
}, [animRef]);
|
|
62717
|
+
React.useLayoutEffect(() => {
|
|
62718
|
+
applyCamera();
|
|
62719
|
+
}, [applyCamera, value, visibleItems, tiers, selected, palette, size, dpr, fit, cameraSnapshot]);
|
|
61869
62720
|
const toggleZone = React.useCallback((key) => {
|
|
61870
|
-
|
|
62721
|
+
const collapsing = openZoneRef.current === key;
|
|
62722
|
+
zoneOverrideRef.current = collapsing ? key : null;
|
|
62723
|
+
setOpenZone(collapsing ? nav.parentOf.get(key) ?? null : key);
|
|
61871
62724
|
}, [nav.parentOf]);
|
|
61872
62725
|
React.useEffect(() => {
|
|
61873
|
-
if (currentZone
|
|
62726
|
+
if (currentZone === void 0) return;
|
|
62727
|
+
if (zoneOverrideRef.current !== null) {
|
|
62728
|
+
if (zoneOverrideRef.current === currentZone) return;
|
|
62729
|
+
zoneOverrideRef.current = null;
|
|
62730
|
+
}
|
|
62731
|
+
setOpenZone(currentZone);
|
|
61874
62732
|
}, [currentZone]);
|
|
61875
62733
|
const openPath = React.useMemo(() => {
|
|
61876
62734
|
const path2 = /* @__PURE__ */ new Set();
|
|
@@ -61895,7 +62753,15 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61895
62753
|
react.Box,
|
|
61896
62754
|
{
|
|
61897
62755
|
css: styles2.navZone,
|
|
61898
|
-
style: {
|
|
62756
|
+
style: {
|
|
62757
|
+
paddingLeft: `${8 + depth * 14}px`,
|
|
62758
|
+
// Pin this header below its ancestors' pinned headers
|
|
62759
|
+
// (each level offset by one row) so the whole path stays
|
|
62760
|
+
// visible while scrolling the zone's items; shallower
|
|
62761
|
+
// levels stack above deeper ones.
|
|
62762
|
+
top: `calc(var(--nav-row-h) * ${depth})`,
|
|
62763
|
+
zIndex: 30 - depth
|
|
62764
|
+
},
|
|
61899
62765
|
...node2.zone.key === currentZone ? { "data-current": "" } : {},
|
|
61900
62766
|
children: [
|
|
61901
62767
|
expandable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -61934,7 +62800,8 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61934
62800
|
))
|
|
61935
62801
|
] }, node2.zone.key);
|
|
61936
62802
|
};
|
|
61937
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.root, children: [
|
|
62803
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.root, ...fixedHeight !== void 0 ? { style: { height: fixedHeight, maxHeight: fixedHeight } } : {}, children: [
|
|
62804
|
+
/* @__PURE__ */ jsxRuntime.jsx(SchematicPaletteProbe, { onResolve: setPalette }),
|
|
61938
62805
|
showNavigator && navCollapsed && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: styles2.navCollapsed, children: /* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "button", css: styles2.navToggle, "aria-label": "Expand index", title: "Show index", onClick: () => setNavCollapsed(false), children: /* @__PURE__ */ jsxRuntime.jsx(FontAwesomeIcon, { icon: faAnglesRight }) }) }),
|
|
61939
62806
|
showNavigator && !navCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.nav, children: [
|
|
61940
62807
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.navHeader, children: [
|
|
@@ -61979,112 +62846,27 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
61979
62846
|
ref: canvasRef,
|
|
61980
62847
|
css: styles2.canvas,
|
|
61981
62848
|
"data-schematic-canvas": "",
|
|
61982
|
-
style: { aspectRatio: `${W2} / ${H}` },
|
|
62849
|
+
style: fixedHeight !== void 0 ? { minHeight: 0 } : { aspectRatio: `${W2} / ${H}` },
|
|
61983
62850
|
onPointerDown: onCanvasPointerDown,
|
|
61984
62851
|
onPointerMove: onCanvasPointerMove,
|
|
61985
62852
|
onPointerUp: onCanvasPointerUp,
|
|
62853
|
+
onPointerCancel: onCanvasPointerCancel,
|
|
62854
|
+
onLostPointerCapture: onCanvasPointerCancel,
|
|
61986
62855
|
onDoubleClick: resetView,
|
|
61987
62856
|
children: [
|
|
61988
|
-
showGrid && size !== null &&
|
|
61989
|
-
|
|
61990
|
-
|
|
61991
|
-
|
|
61992
|
-
react.Box,
|
|
62857
|
+
showGrid && size !== null && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { ref: gridRef, css: styles2.grid }),
|
|
62858
|
+
size !== null && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
62859
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62860
|
+
"canvas",
|
|
61993
62861
|
{
|
|
61994
|
-
|
|
61995
|
-
style: {
|
|
61996
|
-
backgroundSize: `${major}px ${major}px, ${major}px ${major}px, ${minor}px ${minor}px, ${minor}px ${minor}px`,
|
|
61997
|
-
backgroundPosition: `${view.tx}px 0, 0 ${view.ty}px, ${view.tx}px 0, 0 ${view.ty}px`
|
|
61998
|
-
}
|
|
62862
|
+
ref: drawRef,
|
|
62863
|
+
style: { position: "absolute", inset: 0, width: "100%", height: "100%" }
|
|
61999
62864
|
}
|
|
62000
|
-
)
|
|
62001
|
-
|
|
62002
|
-
|
|
62003
|
-
value.zones.map((zone) => {
|
|
62004
|
-
const pattern = zone.pattern;
|
|
62005
|
-
const tone = (pattern.value.tone.type === "some" ? pattern.value.tone.value.type : void 0) ?? "muted";
|
|
62006
|
-
const hatchVars = pattern.type === "hatch" ? {
|
|
62007
|
-
"--hatch-spacing": `${pattern.value.spacing.type === "some" ? pattern.value.spacing.value : 8}px`,
|
|
62008
|
-
"--hatch-angle": `${pattern.value.angle.type === "some" ? pattern.value.angle.value : 45}deg`
|
|
62009
|
-
} : {};
|
|
62010
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
62011
|
-
react.Box,
|
|
62012
|
-
{
|
|
62013
|
-
css: styles2.zone,
|
|
62014
|
-
"data-pattern": pattern.type,
|
|
62015
|
-
"data-tone": tone,
|
|
62016
|
-
style: {
|
|
62017
|
-
left: wx(zone.x),
|
|
62018
|
-
top: wy(zone.y),
|
|
62019
|
-
width: zone.width * ppu,
|
|
62020
|
-
height: zone.height * ppu,
|
|
62021
|
-
...hatchVars
|
|
62022
|
-
},
|
|
62023
|
-
children: zone.width * ppu >= zone.label.length * 6.2 + 24 && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "span", css: styles2.zoneLabel, "data-pattern": pattern.type, children: zone.label })
|
|
62024
|
-
},
|
|
62025
|
-
zone.key
|
|
62026
|
-
);
|
|
62027
|
-
}),
|
|
62028
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "svg", css: styles2.underlay, ...{ viewBox: `0 0 ${size.w} ${size.h}`, width: size.w, height: size.h }, children: value.links.map((link2) => {
|
|
62029
|
-
const from = centers.get(link2.from);
|
|
62030
|
-
const to = centers.get(link2.to);
|
|
62031
|
-
if (!from || !to) return null;
|
|
62032
|
-
const anchors = [from, ...link2.via, to].map((p2) => ({ x: wx(p2.x), y: wy(p2.y) }));
|
|
62033
|
-
const corner = link2.route.type === "orthogonal" ? link2.route.value.corner.type === "some" ? link2.route.value.corner.value : 8 : 0;
|
|
62034
|
-
const pts = link2.route.type === "orthogonal" ? orthogonalize(anchors) : anchors;
|
|
62035
|
-
const style = link2.style;
|
|
62036
|
-
const tone = (style.value.tone.type === "some" ? style.value.tone.value.type : void 0) ?? (style.type === "solid" ? "brand" : "muted");
|
|
62037
|
-
const weight = style.value.weight.type === "some" ? style.value.weight.value : style.type === "solid" ? 2.5 : 1.5;
|
|
62038
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-tone": tone, children: [
|
|
62039
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
62040
|
-
"path",
|
|
62041
|
-
{
|
|
62042
|
-
d: roundedPath(pts, corner),
|
|
62043
|
-
fill: "none",
|
|
62044
|
-
"data-style": style.type,
|
|
62045
|
-
strokeWidth: weight,
|
|
62046
|
-
...style.type === "dashed" ? { strokeDasharray: "6 5" } : {}
|
|
62047
|
-
}
|
|
62048
|
-
),
|
|
62049
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: anchors[0].x, cy: anchors[0].y, r: weight + 1.5 }),
|
|
62050
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: anchors[anchors.length - 1].x, cy: anchors[anchors.length - 1].y, r: weight + 1.5 })
|
|
62051
|
-
] }, link2.key);
|
|
62052
|
-
}) }),
|
|
62053
|
-
visibleItems.map((item) => {
|
|
62865
|
+
),
|
|
62866
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { ref: cardLayerRef, css: styles2.cardLayer, children: visibleItems.map((item) => {
|
|
62867
|
+
if ((tiers.get(item.key) ?? lod) !== "card") return null;
|
|
62054
62868
|
const tone = statusTone(item.status);
|
|
62055
62869
|
const isSelected = selected === item.key;
|
|
62056
|
-
const tier = tiers.get(item.key) ?? lod;
|
|
62057
|
-
if (tier === "dot") {
|
|
62058
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
62059
|
-
react.Box,
|
|
62060
|
-
{
|
|
62061
|
-
css: styles2.itemDot,
|
|
62062
|
-
"data-tone": tone ?? "neutral",
|
|
62063
|
-
...isSelected ? { "data-selected": "" } : {},
|
|
62064
|
-
style: { left: wx(item.x), top: wy(item.y) },
|
|
62065
|
-
onClick: () => flyToItem(item),
|
|
62066
|
-
onPointerDown: (e3) => e3.stopPropagation()
|
|
62067
|
-
},
|
|
62068
|
-
item.key
|
|
62069
|
-
);
|
|
62070
|
-
}
|
|
62071
|
-
if (tier === "label") {
|
|
62072
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62073
|
-
react.Box,
|
|
62074
|
-
{
|
|
62075
|
-
css: styles2.itemPin,
|
|
62076
|
-
...isSelected ? { "data-selected": "" } : {},
|
|
62077
|
-
style: { left: wx(item.x), top: wy(item.y) },
|
|
62078
|
-
onClick: () => flyToItem(item),
|
|
62079
|
-
onPointerDown: (e3) => e3.stopPropagation(),
|
|
62080
|
-
children: [
|
|
62081
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "span", css: styles2.statusDot, "data-tone": tone ?? "neutral" }),
|
|
62082
|
-
item.label
|
|
62083
|
-
]
|
|
62084
|
-
},
|
|
62085
|
-
item.key
|
|
62086
|
-
);
|
|
62087
|
-
}
|
|
62088
62870
|
const sublabel = getSomeorUndefined(item.sublabel);
|
|
62089
62871
|
const icon3 = getSomeorUndefined(item.icon);
|
|
62090
62872
|
const meter = getSomeorUndefined(item.meter);
|
|
@@ -62095,17 +62877,14 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
62095
62877
|
react.Box,
|
|
62096
62878
|
{
|
|
62097
62879
|
css: styles2.item,
|
|
62880
|
+
"data-card-key": item.key,
|
|
62098
62881
|
...isSelected ? { "data-selected": "" } : {},
|
|
62099
62882
|
style: {
|
|
62100
|
-
left:
|
|
62101
|
-
top:
|
|
62102
|
-
|
|
62103
|
-
|
|
62104
|
-
onClick: () => {
|
|
62105
|
-
setSelected(item.key);
|
|
62106
|
-
if (onSelectFn) queueMicrotask(() => onSelectFn(item.key));
|
|
62883
|
+
left: 0,
|
|
62884
|
+
top: 0,
|
|
62885
|
+
transform: `${cardTranslateCss(item.x, item.y)} translate(-50%, -50%)`,
|
|
62886
|
+
...typeof width === "number" ? { width: cardWidthCss(width) } : {}
|
|
62107
62887
|
},
|
|
62108
|
-
onPointerDown: (e3) => e3.stopPropagation(),
|
|
62109
62888
|
children: [
|
|
62110
62889
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.itemHead, children: [
|
|
62111
62890
|
iconDef !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "span", css: styles2.itemIcon, children: /* @__PURE__ */ jsxRuntime.jsx(FontAwesomeIcon, { icon: iconDef }) }),
|
|
@@ -62119,7 +62898,7 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
62119
62898
|
},
|
|
62120
62899
|
item.key
|
|
62121
62900
|
);
|
|
62122
|
-
}),
|
|
62901
|
+
}) }),
|
|
62123
62902
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: styles2.controls, children: [
|
|
62124
62903
|
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "button", css: styles2.controlButton, "aria-label": "Zoom in", title: "Zoom in (scroll)", onClick: () => zoomBy(1.5), children: /* @__PURE__ */ jsxRuntime.jsx(FontAwesomeIcon, { icon: faPlus }) }),
|
|
62125
62904
|
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { as: "button", css: styles2.controlButton, "aria-label": "Zoom out", title: "Zoom out (scroll)", onClick: () => zoomBy(1 / 1.5), children: /* @__PURE__ */ jsxRuntime.jsx(FontAwesomeIcon, { icon: faMinus }) }),
|
|
@@ -62163,16 +62942,20 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
62163
62942
|
style: { width: 150, height: 150 * H / W2 },
|
|
62164
62943
|
onPointerDown: (e3) => {
|
|
62165
62944
|
e3.stopPropagation();
|
|
62166
|
-
const
|
|
62167
|
-
|
|
62168
|
-
|
|
62169
|
-
|
|
62170
|
-
|
|
62171
|
-
|
|
62172
|
-
|
|
62173
|
-
|
|
62174
|
-
|
|
62175
|
-
|
|
62945
|
+
const el = e3.currentTarget;
|
|
62946
|
+
el.setPointerCapture(e3.pointerId);
|
|
62947
|
+
transition("cancel");
|
|
62948
|
+
minimapDragRef.current = true;
|
|
62949
|
+
minimapJump(el, e3.clientX, e3.clientY);
|
|
62950
|
+
},
|
|
62951
|
+
onPointerMove: (e3) => {
|
|
62952
|
+
if (!minimapDragRef.current) return;
|
|
62953
|
+
e3.stopPropagation();
|
|
62954
|
+
minimapJump(e3.currentTarget, e3.clientX, e3.clientY);
|
|
62955
|
+
},
|
|
62956
|
+
onPointerUp: (e3) => {
|
|
62957
|
+
minimapDragRef.current = false;
|
|
62958
|
+
e3.currentTarget.releasePointerCapture(e3.pointerId);
|
|
62176
62959
|
},
|
|
62177
62960
|
children: [
|
|
62178
62961
|
value.zones.map((zone) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -62193,8 +62976,8 @@ const EastChakraSchematic = React.memo(function EastChakraSchematic2({ value })
|
|
|
62193
62976
|
{
|
|
62194
62977
|
css: styles2.minimapViewport,
|
|
62195
62978
|
style: {
|
|
62196
|
-
left: `${Math.max(0, -
|
|
62197
|
-
top: `${Math.max(0, -
|
|
62979
|
+
left: `${Math.max(0, -cameraSnapshot.tx / ppu / W2 * 100)}%`,
|
|
62980
|
+
top: `${Math.max(0, -cameraSnapshot.ty / ppu / H * 100)}%`,
|
|
62198
62981
|
width: `${Math.min(100, size.w / ppu / W2 * 100)}%`,
|
|
62199
62982
|
height: `${Math.min(100, size.h / ppu / H * 100)}%`
|
|
62200
62983
|
}
|