@eyeon/map 2.0.4 → 2.0.6
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/chunks/MapViewer.js +357 -355
- package/dist/chunks/MapViewer.js.map +1 -1
- package/dist/chunks/stacking.js +83 -93
- package/dist/chunks/stacking.js.map +1 -1
- package/dist/chunks/wheelZoom.js +5 -5
- package/dist/chunks/wheelZoom.js.map +1 -1
- package/dist/core/assignment.d.ts +20 -8
- package/dist/core/assignment.d.ts.map +1 -1
- package/dist/core/import/index.d.ts.map +1 -1
- package/dist/core/layerStyles.d.ts +3 -4
- package/dist/core/layerStyles.d.ts.map +1 -1
- package/dist/core/outdoorDecoration.d.ts +2 -1
- package/dist/core/outdoorDecoration.d.ts.map +1 -1
- package/dist/core/publish/index.d.ts +3 -1
- package/dist/core/publish/index.d.ts.map +1 -1
- package/dist/core/types.d.ts +3 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/editor/canvas/EditorCanvas.d.ts.map +1 -1
- package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts +2 -1
- package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts.map +1 -1
- package/dist/editor/index.js +380 -370
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/panels/AssignForm.d.ts.map +1 -1
- package/dist/editor/railListCopy.d.ts.map +1 -1
- package/dist/viewer/ui/MapControls.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapViewer.js","sources":["../../src/viewer/ui/MapControls.tsx","../../src/fonts/mapFont.ts","../../../threejs-map/src/helpers/svgIcons.helper.ts","../../../threejs-map/src/helpers/amenities.helper.ts","../../../threejs-map/src/amenities.ts","../../src/specialIcons.ts","../../src/fonts/Montserrat-Regular.woff?url","../../src/fonts/mapFontUrl.ts","../../src/ui/selectSearch.ts","../../src/ui/ModernSelect.tsx","../../src/viewer/components/openingGeometry.ts","../../src/viewer/components/OpeningWell.tsx","../../src/viewer/pointer.ts","../../src/viewer/components/LevelMeshes.tsx","../../src/viewer/components/RouteLine.tsx","../../../../node_modules/three/examples/jsm/loaders/SVGLoader.js","../../src/viewer/components/SvgVectorLayer.tsx","../../src/viewer/camera.ts","../../src/viewer/components/CameraRig.tsx","../../src/viewer/components/MapScene.tsx","../../src/viewer/ui/RuntimeChrome.tsx","../../src/viewer/MapViewer.tsx"],"sourcesContent":["import React from 'react';\nimport type { StackLevel } from '../../core';\nimport {\n floorSwitcherDisplayLevels,\n hasBuildingFloors,\n shouldShowFloorSwitcher,\n} from '../../core';\n\nexport interface MapControlLevel {\n id: number;\n name: string;\n}\n\nexport interface MapControlsProps {\n levels: Array<MapControlLevel & Partial<StackLevel>>;\n activeLevelId: number | null;\n onActiveLevelChange: (id: number) => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onReset: () => void;\n showFloors?: boolean;\n showZoomReset?: boolean;\n /** Override the viewer building-floor list (e.g. Edit Map + Outdoor). */\n floorOptions?: MapControlLevel[];\n /** Show the floor list even when there is only one floor. */\n alwaysShowFloors?: boolean;\n}\n\nexport function MapControls({\n levels,\n activeLevelId,\n onActiveLevelChange,\n onZoomIn,\n onZoomOut,\n onReset,\n showFloors = true,\n showZoomReset = true,\n floorOptions,\n alwaysShowFloors = false,\n}: MapControlsProps) {\n const switcher = floorOptions ?? floorSwitcherDisplayLevels(levels as StackLevel[]);\n const showFloorList =\n showFloors &&\n (alwaysShowFloors ? switcher.length > 0 : shouldShowFloorSwitcher(levels as StackLevel[]));\n const showZoom = showZoomReset && hasBuildingFloors(levels);\n if (!showFloorList && !showZoom) return null;\n\n return (\n <div className=\"eyeon-map-controls\">\n <div className=\"eyeon-map-controls__stack\">\n {showFloorList && (\n <div className=\"eyeon-map-controls__floors\" role=\"tablist\" aria-label=\"Floors\">\n {switcher.map((level) => {\n const active = level.id === activeLevelId;\n return (\n <button\n key={level.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n className={\n active\n ? 'eyeon-map-controls__floor is-active'\n : 'eyeon-map-controls__floor'\n }\n onClick={() => onActiveLevelChange(level.id)}\n >\n {level.name}\n </button>\n );\n })}\n </div>\n )}\n\n {showZoom && (\n <>\n <button\n type=\"button\"\n className=\"eyeon-map-controls__reset\"\n onClick={onReset}\n aria-label=\"Reset map\"\n >\n Reset\n </button>\n\n <div className=\"eyeon-map-controls__zoom\">\n <button\n type=\"button\"\n className=\"eyeon-map-controls__zoom-btn\"\n onClick={onZoomOut}\n aria-label=\"Zoom out\"\n >\n −\n </button>\n <button\n type=\"button\"\n className=\"eyeon-map-controls__zoom-btn\"\n onClick={onZoomIn}\n aria-label=\"Zoom in\"\n >\n +\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n","/** CSS family — same Montserrat as admin-portal / Edit Map chrome. */\nexport const MAP_FONT_FAMILY = 'Montserrat, sans-serif';\n\n/** Shared by Edit Map SVG tspans and default-map troika `<Text>`. */\nexport const MAP_LABEL_LINE_HEIGHT = 1.15;\n","const SVGIcons = {\n Entrance: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\n <path fill=\"none\" stroke=\"#444444\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 3.75h8.25A3.5 3.5 0 0 1 20 7.25v9.5a3.5 3.5 0 0 1-3.5 3.5H8.25\"/>\n <path fill=\"none\" stroke=\"#444444\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.5 12h12.35M12.2 7.85 16.4 12l-4.2 4.15\"/>\n </svg>`,\n\n Kiosk: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 443.83 787.21\">\n <path fill=\"#444444\" d=\"M451,587.7V8.14H7.14V589.5H111.43V730.89H71.27L38.59,763.58v31.78H416.36V764.93l-34.05-34H345.78V587.7ZM396.91,71.23v452.7H59.85V71.23Z\" transform=\"translate(-7.14 -8.14)\" />\n </svg>`,\n\n Escalator: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 445.3\">\n <path fill=\"#444444\" d=\"M243.4,75.9c21.2,0,38.1-16.8,38.1-38S264.6,0,243.4,0c-21.2,0-38.1,16.8-38.1,38S222.1,75.9,243.4,75.9z M508.5,41.2h-88.7 c-18.5,0-41.9,7.6-56.1,21.7l-82.2,81.9V121c0-51-75.7-50.4-75.7,0v98.2l-71.3,71c-6.5,6.5-7.6,7.1-20.7,7.1H70.2 C26.1,297.2,0,336.8,0,369.9c0,33.6,26.1,75.4,74,75.4h77.9c18.5,0,40.8-7.1,58.8-24.4l228.1-226.7c4.9-4.3,7.6-5.4,15.8-5.4h56.1 c27.2,0,65.3-30.4,65.3-74.8C576.5,70.5,537.9,41.2,508.5,41.2z M504.7,150.8h-47.9c-20.1,0-29.4,2.7-41.4,14.7L185.7,394.3 c-9.3,9.2-21.2,13-36.5,13H73.5c-19.6,0-36.5-16.3-36.5-38c0-21.7,16.3-33.6,33.2-33.6H122c15.2,0,25-4.3,33.7-13L389.3,90 c9.8-9.8,19.1-10.9,35.4-10.9h80c19.6,0,32.7,21.7,32.7,34.7C537.9,126.4,528.6,150.8,504.7,150.8z\" />\n </svg>`,\n\n ATM: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 577.8 577\">\n <path fill=\"#444444\" d=\"M388.7,314c-3.7-10.3-10.3-19.8-17.7-27.2c-7.4-7.4-17.7-14-29.5-19.1c-6.6-2.9-19.2-6.6-39.1-11.8V144.2 c13.3,2.2,22.8,8.1,30.2,16.2c7.4,8.1,11.8,19.9,14,35.3l39.8-5.9c-2.9-24.3-13.3-44.1-30.2-58.1c-13.3-11-31-17.7-53.8-19.8V93.4 h-24.3v18.4c-25.8,2.2-45,9.6-58.2,21.3c-19.9,17.7-29.5,39.7-29.5,67.6c0,15.5,3.7,29.4,10.3,41.9s16.2,22,28.7,28.7 c17,9.6,33.2,16.2,49.4,20.6v121.3c-14.8-1.5-28-8.8-39.1-22.8c-7.4-9.6-13.3-25-16.2-46.3l-39.1,7.4c1.5,20.6,6.6,37.5,15.5,51.5 s19.9,23.5,31.7,30.1c12.5,6.6,28,11,47.9,13.2v39v-0.1V483h22.1v-39c28-0.7,50.1-11,67.1-28.7c17-18.4,25.8-40.4,25.8-67.6 C394.6,336,392.4,324.3,388.7,314z M278.9,145.1v107.2c-17.7-5.2-30.2-11.8-37.6-20.6s-11.1-19.8-11.1-33.1c0-14,4.4-25.7,13.3-35.3 C252.2,153.9,263.7,147.4,278.9,145.1V145h0.7C279.3,145,279.1,145,278.9,145.1z M340,394.2c-9.6,11-22.1,18.4-37.6,19.8l0,0V297.9 c20.6,5.2,34.6,11.8,42,20.6c6.6,8.1,10.3,19.8,10.3,33.8C354.8,369.2,349.6,383.1,340,394.2z\" />\n <path fill=\"#444444\" d=\"M289.8,2.5c-158.7,0-288,128-288,287.2c0,158.3,129.3,287.2,288,287.2s288-128.9,288-287.2S448.6,2.5,289.8,2.5z M289.9,533.9C155,533.9,45.2,424.3,45.2,289.8C45.2,154.5,155,45.7,289.9,45.7s244.7,109.5,244.7,244.1S424.8,533.9,289.9,533.9z\" />\n </svg>`,\n\n Management: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 414.6\">\n <path fill=\"#444444\" d=\"M371.6,180.4c66.8,0,101,58.5,121.4,121.9l16.4,50.4c2.7,8.8-7.5,16.3-16.4,16.3h-56.6l-7.5-27.2 c-17.7-53.1-45-106.2-94.8-125.9c13-8.8,23.9-21.1,30.7-35.4C366.1,180.4,368.8,180.4,371.6,180.4z M441.2,145.7 c64.8,2,98.2,59.2,118.7,121.9l15.7,49.7c2.7,8.8-7.5,17.7-16.4,17.7h-35.5l-12.3-38.1c-16.4-53.1-44.3-106.2-94.8-125.9 C426.2,162.7,434.3,155.2,441.2,145.7z M51.6,334.3H16.8c-9.6,0-19.1-8.2-16.4-17.7l15.7-49.7C35.9,204.2,70.1,147.1,134.9,145 c6.1,9.5,15,18.4,24.6,24.5c-49.8,19.7-77.8,72.8-94.8,125.9L51.6,334.3L51.6,334.3z M437.7,0c35.5,0,64.8,28.6,64.8,64.7 c0,31.3-22.5,57.2-52.5,62.6c3.4-8.8,5.5-18.4,5.5-27.9c0-39.5-27.3-71.5-62.8-81C403.6,6.8,419.3,0,437.7,0L437.7,0z M137.6,0 c17.7,0,34.1,6.8,45,18.4c-35.5,9.5-62.8,41.5-62.8,81c0,9.5,2.1,19.1,5.5,27.9C96,121.9,72.8,96,72.8,64.7 C73.5,28.6,102.1,0,137.6,0L137.6,0z M287.7,0c19.8,0,37.5,8.8,49.8,22.5c-15.7,6.8-29.3,19.1-38.2,34l-3.4,5.5c-2.7,0-5.5,0-7.5,0 c-2,0-6.1,0-8.9,0l-3.4-5.5c-9.6-15-22.5-27.2-38.2-34C250.2,8.9,267.9,0,287.7,0L287.7,0z M287.7,226c66.8,0,101,58.5,122.1,121.9 l15.7,50.4c2.7,8.8-8.2,16.3-16.4,16.3H166.2c-9.6,0-19.8-8.2-16.4-16.3l15.7-50.4C186,284.6,220.8,226,287.7,226z M287.7,81 c35.5,0,64.8,28.6,64.8,64.7s-28.7,64.7-64.8,64.7c-35.5,0-64.8-28.6-64.8-64.7S252.2,81,287.7,81z M138.3,369H82.3 c-9.6,0-19.1-8.2-16.4-16.3l15.7-50.4c21.1-63.3,55.3-121.9,122.1-121.9c2.7,0,5.5,0,7.5,0c6.1,15,17.7,27.2,30.7,35.4 c-49.8,19.7-78.5,72.8-94.8,125.9C147.1,341.8,138.3,369,138.3,369z M203.8,34.7c23.9,0,44.3,12.9,55.9,31.3 c-32.1,12.2-55.9,42.9-55.9,79c0,6.1,0.7,12.2,2.1,18.4h-2.1c-35.5,0-64.8-28.6-64.8-64.7S168.3,34.7,203.8,34.7z M371.6,34.7 c35.5,0,64.8,28.6,64.8,64.7s-29.3,64-64.8,64h-2.7c2.1-6.1,2.7-12.2,2.7-18.4c0-36.8-23.9-66.7-55.9-79 C327.2,47.7,347,34.7,371.6,34.7z\" />\n </svg>`,\n\n PlayArea: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 537.9\">\n <path fill=\"#444444\" d=\"M384.3,137c38,0,68.8-30.7,68.8-68.5S422.3,0,384.3,0s-68.8,30.7-68.8,68.5S346.4,137,384.3,137z\" />\n <path fill=\"#444444\" d=\"M283.3,96c20,26.3,35.9,53.3,67.6,64.4c31.2,11.1,60.5,11.1,83.5-5.3c22.9-16.4,34.7-46.8,54.1-87.2 c18.8-40.4,34.1-48,57-48c23.5,0,31.2,28.1,30.6,39.8s-10.6,31-40,52.7c-49.4,36.3-57.6,108.3-59.4,127.7 c-1.8,19.3-2.9,50.4,17.6,169.2c20.6,118.9-20,125.9-25.3,127.1c-5.3,0.6-21.2,8.2-31.1-16.4c-10-24.6-11.8-91.3-14.1-120 c-2.9-28.7-6.5-70.9-35.9-79c-30-8.2-40.6,39.8-51.7,76.1c-10.6,36.9-40,71.4-72.3,59.1s-29.4-50.4-10-78.5 c19.4-27.5,61.7-57.4,67.6-124.1c5.9-66.8-11.8-69.1-68.2-90.8c-55.8-22.3-60.5-33.4-67.6-48.6s7.6-46.8,31.1-52.7 C239.2,55.1,259.1,63.9,283.3,96L283.3,96z\" />\n <path fill=\"#444444\" d=\"M134.7,251.7c26.9,0,48.8-21.8,48.8-48.6s-21.8-48.6-48.8-48.6s-48.8,21.8-48.8,48.6S107.7,251.7,134.7,251.7z\" />\n <path fill=\"#444444\" d=\"M204,227.8c-15.3,17.6-28.2,35.7-51.1,41.6c-22.9,6.4-43.5,4.7-58.8-8.2c-15.3-12.9-21.7-35.1-32.9-64.4S40,161,23.5,159.8 C7.1,158.7,0,178,0,186.2c-0.6,8.2,5.9,22.3,25.3,39.2C58.2,253.5,60,305.1,60,318.5c0.6,13.5-0.6,35.7-21.7,118.3 s7.1,89.6,10.6,90.8s14.7,7,22.9-10s12.9-63.8,16.5-83.7c3.5-19.9,8.2-49.8,29.4-53.9s26.5,30.4,32.3,56.8 c5.9,26.3,24.7,52.7,47.6,45.7c22.9-7,23.5-34,11.2-54.4c-12.3-20.5-40-43.9-40.6-90.8c-0.6-47.4,12.3-48,52.9-60.3 c40.6-12.3,44.7-20.5,50.5-30.4c5.9-10-2.9-33.4-18.8-38.6C237.5,201.4,222.8,206.7,204,227.8L204,227.8z\" />\n </svg>`,\n\n RestRoom: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 533.9\">\n <path fill=\"#444444\" d=\"M282.3,533.9h9.2V0h-9.2V533.9z\" />\n <path fill=\"#444444\" d=\"M118.2,97.1c25.4-4.6,41.6-30.1,34.7-55.5C146,16.2,122.9,2.3,97.4,6.9S58.1,39.3,62.8,62.4S95.1,104,118.2,97.1z\" />\n <path fill=\"#444444\" d=\"M159.8,145.6h4.6c0,0,2.3,0,2.3,2.3L183,270.4c2.3,9.2,9.2,16.2,18.5,16.2c11.6,0,18.5-9.2,18.5-20.8l-18.5-129.4 c-2.3-13.9-13.9-23.1-27.7-23.1H44.3c-13.9,0-25.4,9.2-27.7,23.1L0.4,265.8c-2.3,11.6,6.9,20.8,18.5,20.8c9.2,0,16.2-6.9,18.5-16.2 l16.2-122.5c0,0,0-2.3,2.3-2.3h4.6c0,0,2.3,0,2.3,2.3L30.4,390.6c0,0,0,2.3,2.3,2.3h37c0,0,2.3,0,2.3,2.3v117.9 c0,9.2,6.9,16.2,16.2,16.2s16.2-6.9,16.2-16.2V393c0,0,0-2.3,2.3-2.3h11.6c0,0,2.3,0,2.3,2.3v117.9c0,9.2,6.9,16.2,16.2,16.2 c9.2,0,16.2-6.9,16.2-16.2V393c0,0,0-2.3,2.3-2.3h30.1c0,0,2.3,0,2.3-2.3l-27.7-242.7l0,0l0,0L159.8,145.6z\" />\n <path fill=\"#444444\" d=\"M497.3,76.3c13.9-23.1,4.6-50.9-16.2-62.4s-50.9-6.9-64.7,16.2c-13.9,23.1-4.6,50.9,16.2,62.4 C455.7,106.3,483.5,99.4,497.3,76.3z\" />\n <path fill=\"#444444\" d=\"M545.9,113.3h-178c-13.9,0-25.4,9.2-27.7,23.1v129.4c0,11.6,9.2,20.8,20.8,20.8s18.5-9.2,18.5-20.8V159.5c0,0,0-2.3,2.3-2.3 h2.3c0,0,2.3,0,2.3,2.3l25.4,161.8v187.2c0,11.6,9.2,20.8,20.8,20.8l0,0c11.6,0,20.8-9.2,20.8-20.8V323.6c0,0,0-2.3,2.3-2.3h6.9 c0,0,2.3,0,2.3,2.3v184.9c0,11.6,9.2,20.8,20.8,20.8l0,0c11.6,0,20.8-9.2,20.8-20.8V321.3l25.4-161.8c0,0,0-2.3,2.3-2.3h-2.3 c0,0,2.3,0,2.3,2.3v106.3c0,11.6,9.2,20.8,20.8,20.8s20.8-9.2,20.8-20.8V136.4C571.4,122.5,559.8,113.3,545.9,113.3L545.9,113.3 L545.9,113.3z\" />\n </svg>`,\n\n FamilyRestRoom: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 522.5\">\n <path fill=\"#444444\" d=\"M119.8,91.5c25-5.9,40.5-30.8,34.6-55.7c-5.9-24.9-30.9-40.4-55.9-34.5S58,32,63.9,56.9S94.8,97.3,119.8,91.5z\" />\n <path fill=\"#444444\" d=\"M160.6,139.1h4.5c0.6,0,1.3,0.6,1.3,1.3l15.3,123.1c1.3,8.9,8.9,15.9,17.8,15.9c10.8,0,19.1-9.5,17.8-20.3l-15.9-128.9 c-1.9-13.3-13.4-24.1-27.4-24.1H43.4c-14,0-25.5,10.2-27.4,24.1L0.1,259.1c-1.3,10.8,7,20.3,17.8,20.3c8.9,0,16.5-7,17.8-15.9 l15.3-123.8c0-0.6,0.6-1.3,1.3-1.3h4.5c0.6,0,1.3,0.6,1.3,1.3L29.4,384.1c0,0.6,0.6,1.3,1.3,1.3H67c0.6,0,1.3,0.6,1.3,1.3v118.1 c0,9.5,7.6,16.5,16.5,16.5c9.5,0,16.5-7.6,16.5-16.5V387.3c0-0.6,0.6-1.3,1.3-1.3h10.8c0.6,0,1.3,0.6,1.3,1.3v118.1 c0,9.5,7.6,16.5,16.5,16.5c9.5,0,16.5-7.6,16.5-16.5V387.3c0-0.6,0.6-1.3,1.3-1.3h36.3c0.6,0,1.3-0.6,1.3-1.3L158,140.3 C159.3,139.7,159.9,139.1,160.6,139.1L160.6,139.1z\" />\n <path fill=\"#444444\" d=\"M498.9,69.8c12.9-22.1,5.4-50.5-16.8-63.4c-22.2-12.9-50.6-5.4-63.6,16.7c-12.9,22.1-5.4,50.5,16.8,63.4 C457.5,99.4,486,91.9,498.9,69.8z\" />\n <path fill=\"#444444\" d=\"M547.9,106.1H369.6c-14,0-25.5,10.2-27.4,24.1v128.9c0,10.8,8.9,19.7,19.7,19.7s19.7-8.9,19.7-19.7v-106 c0-0.6,0.6-1.3,1.3-1.3h2.5c0.6,0,1.3,0.6,1.3,1.3l25.5,162.5v187.3c0,10.8,8.9,19.7,19.7,19.7h0.6c10.8,0,19.7-8.9,19.7-19.7v-186 c0-0.6,0.6-1.3,1.3-1.3h10.8c0.6,0,1.3,0.6,1.3,1.3v186c0,10.8,8.9,19.7,19.7,19.7h0.6c10.8,0,19.7-8.9,19.7-19.7V315.6l25.5-162.5 c0-0.6,0.6-1.3,1.3-1.3h2.6c0.6,0,1.3,0.6,1.3,1.3v106c0,10.8,8.9,19.7,19.7,19.7s19.7-8.9,19.7-19.7V130.2 C573.4,116.2,562,106.1,547.9,106.1L547.9,106.1z\" />\n <path fill=\"#444444\" d=\"M259.6,480l19.7-19.7L251.9,433L229,455.8c-7.6,7.6-5.7,20.3,1.3,27.3l32.5,33.6c12.7,12.7,29.3-5.1,17.2-17.1L259.6,480 L259.6,480z M288.9,347.9c19.1,0,34.4-15.2,34.4-34.3s-15.3-34.3-34.4-34.3s-34.4,15.2-34.4,34.3S269.7,347.9,288.9,347.9z M369.7,405.7l-46.5-46.3c-3.8-3.8-8.3-6.3-14.7-6.3h-41.4c-6.4,0-10.8,2.5-14,6.3l-45.9,45.7c-12.7,12.7,4.5,28.6,17.2,15.9 l28-27.9v26h72.6v-26l28.6,28.6C364.6,433.6,381.8,417.1,369.7,405.7L369.7,405.7z M324.5,433l-27.4,27.3l19.7,19.7l-20.4,20.3 c-12.1,12.1,4.5,29.2,17.2,17.1l32.5-33.6c7-7,8.9-20.3,1.3-27.3C347.4,455.9,324.5,433,324.5,433z\" />\n </svg>`,\n\n Elevator: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 576\">\n <path fill=\"#444444\" d=\"M576,145.2v268.6c-0.1,1.6-0.3,3.1-0.3,4.7c-0.3,33.3-0.6,66.6-0.8,99.9c-0.1,21.1-9.7,37.2-26.7,49 c-7.7,5.4-15.9,9.3-25.9,8c-3.8-0.5-7.7-0.1-11.5-0.1c-115.3,0.1-230.6,0.2-345.9,0.3c-1.1,0-2.2,0.2-3.3,0.3h-16.9 c-1.2-0.1-2.4-0.3-3.6-0.3c-30.2-0.3-60.4-0.6-90.7-0.8c-11.1-0.1-20.7-4.1-29.1-11.2c-8.7-7.4-15.5-16.7-19.9-27.3l-0.2-0.5 c-0.7-1.6-1.1-3.4-1.2-5.4v0C0,492.8,0,455.1,0,417.4c0-124.1,0-248.1,0-372.2c0-0.2,0-0.3,0-0.5c0-1.5,0.3-2.9,0.7-4.2l0,0.1 C8.3,22.5,20.5,8.9,38.7,1c1.2-0.5,2.6-0.9,4-0.9h0c162.8,0,325.6,0,488.4,0c1.5,0,2.8,0.4,4.1,0.9l-0.1,0c3.4,1.4,6.1,2.7,8.8,4.2 l-0.4-0.2c19.7,11.2,30.9,27.8,31.3,50.8c0.4,28.2,0.6,56.3,0.8,84.5C575.7,141.8,575.8,143.5,576,145.2L576,145.2z M536.4,288.6 h0.3c0-56.7,0-113.4,0-170c0-18.2-0.4-36.4-0.7-54.6c-0.1-8-8.4-19.8-15.9-22.7c-1-0.4-2.1-0.6-3.2-0.7h0c-3.2-0.3-6.4-0.6-9.5-0.6 c-25.5-0.4-51-0.9-76.6-1c-96.4-0.2-192.7-0.4-289.1-0.4c-22.9,0-45.8,0.1-68.7,0.3c-3.4,0-6.8,0.1-10,0.9 c-9.9,2.3-17.1,8.3-21.7,17.3c-1,1.9-2,3.9-2.1,5.9c-0.1,149.8-0.1,299.6-0.1,449.4c0,0.9-0.1,2,0.3,2.7c2.7,4.2,5.1,8.6,8.3,12.3 c5.6,6.3,13.2,8.4,21.6,8.4c23.7,0.1,47.5,0.6,71.2,0.6c123.5,0,247,0,370.5,0c0.1,0,0.2,0,0.3,0c1.1,0,2.1-0.2,3-0.6l-0.1,0 c8.3-3.5,15.4-8.4,20.2-16.3c1.2-1.8,2-4.1,2-6.5l0,0C536.4,438.2,536.4,363.4,536.4,288.6L536.4,288.6z\" />\n <path fill=\"#444444\" d=\"M307,277.5l75.9,68.4l0.9-0.2V150.9h49.7v194.8l1,0.3l78.2-67.4c0.1,1,0.2,1.7,0.3,2.4c0.3,19.9,0.6,39.8,0.8,59.7 c0,0,0,0,0,0.1c0,1.4-0.5,2.6-1.4,3.6l0,0c-34.1,32.7-68.2,65.3-102.3,97.9c-0.3,0.3-0.6,0.5-1,0.9c-0.6-0.5-1.3-1-1.9-1.5 c-32.7-30.7-65.5-61.4-98.2-92c-1.4-1.2-2.3-3-2.3-5c0-0.1,0-0.3,0-0.4v0c0.2-20.9,0.3-41.9,0.4-62.8C307,280.5,307,279.4,307,277.5 L307,277.5z\" />\n <path fill=\"#444444\" d=\"M142.2,234.5L67,301.8c-0.1-1.2-0.3-1.9-0.3-2.7c-0.3-20.7-0.7-41.5-1-62.2c0-1.3,0.5-2.5,1.3-3.4l0,0 c33.3-31.4,66.7-62.8,100.1-94.1c0.3-0.3,0.6-0.5,1-0.8c5.9,5.7,11.8,11.3,17.7,16.9c28.1,26.9,56.2,53.9,84.3,80.9 c0.9,0.8,1.4,2,1.5,3.3v0c-0.5,20.2-1.1,40.3-1.6,60.5c0,0.3-0.1,0.7-0.2,1.7l-77.4-67.1l-0.9,0.1v193.9h-48.3v-194L142.2,234.5z\" />\n </svg>`,\n\n Security: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 597.6\">\n <path fill=\"#444444\" d=\"M554,80.7L298.5,1.5c-6.6-2-13.2-2-19.9,0L23.2,80.7C9.3,84.7,0,97.9,0,112.4c0,352.5,178.7,436.4,274,481.9 c4.6,2,9.3,3.3,13.9,3.3c4.6,0,9.9-1.3,13.9-3.3c96-45.5,274-129.4,274-481.9C577.2,97.9,567.9,85.3,554,80.7z M288.6,527.6 C197.2,484.1,73.5,411.4,66.2,136.2l222.4-68.6L511,136.8C503.7,412.1,379.3,484.1,288.6,527.6z\" />\n <path fill=\"#444444\" d=\"M278.7,152l-26.5,87.1l-90.7-2.6c-4.6,0-8.6,2.6-9.9,7.3c-1.3,4.6,0,9.2,4,11.9l74.8,51.5L200.6,393c-1.3,4.6,0,9.2,4,11.9 c4,2.6,8.6,2.6,12.6,0l72.1-54.8l72.1,54.8c4,2.6,8.6,2.6,12.6,0c4-2.6,5.3-7.3,4-11.9l-29.8-85.8l74.8-51.5c4-2.6,5.3-7.3,4-11.9 c-1.3-4.6-5.3-7.3-9.9-7.3l-90.7,2l-26.5-87.1c-1.3-4.6-5.3-7.3-9.9-7.3C283.9,144.1,280,147.4,278.7,152L278.7,152z\" />\n </svg>`,\n\n ChildStroller: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 432 370.06\">\n <path fill=\"#444444\" d=\"M130.29,178.61l-42.67,34L33.24,254.13c-15.48,12.09-28.32-2.64-28.32-2.64-12.08-15.86,1.89-26.06,1.89-26.06l68-53.24s7.55-7.93,26.81-2.26l28.7,8.68\"/>\n <path fill=\"#444444\" d=\"M210,111A38.52,38.52,0,1,1,248.48,72.5,38.68,38.68,0,0,1,210,111\"/>\n <path fill=\"#444444\" d=\"M390.84,0a42.88,42.88,0,0,0-24.92,8.31L80.44,235.63a43.71,43.71,0,0,0-13.59,22.28,40.67,40.67,0,0,0,1.89,23.41,47.9,47.9,0,0,0-22.28,41.16A47.58,47.58,0,1,0,94,274.9,41.43,41.43,0,0,0,84.22,276a22.77,22.77,0,0,1-1.51-14.35,25.82,25.82,0,0,1,8.68-13.59l17.37-14,88,29.08a33.54,33.54,0,0,0,42.67-21.53l1.51-4.91,18.88,45.32a47.09,47.09,0,0,0-22.28,40.4,47.58,47.58,0,1,0,47.58-47.58,41.43,41.43,0,0,0-9.82,1.13l-26.43-62.68,43.8-126.12,83.08-66.08a23.7,23.7,0,0,1,15.1-5.29,25.3,25.3,0,0,1,25.3,25.3,25.72,25.72,0,0,1-10.2,20.39,8,8,0,0,0,10.58,12.08A41.37,41.37,0,0,0,390.84,0ZM93.66,301.33A20.77,20.77,0,1,1,72.89,322.1,20.71,20.71,0,0,1,93.66,301.33Zm191.07,0A20.77,20.77,0,1,1,264,322.1,20.71,20.71,0,0,1,284.73,301.33Z\"/>\n </svg>`,\n\n VendingMachine: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 594\">\n <circle fill=\"#444444\" cx=\"324\" cy=\"175.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"175.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"324\" cy=\"243\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"243\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"324\" cy=\"310.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"310.5\" r=\"13.5\"/>\n <path fill=\"#444444\" d=\"M216,94.5H67.5C59.4,94.5,54,99.9,54,108c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,99.9,224.1,94.5,216,94.5z\"/>\n <path fill=\"#444444\" d=\"M216,162H67.5c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,167.4,224.1,162,216,162z\"/>\n <path fill=\"#444444\" d=\"M216,229.5H67.5c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,234.9,224.1,229.5,216,229.5z\"/>\n <path fill=\"#444444\" d=\"M216,297H67.5c-8.1,0-13.5,5.4-13.5,13.5S59.4,324,67.5,324H216c8.1,0,13.5-5.4,13.5-13.5S224.1,297,216,297z\"/>\n <path fill=\"#444444\" d=\"M391.5,0H324c-8.1,0-13.5,5.4-13.5,13.5S315.9,27,324,27h67.5c8.1,0,13.5,5.4,13.5,13.5V567H27V40.5 C27,32.4,32.4,27,40.5,27h216v499.5c0,8.1,5.4,13.5,13.5,13.5s13.5-5.4,13.5-13.5v-513C283.5,5.4,278.1,0,270,0H40.5 C17.5,0,0,17.5,0,40.5v540c0,8.1,5.4,13.5,13.5,13.5h405c8.1,0,13.5-5.4,13.5-13.5v-540C432,17.5,414.5,0,391.5,0z\"/>\n <path fill=\"#444444\" d=\"M364.5,94.5H324c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5h40.5c8.1,0,13.5-5.4,13.5-13.5 C378,99.9,372.6,94.5,364.5,94.5z\"/>\n <path fill=\"#444444\" d=\"M216,432H67.5c-8.1,0-13.5,5.4-13.5,13.5V513c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5v-67.5 C229.5,437.4,224.1,432,216,432z M81,499.5V459h121.5v40.5H81z\"/>\n </svg>`,\n\n Stairs: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 448.5\">\n <path fill=\"#444444\" d=\"M432,243.3h-81.7v33.1h-72.2v33.1h-72.2v33.1h-72.2v33.1H61.5v33.1H0v39.7h101.2v-33.1h72.2v-33.1h72.2v-33.1h72.2v-33.1 h72.2V283H432L432,243.3\"/>\n <path fill=\"#444444\" d=\"M99.9,109.3c12,0,21.8-9.7,21.8-21.8c0-12-9.8-21.8-21.8-21.8c-12,0-21.8,9.7-21.8,21.8C78.1,99.6,87.9,109.3,99.9,109.3\"/>\n <path fill=\"#444444\" d=\"M179.4,299.8l-56.5-47.4l11.7-82.9c12.5,14.8,20.7,33.4,22.7,53.8l17.8-4.8c-0.9-32.2-14.2-61.3-35.3-82.6 c-14.4-14.5-32.9-19.2-45.9-20.6c-0.1,0-0.2,0-0.3,0c-1.6,0-2.9,1.2-3.2,2.7c-6.5,34.7-27.7,64.2-56.9,81.9l9.3,16.1 c15.6-6.6,29.5-16.4,40.9-28.6v177.3H107l10.4-73.7l57.7,33.3L179.4,299.8\"/>\n <path fill=\"#444444\" d=\"M294.1,43.6c12,0,21.8-9.8,21.8-21.8c0-12-9.8-21.8-21.8-21.8c-12,0-21.8,9.8-21.8,21.8C272.3,33.8,282.1,43.6,294.1,43.6\" />\n <path fill=\"#444444\" d=\"M337.2,154.3l-41.8-24.1l3.9-20c1.4-7.5,2.2-15.2,2.2-23.1c0-12-1.8-23.7-5-34.6c-0.4-1.4-1.7-2.4-3.1-2.4c0,0-0.1,0-0.1,0 c-46.7,1.6-84.1,40-84.1,87.1c0,2.3,0.1,4.6,0.3,6.9l18.3,3.2c0-0.5,0-0.9,0-1.4c0-19.5,8.6-36.9,22.3-48.7l-10.5,201.1h23.3 l24.9-128l23,10.7L294.9,240l16.6,16.6l34.6-74.3c1.3-2.8,2-5.9,2-9.2C348.1,165.1,343.8,158,337.2,154.3\"/>\n </svg>`,\n\n ChargingStation: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 627.4\">\n <polygon fill=\"#444444\" points=\"314.4,282.1 133.8,467.8 188.6,334.2 114.9,334.2 225.6,148.6 314.4,148.6 236.7,282.1 \"/>\n <path fill=\"#444444\" d=\"M374.2,0H63.3C28.4,0.1,0.1,28.4,0,63.3v503.6c0,32.8,30.1,60.5,62.6,60.5h309.2c33.3,0,60.3-27,60.3-60.3V374.2l0,0V57.8 C432,25.9,406.1,0,374.2,0z M220.3,600.4c-8.3,0.2-15.2-6.4-15.4-14.7c0-0.2,0-0.5,0-0.7c0.1-8.5,6.9-15.3,15.4-15.4 c8.3-0.2,15.2,6.4,15.4,14.7c0,0.2,0,0.5,0,0.7C235.4,593.8,229.1,600.4,220.3,600.4z M391.1,544.8H44v-465h346.7v294.4l0.4,55 V544.8z\"/>\n </svg>`,\n\n WheelChair: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 492.2\">\n <path fill=\"#444444\" d=\"M134.7,80.1l9.5,103h104.6v33.3H146.6l3.2,30.9h147.4l66.6,157l56.3-23.8l11.9,27l-84,36.4l-69.7-163.3H118.9l-19-221.9 c-3.2-5.5-4.7-11.9-4.7-18.2C95.1,18.2,112.5,0,134.7,0c22.2,0,40.4,18.2,40.4,40.4C175.2,61.8,156.9,80.1,134.7,80.1L134.7,80.1z\" />\n <path fill=\"#444444\" d=\"M306.7,397.1c-25.3,56.3-81.6,95.1-146.6,95.1C72.1,492.2,0,420.9,0,332.1C0,268.7,37.2,214,91.1,187.9l3.2,36.5 c-36.5,22.2-61,61.8-61,107.8c0,69.8,57.1,126.8,126.8,126.8c65,0,118.1-48.3,126-110.2L306.7,397.1\"/>\n </svg>`,\n\n};\n\nexport default SVGIcons;","import SVGIcons from \"./svgIcons.helper\";\n\nexport type MapAmenityID = 'atm' | 'management' | 'playarea' | 'restroom' | 'family-restroom' | 'elevator' | 'escalator' | 'security' | 'dog-poop-station' | 'child-stroller' | 'vending-machine' | 'stairs' | 'charging-station' | 'wheelchair';\n\nexport interface MapAmenity {\n name: string;\n type: MapAmenityID;\n svgCode: string;\n}\n\nexport const AllAmenities: MapAmenity[] = [\n {\n name: \"ATM\",\n type: \"atm\",\n svgCode: SVGIcons.ATM\n },\n {\n name: \"Management\",\n type: \"management\",\n svgCode: SVGIcons.Management\n },\n {\n name: \"Kids Area\",\n type: \"playarea\",\n svgCode: SVGIcons.PlayArea\n },\n {\n name: \"Restroom\",\n type: \"restroom\",\n svgCode: SVGIcons.RestRoom\n },\n {\n name: \"Family Restroom\",\n type: \"family-restroom\",\n svgCode: SVGIcons.FamilyRestRoom\n },\n {\n name: \"Elevator\",\n type: \"elevator\",\n svgCode: SVGIcons.Elevator\n },\n {\n name: \"Security\",\n type: \"security\",\n svgCode: SVGIcons.Security\n },\n {\n name: \"Escalator\",\n type: \"escalator\",\n svgCode: SVGIcons.Escalator\n },\n {\n name: 'Child Stroller',\n type: 'child-stroller',\n svgCode: SVGIcons.ChildStroller\n },\n {\n name: 'Vending Machine',\n type: 'vending-machine',\n svgCode: SVGIcons.VendingMachine\n },\n {\n name: 'Stairs',\n type: 'stairs',\n svgCode: SVGIcons.Stairs\n },\n {\n name: 'Charging Station',\n type: 'charging-station',\n svgCode: SVGIcons.ChargingStation\n },\n {\n name: 'Wheelchair',\n type: 'wheelchair',\n svgCode: SVGIcons.WheelChair\n },\n];\n\n","/**\n * Lightweight amenity + kiosk icon catalog for every EyeOn surface.\n * Import from `@eyeon/threejs-map/amenities` (or `@eyeon/threejs-map`) —\n * do not copy these SVGs into other packages.\n */\nimport SVGIcons from './helpers/svgIcons.helper';\nimport {\n AllAmenities,\n type MapAmenity,\n type MapAmenityID,\n} from './helpers/amenities.helper';\n\nexport { AllAmenities };\nexport type { MapAmenity, MapAmenityID };\n\n/** Elevator / escalator are their own v1 modules, not amenity assignments. */\nconst CONNECTOR_AMENITY_TYPES = new Set<MapAmenityID>([\n 'elevator',\n 'escalator',\n]);\n\nexport const AssignAmenities: MapAmenity[] = AllAmenities.filter(\n (item) => !CONNECTOR_AMENITY_TYPES.has(item.type),\n);\n\nexport const KioskSvg = SVGIcons.Kiosk;\nexport const EntranceSvg = SVGIcons.Entrance;\n\nexport function isAssignAmenity(type: string): boolean {\n return AssignAmenities.some((item) => item.type === type);\n}\n\nexport function getAmenityByType(type: string): MapAmenity | undefined {\n return AssignAmenities.find((item) => item.type === type) ??\n AllAmenities.find((item) => item.type === type);\n}\n\nexport function getMapSpecialSvg(id: string): string | undefined {\n if (id === 'kiosk') return KioskSvg;\n if (id === 'entrance') return EntranceSvg;\n return getAmenityByType(id)?.svgCode;\n}\n\nexport function recolorMapSvg(svg: string, color: string): string {\n const hex = color.startsWith('#') ? color : `#${color}`;\n return svg\n .replace(/fill=\"(?!none\")[^\"]*\"/gi, `fill=\"${hex}\"`)\n .replace(/stroke=\"(?!none\")[^\"]*\"/gi, `stroke=\"${hex}\"`);\n}\n\nexport function mapSpecialSvgToDataUrl(\n svg: string,\n color?: string | null,\n): string {\n const colored = color ? recolorMapSvg(svg, color) : svg;\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(colored)}`;\n}\n","/**\n * v2 render helpers for amenity / kiosk icons.\n * SVG markup lives only in `@eyeon/threejs-map/amenities`.\n */\nimport {\n AllAmenities,\n AssignAmenities,\n getAmenityByType,\n getMapSpecialSvg,\n isAssignAmenity,\n mapSpecialSvgToDataUrl,\n recolorMapSvg,\n} from '@eyeon/threejs-map/amenities';\nimport type { CmAmenityCatalogItem, CmShapeAssignment } from './core';\nimport { assignmentSpecialIconId } from './core';\n\nexport {\n AllAmenities,\n AssignAmenities,\n getAmenityByType,\n isAssignAmenity,\n getMapSpecialSvg,\n mapSpecialSvgToDataUrl,\n recolorMapSvg,\n};\n\nexport function entranceIconDataUrl(color?: string | null): string | undefined {\n const svg = getMapSpecialSvg('entrance');\n if (!svg) return undefined;\n return mapSpecialSvgToDataUrl(svg, color);\n}\n\n/** v1 amenity list for the assign dropdown — elevator / escalator are separate modules. */\nexport function amenityAssignOptions(): { value: string; label: string }[] {\n return AssignAmenities.map((item) => ({\n value: item.type,\n label: item.name,\n }));\n}\n\nexport function amenityTypeFromCatalogId(\n amenityId: number | null | undefined,\n amenities: CmAmenityCatalogItem[],\n): string {\n if (amenityId == null) return '';\n return amenities.find((item) => item.id === amenityId)?.code ?? '';\n}\n\nexport function amenityCatalogIdForType(\n type: string,\n amenities: CmAmenityCatalogItem[],\n): number | null {\n const row = amenities.find(\n (item) => item.isActive !== false && item.code === type,\n );\n return row?.id ?? null;\n}\n\nexport function assignmentSpecialIconDataUrl(\n assignment: CmShapeAssignment | null | undefined,\n amenities: Array<{ id: number; code: string }>,\n color?: string | null,\n): string | undefined {\n const id = assignmentSpecialIconId(assignment, amenities);\n if (!id) return undefined;\n const svg = getMapSpecialSvg(id);\n if (!svg) return undefined;\n return mapSpecialSvgToDataUrl(svg, color);\n}\n\nexport type ConnectorSpecialKind = 'escalator' | 'elevator';\n\nconst ASSIGNED_CONNECTOR_ICON = '#0763b1';\nconst UNASSIGNED_CONNECTOR_ICON = '#94a3b8';\n\n/** Escalator / elevator SVG ids from the floor file (`escalator-5-up-start`). */\nexport function connectorSpecialKind(shape: {\n key: string;\n sourceSvgId?: string | null;\n}): ConnectorSpecialKind | null {\n const raw = (shape.sourceSvgId ?? shape.key)\n .trim()\n .toLowerCase()\n .replace(/_/g, '-');\n if (raw === 'escalator' || raw.startsWith('escalator-')) return 'escalator';\n if (raw === 'elevator' || raw.startsWith('elevator-')) return 'elevator';\n return null;\n}\n\nexport function connectorSpecialIconDataUrl(\n kind: ConnectorSpecialKind,\n assigned: boolean,\n color?: string | null,\n): string | undefined {\n const svg = getMapSpecialSvg(kind);\n if (!svg) return undefined;\n const fill = color?.trim()\n ? color.trim()\n : assigned\n ? ASSIGNED_CONNECTOR_ICON\n : UNASSIGNED_CONNECTOR_ICON;\n return mapSpecialSvgToDataUrl(svg, fill);\n}\n\n/** Landings that belong to a linked escalator ride / elevator shaft. */\nexport function assignedConnectorShapeIds(\n anchors: Array<{ shapeId?: number | null; connectorId?: number | null }>,\n): Set<number> {\n const ids = new Set<number>();\n for (const anchor of anchors) {\n if (anchor.shapeId != null && anchor.connectorId != null) {\n ids.add(anchor.shapeId);\n }\n }\n return ids;\n}\n\n/**\n * Map overlay: only a linked landing gets an icon. Unassigned escalators\n * (and elevators) stay as empty polygons so the floor is not covered in gray\n * markers.\n */\nexport function connectorMapIconKind(\n shape: {\n id: number;\n key: string;\n sourceSvgId?: string | null;\n orphanedAt?: string | Date | null;\n },\n assignedShapeIds: Set<number>,\n): ConnectorSpecialKind | null {\n if (shape.orphanedAt) return null;\n const kind = connectorSpecialKind(shape);\n if (!kind || !assignedShapeIds.has(shape.id)) return null;\n return kind;\n}\n","export default \"data:font/woff;base64,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\"","import mapFontUrl from './Montserrat-Regular.woff?url';\n\n/**\n * Troika (drei `<Text>`) cannot use CSS `font-family`; it needs a font file.\n * Latin 400 WOFF, same face as `@fontsource/montserrat` / admin-portal.\n */\nexport const MAP_FONT_URL = mapFontUrl;\n\nlet registered = false;\n\n/** Register Montserrat so SVG + canvas measurement match the 3D overlay. */\nexport function ensureMapFont(): void {\n if (registered || typeof document === 'undefined' || !('fonts' in document)) {\n return;\n }\n registered = true;\n const face = new FontFace('Montserrat', `url(${MAP_FONT_URL})`);\n void face.load().then((loaded) => {\n document.fonts.add(loaded);\n });\n}\n\nensureMapFont();\n","export interface ModernSelectOption {\n value: string;\n label: string;\n hint?: string;\n iconUrl?: string;\n iconMuted?: boolean;\n}\n\n/** Show a search field once a list is long enough to scan by eye. */\nexport const MODERN_SELECT_SEARCH_AFTER = 8;\n\nexport function filterModernSelectOptions(\n options: ModernSelectOption[],\n query: string,\n): ModernSelectOption[] {\n const q = query.trim().toLowerCase();\n if (!q) return options;\n return options.filter((o) => {\n const haystack = `${o.label} ${o.hint ?? ''}`.toLowerCase();\n return haystack.includes(q);\n });\n}\n\nexport function modernSelectIsSearchable(\n optionCount: number,\n searchable?: boolean,\n): boolean {\n return searchable ?? optionCount >= MODERN_SELECT_SEARCH_AFTER;\n}\n","import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport './modern-select.css';\nimport {\n filterModernSelectOptions,\n modernSelectIsSearchable,\n type ModernSelectOption,\n} from './selectSearch';\n\nexport type { ModernSelectOption } from './selectSearch';\nexport { filterModernSelectOptions } from './selectSearch';\n\nfunction Chevron() {\n return (\n <svg\n className=\"eyeon-map-select__chevron\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n aria-hidden\n >\n <path\n d=\"M2.5 4.5 6 8l3.5-3.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nexport function ModernSelect({\n value,\n options,\n onChange,\n disabled = false,\n placeholder = 'Select…',\n searchable,\n ariaLabel,\n}: {\n value: string;\n options: ModernSelectOption[];\n onChange: (value: string) => void;\n disabled?: boolean;\n placeholder?: string;\n searchable?: boolean;\n ariaLabel?: string;\n}) {\n const listId = useId();\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const [menuPos, setMenuPos] = useState<{\n top: number;\n left: number;\n width: number;\n maxHeight: number;\n } | null>(null);\n\n const withSearch = modernSelectIsSearchable(options.length, searchable);\n const selected = options.find((o) => o.value === value);\n const filtered = useMemo(\n () => filterModernSelectOptions(options, withSearch && open ? query : ''),\n [open, options, query, withSearch],\n );\n\n const close = useCallback(() => {\n setOpen(false);\n setQuery('');\n setActiveIndex(0);\n }, []);\n\n const pick = useCallback(\n (next: string) => {\n onChange(next);\n close();\n },\n [close, onChange],\n );\n\n const updateMenuPos = useCallback(() => {\n const el = triggerRef.current ?? buttonRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom - 8;\n const spaceAbove = rect.top - 8;\n const maxHeight = Math.min(280, Math.max(spaceBelow, spaceAbove, 120));\n const openAbove = spaceBelow < 160 && spaceAbove > spaceBelow;\n setMenuPos({\n top: openAbove ? Math.max(8, rect.top - maxHeight - 4) : rect.bottom + 4,\n left: rect.left,\n width: Math.max(rect.width, 160),\n maxHeight,\n });\n }, []);\n\n useEffect(() => {\n if (!open) {\n setMenuPos(null);\n return;\n }\n updateMenuPos();\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (rootRef.current?.contains(t) || menuRef.current?.contains(t)) return;\n close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n close();\n (withSearch ? searchRef.current : buttonRef.current)?.blur();\n }\n };\n const onMove = () => updateMenuPos();\n document.addEventListener('mousedown', onDoc);\n document.addEventListener('keydown', onKey);\n window.addEventListener('resize', onMove);\n window.addEventListener('scroll', onMove, true);\n return () => {\n document.removeEventListener('mousedown', onDoc);\n document.removeEventListener('keydown', onKey);\n window.removeEventListener('resize', onMove);\n window.removeEventListener('scroll', onMove, true);\n };\n }, [close, open, updateMenuPos, withSearch]);\n\n useEffect(() => {\n if (!open || !withSearch) return;\n requestAnimationFrame(() => searchRef.current?.focus());\n }, [open, withSearch]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query, filtered.length]);\n\n const moveActive = (delta: number) => {\n if (filtered.length === 0) return;\n setActiveIndex((i) => (i + delta + filtered.length) % filtered.length);\n };\n\n const onSearchKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!open) setOpen(true);\n else moveActive(1);\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (!open) setOpen(true);\n else moveActive(-1);\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n const option = filtered[activeIndex];\n if (open && option) pick(option.value);\n else setOpen(true);\n }\n };\n\n const menu =\n open && menuPos && !disabled\n ? createPortal(\n <div\n ref={menuRef}\n id={listId}\n className=\"eyeon-map-select__menu\"\n role=\"listbox\"\n aria-label={ariaLabel}\n style={{\n top: menuPos.top,\n left: menuPos.left,\n width: menuPos.width,\n maxHeight: menuPos.maxHeight,\n }}\n >\n <ul className=\"eyeon-map-select__list\">\n {filtered.length === 0 ? (\n <li className=\"eyeon-map-select__empty\">No matches</li>\n ) : (\n filtered.map((option, index) => {\n const active = option.value === value;\n const highlighted = index === activeIndex;\n return (\n <li\n key={option.value}\n id={`${listId}-${option.value}`}\n role=\"option\"\n aria-selected={active}\n >\n <button\n type=\"button\"\n className={[\n 'eyeon-map-select__option',\n active ? 'is-active' : '',\n highlighted ? 'is-highlight' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseDown={(e) => e.preventDefault()}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => pick(option.value)}\n >\n {option.iconUrl ? (\n <img\n className={\n option.iconMuted\n ? 'eyeon-map-select__option-icon is-muted'\n : 'eyeon-map-select__option-icon'\n }\n src={option.iconUrl}\n alt=\"\"\n />\n ) : null}\n <span className=\"eyeon-map-select__option-copy\">\n <span>{option.label}</span>\n {option.hint ? (\n <span className=\"eyeon-map-select__option-hint\">\n {option.hint}\n </span>\n ) : null}\n </span>\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>,\n document.body,\n )\n : null;\n\n return (\n <div ref={rootRef} className=\"eyeon-map-select\">\n {withSearch ? (\n <div\n ref={triggerRef}\n className={\n open\n ? 'eyeon-map-select__trigger is-open'\n : 'eyeon-map-select__trigger'\n }\n onMouseDown={(e) => {\n if (disabled) return;\n const target = e.target as HTMLElement;\n if (target.closest('.eyeon-map-select__chevron-btn')) return;\n if (target !== searchRef.current) {\n e.preventDefault();\n searchRef.current?.focus();\n }\n if (!open) setOpen(true);\n }}\n >\n <input\n ref={searchRef}\n className=\"eyeon-map-select__input\"\n type=\"text\"\n role=\"combobox\"\n aria-label={ariaLabel}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={\n open && filtered[activeIndex]\n ? `${listId}-${filtered[activeIndex].value}`\n : undefined\n }\n disabled={disabled}\n placeholder={placeholder}\n value={open ? query : (selected?.label ?? '')}\n onChange={(e) => {\n setQuery(e.target.value);\n if (!open) setOpen(true);\n }}\n onFocus={() => {\n if (!disabled) setOpen(true);\n }}\n onKeyDown={onSearchKeyDown}\n />\n <button\n type=\"button\"\n className=\"eyeon-map-select__chevron-btn\"\n tabIndex={-1}\n aria-hidden\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (disabled) return;\n setOpen((v) => !v);\n }}\n >\n <Chevron />\n </button>\n </div>\n ) : (\n <button\n ref={buttonRef}\n type=\"button\"\n className=\"eyeon-map-select__trigger\"\n aria-label={ariaLabel}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n disabled={disabled}\n onClick={() => {\n if (disabled) return;\n setOpen((v) => !v);\n }}\n >\n <span\n className={\n selected\n ? 'eyeon-map-select__value'\n : 'eyeon-map-select__placeholder'\n }\n >\n {selected?.iconUrl ? (\n <img\n className={\n selected.iconMuted\n ? 'eyeon-map-select__option-icon is-muted'\n : 'eyeon-map-select__option-icon'\n }\n src={selected.iconUrl}\n alt=\"\"\n />\n ) : null}\n {selected?.label ?? placeholder}\n </span>\n <Chevron />\n </button>\n )}\n {menu}\n </div>\n );\n}\n","import * as THREE from 'three';\nimport type { Vec2 } from '../../core';\nimport { holesOverlappingOuter } from '../../core';\n\nexport function polygonToThreeShape(points: Vec2[]): THREE.Shape | null {\n if (points.length < 3) return null;\n const shape = new THREE.Shape();\n shape.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n shape.lineTo(points[i].x, points[i].y);\n }\n shape.closePath();\n return shape;\n}\n\nexport function polygonToThreePath(points: Vec2[]): THREE.Path | null {\n if (points.length < 3) return null;\n const path = new THREE.Path();\n path.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n path.lineTo(points[i].x, points[i].y);\n }\n path.closePath();\n return path;\n}\n\n/** Punch overlapping openings out of a slab polygon. */\nexport function slabShapeWithHoles(\n outer: Vec2[],\n holes: Vec2[][],\n): THREE.Shape | null {\n const shape = polygonToThreeShape(outer);\n if (!shape) return null;\n for (const hole of holesOverlappingOuter(outer, holes)) {\n const path = polygonToThreePath(hole);\n if (path) shape.holes.push(path);\n }\n return shape;\n}\n","import React, { useEffect, useMemo } from 'react';\nimport * as THREE from 'three';\nimport type { Vec2 } from '../../core';\nimport {\n OPENING_VOID_FILL,\n OPENING_VOID_MARK,\n OPENING_VOID_STROKE,\n polygonBBox,\n} from '../../core';\nimport { polygonToThreeShape } from './openingGeometry';\n\nfunction skipRaycast() {}\n\n/** X mark in bbox UV space — ShapeGeometry clips it to the opening. */\nfunction createOpeningMarkTexture(aspect: number): THREE.CanvasTexture {\n const height = 256;\n const width = Math.max(48, Math.round(height * Math.max(aspect, 0.2)));\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new THREE.CanvasTexture(canvas);\n ctx.clearRect(0, 0, width, height);\n const pad = Math.min(width, height) * 0.14;\n ctx.strokeStyle = OPENING_VOID_MARK;\n ctx.globalAlpha = 0.82;\n ctx.lineWidth = Math.max(5, Math.min(width, height) * 0.045);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(pad, pad);\n ctx.lineTo(width - pad, height - pad);\n ctx.moveTo(width - pad, pad);\n ctx.lineTo(pad, height - pad);\n ctx.stroke();\n const texture = new THREE.CanvasTexture(canvas);\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.anisotropy = 4;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction OpeningVoidMesh({ polygon }: { polygon: Vec2[] }) {\n const shape = useMemo(() => polygonToThreeShape(polygon), [polygon]);\n const box = useMemo(() => polygonBBox(polygon), [polygon]);\n const dash = Math.max(8, openingSpanDash(box));\n const outline = useMemo(() => {\n if (polygon.length < 2) return null;\n const first = polygon[0];\n const points = [\n ...polygon.map((p) => new THREE.Vector3(p.x, p.y, 0.05)),\n new THREE.Vector3(first.x, first.y, 0.05),\n ];\n const geometry = new THREE.BufferGeometry().setFromPoints(points);\n const material = new THREE.LineDashedMaterial({\n color: OPENING_VOID_STROKE,\n dashSize: dash,\n gapSize: dash * 0.65,\n });\n const line = new THREE.Line(geometry, material);\n line.renderOrder = 8;\n line.computeLineDistances();\n line.raycast = skipRaycast;\n return line;\n }, [dash, polygon]);\n\n useEffect(\n () => () => {\n if (!outline) return;\n outline.geometry.dispose();\n const material = outline.material;\n if (Array.isArray(material)) material.forEach((item) => item.dispose());\n else material.dispose();\n },\n [outline],\n );\n const mark = useMemo(() => {\n const width = Math.max(box.maxX - box.minX, 1);\n const height = Math.max(box.maxY - box.minY, 1);\n return createOpeningMarkTexture(width / height);\n }, [box]);\n\n useEffect(() => () => mark.dispose(), [mark]);\n\n if (!shape || !outline) return null;\n\n return (\n <group>\n <mesh\n position={[0, 0, 0.02]}\n renderOrder={6}\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <shapeGeometry args={[shape]} />\n <meshBasicMaterial\n color={OPENING_VOID_FILL}\n side={THREE.DoubleSide}\n depthWrite={false}\n />\n </mesh>\n <mesh position={[0, 0, 0.03]} renderOrder={7} raycast={skipRaycast}>\n <shapeGeometry args={[shape]} />\n <meshBasicMaterial\n map={mark}\n transparent\n depthWrite={false}\n side={THREE.DoubleSide}\n toneMapped={false}\n />\n </mesh>\n {outline ? <primitive object={outline} /> : null}\n </group>\n );\n}\n\nfunction openingSpanDash(bbox: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}): number {\n const span = Math.min(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY);\n return Math.min(18, Math.max(7, span * 0.08));\n}\n\nexport function OpeningWells({\n polygons,\n}: {\n polygons: Vec2[][];\n is3d?: boolean;\n}) {\n if (polygons.length === 0) return null;\n return (\n <group>\n {polygons.map((polygon, index) => (\n <OpeningVoidMesh key={`opening-void-${index}`} polygon={polygon} />\n ))}\n </group>\n );\n}\n","import type { ShapeKind } from '../core';\n\n/** Kinds that select (or Shift-add) on the assign / public map. */\nexport const VIEWER_SELECTABLE_KINDS: ShapeKind[] = [\n 'unit',\n 'amenity',\n 'kiosk_screen',\n 'connector',\n 'entrance',\n 'parking_zone',\n];\n\nexport function isViewerSelectableKind(kind: string): boolean {\n return (VIEWER_SELECTABLE_KINDS as readonly string[]).includes(kind);\n}\n\n/** Hover and the current selection share the same assign-map highlight. */\nexport function viewerShapeHighlighted(\n shapeId: number,\n hoveredShapeId: number | null,\n selectedShapeIds: readonly number[],\n): boolean {\n return hoveredShapeId === shapeId || selectedShapeIds.includes(shapeId);\n}\n\n/** Map pointer hover wins over a leftover list hover. */\nexport function resolvedViewerHoverId(\n listHoverId: number | null | undefined,\n pointerHoverId: number | null,\n): number | null {\n return pointerHoverId ?? listHoverId ?? null;\n}\n\nexport function viewerHoverCursor(kind: string): 'pointer' | '' {\n return isViewerSelectableKind(kind) ? 'pointer' : '';\n}\n\n/** R3F `eventSource` hosts the cursor — the WebGL canvas has pointer-events: none. */\nexport function applyViewerHoverCursor(\n host: HTMLElement | null | undefined,\n cursor: 'pointer' | '',\n): void {\n if (!host) return;\n host.classList.toggle('is-hover-shape', cursor === 'pointer');\n}\n\n/** Amenities are almost invisible; hover must still read. */\nexport function viewerHoverFillOpacity(\n kind: string,\n base: number,\n hovered: boolean,\n): number {\n if (!hovered || !isViewerSelectableKind(kind)) return base;\n if (base < 0.08) return 0.28;\n return base;\n}\n\nfunction parseHex(hex: string): [number, number, number] | null {\n const h = hex.replace('#', '').trim();\n if (h.length === 3) {\n return [\n parseInt(h[0] + h[0], 16),\n parseInt(h[1] + h[1], 16),\n parseInt(h[2] + h[2], 16),\n ];\n }\n if (h.length !== 6) return null;\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return [r, g, b];\n}\n\nfunction toHex(r: number, g: number, b: number): string {\n const hex = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\n return `#${hex(r)}${hex(g)}${hex(b)}`;\n}\n\n/** Tint a store fill toward the accent so hover matches Edit Map. */\nexport function viewerHoverFillColor(\n fill: string,\n accent: string,\n hovered: boolean,\n amount = 0.2,\n): string {\n if (!hovered) return fill;\n const a = parseHex(fill);\n const b = parseHex(accent);\n if (!a || !b) return fill;\n return toHex(\n a[0] + (b[0] - a[0]) * amount,\n a[1] + (b[1] - a[1]) * amount,\n a[2] + (b[2] - a[2]) * amount,\n );\n}\n\n/** Pan farther than this and a pointer-up on empty space is not a clear. */\nexport const VIEWER_CLICK_DRAG_PX = 5;\n\nexport function pointerMissClearsSelection(\n down: { x: number; y: number } | null,\n up: { x: number; y: number; button?: number },\n): boolean {\n if ((up.button ?? 0) !== 0) return false;\n if (!down) return true;\n const dx = up.x - down.x;\n const dy = up.y - down.y;\n return dx * dx + dy * dy <= VIEWER_CLICK_DRAG_PX * VIEWER_CLICK_DRAG_PX;\n}\n","import React, { useEffect, useMemo, useState } from 'react';\nimport * as THREE from 'three';\nimport { Text } from '@react-three/drei';\nimport type {\n CmAmenityCatalogItem,\n PublishedLevel,\n ThemeDefaults,\n ShapeKind,\n} from '../../core';\nimport {\n assignmentOverlayImageUrl,\n assignmentOverlayRenderSize,\n assignmentOverlayVisible,\n connectorIconLayout,\n DEFAULT_ASSIGNMENT_SIZE,\n DEFAULT_ENTRANCE_SIZE,\n filletPolygon,\n geometryBBox,\n INTERACTIVE_SHAPE_KINDS,\n isEntranceIcon,\n isSlabShapeKind,\n isTransparentColor,\n labelAlignX,\n normalizeLabelAlign,\n resolveFetchUrl,\n resolveLayerStyle,\n resolvedAssignmentBgColor,\n voidPolygonsOnLevel,\n} from '../../core';\nimport { polygonToThreeShape, slabShapeWithHoles } from './openingGeometry';\nimport { OpeningWells } from './OpeningWell';\nimport { MAP_LABEL_LINE_HEIGHT } from '../../fonts/mapFont';\nimport { MAP_FONT_URL } from '../../fonts/mapFontUrl';\nimport {\n applyViewerHoverCursor,\n isViewerSelectableKind,\n viewerHoverCursor,\n viewerHoverFillColor,\n viewerHoverFillOpacity,\n resolvedViewerHoverId,\n viewerShapeHighlighted,\n} from '../pointer';\nimport {\n assignedConnectorShapeIds,\n assignmentSpecialIconDataUrl,\n connectorMapIconKind,\n connectorSpecialIconDataUrl,\n entranceIconDataUrl,\n} from '../../specialIcons';\n\nfunction kindColor(\n kind: ShapeKind,\n theme: ThemeDefaults,\n fill?: string,\n assignment?: { bgColor?: string | null } | null,\n): string {\n if (kind === 'walkable') return theme.WALKABLE_COLOR;\n if (kind === 'unit') {\n return resolvedAssignmentBgColor(assignment, theme.STORE_DEFAULT_COLOR);\n }\n if (kind === 'connector' && assignment?.bgColor) {\n return resolvedAssignmentBgColor(assignment, fill || '#e2e8f0');\n }\n if (fill) return fill;\n switch (kind) {\n case 'wall':\n case 'boundary':\n return theme.WALL_COLOR;\n case 'parking_zone':\n return theme.PARKING_ZONE_COLOR;\n case 'green_area':\n return theme.GREEN_AREA_COLOR;\n case 'water':\n return theme.WATER_COLOR;\n case 'floorplate':\n return theme.BASE_COLOR;\n case 'void':\n return '#00000000';\n default:\n return '#e2e8f0';\n }\n}\n\nfunction polygonShape(points: { x: number; y: number }[]): THREE.Shape | null {\n return polygonToThreeShape(points);\n}\n\nexport interface LevelMeshesProps {\n level: PublishedLevel;\n theme: ThemeDefaults;\n is3d: boolean;\n onSelectShape?: (shapeId: number | null, opts?: { additive?: boolean }) => void;\n /** Assign-map selection — same highlight as hover so staff can see the set. */\n selectedShapeIds?: readonly number[];\n /** Rail / search hover — same darker fill as pointer hover. */\n hoveredShapeId?: number | null;\n /** Host that owns pointer events (and therefore the CSS cursor). */\n eventSource?: React.RefObject<HTMLElement | null>;\n /**\n * When true (outdoor with live SVG), only interactive shapes are drawn —\n * decoration comes from SvgVectorLayer.\n */\n interactiveOnly?: boolean;\n /** Same media proxy as outdoor SVGs — retailer logos are often cross-origin. */\n imageProxyUrl?: string | null;\n /** Published amenity catalog — used to resolve v1 amenity icons by code. */\n amenities?: CmAmenityCatalogItem[];\n}\n\nfunction HoverOutline({\n shape,\n extrude,\n color,\n}: {\n shape: THREE.Shape;\n extrude: number;\n color: string;\n}) {\n const sourceGeometry = useMemo(\n () =>\n extrude > 0\n ? new THREE.ExtrudeGeometry(shape, {\n depth: extrude,\n bevelEnabled: false,\n })\n : new THREE.ShapeGeometry(shape),\n [extrude, shape],\n );\n\n useEffect(() => () => sourceGeometry.dispose(), [sourceGeometry]);\n\n return (\n <lineSegments renderOrder={40}>\n <edgesGeometry args={[sourceGeometry]} />\n <lineBasicMaterial color={color} depthTest={false} />\n </lineSegments>\n );\n}\n\nexport function LevelMeshes({\n level,\n theme,\n is3d,\n onSelectShape,\n selectedShapeIds = [],\n hoveredShapeId: hoveredShapeIdProp = null,\n eventSource,\n interactiveOnly = false,\n imageProxyUrl = null,\n amenities = [],\n}: LevelMeshesProps) {\n const [pointerHoverId, setPointerHoverId] = useState<number | null>(null);\n const hoveredShapeId = resolvedViewerHoverId(\n hoveredShapeIdProp,\n pointerHoverId,\n );\n useEffect(\n () => () => applyViewerHoverCursor(eventSource?.current, ''),\n [eventSource],\n );\n const openings = useMemo(() => voidPolygonsOnLevel(level), [level]);\n const meshes = useMemo(() => {\n return level.shapes\n .filter((s) => s.kind !== 'void')\n .filter((s) => !(s.kind === 'label' && s.label?.text?.trim()))\n .filter((s) => !isEntranceIcon(s))\n .filter(\n (s) =>\n !interactiveOnly ||\n INTERACTIVE_SHAPE_KINDS.includes(s.kind) ||\n (s.kind === 'label' && Boolean(s.label?.text?.trim())) ||\n (s.kind === 'walkable' && !resolveLayerStyle(s.sourceSvgId)),\n )\n .filter((s) => !s.orphanedAt)\n .map((shape) => {\n const radius = shape.kind === 'unit' ? theme.STORE_RADIUS : 0;\n const punch = isSlabShapeKind(shape.kind) && openings.length > 0;\n const polys = shape.geometry.polygons.map((poly) =>\n radius > 0 ? filletPolygon(poly, radius) : poly,\n );\n const threeShapes = polys\n .map((poly) =>\n punch ? slabShapeWithHoles(poly, openings) : polygonShape(poly),\n )\n .filter((s): s is THREE.Shape => s != null);\n if (threeShapes.length === 0) return null;\n\n const color = kindColor(\n shape.kind,\n theme,\n shape.style.fill,\n shape.assignment,\n );\n const extrude =\n is3d && (shape.kind === 'unit' || shape.kind === 'wall')\n ? shape.style.extrudeHeight ??\n (shape.kind === 'unit' ? theme.STORE_HEIGHT : 2)\n : 0;\n\n return { shape, threeShapes, color, extrude };\n })\n .filter(Boolean) as Array<{\n shape: (typeof level.shapes)[number];\n threeShapes: THREE.Shape[];\n color: string;\n extrude: number;\n }>;\n }, [level, theme, is3d, interactiveOnly, openings]);\n\n const labels = useMemo(\n () =>\n level.shapes.filter(\n (s) => !s.orphanedAt && s.kind === 'label' && Boolean(s.label?.text?.trim()),\n ),\n [level.shapes],\n );\n\n const entranceIcons = useMemo(\n () => level.shapes.filter((s) => !s.orphanedAt && isEntranceIcon(s)),\n [level.shapes],\n );\n\n const overlays = useMemo(\n () =>\n level.shapes.filter(\n (s) =>\n !s.orphanedAt &&\n s.kind !== 'label' &&\n !isEntranceIcon(s) &&\n assignmentOverlayVisible(s.assignment, s.label),\n ),\n [level.shapes],\n );\n\n const connectorOverlays = useMemo(() => {\n const assignedIds = assignedConnectorShapeIds(level.anchors);\n return level.shapes.flatMap((shape) => {\n const kind = connectorMapIconKind(shape, assignedIds);\n if (!kind) return [];\n const layout = connectorIconLayout(shape);\n const url = connectorSpecialIconDataUrl(kind, true, layout.iconColor);\n if (!url) return [];\n const box = geometryBBox(shape.geometry);\n return [\n {\n shape,\n url,\n width: layout.size,\n rotation: (layout.rotate * Math.PI) / 180,\n x: (box.minX + box.maxX) / 2 + layout.offsetX,\n y: (box.minY + box.maxY) / 2 + layout.offsetY,\n },\n ];\n });\n }, [level.anchors, level.shapes]);\n\n return (\n <group>\n {labels.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const align = normalizeLabelAlign(shape.label.align);\n const cx = (box.minX + box.maxX) / 2;\n const cy = (box.minY + box.maxY) / 2;\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n return (\n <group\n key={`label-${shape.id}`}\n position={[cx, cy, 0.15]}\n rotation={[0, 0, tilt]}\n >\n <Text\n font={MAP_FONT_URL}\n position={[labelAlignX(box, align) - cx, 0, 0]}\n fontSize={shape.label.size ?? 24}\n color={shape.label.color ?? theme.STORE_TEXT_COLOR}\n anchorX={align}\n anchorY=\"middle\"\n textAlign={align}\n lineHeight={MAP_LABEL_LINE_HEIGHT}\n scale={[1, -1, 1]}\n >\n {shape.label.text}\n </Text>\n </group>\n );\n })}\n {entranceIcons.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const cx = (box.minX + box.maxX) / 2 + (shape.label.offsetX ?? 0);\n const cy = (box.minY + box.maxY) / 2 + (shape.label.offsetY ?? 0);\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n const size = shape.label.size || DEFAULT_ENTRANCE_SIZE;\n const url = entranceIconDataUrl(\n shape.label.color ?? theme.STORE_TEXT_COLOR,\n );\n if (!url) return null;\n return (\n <AssignmentImageOverlay\n key={`entrance-${shape.id}`}\n url={url}\n width={size}\n position={[cx, cy, 0.18]}\n rotation={tilt}\n />\n );\n })}\n {overlays.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const cx = (box.minX + box.maxX) / 2 + (shape.label.offsetX ?? 0);\n const cy = (box.minY + box.maxY) / 2 + (shape.label.offsetY ?? 0);\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n const fontSize = shape.label.size || shape.assignment?.size || DEFAULT_ASSIGNMENT_SIZE;\n const extrude =\n is3d && (shape.kind === 'unit' || shape.kind === 'wall')\n ? shape.style.extrudeHeight ??\n (shape.kind === 'unit' ? theme.STORE_HEIGHT : 2)\n : 0;\n const z = extrude > 0 ? extrude + 0.15 : 0.2;\n const iconColor =\n shape.label.color ??\n shape.assignment?.textColor ??\n theme.STORE_TEXT_COLOR;\n const imageKey =\n assignmentOverlayImageUrl(shape.assignment, null, shape.label) ??\n assignmentSpecialIconDataUrl(\n shape.assignment,\n amenities,\n iconColor,\n );\n const text = shape.label.text?.trim();\n const align = normalizeLabelAlign(shape.label.align);\n return imageKey ? (\n <AssignmentImageOverlay\n key={`overlay-${shape.id}`}\n url={imageKey}\n width={assignmentOverlayRenderSize(fontSize, shape.assignment)}\n position={[cx, cy, z]}\n rotation={tilt}\n imageProxyUrl={imageProxyUrl}\n />\n ) : (\n <Text\n key={`overlay-${shape.id}`}\n font={MAP_FONT_URL}\n position={[cx, cy, z]}\n rotation={[0, 0, tilt]}\n fontSize={fontSize}\n color={shape.label.color ?? theme.STORE_TEXT_COLOR}\n anchorX=\"center\"\n anchorY=\"middle\"\n textAlign={align}\n lineHeight={MAP_LABEL_LINE_HEIGHT}\n scale={[1, -1, 1]}\n raycast={skipRaycast}\n >\n {text}\n </Text>\n );\n })}\n {connectorOverlays.map(({ shape, url, width, rotation, x, y }) => (\n <AssignmentImageOverlay\n key={`connector-icon-${shape.id}`}\n url={url}\n width={width}\n position={[x, y, 0.22]}\n rotation={rotation}\n />\n ))}\n <OpeningWells polygons={openings} />\n {meshes.map(({ shape, threeShapes, color, extrude }) => {\n const selectable = isViewerSelectableKind(shape.kind);\n const hovered =\n selectable &&\n viewerShapeHighlighted(shape.id, hoveredShapeId, selectedShapeIds);\n const baseOpacity =\n shape.style.opacity ?? (shape.kind === 'amenity' ? 0.01 : 1);\n const fillTransparent = isTransparentColor(color);\n const opacity = fillTransparent\n ? hovered\n ? 0.2\n : 0\n : viewerHoverFillOpacity(\n shape.kind,\n baseOpacity,\n hovered,\n );\n const fill = fillTransparent\n ? hovered\n ? theme.ACCENT_COLOR\n : '#000000'\n : viewerHoverFillColor(color, theme.ACCENT_COLOR, hovered);\n return (\n <group key={shape.id}>\n {threeShapes.map((geoShape, idx) => (\n <mesh\n key={`${shape.id}-${idx}`}\n position={[0, 0, shape.zIndex * 0.01]}\n onPointerOver={(e) => {\n if (!selectable) return;\n e.stopPropagation();\n setPointerHoverId(shape.id);\n applyViewerHoverCursor(\n eventSource?.current,\n viewerHoverCursor(shape.kind),\n );\n }}\n onPointerOut={(e) => {\n if (!selectable) return;\n e.stopPropagation();\n setPointerHoverId((id) => (id === shape.id ? null : id));\n applyViewerHoverCursor(eventSource?.current, '');\n }}\n onPointerDown={(e) => {\n const additive = Boolean(\n e.shiftKey ||\n (e.nativeEvent as MouseEvent | undefined)?.shiftKey,\n );\n if (additive) e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n if (selectable) {\n onSelectShape?.(shape.id, {\n additive: Boolean(\n e.shiftKey ||\n (e.nativeEvent as MouseEvent | undefined)?.shiftKey,\n ),\n });\n return;\n }\n onSelectShape?.(null);\n }}\n >\n {extrude > 0 ? (\n <extrudeGeometry\n args={[\n geoShape,\n { depth: extrude, bevelEnabled: false },\n ]}\n />\n ) : (\n <shapeGeometry args={[geoShape]} />\n )}\n <meshBasicMaterial\n color={fill}\n transparent={\n shape.style.transparent ||\n shape.kind === 'amenity' ||\n opacity < 1\n }\n opacity={opacity}\n side={THREE.DoubleSide}\n />\n {hovered ? (\n <HoverOutline\n shape={geoShape}\n extrude={extrude}\n color={theme.ACCENT_COLOR}\n />\n ) : null}\n </mesh>\n ))}\n </group>\n );\n })}\n </group>\n );\n}\n\nfunction skipRaycast() {}\n\nfunction loadCanvasTexture(\n url: string,\n signal?: AbortSignal,\n): Promise<{ texture: THREE.CanvasTexture; aspect: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const cleanup = () => {\n signal?.removeEventListener('abort', onAbort);\n img.onload = null;\n img.onerror = null;\n };\n const onAbort = () => {\n cleanup();\n img.src = '';\n reject(new DOMException('Image load aborted', 'AbortError'));\n };\n if (signal?.aborted) {\n onAbort();\n return;\n }\n signal?.addEventListener('abort', onAbort, { once: true });\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n cleanup();\n const width = img.naturalWidth || img.width;\n const height = img.naturalHeight || img.height;\n if (!width || !height) {\n reject(new Error('empty image'));\n return;\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('canvas'));\n return;\n }\n ctx.drawImage(img, 0, 0);\n const texture = new THREE.CanvasTexture(canvas);\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.needsUpdate = true;\n resolve({ texture, aspect: height / width });\n };\n img.onerror = () => {\n cleanup();\n reject(new Error(`Failed to load ${url}`));\n };\n img.src = url;\n });\n}\n\nfunction AssignmentImageOverlay({\n url,\n width,\n position,\n rotation,\n imageProxyUrl,\n}: {\n url: string;\n width: number;\n position: [number, number, number];\n rotation: number;\n imageProxyUrl?: string | null;\n}) {\n const [texture, setTexture] = useState<THREE.CanvasTexture | null>(null);\n const [aspect, setAspect] = useState(1);\n\n useEffect(() => {\n let disposed = false;\n let loaded: THREE.CanvasTexture | null = null;\n const controller = new AbortController();\n setTexture(null);\n const proxied = resolveFetchUrl(url, imageProxyUrl);\n const candidates = proxied === url ? [url] : [proxied, url];\n const load = async () => {\n let lastError: unknown;\n for (const src of candidates) {\n try {\n const next = await loadCanvasTexture(src, controller.signal);\n if (disposed) {\n next.texture.dispose();\n return;\n }\n loaded = next.texture;\n setAspect(next.aspect);\n setTexture(next.texture);\n return;\n } catch (error) {\n if (controller.signal.aborted) return;\n lastError = error;\n }\n }\n if (!disposed) {\n setTexture(null);\n if (lastError) console.warn('Retail logo failed to load', url, lastError);\n }\n };\n void load();\n return () => {\n disposed = true;\n controller.abort();\n loaded?.dispose();\n };\n }, [url, imageProxyUrl]);\n\n if (!texture || width <= 0) return null;\n\n return (\n <mesh\n position={position}\n rotation={[0, 0, rotation]}\n scale={[1, -1, 1]}\n renderOrder={30}\n raycast={skipRaycast}\n >\n <planeGeometry args={[width, width * aspect]} />\n <meshBasicMaterial\n map={texture}\n transparent\n depthTest={false}\n depthWrite={false}\n side={THREE.DoubleSide}\n toneMapped={false}\n />\n </mesh>\n );\n}\n","import React, { useMemo } from 'react';\nimport * as THREE from 'three';\nimport type { PathResult } from '../../core';\n\nexport function RouteLine({\n route,\n activeLevelId,\n color,\n}: {\n route: PathResult;\n activeLevelId: number | null;\n color: string;\n}) {\n const points = useMemo(() => {\n return route.points\n .filter((p) => activeLevelId == null || p.levelId === activeLevelId)\n .map((p) => new THREE.Vector3(p.x, p.y, 2));\n }, [route, activeLevelId]);\n const curve = useMemo(\n () => (points.length >= 2 ? new THREE.CatmullRomCurve3(points) : null),\n [points],\n );\n\n if (!curve) return null;\n\n return (\n <mesh>\n <tubeGeometry args={[curve, Math.max(points.length * 4, 8), 1.5, 8, false]} />\n <meshBasicMaterial color={color} />\n </mesh>\n );\n}\n","import {\n\tBox2,\n\tBufferGeometry,\n\tFileLoader,\n\tFloat32BufferAttribute,\n\tLoader,\n\tMatrix3,\n\tPath,\n\tShape,\n\tShapePath,\n\tShapeUtils,\n\tSRGBColorSpace,\n\tVector2,\n\tVector3\n} from 'three';\n\nconst COLOR_SPACE_SVG = SRGBColorSpace;\n\n/**\n * A loader for the SVG format.\n *\n * Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics\n * with support for interactivity and animation.\n *\n * ```js\n * const loader = new SVGLoader();\n * const data = await loader.loadAsync( 'data/svgSample.svg' );\n *\n * const paths = data.paths;\n * const group = new THREE.Group();\n *\n * for ( let i = 0; i < paths.length; i ++ ) {\n *\n * \tconst path = paths[ i ];\n * \tconst material = new THREE.MeshBasicMaterial( {\n * \t\tcolor: path.color,\n * \t\tside: THREE.DoubleSide,\n * \t\tdepthWrite: false\n * \t} );\n *\n * \tconst shapes = SVGLoader.createShapes( path );\n *\n * \tfor ( let j = 0; j < shapes.length; j ++ ) {\n *\n * \t\tconst shape = shapes[ j ];\n * \t\tconst geometry = new THREE.ShapeGeometry( shape );\n * \t\tconst mesh = new THREE.Mesh( geometry, material );\n * \t\tgroup.add( mesh );\n *\n * \t}\n *\n * }\n *\n * scene.add( group );\n * ```\n *\n * @augments Loader\n * @three_import import { SVGLoader } from 'three/addons/loaders/SVGLoader.js';\n */\nclass SVGLoader extends Loader {\n\n\t/**\n\t * Constructs a new SVG loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\t/**\n\t\t * Default dots per inch.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 90\n\t\t */\n\t\tthis.defaultDPI = 90;\n\n\t\t/**\n\t\t * Default unit.\n\t\t *\n\t\t * @type {('mm'|'cm'|'in'|'pt'|'pc'|'px')}\n\t\t * @default 'px'\n\t\t */\n\t\tthis.defaultUnit = 'px';\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded SVG asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function({paths:Array<ShapePath>,xml:string})} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( scope.manager );\n\t\tloader.setPath( scope.path );\n\t\tloader.setRequestHeader( scope.requestHeader );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( text ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\t/**\n\t * Parses the given SVG data and returns the resulting data.\n\t *\n\t * @param {string} text - The raw SVG data as a string.\n\t * @return {{paths:Array<ShapePath>,xml:string}} An object holding an array of shape paths and the\n\t * SVG XML document.\n\t */\n\tparse( text ) {\n\n\t\tconst scope = this;\n\n\t\tfunction parseNode( node, style ) {\n\n\t\t\tif ( node.nodeType !== 1 ) return;\n\n\t\t\tconst transform = getNodeTransform( node );\n\n\t\t\tlet isDefsNode = false;\n\n\t\t\tlet path = null;\n\n\t\t\tswitch ( node.nodeName ) {\n\n\t\t\t\tcase 'svg':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'style':\n\t\t\t\t\tparseCSSStylesheet( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'g':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'path':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tif ( node.hasAttribute( 'd' ) ) path = parsePathNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'rect':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseRectNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'polygon':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parsePolygonNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'polyline':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parsePolylineNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'circle':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseCircleNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'ellipse':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseEllipseNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'line':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseLineNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'defs':\n\t\t\t\t\tisDefsNode = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'use':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\n\t\t\t\t\tconst href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || '';\n\t\t\t\t\tconst usedNodeId = href.substring( 1 );\n\t\t\t\t\tconst usedNode = node.viewportElement.getElementById( usedNodeId );\n\t\t\t\t\tif ( usedNode ) {\n\n\t\t\t\t\t\tparseNode( usedNode, style );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'SVGLoader: \\'use node\\' references non-existent node id: ' + usedNodeId );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t// console.log( node );\n\n\t\t\t}\n\n\t\t\tif ( path ) {\n\n\t\t\t\tif ( style.fill !== undefined && style.fill !== 'none' ) {\n\n\t\t\t\t\tpath.color.setStyle( style.fill, COLOR_SPACE_SVG );\n\n\t\t\t\t}\n\n\t\t\t\ttransformPath( path, currentTransform );\n\n\t\t\t\tpaths.push( path );\n\n\t\t\t\tpath.userData = { node: node, style: style };\n\n\t\t\t}\n\n\t\t\tconst childNodes = node.childNodes;\n\n\t\t\tfor ( let i = 0; i < childNodes.length; i ++ ) {\n\n\t\t\t\tconst node = childNodes[ i ];\n\n\t\t\t\tif ( isDefsNode && node.nodeName !== 'style' && node.nodeName !== 'defs' ) {\n\n\t\t\t\t\t// Ignore everything in defs except CSS style definitions\n\t\t\t\t\t// and nested defs, because it is OK by the standard to have\n\t\t\t\t\t// <style/> there.\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tparseNode( node, style );\n\n\t\t\t}\n\n\n\t\t\tif ( transform ) {\n\n\t\t\t\ttransformStack.pop();\n\n\t\t\t\tif ( transformStack.length > 0 ) {\n\n\t\t\t\t\tcurrentTransform.copy( transformStack[ transformStack.length - 1 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcurrentTransform.identity();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction parsePathNode( node ) {\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tconst point = new Vector2();\n\t\t\tconst control = new Vector2();\n\n\t\t\tconst firstPoint = new Vector2();\n\t\t\tlet isFirstPoint = true;\n\t\t\tlet doSetFirstPoint = false;\n\n\t\t\tconst d = node.getAttribute( 'd' );\n\n\t\t\tif ( d === '' || d === 'none' ) return null;\n\n\t\t\t// console.log( d );\n\n\t\t\tconst commands = d.match( /[a-df-z][^a-df-z]*/ig );\n\n\t\t\tfor ( let i = 0, l = commands.length; i < l; i ++ ) {\n\n\t\t\t\tconst command = commands[ i ];\n\n\t\t\t\tconst type = command.charAt( 0 );\n\t\t\t\tconst data = command.slice( 1 ).trim();\n\n\t\t\t\tif ( isFirstPoint === true ) {\n\n\t\t\t\t\tdoSetFirstPoint = true;\n\t\t\t\t\tisFirstPoint = false;\n\n\t\t\t\t}\n\n\t\t\t\tlet numbers;\n\n\t\t\t\tswitch ( type ) {\n\n\t\t\t\t\tcase 'M':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\n\t\t\t\t\t\t\tif ( j === 0 ) {\n\n\t\t\t\t\t\t\t\tpath.moveTo( point.x, point.y );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( j === 0 ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'H':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'V':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.y = numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'L':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'C':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 4 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 5 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 3 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 4 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 5 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'S':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tgetReflection( point.x, control.x ),\n\t\t\t\t\t\t\t\tgetReflection( point.y, control.y ),\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Q':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'T':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tconst rx = getReflection( point.x, control.x );\n\t\t\t\t\t\t\tconst ry = getReflection( point.y, control.y );\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\trx,\n\t\t\t\t\t\t\t\try,\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = rx;\n\t\t\t\t\t\t\tcontrol.y = ry;\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'A':\n\t\t\t\t\t\tnumbers = parseFloats( data, [ 3, 4 ], 7 );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {\n\n\t\t\t\t\t\t\t// skip command if start point == end point\n\t\t\t\t\t\t\tif ( numbers[ j + 5 ] == point.x && numbers[ j + 6 ] == point.y ) continue;\n\n\t\t\t\t\t\t\tconst start = point.clone();\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 5 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 6 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tparseArcCommand(\n\t\t\t\t\t\t\t\tpath, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'm':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\n\t\t\t\t\t\t\tif ( j === 0 ) {\n\n\t\t\t\t\t\t\t\tpath.moveTo( point.x, point.y );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( j === 0 ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'h':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'v':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.y += numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'l':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'c':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 4 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 5 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 2 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 3 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 4 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 5 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 's':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tgetReflection( point.x, control.x ),\n\t\t\t\t\t\t\t\tgetReflection( point.y, control.y ),\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 't':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tconst rx = getReflection( point.x, control.x );\n\t\t\t\t\t\t\tconst ry = getReflection( point.y, control.y );\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\trx,\n\t\t\t\t\t\t\t\try,\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = rx;\n\t\t\t\t\t\t\tcontrol.y = ry;\n\t\t\t\t\t\t\tpoint.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = point.y + numbers[ j + 1 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'a':\n\t\t\t\t\t\tnumbers = parseFloats( data, [ 3, 4 ], 7 );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {\n\n\t\t\t\t\t\t\t// skip command if no displacement\n\t\t\t\t\t\t\tif ( numbers[ j + 5 ] == 0 && numbers[ j + 6 ] == 0 ) continue;\n\n\t\t\t\t\t\t\tconst start = point.clone();\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 5 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 6 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tparseArcCommand(\n\t\t\t\t\t\t\t\tpath, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\tcase 'z':\n\t\t\t\t\t\tpath.currentPath.autoClose = true;\n\n\t\t\t\t\t\tif ( path.currentPath.curves.length > 0 ) {\n\n\t\t\t\t\t\t\t// Reset point to beginning of Path\n\t\t\t\t\t\t\tpoint.copy( firstPoint );\n\t\t\t\t\t\t\tpath.currentPath.currentPoint.copy( point );\n\t\t\t\t\t\t\tisFirstPoint = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tconsole.warn( command );\n\n\t\t\t\t}\n\n\t\t\t\t// console.log( type, parseFloats( data ), parseFloats( data ).length )\n\n\t\t\t\tdoSetFirstPoint = false;\n\n\t\t\t}\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseCSSStylesheet( node ) {\n\n\t\t\tif ( ! node.sheet || ! node.sheet.cssRules || ! node.sheet.cssRules.length ) return;\n\n\t\t\tfor ( let i = 0; i < node.sheet.cssRules.length; i ++ ) {\n\n\t\t\t\tconst stylesheet = node.sheet.cssRules[ i ];\n\n\t\t\t\tif ( stylesheet.type !== 1 ) continue;\n\n\t\t\t\tconst selectorList = stylesheet.selectorText\n\t\t\t\t\t.split( /,/gm )\n\t\t\t\t\t.filter( Boolean )\n\t\t\t\t\t.map( i => i.trim() );\n\n\t\t\t\tfor ( let j = 0; j < selectorList.length; j ++ ) {\n\n\t\t\t\t\t// Remove empty rules\n\t\t\t\t\tconst definitions = Object.fromEntries(\n\t\t\t\t\t\tObject.entries( stylesheet.style ).filter( ( [ , v ] ) => v !== '' )\n\t\t\t\t\t);\n\n\t\t\t\t\tstylesheets[ selectorList[ j ] ] = Object.assign(\n\t\t\t\t\t\tstylesheets[ selectorList[ j ] ] || {},\n\t\t\t\t\t\tdefinitions\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/**\n\t\t * https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes\n\t\t * https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ Appendix: Endpoint to center arc conversion\n\t\t * From\n\t\t * rx ry x-axis-rotation large-arc-flag sweep-flag x y\n\t\t * To\n\t\t * aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation\n\t\t */\n\n\t\tfunction parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) {\n\n\t\t\tif ( rx == 0 || ry == 0 ) {\n\n\t\t\t\t// draw a line if either of the radii == 0\n\t\t\t\tpath.lineTo( end.x, end.y );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tx_axis_rotation = x_axis_rotation * Math.PI / 180;\n\n\t\t\t// Ensure radii are positive\n\t\t\trx = Math.abs( rx );\n\t\t\try = Math.abs( ry );\n\n\t\t\t// Compute (x1', y1')\n\t\t\tconst dx2 = ( start.x - end.x ) / 2.0;\n\t\t\tconst dy2 = ( start.y - end.y ) / 2.0;\n\t\t\tconst x1p = Math.cos( x_axis_rotation ) * dx2 + Math.sin( x_axis_rotation ) * dy2;\n\t\t\tconst y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2;\n\n\t\t\t// Compute (cx', cy')\n\t\t\tlet rxs = rx * rx;\n\t\t\tlet rys = ry * ry;\n\t\t\tconst x1ps = x1p * x1p;\n\t\t\tconst y1ps = y1p * y1p;\n\n\t\t\t// Ensure radii are large enough\n\t\t\tconst cr = x1ps / rxs + y1ps / rys;\n\n\t\t\tif ( cr > 1 ) {\n\n\t\t\t\t// scale up rx,ry equally so cr == 1\n\t\t\t\tconst s = Math.sqrt( cr );\n\t\t\t\trx = s * rx;\n\t\t\t\try = s * ry;\n\t\t\t\trxs = rx * rx;\n\t\t\t\trys = ry * ry;\n\n\t\t\t}\n\n\t\t\tconst dq = ( rxs * y1ps + rys * x1ps );\n\t\t\tconst pq = ( rxs * rys - dq ) / dq;\n\t\t\tlet q = Math.sqrt( Math.max( 0, pq ) );\n\t\t\tif ( large_arc_flag === sweep_flag ) q = - q;\n\t\t\tconst cxp = q * rx * y1p / ry;\n\t\t\tconst cyp = - q * ry * x1p / rx;\n\n\t\t\t// Step 3: Compute (cx, cy) from (cx', cy')\n\t\t\tconst cx = Math.cos( x_axis_rotation ) * cxp - Math.sin( x_axis_rotation ) * cyp + ( start.x + end.x ) / 2;\n\t\t\tconst cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2;\n\n\t\t\t// Step 4: Compute θ1 and Δθ\n\t\t\tconst theta = svgAngle( 1, 0, ( x1p - cxp ) / rx, ( y1p - cyp ) / ry );\n\t\t\tconst delta = svgAngle( ( x1p - cxp ) / rx, ( y1p - cyp ) / ry, ( - x1p - cxp ) / rx, ( - y1p - cyp ) / ry ) % ( Math.PI * 2 );\n\n\t\t\tpath.currentPath.absellipse( cx, cy, rx, ry, theta, theta + delta, sweep_flag === 0, x_axis_rotation );\n\n\t\t}\n\n\t\tfunction svgAngle( ux, uy, vx, vy ) {\n\n\t\t\tconst dot = ux * vx + uy * vy;\n\t\t\tconst len = Math.sqrt( ux * ux + uy * uy ) * Math.sqrt( vx * vx + vy * vy );\n\t\t\tlet ang = Math.acos( Math.max( - 1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear\n\t\t\tif ( ( ux * vy - uy * vx ) < 0 ) ang = - ang;\n\t\t\treturn ang;\n\n\t\t}\n\n\t\t/*\n\t\t* According to https://www.w3.org/TR/SVG/shapes.html#RectElementRXAttribute\n\t\t* rounded corner should be rendered to elliptical arc, but bezier curve does the job well enough\n\t\t*/\n\n\t\tfunction parseRectNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'x' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'y' ) || 0 );\n\t\t\tconst rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || node.getAttribute( 'ry' ) || 0 );\n\t\t\tconst ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || node.getAttribute( 'rx' ) || 0 );\n\t\t\tconst w = parseFloatWithUnits( node.getAttribute( 'width' ) );\n\t\t\tconst h = parseFloatWithUnits( node.getAttribute( 'height' ) );\n\n\t\t\t// Ellipse arc to Bezier approximation Coefficient (Inversed). See:\n\t\t\t// https://spencermortensen.com/articles/bezier-circle/\n\t\t\tconst bci = 1 - 0.551915024494;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\t// top left\n\t\t\tpath.moveTo( x + rx, y );\n\n\t\t\t// top right\n\t\t\tpath.lineTo( x + w - rx, y );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + w - rx * bci,\n\t\t\t\t\ty,\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + ry * bci,\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + ry\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// bottom right\n\t\t\tpath.lineTo( x + w, y + h - ry );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + h - ry * bci,\n\t\t\t\t\tx + w - rx * bci,\n\t\t\t\t\ty + h,\n\t\t\t\t\tx + w - rx,\n\t\t\t\t\ty + h\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// bottom left\n\t\t\tpath.lineTo( x + rx, y + h );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + rx * bci,\n\t\t\t\t\ty + h,\n\t\t\t\t\tx,\n\t\t\t\t\ty + h - ry * bci,\n\t\t\t\t\tx,\n\t\t\t\t\ty + h - ry\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// back to top left\n\t\t\tpath.lineTo( x, y + ry );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo( x, y + ry * bci, x + rx * bci, y, x + rx, y );\n\n\t\t\t}\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parsePolygonNode( node ) {\n\n\t\t\tfunction iterator( match, a, b ) {\n\n\t\t\t\tconst x = parseFloatWithUnits( a );\n\t\t\t\tconst y = parseFloatWithUnits( b );\n\n\t\t\t\tif ( index === 0 ) {\n\n\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t}\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tconst regex = /([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)(?:,|\\s)([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)/g;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tlet index = 0;\n\n\t\t\tnode.getAttribute( 'points' ).replace( regex, iterator );\n\n\t\t\tpath.currentPath.autoClose = true;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parsePolylineNode( node ) {\n\n\t\t\tfunction iterator( match, a, b ) {\n\n\t\t\t\tconst x = parseFloatWithUnits( a );\n\t\t\t\tconst y = parseFloatWithUnits( b );\n\n\t\t\t\tif ( index === 0 ) {\n\n\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t}\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tconst regex = /([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)(?:,|\\s)([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)/g;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tlet index = 0;\n\n\t\t\tnode.getAttribute( 'points' ).replace( regex, iterator );\n\n\t\t\tpath.currentPath.autoClose = false;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseCircleNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'cx' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'cy' ) || 0 );\n\t\t\tconst r = parseFloatWithUnits( node.getAttribute( 'r' ) || 0 );\n\n\t\t\tconst subpath = new Path();\n\t\t\tsubpath.absarc( x, y, r, 0, Math.PI * 2 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.subPaths.push( subpath );\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseEllipseNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'cx' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'cy' ) || 0 );\n\t\t\tconst rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || 0 );\n\t\t\tconst ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || 0 );\n\n\t\t\tconst subpath = new Path();\n\t\t\tsubpath.absellipse( x, y, rx, ry, 0, Math.PI * 2 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.subPaths.push( subpath );\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseLineNode( node ) {\n\n\t\t\tconst x1 = parseFloatWithUnits( node.getAttribute( 'x1' ) || 0 );\n\t\t\tconst y1 = parseFloatWithUnits( node.getAttribute( 'y1' ) || 0 );\n\t\t\tconst x2 = parseFloatWithUnits( node.getAttribute( 'x2' ) || 0 );\n\t\t\tconst y2 = parseFloatWithUnits( node.getAttribute( 'y2' ) || 0 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.moveTo( x1, y1 );\n\t\t\tpath.lineTo( x2, y2 );\n\t\t\tpath.currentPath.autoClose = false;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction parseStyle( node, style ) {\n\n\t\t\tstyle = Object.assign( {}, style ); // clone style\n\n\t\t\tlet stylesheetStyles = {};\n\n\t\t\tif ( node.hasAttribute( 'class' ) ) {\n\n\t\t\t\tconst classSelectors = node.getAttribute( 'class' )\n\t\t\t\t\t.split( /\\s/ )\n\t\t\t\t\t.filter( Boolean )\n\t\t\t\t\t.map( i => i.trim() );\n\n\t\t\t\tfor ( let i = 0; i < classSelectors.length; i ++ ) {\n\n\t\t\t\t\tstylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '.' + classSelectors[ i ] ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( node.hasAttribute( 'id' ) ) {\n\n\t\t\t\tstylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '#' + node.getAttribute( 'id' ) ] );\n\n\t\t\t}\n\n\t\t\tfunction addStyle( svgName, jsName, adjustFunction ) {\n\n\t\t\t\tif ( adjustFunction === undefined ) adjustFunction = function copy( v ) {\n\n\t\t\t\t\tif ( v.startsWith( 'url' ) ) console.warn( 'SVGLoader: url access in attributes is not implemented.' );\n\n\t\t\t\t\treturn v;\n\n\t\t\t\t};\n\n\t\t\t\tif ( node.hasAttribute( svgName ) ) style[ jsName ] = adjustFunction( node.getAttribute( svgName ) );\n\t\t\t\tif ( stylesheetStyles[ svgName ] ) style[ jsName ] = adjustFunction( stylesheetStyles[ svgName ] );\n\t\t\t\tif ( node.style && node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] );\n\n\t\t\t}\n\n\t\t\tfunction clamp( v ) {\n\n\t\t\t\treturn Math.max( 0, Math.min( 1, parseFloatWithUnits( v ) ) );\n\n\t\t\t}\n\n\t\t\tfunction positive( v ) {\n\n\t\t\t\treturn Math.max( 0, parseFloatWithUnits( v ) );\n\n\t\t\t}\n\n\t\t\taddStyle( 'fill', 'fill' );\n\t\t\taddStyle( 'fill-opacity', 'fillOpacity', clamp );\n\t\t\taddStyle( 'fill-rule', 'fillRule' );\n\t\t\taddStyle( 'opacity', 'opacity', clamp );\n\t\t\taddStyle( 'stroke', 'stroke' );\n\t\t\taddStyle( 'stroke-opacity', 'strokeOpacity', clamp );\n\t\t\taddStyle( 'stroke-width', 'strokeWidth', positive );\n\t\t\taddStyle( 'stroke-linejoin', 'strokeLineJoin' );\n\t\t\taddStyle( 'stroke-linecap', 'strokeLineCap' );\n\t\t\taddStyle( 'stroke-miterlimit', 'strokeMiterLimit', positive );\n\t\t\taddStyle( 'visibility', 'visibility' );\n\n\t\t\treturn style;\n\n\t\t}\n\n\t\t// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes\n\n\t\tfunction getReflection( a, b ) {\n\n\t\t\treturn a - ( b - a );\n\n\t\t}\n\n\t\t// from https://github.com/ppvg/svg-numbers (MIT License)\n\n\t\tfunction parseFloats( input, flags, stride ) {\n\n\t\t\tif ( typeof input !== 'string' ) {\n\n\t\t\t\tthrow new TypeError( 'Invalid input: ' + typeof input );\n\n\t\t\t}\n\n\t\t\t// Character groups\n\t\t\tconst RE = {\n\t\t\t\tSEPARATOR: /[ \\t\\r\\n\\,.\\-+]/,\n\t\t\t\tWHITESPACE: /[ \\t\\r\\n]/,\n\t\t\t\tDIGIT: /[\\d]/,\n\t\t\t\tSIGN: /[-+]/,\n\t\t\t\tPOINT: /\\./,\n\t\t\t\tCOMMA: /,/,\n\t\t\t\tEXP: /e/i,\n\t\t\t\tFLAGS: /[01]/\n\t\t\t};\n\n\t\t\t// States\n\t\t\tconst SEP = 0;\n\t\t\tconst INT = 1;\n\t\t\tconst FLOAT = 2;\n\t\t\tconst EXP = 3;\n\n\t\t\tlet state = SEP;\n\t\t\tlet seenComma = true;\n\t\t\tlet number = '', exponent = '';\n\t\t\tconst result = [];\n\n\t\t\tfunction throwSyntaxError( current, i, partial ) {\n\n\t\t\t\tconst error = new SyntaxError( 'Unexpected character \"' + current + '\" at index ' + i + '.' );\n\t\t\t\terror.partial = partial;\n\t\t\t\tthrow error;\n\n\t\t\t}\n\n\t\t\tfunction newNumber() {\n\n\t\t\t\tif ( number !== '' ) {\n\n\t\t\t\t\tif ( exponent === '' ) result.push( Number( number ) );\n\t\t\t\t\telse result.push( Number( number ) * Math.pow( 10, Number( exponent ) ) );\n\n\t\t\t\t}\n\n\t\t\t\tnumber = '';\n\t\t\t\texponent = '';\n\n\t\t\t}\n\n\t\t\tlet current;\n\t\t\tconst length = input.length;\n\n\t\t\tfor ( let i = 0; i < length; i ++ ) {\n\n\t\t\t\tcurrent = input[ i ];\n\n\t\t\t\t// check for flags\n\t\t\t\tif ( Array.isArray( flags ) && flags.includes( result.length % stride ) && RE.FLAGS.test( current ) ) {\n\n\t\t\t\t\tstate = INT;\n\t\t\t\t\tnumber = current;\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\t// parse until next number\n\t\t\t\tif ( state === SEP ) {\n\n\t\t\t\t\t// eat whitespace\n\t\t\t\t\tif ( RE.WHITESPACE.test( current ) ) {\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// start new number\n\t\t\t\t\tif ( RE.DIGIT.test( current ) || RE.SIGN.test( current ) ) {\n\n\t\t\t\t\t\tstate = INT;\n\t\t\t\t\t\tnumber = current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\t\tnumber = current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double commas (e.g. \"1, , 2\")\n\t\t\t\t\tif ( RE.COMMA.test( current ) ) {\n\n\t\t\t\t\t\tif ( seenComma ) {\n\n\t\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tseenComma = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse integer part\n\t\t\t\tif ( state === INT ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.EXP.test( current ) ) {\n\n\t\t\t\t\t\tstate = EXP;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double signs (\"-+1\"), but not on sign as separator (\"-1-2\")\n\t\t\t\t\tif ( RE.SIGN.test( current )\n\t\t\t\t\t\t\t&& number.length === 1\n\t\t\t\t\t\t\t&& RE.SIGN.test( number[ 0 ] ) ) {\n\n\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse decimal part\n\t\t\t\tif ( state === FLOAT ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.EXP.test( current ) ) {\n\n\t\t\t\t\t\tstate = EXP;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double decimal points (e.g. \"1..2\")\n\t\t\t\t\tif ( RE.POINT.test( current ) && number[ number.length - 1 ] === '.' ) {\n\n\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse exponent part\n\t\t\t\tif ( state === EXP ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\texponent += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.SIGN.test( current ) ) {\n\n\t\t\t\t\t\tif ( exponent === '' ) {\n\n\t\t\t\t\t\t\texponent += current;\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( exponent.length === 1 && RE.SIGN.test( exponent ) ) {\n\n\t\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t\t// end of number\n\t\t\t\tif ( RE.WHITESPACE.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = SEP;\n\t\t\t\t\tseenComma = false;\n\n\t\t\t\t} else if ( RE.COMMA.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = SEP;\n\t\t\t\t\tseenComma = true;\n\n\t\t\t\t} else if ( RE.SIGN.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = INT;\n\t\t\t\t\tnumber = current;\n\n\t\t\t\t} else if ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\tnumber = current;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add the last number found (if any)\n\t\t\tnewNumber();\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\t// Units\n\n\t\tconst units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ];\n\n\t\t// Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent)\n\t\tconst unitConversion = {\n\n\t\t\t'mm': {\n\t\t\t\t'mm': 1,\n\t\t\t\t'cm': 0.1,\n\t\t\t\t'in': 1 / 25.4,\n\t\t\t\t'pt': 72 / 25.4,\n\t\t\t\t'pc': 6 / 25.4,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'cm': {\n\t\t\t\t'mm': 10,\n\t\t\t\t'cm': 1,\n\t\t\t\t'in': 1 / 2.54,\n\t\t\t\t'pt': 72 / 2.54,\n\t\t\t\t'pc': 6 / 2.54,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'in': {\n\t\t\t\t'mm': 25.4,\n\t\t\t\t'cm': 2.54,\n\t\t\t\t'in': 1,\n\t\t\t\t'pt': 72,\n\t\t\t\t'pc': 6,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'pt': {\n\t\t\t\t'mm': 25.4 / 72,\n\t\t\t\t'cm': 2.54 / 72,\n\t\t\t\t'in': 1 / 72,\n\t\t\t\t'pt': 1,\n\t\t\t\t'pc': 6 / 72,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'pc': {\n\t\t\t\t'mm': 25.4 / 6,\n\t\t\t\t'cm': 2.54 / 6,\n\t\t\t\t'in': 1 / 6,\n\t\t\t\t'pt': 72 / 6,\n\t\t\t\t'pc': 1,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'px': {\n\t\t\t\t'px': 1\n\t\t\t}\n\n\t\t};\n\n\t\tfunction parseFloatWithUnits( string ) {\n\n\t\t\tlet theUnit = 'px';\n\n\t\t\tif ( typeof string === 'string' || string instanceof String ) {\n\n\t\t\t\tfor ( let i = 0, n = units.length; i < n; i ++ ) {\n\n\t\t\t\t\tconst u = units[ i ];\n\n\t\t\t\t\tif ( string.endsWith( u ) ) {\n\n\t\t\t\t\t\ttheUnit = u;\n\t\t\t\t\t\tstring = string.substring( 0, string.length - u.length );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlet scale = undefined;\n\n\t\t\tif ( theUnit === 'px' && scope.defaultUnit !== 'px' ) {\n\n\t\t\t\t// Conversion scale from pixels to inches, then to default units\n\n\t\t\t\tscale = unitConversion[ 'in' ][ scope.defaultUnit ] / scope.defaultDPI;\n\n\t\t\t} else {\n\n\t\t\t\tscale = unitConversion[ theUnit ][ scope.defaultUnit ];\n\n\t\t\t\tif ( scale < 0 ) {\n\n\t\t\t\t\t// Conversion scale to pixels\n\n\t\t\t\t\tscale = unitConversion[ theUnit ][ 'in' ] * scope.defaultDPI;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn scale * parseFloat( string );\n\n\t\t}\n\n\t\t// Transforms\n\n\t\tfunction getNodeTransform( node ) {\n\n\t\t\tif ( ! ( node.hasAttribute( 'transform' ) || ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) ) ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tconst transform = parseNodeTransform( node );\n\n\t\t\tif ( transformStack.length > 0 ) {\n\n\t\t\t\ttransform.premultiply( transformStack[ transformStack.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tcurrentTransform.copy( transform );\n\t\t\ttransformStack.push( transform );\n\n\t\t\treturn transform;\n\n\t\t}\n\n\t\tfunction parseNodeTransform( node ) {\n\n\t\t\tconst transform = new Matrix3();\n\t\t\tconst currentTransform = tempTransform0;\n\n\t\t\tif ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) {\n\n\t\t\t\tconst tx = parseFloatWithUnits( node.getAttribute( 'x' ) );\n\t\t\t\tconst ty = parseFloatWithUnits( node.getAttribute( 'y' ) );\n\n\t\t\t\ttransform.translate( tx, ty );\n\n\t\t\t}\n\n\t\t\tif ( node.hasAttribute( 'transform' ) ) {\n\n\t\t\t\tconst transformsTexts = node.getAttribute( 'transform' ).split( ')' );\n\n\t\t\t\tfor ( let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) {\n\n\t\t\t\t\tconst transformText = transformsTexts[ tIndex ].trim();\n\n\t\t\t\t\tif ( transformText === '' ) continue;\n\n\t\t\t\t\tconst openParPos = transformText.indexOf( '(' );\n\t\t\t\t\tconst closeParPos = transformText.length;\n\n\t\t\t\t\tif ( openParPos > 0 && openParPos < closeParPos ) {\n\n\t\t\t\t\t\tconst transformType = transformText.slice( 0, openParPos );\n\n\t\t\t\t\t\tconst array = parseFloats( transformText.slice( openParPos + 1 ) );\n\n\t\t\t\t\t\tcurrentTransform.identity();\n\n\t\t\t\t\t\tswitch ( transformType ) {\n\n\t\t\t\t\t\t\tcase 'translate':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tconst tx = array[ 0 ];\n\t\t\t\t\t\t\t\t\tlet ty = 0;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 2 ) {\n\n\t\t\t\t\t\t\t\t\t\tty = array[ 1 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.translate( tx, ty );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'rotate':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tlet angle = 0;\n\t\t\t\t\t\t\t\t\tlet cx = 0;\n\t\t\t\t\t\t\t\t\tlet cy = 0;\n\n\t\t\t\t\t\t\t\t\t// Angle\n\t\t\t\t\t\t\t\t\tangle = array[ 0 ] * Math.PI / 180;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 3 ) {\n\n\t\t\t\t\t\t\t\t\t\t// Center x, y\n\t\t\t\t\t\t\t\t\t\tcx = array[ 1 ];\n\t\t\t\t\t\t\t\t\t\tcy = array[ 2 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Rotate around center (cx, cy)\n\t\t\t\t\t\t\t\t\ttempTransform1.makeTranslation( - cx, - cy );\n\t\t\t\t\t\t\t\t\ttempTransform2.makeRotation( angle );\n\t\t\t\t\t\t\t\t\ttempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );\n\t\t\t\t\t\t\t\t\ttempTransform1.makeTranslation( cx, cy );\n\t\t\t\t\t\t\t\t\tcurrentTransform.multiplyMatrices( tempTransform1, tempTransform3 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'scale':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tconst scaleX = array[ 0 ];\n\t\t\t\t\t\t\t\t\tlet scaleY = scaleX;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 2 ) {\n\n\t\t\t\t\t\t\t\t\t\tscaleY = array[ 1 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.scale( scaleX, scaleY );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'skewX':\n\n\t\t\t\t\t\t\t\tif ( array.length === 1 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\t1, Math.tan( array[ 0 ] * Math.PI / 180 ), 0,\n\t\t\t\t\t\t\t\t\t\t0, 1, 0,\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'skewY':\n\n\t\t\t\t\t\t\t\tif ( array.length === 1 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\t1, 0, 0,\n\t\t\t\t\t\t\t\t\t\tMath.tan( array[ 0 ] * Math.PI / 180 ), 1, 0,\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'matrix':\n\n\t\t\t\t\t\t\t\tif ( array.length === 6 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\tarray[ 0 ], array[ 2 ], array[ 4 ],\n\t\t\t\t\t\t\t\t\t\tarray[ 1 ], array[ 3 ], array[ 5 ],\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttransform.premultiply( currentTransform );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn transform;\n\n\t\t}\n\n\t\tfunction transformPath( path, m ) {\n\n\t\t\tfunction transfVec2( v2 ) {\n\n\t\t\t\ttempV3.set( v2.x, v2.y, 1 ).applyMatrix3( m );\n\n\t\t\t\tv2.set( tempV3.x, tempV3.y );\n\n\t\t\t}\n\n\t\t\tfunction transfEllipseGeneric( curve ) {\n\n\t\t\t\t// For math description see:\n\t\t\t\t// https://math.stackexchange.com/questions/4544164\n\n\t\t\t\tconst a = curve.xRadius;\n\t\t\t\tconst b = curve.yRadius;\n\n\t\t\t\tconst cosTheta = Math.cos( curve.aRotation );\n\t\t\t\tconst sinTheta = Math.sin( curve.aRotation );\n\n\t\t\t\tconst v1 = new Vector3( a * cosTheta, a * sinTheta, 0 );\n\t\t\t\tconst v2 = new Vector3( - b * sinTheta, b * cosTheta, 0 );\n\n\t\t\t\tconst f1 = v1.applyMatrix3( m );\n\t\t\t\tconst f2 = v2.applyMatrix3( m );\n\n\t\t\t\tconst mF = tempTransform0.set(\n\t\t\t\t\tf1.x, f2.x, 0,\n\t\t\t\t\tf1.y, f2.y, 0,\n\t\t\t\t\t0, 0, 1,\n\t\t\t\t);\n\n\t\t\t\tconst mFInv = tempTransform1.copy( mF ).invert();\n\t\t\t\tconst mFInvT = tempTransform2.copy( mFInv ).transpose();\n\t\t\t\tconst mQ = mFInvT.multiply( mFInv );\n\t\t\t\tconst mQe = mQ.elements;\n\n\t\t\t\tconst ed = eigenDecomposition( mQe[ 0 ], mQe[ 1 ], mQe[ 4 ] );\n\t\t\t\tconst rt1sqrt = Math.sqrt( ed.rt1 );\n\t\t\t\tconst rt2sqrt = Math.sqrt( ed.rt2 );\n\n\t\t\t\tcurve.xRadius = 1 / rt1sqrt;\n\t\t\t\tcurve.yRadius = 1 / rt2sqrt;\n\t\t\t\tcurve.aRotation = Math.atan2( ed.sn, ed.cs );\n\n\t\t\t\tconst isFullEllipse =\n\t\t\t\t\t( curve.aEndAngle - curve.aStartAngle ) % ( 2 * Math.PI ) < Number.EPSILON;\n\n\t\t\t\t// Do not touch angles of a full ellipse because after transformation they\n\t\t\t\t// would converge to a single value effectively removing the whole curve\n\n\t\t\t\tif ( ! isFullEllipse ) {\n\n\t\t\t\t\tconst mDsqrt = tempTransform1.set(\n\t\t\t\t\t\trt1sqrt, 0, 0,\n\t\t\t\t\t\t0, rt2sqrt, 0,\n\t\t\t\t\t\t0, 0, 1,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst mRT = tempTransform2.set(\n\t\t\t\t\t\ted.cs, ed.sn, 0,\n\t\t\t\t\t\t- ed.sn, ed.cs, 0,\n\t\t\t\t\t\t0, 0, 1,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst mDRF = mDsqrt.multiply( mRT ).multiply( mF );\n\n\t\t\t\t\tconst transformAngle = phi => {\n\n\t\t\t\t\t\tconst { x: cosR, y: sinR } =\n\t\t\t\t\t\t\tnew Vector3( Math.cos( phi ), Math.sin( phi ), 0 ).applyMatrix3( mDRF );\n\n\t\t\t\t\t\treturn Math.atan2( sinR, cosR );\n\n\t\t\t\t\t};\n\n\t\t\t\t\tcurve.aStartAngle = transformAngle( curve.aStartAngle );\n\t\t\t\t\tcurve.aEndAngle = transformAngle( curve.aEndAngle );\n\n\t\t\t\t\tif ( isTransformFlipped( m ) ) {\n\n\t\t\t\t\t\tcurve.aClockwise = ! curve.aClockwise;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction transfEllipseNoSkew( curve ) {\n\n\t\t\t\t// Faster shortcut if no skew is applied\n\t\t\t\t// (e.g, a euclidean transform of a group containing the ellipse)\n\n\t\t\t\tconst sx = getTransformScaleX( m );\n\t\t\t\tconst sy = getTransformScaleY( m );\n\n\t\t\t\tcurve.xRadius *= sx;\n\t\t\t\tcurve.yRadius *= sy;\n\n\t\t\t\t// Extract rotation angle from the matrix of form:\n\t\t\t\t//\n\t\t\t\t// | cosθ sx -sinθ sy |\n\t\t\t\t// | sinθ sx cosθ sy |\n\t\t\t\t//\n\t\t\t\t// Remembering that tanθ = sinθ / cosθ; and that\n\t\t\t\t// `sx`, `sy`, or both might be zero.\n\t\t\t\tconst theta =\n\t\t\t\t\tsx > Number.EPSILON\n\t\t\t\t\t\t? Math.atan2( m.elements[ 1 ], m.elements[ 0 ] )\n\t\t\t\t\t\t: Math.atan2( - m.elements[ 3 ], m.elements[ 4 ] );\n\n\t\t\t\tcurve.aRotation += theta;\n\n\t\t\t\tif ( isTransformFlipped( m ) ) {\n\n\t\t\t\t\tcurve.aStartAngle *= - 1;\n\t\t\t\t\tcurve.aEndAngle *= - 1;\n\t\t\t\t\tcurve.aClockwise = ! curve.aClockwise;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst subPaths = path.subPaths;\n\n\t\t\tfor ( let i = 0, n = subPaths.length; i < n; i ++ ) {\n\n\t\t\t\tconst subPath = subPaths[ i ];\n\t\t\t\tconst curves = subPath.curves;\n\n\t\t\t\tfor ( let j = 0; j < curves.length; j ++ ) {\n\n\t\t\t\t\tconst curve = curves[ j ];\n\n\t\t\t\t\tif ( curve.isLineCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\n\t\t\t\t\t} else if ( curve.isCubicBezierCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v0 );\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\t\t\t\t\t\ttransfVec2( curve.v3 );\n\n\t\t\t\t\t} else if ( curve.isQuadraticBezierCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v0 );\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\n\t\t\t\t\t} else if ( curve.isEllipseCurve ) {\n\n\t\t\t\t\t\t// Transform ellipse center point\n\n\t\t\t\t\t\ttempV2.set( curve.aX, curve.aY );\n\t\t\t\t\t\ttransfVec2( tempV2 );\n\t\t\t\t\t\tcurve.aX = tempV2.x;\n\t\t\t\t\t\tcurve.aY = tempV2.y;\n\n\t\t\t\t\t\t// Transform ellipse shape parameters\n\n\t\t\t\t\t\tif ( isTransformSkewed( m ) ) {\n\n\t\t\t\t\t\t\ttransfEllipseGeneric( curve );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttransfEllipseNoSkew( curve );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction isTransformFlipped( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn te[ 0 ] * te[ 4 ] - te[ 1 ] * te[ 3 ] < 0;\n\n\t\t}\n\n\t\tfunction isTransformSkewed( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\tconst basisDot = te[ 0 ] * te[ 3 ] + te[ 1 ] * te[ 4 ];\n\n\t\t\t// Shortcut for trivial rotations and transformations\n\t\t\tif ( basisDot === 0 ) return false;\n\n\t\t\tconst sx = getTransformScaleX( m );\n\t\t\tconst sy = getTransformScaleY( m );\n\n\t\t\treturn Math.abs( basisDot / ( sx * sy ) ) > Number.EPSILON;\n\n\t\t}\n\n\t\tfunction getTransformScaleX( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn Math.sqrt( te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] );\n\n\t\t}\n\n\t\tfunction getTransformScaleY( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] );\n\n\t\t}\n\n\t\t// Calculates the eigensystem of a real symmetric 2x2 matrix\n\t\t// [ A B ]\n\t\t// [ B C ]\n\t\t// in the form\n\t\t// [ A B ] = [ cs -sn ] [ rt1 0 ] [ cs sn ]\n\t\t// [ B C ] [ sn cs ] [ 0 rt2 ] [ -sn cs ]\n\t\t// where rt1 >= rt2.\n\t\t//\n\t\t// Adapted from: https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html\n\t\t// -> Algorithms for real symmetric matrices -> Analytical (2x2 symmetric)\n\t\tfunction eigenDecomposition( A, B, C ) {\n\n\t\t\tlet rt1, rt2, cs, sn, t;\n\t\t\tconst sm = A + C;\n\t\t\tconst df = A - C;\n\t\t\tconst rt = Math.sqrt( df * df + 4 * B * B );\n\n\t\t\tif ( sm > 0 ) {\n\n\t\t\t\trt1 = 0.5 * ( sm + rt );\n\t\t\t\tt = 1 / rt1;\n\t\t\t\trt2 = A * t * C - B * t * B;\n\n\t\t\t} else if ( sm < 0 ) {\n\n\t\t\t\trt2 = 0.5 * ( sm - rt );\n\n\t\t\t} else {\n\n\t\t\t\t// This case needs to be treated separately to avoid div by 0\n\n\t\t\t\trt1 = 0.5 * rt;\n\t\t\t\trt2 = - 0.5 * rt;\n\n\t\t\t}\n\n\t\t\t// Calculate eigenvectors\n\n\t\t\tif ( df > 0 ) {\n\n\t\t\t\tcs = df + rt;\n\n\t\t\t} else {\n\n\t\t\t\tcs = df - rt;\n\n\t\t\t}\n\n\t\t\tif ( Math.abs( cs ) > 2 * Math.abs( B ) ) {\n\n\t\t\t\tt = - 2 * B / cs;\n\t\t\t\tsn = 1 / Math.sqrt( 1 + t * t );\n\t\t\t\tcs = t * sn;\n\n\t\t\t} else if ( Math.abs( B ) === 0 ) {\n\n\t\t\t\tcs = 1;\n\t\t\t\tsn = 0;\n\n\t\t\t} else {\n\n\t\t\t\tt = - 0.5 * cs / B;\n\t\t\t\tcs = 1 / Math.sqrt( 1 + t * t );\n\t\t\t\tsn = t * cs;\n\n\t\t\t}\n\n\t\t\tif ( df > 0 ) {\n\n\t\t\t\tt = cs;\n\t\t\t\tcs = - sn;\n\t\t\t\tsn = t;\n\n\t\t\t}\n\n\t\t\treturn { rt1, rt2, cs, sn };\n\n\t\t}\n\n\t\t//\n\n\t\tconst paths = [];\n\t\tconst stylesheets = {};\n\n\t\tconst transformStack = [];\n\n\t\tconst tempTransform0 = new Matrix3();\n\t\tconst tempTransform1 = new Matrix3();\n\t\tconst tempTransform2 = new Matrix3();\n\t\tconst tempTransform3 = new Matrix3();\n\t\tconst tempV2 = new Vector2();\n\t\tconst tempV3 = new Vector3();\n\n\t\tconst currentTransform = new Matrix3();\n\n\t\tconst xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml\n\n\t\tparseNode( xml.documentElement, {\n\t\t\tfill: '#000',\n\t\t\tfillOpacity: 1,\n\t\t\tstrokeOpacity: 1,\n\t\t\tstrokeWidth: 1,\n\t\t\tstrokeLineJoin: 'miter',\n\t\t\tstrokeLineCap: 'butt',\n\t\t\tstrokeMiterLimit: 4\n\t\t} );\n\n\t\tconst data = { paths: paths, xml: xml.documentElement };\n\n\t\t// console.log( paths );\n\t\treturn data;\n\n\t}\n\n\t/**\n\t * Creates from the given shape path and array of shapes.\n\t *\n\t * @param {ShapePath} shapePath - The shape path.\n\t * @return {Array<Shape>} An array of shapes.\n\t */\n\tstatic createShapes( shapePath ) {\n\n\t\tconst BIGNUMBER = 999999999;\n\n\t\tconst IntersectionLocationType = {\n\t\t\tORIGIN: 0,\n\t\t\tDESTINATION: 1,\n\t\t\tBETWEEN: 2,\n\t\t\tLEFT: 3,\n\t\t\tRIGHT: 4,\n\t\t\tBEHIND: 5,\n\t\t\tBEYOND: 6\n\t\t};\n\n\t\tconst classifyResult = {\n\t\t\tloc: IntersectionLocationType.ORIGIN,\n\t\t\tt: 0\n\t\t};\n\n\t\tfunction findEdgeIntersection( a0, a1, b0, b1 ) {\n\n\t\t\tconst x1 = a0.x;\n\t\t\tconst x2 = a1.x;\n\t\t\tconst x3 = b0.x;\n\t\t\tconst x4 = b1.x;\n\t\t\tconst y1 = a0.y;\n\t\t\tconst y2 = a1.y;\n\t\t\tconst y3 = b0.y;\n\t\t\tconst y4 = b1.y;\n\t\t\tconst nom1 = ( x4 - x3 ) * ( y1 - y3 ) - ( y4 - y3 ) * ( x1 - x3 );\n\t\t\tconst nom2 = ( x2 - x1 ) * ( y1 - y3 ) - ( y2 - y1 ) * ( x1 - x3 );\n\t\t\tconst denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );\n\t\t\tconst t1 = nom1 / denom;\n\t\t\tconst t2 = nom2 / denom;\n\n\t\t\tif ( ( ( denom === 0 ) && ( nom1 !== 0 ) ) || ( t1 <= 0 ) || ( t1 >= 1 ) || ( t2 < 0 ) || ( t2 > 1 ) ) {\n\n\t\t\t\t//1. lines are parallel or edges don't intersect\n\n\t\t\t\treturn null;\n\n\t\t\t} else if ( ( nom1 === 0 ) && ( denom === 0 ) ) {\n\n\t\t\t\t//2. lines are colinear\n\n\t\t\t\t//check if endpoints of edge2 (b0-b1) lies on edge1 (a0-a1)\n\t\t\t\tfor ( let i = 0; i < 2; i ++ ) {\n\n\t\t\t\t\tclassifyPoint( i === 0 ? b0 : b1, a0, a1 );\n\t\t\t\t\t//find position of this endpoints relatively to edge1\n\t\t\t\t\tif ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {\n\n\t\t\t\t\t\tconst point = ( i === 0 ? b0 : b1 );\n\t\t\t\t\t\treturn { x: point.x, y: point.y, t: classifyResult.t };\n\n\t\t\t\t\t} else if ( classifyResult.loc == IntersectionLocationType.BETWEEN ) {\n\n\t\t\t\t\t\tconst x = + ( ( x1 + classifyResult.t * ( x2 - x1 ) ).toPrecision( 10 ) );\n\t\t\t\t\t\tconst y = + ( ( y1 + classifyResult.t * ( y2 - y1 ) ).toPrecision( 10 ) );\n\t\t\t\t\t\treturn { x: x, y: y, t: classifyResult.t, };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t} else {\n\n\t\t\t\t//3. edges intersect\n\n\t\t\t\tfor ( let i = 0; i < 2; i ++ ) {\n\n\t\t\t\t\tclassifyPoint( i === 0 ? b0 : b1, a0, a1 );\n\n\t\t\t\t\tif ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {\n\n\t\t\t\t\t\tconst point = ( i === 0 ? b0 : b1 );\n\t\t\t\t\t\treturn { x: point.x, y: point.y, t: classifyResult.t };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconst x = + ( ( x1 + t1 * ( x2 - x1 ) ).toPrecision( 10 ) );\n\t\t\t\tconst y = + ( ( y1 + t1 * ( y2 - y1 ) ).toPrecision( 10 ) );\n\t\t\t\treturn { x: x, y: y, t: t1 };\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction classifyPoint( p, edgeStart, edgeEnd ) {\n\n\t\t\tconst ax = edgeEnd.x - edgeStart.x;\n\t\t\tconst ay = edgeEnd.y - edgeStart.y;\n\t\t\tconst bx = p.x - edgeStart.x;\n\t\t\tconst by = p.y - edgeStart.y;\n\t\t\tconst sa = ax * by - bx * ay;\n\n\t\t\tif ( ( p.x === edgeStart.x ) && ( p.y === edgeStart.y ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.ORIGIN;\n\t\t\t\tclassifyResult.t = 0;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( ( p.x === edgeEnd.x ) && ( p.y === edgeEnd.y ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.DESTINATION;\n\t\t\t\tclassifyResult.t = 1;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( sa < - Number.EPSILON ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.LEFT;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( sa > Number.EPSILON ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.RIGHT;\n\t\t\t\treturn;\n\n\n\t\t\t}\n\n\t\t\tif ( ( ( ax * bx ) < 0 ) || ( ( ay * by ) < 0 ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.BEHIND;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( ( Math.sqrt( ax * ax + ay * ay ) ) < ( Math.sqrt( bx * bx + by * by ) ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.BEYOND;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tlet t;\n\n\t\t\tif ( ax !== 0 ) {\n\n\t\t\t\tt = bx / ax;\n\n\t\t\t} else {\n\n\t\t\t\tt = by / ay;\n\n\t\t\t}\n\n\t\t\tclassifyResult.loc = IntersectionLocationType.BETWEEN;\n\t\t\tclassifyResult.t = t;\n\n\t\t}\n\n\t\tfunction getIntersections( path1, path2 ) {\n\n\t\t\tconst intersectionsRaw = [];\n\t\t\tconst intersections = [];\n\n\t\t\tfor ( let index = 1; index < path1.length; index ++ ) {\n\n\t\t\t\tconst path1EdgeStart = path1[ index - 1 ];\n\t\t\t\tconst path1EdgeEnd = path1[ index ];\n\n\t\t\t\tfor ( let index2 = 1; index2 < path2.length; index2 ++ ) {\n\n\t\t\t\t\tconst path2EdgeStart = path2[ index2 - 1 ];\n\t\t\t\t\tconst path2EdgeEnd = path2[ index2 ];\n\n\t\t\t\t\tconst intersection = findEdgeIntersection( path1EdgeStart, path1EdgeEnd, path2EdgeStart, path2EdgeEnd );\n\n\t\t\t\t\tif ( intersection !== null && intersectionsRaw.find( i => i.t <= intersection.t + Number.EPSILON && i.t >= intersection.t - Number.EPSILON ) === undefined ) {\n\n\t\t\t\t\t\tintersectionsRaw.push( intersection );\n\t\t\t\t\t\tintersections.push( new Vector2( intersection.x, intersection.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn intersections;\n\n\t\t}\n\n\t\tfunction getScanlineIntersections( scanline, boundingBox, paths ) {\n\n\t\t\tconst center = new Vector2();\n\t\t\tboundingBox.getCenter( center );\n\n\t\t\tconst allIntersections = [];\n\n\t\t\tpaths.forEach( path => {\n\n\t\t\t\t// check if the center of the bounding box is in the bounding box of the paths.\n\t\t\t\t// this is a pruning method to limit the search of intersections in paths that can't envelop of the current path.\n\t\t\t\t// if a path envelops another path. The center of that other path, has to be inside the bounding box of the enveloping path.\n\t\t\t\tif ( path.boundingBox.containsPoint( center ) ) {\n\n\t\t\t\t\tconst intersections = getIntersections( scanline, path.points );\n\n\t\t\t\t\tintersections.forEach( p => {\n\n\t\t\t\t\t\tallIntersections.push( { identifier: path.identifier, isCW: path.isCW, point: p } );\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tallIntersections.sort( ( i1, i2 ) => {\n\n\t\t\t\treturn i1.point.x - i2.point.x;\n\n\t\t\t} );\n\n\t\t\treturn allIntersections;\n\n\t\t}\n\n\t\tfunction isHoleTo( simplePath, allPaths, scanlineMinX, scanlineMaxX, _fillRule ) {\n\n\t\t\tif ( _fillRule === null || _fillRule === undefined || _fillRule === '' ) {\n\n\t\t\t\t_fillRule = 'nonzero';\n\n\t\t\t}\n\n\t\t\tconst centerBoundingBox = new Vector2();\n\t\t\tsimplePath.boundingBox.getCenter( centerBoundingBox );\n\n\t\t\tconst scanline = [ new Vector2( scanlineMinX, centerBoundingBox.y ), new Vector2( scanlineMaxX, centerBoundingBox.y ) ];\n\n\t\t\tconst scanlineIntersections = getScanlineIntersections( scanline, simplePath.boundingBox, allPaths );\n\n\t\t\tscanlineIntersections.sort( ( i1, i2 ) => {\n\n\t\t\t\treturn i1.point.x - i2.point.x;\n\n\t\t\t} );\n\n\t\t\tconst baseIntersections = [];\n\t\t\tconst otherIntersections = [];\n\n\t\t\tscanlineIntersections.forEach( i => {\n\n\t\t\t\tif ( i.identifier === simplePath.identifier ) {\n\n\t\t\t\t\tbaseIntersections.push( i );\n\n\t\t\t\t} else {\n\n\t\t\t\t\totherIntersections.push( i );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tconst firstXOfPath = baseIntersections[ 0 ].point.x;\n\n\t\t\t// build up the path hierarchy\n\t\t\tconst stack = [];\n\t\t\tlet i = 0;\n\n\t\t\twhile ( i < otherIntersections.length && otherIntersections[ i ].point.x < firstXOfPath ) {\n\n\t\t\t\tif ( stack.length > 0 && stack[ stack.length - 1 ] === otherIntersections[ i ].identifier ) {\n\n\t\t\t\t\tstack.pop();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstack.push( otherIntersections[ i ].identifier );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\tstack.push( simplePath.identifier );\n\n\t\t\tif ( _fillRule === 'evenodd' ) {\n\n\t\t\t\tconst isHole = stack.length % 2 === 0 ? true : false;\n\t\t\t\tconst isHoleFor = stack[ stack.length - 2 ];\n\n\t\t\t\treturn { identifier: simplePath.identifier, isHole: isHole, for: isHoleFor };\n\n\t\t\t} else if ( _fillRule === 'nonzero' ) {\n\n\t\t\t\t// check if path is a hole by counting the amount of paths with alternating rotations it has to cross.\n\t\t\t\tlet isHole = true;\n\t\t\t\tlet isHoleFor = null;\n\t\t\t\tlet lastCWValue = null;\n\n\t\t\t\tfor ( let i = 0; i < stack.length; i ++ ) {\n\n\t\t\t\t\tconst identifier = stack[ i ];\n\t\t\t\t\tif ( isHole ) {\n\n\t\t\t\t\t\tlastCWValue = allPaths[ identifier ].isCW;\n\t\t\t\t\t\tisHole = false;\n\t\t\t\t\t\tisHoleFor = identifier;\n\n\t\t\t\t\t} else if ( lastCWValue !== allPaths[ identifier ].isCW ) {\n\n\t\t\t\t\t\tlastCWValue = allPaths[ identifier ].isCW;\n\t\t\t\t\t\tisHole = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { identifier: simplePath.identifier, isHole: isHole, for: isHoleFor };\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'fill-rule: \"' + _fillRule + '\" is currently not implemented.' );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check for self intersecting paths\n\t\t// TODO\n\n\t\t// check intersecting paths\n\t\t// TODO\n\n\t\t// prepare paths for hole detection\n\t\tlet scanlineMinX = BIGNUMBER;\n\t\tlet scanlineMaxX = - BIGNUMBER;\n\n\t\tlet simplePaths = shapePath.subPaths.map( p => {\n\n\t\t\tconst points = p.getPoints();\n\t\t\tlet maxY = - BIGNUMBER;\n\t\t\tlet minY = BIGNUMBER;\n\t\t\tlet maxX = - BIGNUMBER;\n\t\t\tlet minX = BIGNUMBER;\n\n\t \t//points.forEach(p => p.y *= -1);\n\n\t\t\tfor ( let i = 0; i < points.length; i ++ ) {\n\n\t\t\t\tconst p = points[ i ];\n\n\t\t\t\tif ( p.y > maxY ) {\n\n\t\t\t\t\tmaxY = p.y;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.y < minY ) {\n\n\t\t\t\t\tminY = p.y;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.x > maxX ) {\n\n\t\t\t\t\tmaxX = p.x;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.x < minX ) {\n\n\t\t\t\t\tminX = p.x;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\t\t\tif ( scanlineMaxX <= maxX ) {\n\n\t\t\t\tscanlineMaxX = maxX + 1;\n\n\t\t\t}\n\n\t\t\tif ( scanlineMinX >= minX ) {\n\n\t\t\t\tscanlineMinX = minX - 1;\n\n\t\t\t}\n\n\t\t\treturn { curves: p.curves, points: points, isCW: ShapeUtils.isClockWise( points ), identifier: - 1, boundingBox: new Box2( new Vector2( minX, minY ), new Vector2( maxX, maxY ) ) };\n\n\t\t} );\n\n\t\tsimplePaths = simplePaths.filter( sp => sp.points.length > 1 );\n\n\t\tfor ( let identifier = 0; identifier < simplePaths.length; identifier ++ ) {\n\n\t\t\tsimplePaths[ identifier ].identifier = identifier;\n\n\t\t}\n\n\t\t// check if path is solid or a hole\n\t\tconst isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, ( shapePath.userData ? shapePath.userData.style.fillRule : undefined ) ) );\n\n\n\t\tconst shapesToReturn = [];\n\t\tsimplePaths.forEach( p => {\n\n\t\t\tconst amIAHole = isAHole[ p.identifier ];\n\n\t\t\tif ( ! amIAHole.isHole ) {\n\n\t\t\t\tconst shape = new Shape();\n\t\t\t\tshape.curves = p.curves;\n\t\t\t\tconst holes = isAHole.filter( h => h.isHole && h.for === p.identifier );\n\t\t\t\tholes.forEach( h => {\n\n\t\t\t\t\tconst hole = simplePaths[ h.identifier ];\n\t\t\t\t\tconst path = new Path();\n\t\t\t\t\tpath.curves = hole.curves;\n\t\t\t\t\tshape.holes.push( path );\n\n\t\t\t\t} );\n\t\t\t\tshapesToReturn.push( shape );\n\n\t\t\t}\n\n\t\t} );\n\n\t\treturn shapesToReturn;\n\n\t}\n\n\t/**\n\t * Returns a stroke style object from the given parameters.\n\t *\n\t * @param {number} [width=1] - The stroke width.\n\t * @param {string} [color='#000'] - The stroke color, as returned by {@link Color#getStyle}.\n\t * @param {'round'|'bevel'|'miter'|'miter-limit'} [lineJoin='miter'] - The line join style.\n\t * @param {'round'|'square'|'butt'} [lineCap='butt'] - The line cap style.\n\t * @param {number} [miterLimit=4] - Maximum join length, in multiples of the `width` parameter (join is truncated if it exceeds that distance).\n\t * @return {Object} The style object.\n\t */\n\tstatic getStrokeStyle( width, color, lineJoin, lineCap, miterLimit ) {\n\n\t\twidth = width !== undefined ? width : 1;\n\t\tcolor = color !== undefined ? color : '#000';\n\t\tlineJoin = lineJoin !== undefined ? lineJoin : 'miter';\n\t\tlineCap = lineCap !== undefined ? lineCap : 'butt';\n\t\tmiterLimit = miterLimit !== undefined ? miterLimit : 4;\n\n\t\treturn {\n\t\t\tstrokeColor: color,\n\t\t\tstrokeWidth: width,\n\t\t\tstrokeLineJoin: lineJoin,\n\t\t\tstrokeLineCap: lineCap,\n\t\t\tstrokeMiterLimit: miterLimit\n\t\t};\n\n\t}\n\n\t/**\n\t * Creates a stroke from an array of points.\n\t *\n\t * @param {Array<Vector2>} points - The points in 2D space. Minimum 2 points. The path can be open or closed (last point equals to first point).\n\t * @param {Object} style - Object with SVG properties as returned by `SVGLoader.getStrokeStyle()`, or `SVGLoader.parse()` in the `path.userData.style` object.\n\t * @param {number} [arcDivisions=12] - Arc divisions for round joins and endcaps.\n\t * @param {number} [minDistance=0.001] - Points closer to this distance will be merged.\n\t * @return {?BufferGeometry} The stroke geometry. UV coordinates are generated ('u' along path. 'v' across it, from left to right).\n\t * Returns `null` if not geometry was generated.\n\t */\n\tstatic pointsToStroke( points, style, arcDivisions, minDistance ) {\n\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tif ( SVGLoader.pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs ) === 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tgeometry.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\treturn geometry;\n\n\t}\n\n\t/**\n\t * Creates a stroke from an array of points.\n\t *\n\t * @param {Array<Vector2>} points - The points in 2D space. Minimum 2 points.\n\t * @param {Object} style - Object with SVG properties as returned by `SVGLoader.getStrokeStyle()`, or `SVGLoader.parse()` in the `path.userData.style` object.\n\t * @param {number} [arcDivisions=12] - Arc divisions for round joins and endcaps.\n\t * @param {number} [minDistance=0.001] - Points closer to this distance will be merged.\n\t * @param {Array<number>} vertices - An array holding vertices.\n\t * @param {Array<number>} normals - An array holding normals.\n\t * @param {Array<number>} uvs - An array holding uvs.\n\t * @param {number} [vertexOffset=0] - The vertex offset.\n\t * @return {number} The number of vertices.\n\t */\n\tstatic pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs, vertexOffset ) {\n\n\t\t// This function can be called to update existing arrays or buffers.\n\t\t// Accepts same parameters as pointsToStroke, plus the buffers and optional offset.\n\t\t// Param vertexOffset: Offset vertices to start writing in the buffers (3 elements/vertex for vertices and normals, and 2 elements/vertex for uvs)\n\t\t// Returns number of written vertices / normals / uvs pairs\n\t\t// if 'vertices' parameter is undefined no triangles will be generated, but the returned vertices count will still be valid (useful to preallocate the buffers)\n\t\t// 'normals' and 'uvs' buffers are optional\n\n\t\tconst tempV2_1 = new Vector2();\n\t\tconst tempV2_2 = new Vector2();\n\t\tconst tempV2_3 = new Vector2();\n\t\tconst tempV2_4 = new Vector2();\n\t\tconst tempV2_5 = new Vector2();\n\t\tconst tempV2_6 = new Vector2();\n\t\tconst tempV2_7 = new Vector2();\n\t\tconst lastPointL = new Vector2();\n\t\tconst lastPointR = new Vector2();\n\t\tconst point0L = new Vector2();\n\t\tconst point0R = new Vector2();\n\t\tconst currentPointL = new Vector2();\n\t\tconst currentPointR = new Vector2();\n\t\tconst nextPointL = new Vector2();\n\t\tconst nextPointR = new Vector2();\n\t\tconst innerPoint = new Vector2();\n\t\tconst outerPoint = new Vector2();\n\n\t\tarcDivisions = arcDivisions !== undefined ? arcDivisions : 12;\n\t\tminDistance = minDistance !== undefined ? minDistance : 0.001;\n\t\tvertexOffset = vertexOffset !== undefined ? vertexOffset : 0;\n\n\t\t// First ensure there are no duplicated points\n\t\tpoints = removeDuplicatedPoints( points );\n\n\t\tconst numPoints = points.length;\n\n\t\tif ( numPoints < 2 ) return 0;\n\n\t\tconst isClosed = points[ 0 ].equals( points[ numPoints - 1 ] );\n\n\t\tlet currentPoint;\n\t\tlet previousPoint = points[ 0 ];\n\t\tlet nextPoint;\n\n\t\tconst strokeWidth2 = style.strokeWidth / 2;\n\n\t\tconst deltaU = 1 / ( numPoints - 1 );\n\t\tlet u0 = 0, u1;\n\n\t\tlet innerSideModified;\n\t\tlet joinIsOnLeftSide;\n\t\tlet isMiter;\n\t\tlet initialJoinIsOnLeftSide = false;\n\n\t\tlet numVertices = 0;\n\t\tlet currentCoordinate = vertexOffset * 3;\n\t\tlet currentCoordinateUV = vertexOffset * 2;\n\n\t\t// Get initial left and right stroke points\n\t\tgetNormal( points[ 0 ], points[ 1 ], tempV2_1 ).multiplyScalar( strokeWidth2 );\n\t\tlastPointL.copy( points[ 0 ] ).sub( tempV2_1 );\n\t\tlastPointR.copy( points[ 0 ] ).add( tempV2_1 );\n\t\tpoint0L.copy( lastPointL );\n\t\tpoint0R.copy( lastPointR );\n\n\t\tfor ( let iPoint = 1; iPoint < numPoints; iPoint ++ ) {\n\n\t\t\tcurrentPoint = points[ iPoint ];\n\n\t\t\t// Get next point\n\t\t\tif ( iPoint === numPoints - 1 ) {\n\n\t\t\t\tif ( isClosed ) {\n\n\t\t\t\t\t// Skip duplicated initial point\n\t\t\t\t\tnextPoint = points[ 1 ];\n\n\t\t\t\t} else nextPoint = undefined;\n\n\t\t\t} else {\n\n\t\t\t\tnextPoint = points[ iPoint + 1 ];\n\n\t\t\t}\n\n\t\t\t// Normal of previous segment in tempV2_1\n\t\t\tconst normal1 = tempV2_1;\n\t\t\tgetNormal( previousPoint, currentPoint, normal1 );\n\n\t\t\ttempV2_3.copy( normal1 ).multiplyScalar( strokeWidth2 );\n\t\t\tcurrentPointL.copy( currentPoint ).sub( tempV2_3 );\n\t\t\tcurrentPointR.copy( currentPoint ).add( tempV2_3 );\n\n\t\t\tu1 = u0 + deltaU;\n\n\t\t\tinnerSideModified = false;\n\n\t\t\tif ( nextPoint !== undefined ) {\n\n\t\t\t\t// Normal of next segment in tempV2_2\n\t\t\t\tgetNormal( currentPoint, nextPoint, tempV2_2 );\n\n\t\t\t\ttempV2_3.copy( tempV2_2 ).multiplyScalar( strokeWidth2 );\n\t\t\t\tnextPointL.copy( currentPoint ).sub( tempV2_3 );\n\t\t\t\tnextPointR.copy( currentPoint ).add( tempV2_3 );\n\n\t\t\t\tjoinIsOnLeftSide = true;\n\t\t\t\ttempV2_3.subVectors( nextPoint, previousPoint );\n\t\t\t\tif ( normal1.dot( tempV2_3 ) < 0 ) {\n\n\t\t\t\t\tjoinIsOnLeftSide = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( iPoint === 1 ) initialJoinIsOnLeftSide = joinIsOnLeftSide;\n\n\t\t\t\ttempV2_3.subVectors( nextPoint, currentPoint );\n\t\t\t\ttempV2_3.normalize();\n\t\t\t\tconst dot = Math.abs( normal1.dot( tempV2_3 ) );\n\n\t\t\t\t// If path is straight, don't create join\n\t\t\t\tif ( dot > Number.EPSILON ) {\n\n\t\t\t\t\t// Compute inner and outer segment intersections\n\t\t\t\t\tconst miterSide = strokeWidth2 / dot;\n\t\t\t\t\ttempV2_3.multiplyScalar( - miterSide );\n\t\t\t\t\ttempV2_4.subVectors( currentPoint, previousPoint );\n\t\t\t\t\ttempV2_5.copy( tempV2_4 ).setLength( miterSide ).add( tempV2_3 );\n\t\t\t\t\tinnerPoint.copy( tempV2_5 ).negate();\n\t\t\t\t\tconst miterLength2 = tempV2_5.length();\n\t\t\t\t\tconst segmentLengthPrev = tempV2_4.length();\n\t\t\t\t\ttempV2_4.divideScalar( segmentLengthPrev );\n\t\t\t\t\ttempV2_6.subVectors( nextPoint, currentPoint );\n\t\t\t\t\tconst segmentLengthNext = tempV2_6.length();\n\t\t\t\t\ttempV2_6.divideScalar( segmentLengthNext );\n\t\t\t\t\t// Check that previous and next segments doesn't overlap with the innerPoint of intersection\n\t\t\t\t\tif ( tempV2_4.dot( innerPoint ) < segmentLengthPrev && tempV2_6.dot( innerPoint ) < segmentLengthNext ) {\n\n\t\t\t\t\t\tinnerSideModified = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\touterPoint.copy( tempV2_5 ).add( currentPoint );\n\t\t\t\t\tinnerPoint.add( currentPoint );\n\n\t\t\t\t\tisMiter = false;\n\n\t\t\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\tnextPointR.copy( innerPoint );\n\t\t\t\t\t\t\tcurrentPointR.copy( innerPoint );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tnextPointL.copy( innerPoint );\n\t\t\t\t\t\t\tcurrentPointL.copy( innerPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// The segment triangles are generated here if there was overlapping\n\n\t\t\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch ( style.strokeLineJoin ) {\n\n\t\t\t\t\t\tcase 'bevel':\n\n\t\t\t\t\t\t\tmakeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'round':\n\n\t\t\t\t\t\t\t// Segment triangles\n\n\t\t\t\t\t\t\tcreateSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );\n\n\t\t\t\t\t\t\t// Join triangles\n\n\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\tmakeCircularSector( currentPoint, currentPointL, nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tmakeCircularSector( currentPoint, nextPointR, currentPointR, u1, 1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'miter':\n\t\t\t\t\t\tcase 'miter-clip':\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconst miterFraction = ( strokeWidth2 * style.strokeMiterLimit ) / miterLength2;\n\n\t\t\t\t\t\t\tif ( miterFraction < 1 ) {\n\n\t\t\t\t\t\t\t\t// The join miter length exceeds the miter limit\n\n\t\t\t\t\t\t\t\tif ( style.strokeLineJoin !== 'miter-clip' ) {\n\n\t\t\t\t\t\t\t\t\tmakeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t// Segment triangles\n\n\t\t\t\t\t\t\t\t\tcreateSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );\n\n\t\t\t\t\t\t\t\t\t// Miter-clip join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\ttempV2_6.subVectors( outerPoint, currentPointL ).multiplyScalar( miterFraction ).add( currentPointL );\n\t\t\t\t\t\t\t\t\t\ttempV2_7.subVectors( outerPoint, nextPointL ).multiplyScalar( miterFraction ).add( nextPointL );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\ttempV2_6.subVectors( outerPoint, currentPointR ).multiplyScalar( miterFraction ).add( currentPointR );\n\t\t\t\t\t\t\t\t\t\ttempV2_7.subVectors( outerPoint, nextPointR ).multiplyScalar( miterFraction ).add( nextPointR );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointR, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Miter join segment triangles\n\n\t\t\t\t\t\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t\t\t\t\t\t// Optimized segment + join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\tnextPointL.copy( outerPoint );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tnextPointR.copy( outerPoint );\n\n\t\t\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t// Add extra miter join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointR, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tisMiter = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// The segment triangles are generated here when two consecutive points are collinear\n\n\t\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// The segment triangles are generated here if it is the ending segment\n\n\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t}\n\n\t\t\tif ( ! isClosed && iPoint === numPoints - 1 ) {\n\n\t\t\t\t// Start line endcap\n\t\t\t\taddCapGeometry( points[ 0 ], point0L, point0R, joinIsOnLeftSide, true, u0 );\n\n\t\t\t}\n\n\t\t\t// Increment loop variables\n\n\t\t\tu0 = u1;\n\n\t\t\tpreviousPoint = currentPoint;\n\n\t\t\tlastPointL.copy( nextPointL );\n\t\t\tlastPointR.copy( nextPointR );\n\n\t\t}\n\n\t\tif ( ! isClosed ) {\n\n\t\t\t// Ending line endcap\n\t\t\taddCapGeometry( currentPoint, currentPointL, currentPointR, joinIsOnLeftSide, false, u1 );\n\n\t\t} else if ( innerSideModified && vertices ) {\n\n\t\t\t// Modify path first segment vertices to adjust to the segments inner and outer intersections\n\n\t\t\tlet lastOuter = outerPoint;\n\t\t\tlet lastInner = innerPoint;\n\n\t\t\tif ( initialJoinIsOnLeftSide !== joinIsOnLeftSide ) {\n\n\t\t\t\tlastOuter = innerPoint;\n\t\t\t\tlastInner = outerPoint;\n\n\t\t\t}\n\n\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\tif ( isMiter || initialJoinIsOnLeftSide ) {\n\n\t\t\t\t\tlastInner.toArray( vertices, 0 * 3 );\n\t\t\t\t\tlastInner.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\tif ( isMiter ) {\n\n\t\t\t\t\t\tlastOuter.toArray( vertices, 1 * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( isMiter || ! initialJoinIsOnLeftSide ) {\n\n\t\t\t\t\tlastInner.toArray( vertices, 1 * 3 );\n\t\t\t\t\tlastInner.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\tif ( isMiter ) {\n\n\t\t\t\t\t\tlastOuter.toArray( vertices, 0 * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn numVertices;\n\n\t\t// -- End of algorithm\n\n\t\t// -- Functions\n\n\t\tfunction getNormal( p1, p2, result ) {\n\n\t\t\tresult.subVectors( p2, p1 );\n\t\t\treturn result.set( - result.y, result.x ).normalize();\n\n\t\t}\n\n\t\tfunction addVertex( position, u, v ) {\n\n\t\t\tif ( vertices ) {\n\n\t\t\t\tvertices[ currentCoordinate ] = position.x;\n\t\t\t\tvertices[ currentCoordinate + 1 ] = position.y;\n\t\t\t\tvertices[ currentCoordinate + 2 ] = 0;\n\n\t\t\t\tif ( normals ) {\n\n\t\t\t\t\tnormals[ currentCoordinate ] = 0;\n\t\t\t\t\tnormals[ currentCoordinate + 1 ] = 0;\n\t\t\t\t\tnormals[ currentCoordinate + 2 ] = 1;\n\n\t\t\t\t}\n\n\t\t\t\tcurrentCoordinate += 3;\n\n\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\tuvs[ currentCoordinateUV ] = u;\n\t\t\t\t\tuvs[ currentCoordinateUV + 1 ] = v;\n\n\t\t\t\t\tcurrentCoordinateUV += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tnumVertices += 3;\n\n\t\t}\n\n\t\tfunction makeCircularSector( center, p1, p2, u, v ) {\n\n\t\t\t// param p1, p2: Points in the circle arc.\n\t\t\t// p1 and p2 are in clockwise direction.\n\n\t\t\ttempV2_1.copy( p1 ).sub( center ).normalize();\n\t\t\ttempV2_2.copy( p2 ).sub( center ).normalize();\n\n\t\t\tlet angle = Math.PI;\n\t\t\tconst dot = tempV2_1.dot( tempV2_2 );\n\t\t\tif ( Math.abs( dot ) < 1 ) angle = Math.abs( Math.acos( dot ) );\n\n\t\t\tangle /= arcDivisions;\n\n\t\t\ttempV2_3.copy( p1 );\n\n\t\t\tfor ( let i = 0, il = arcDivisions - 1; i < il; i ++ ) {\n\n\t\t\t\ttempV2_4.copy( tempV2_3 ).rotateAround( center, angle );\n\n\t\t\t\taddVertex( tempV2_3, u, v );\n\t\t\t\taddVertex( tempV2_4, u, v );\n\t\t\t\taddVertex( center, u, 0.5 );\n\n\t\t\t\ttempV2_3.copy( tempV2_4 );\n\n\t\t\t}\n\n\t\t\taddVertex( tempV2_4, u, v );\n\t\t\taddVertex( p2, u, v );\n\t\t\taddVertex( center, u, 0.5 );\n\n\t\t}\n\n\t\tfunction makeSegmentTriangles() {\n\n\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t}\n\n\t\tfunction makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u ) {\n\n\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t// Optimized segment + bevel triangles\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t// Path segments triangles\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\t// Bevel join triangle\n\n\t\t\t\t\taddVertex( currentPointL, u, 0 );\n\t\t\t\t\taddVertex( nextPointL, u, 0 );\n\t\t\t\t\taddVertex( innerPoint, u, 0.5 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Path segments triangles\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\t// Bevel join triangle\n\n\t\t\t\t\taddVertex( currentPointR, u, 1 );\n\t\t\t\t\taddVertex( innerPoint, u, 0 );\n\t\t\t\t\taddVertex( nextPointR, u, 1 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bevel join triangle. The segment triangles are done in the main loop\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\taddVertex( currentPointL, u, 0 );\n\t\t\t\t\taddVertex( nextPointL, u, 0 );\n\t\t\t\t\taddVertex( currentPoint, u, 0.5 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\taddVertex( currentPointR, u, 1 );\n\t\t\t\t\taddVertex( nextPointR, u, 0 );\n\t\t\t\t\taddVertex( currentPoint, u, 0.5 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ) {\n\n\t\t\tif ( innerSideModified ) {\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( nextPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPointR, u0, 1 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( nextPointR, u0, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction addCapGeometry( center, p1, p2, joinIsOnLeftSide, start, u ) {\n\n\t\t\t// param center: End point of the path\n\t\t\t// param p1, p2: Left and right cap points\n\n\t\t\tswitch ( style.strokeLineCap ) {\n\n\t\t\t\tcase 'round':\n\n\t\t\t\t\tif ( start ) {\n\n\t\t\t\t\t\tmakeCircularSector( center, p2, p1, u, 0.5 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmakeCircularSector( center, p1, p2, u, 0.5 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'square':\n\n\t\t\t\t\tif ( start ) {\n\n\t\t\t\t\t\ttempV2_1.subVectors( p1, center );\n\t\t\t\t\t\ttempV2_2.set( tempV2_1.y, - tempV2_1.x );\n\n\t\t\t\t\t\ttempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );\n\t\t\t\t\t\ttempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );\n\n\t\t\t\t\t\t// Modify already existing vertices\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 0 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, 1 * 3 );\n\t\t\t\t\t\t\t// using tempV2_4 to update 3rd vertex if the uv.y of 3rd vertex is 1\n\t\t\t\t\t\t\tuvs[ 3 * 2 + 1 ] === 1 ? tempV2_4.toArray( vertices, 3 * 3 ) : tempV2_3.toArray( vertices, 3 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 0 * 3 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttempV2_1.subVectors( p2, center );\n\t\t\t\t\t\ttempV2_2.set( tempV2_1.y, - tempV2_1.x );\n\n\t\t\t\t\t\ttempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );\n\t\t\t\t\t\ttempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );\n\n\t\t\t\t\t\tconst vl = vertices.length;\n\n\t\t\t\t\t\t// Modify already existing vertices\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, vl - 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 2 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 4 * 3 );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 2 * 3 );\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, vl - 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 4 * 3 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'butt':\n\t\t\t\tdefault:\n\n\t\t\t\t\t// Nothing to do here\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeDuplicatedPoints( points ) {\n\n\t\t\t// Creates a new array if necessary with duplicated points removed.\n\t\t\t// This does not remove duplicated initial and ending points of a closed path.\n\n\t\t\tlet dupPoints = false;\n\t\t\tfor ( let i = 1, n = points.length - 1; i < n; i ++ ) {\n\n\t\t\t\tif ( points[ i ].distanceTo( points[ i + 1 ] ) < minDistance ) {\n\n\t\t\t\t\tdupPoints = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! dupPoints ) return points;\n\n\t\t\tconst newPoints = [];\n\t\t\tnewPoints.push( points[ 0 ] );\n\n\t\t\tfor ( let i = 1, n = points.length - 1; i < n; i ++ ) {\n\n\t\t\t\tif ( points[ i ].distanceTo( points[ i + 1 ] ) >= minDistance ) {\n\n\t\t\t\t\tnewPoints.push( points[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tnewPoints.push( points[ points.length - 1 ] );\n\n\t\t\treturn newPoints;\n\n\t\t}\n\n\t}\n\n\n}\n\nexport { SVGLoader };\n","import React, { useEffect, useMemo, useState } from 'react';\nimport * as THREE from 'three';\nimport { SVGLoader, type SVGResult } from 'three/examples/jsm/loaders/SVGLoader.js';\nimport {\n inlineSvgStyles,\n isInteractiveGroupLabel,\n isRouteFolderLabel,\n isRoutePathLabel,\n isStoreFolderLabel,\n isTransparentColor,\n resolveFetchUrl,\n resolveLayerStyle,\n} from '../../core';\n\nexport { resolveFetchUrl };\n\nconst BASE_Z = -2;\n\nfunction getLayerNameFromNode(node: Element | undefined): string | undefined {\n if (!node || node.nodeType !== 1) return undefined;\n let current: Element | null = node;\n while (current) {\n const id = current.getAttribute('id');\n if (id) return id;\n current = current.parentElement;\n }\n return undefined;\n}\n\nfunction isInteractiveAncestor(node: Element | undefined): boolean {\n if (!node) return false;\n let current: Element | null = node;\n while (current) {\n const id = current.getAttribute('id') ?? '';\n const dataName = current.getAttribute('data-name') ?? '';\n if (isInteractiveGroupLabel(id) || isInteractiveGroupLabel(dataName)) return true;\n if (isStoreFolderLabel(id) || isStoreFolderLabel(dataName)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\nexport interface SvgVectorLayerProps {\n url: string;\n /** sourceSvgId values held in cm_shapes — skip drawing these (DB owns them). */\n suppressIds?: ReadonlySet<string>;\n imageProxyUrl?: string | null;\n is3d?: boolean;\n /** Settings overrides for house outdoor colors. */\n theme?: Partial<Record<string, string>> | null;\n}\n\ninterface PreparedMesh {\n key: string;\n shapes: THREE.Shape[];\n color: THREE.Color;\n opacity: number;\n extrude: number;\n renderOrder: number;\n}\n\n/**\n * Live outdoor SVG as real vector geometry (not a raster texture).\n * Applies house-style colors for reserved layer names; otherwise keeps\n * Illustrator fills. Skips route-path* and interactive ids owned by the DB.\n * Coordinates stay in SVG user space — `MapScene` flips the whole scene.\n */\nexport function SvgVectorLayer({\n url,\n suppressIds,\n imageProxyUrl,\n is3d = false,\n theme,\n}: SvgVectorLayerProps) {\n const [result, setResult] = useState<SVGResult | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n const controller = new AbortController();\n const fetchUrl = resolveFetchUrl(url, imageProxyUrl);\n fetch(fetchUrl, { signal: controller.signal })\n .then((res) => {\n if (!res.ok) throw new Error(`SVG fetch ${res.status}`);\n return res.text();\n })\n .then((text) => {\n if (cancelled) return;\n const inlined = inlineSvgStyles(text);\n const loader = new SVGLoader();\n setResult(loader.parse(inlined));\n })\n .catch((err) => {\n if (cancelled) return;\n if (err instanceof DOMException && err.name === 'AbortError') return;\n setResult(null);\n // Silence here used to hide CORS failures as \"outdoor has no decoration\".\n console.warn(\n `[eyeon-map] Outdoor SVG failed to load from ${fetchUrl}. ` +\n 'If this is a cross-origin error, pass `imageProxyUrl` to MapViewer.',\n err,\n );\n });\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [url, imageProxyUrl]);\n\n const meshes = useMemo(() => {\n if (!result) return [] as PreparedMesh[];\n const out: PreparedMesh[] = [];\n let idx = 0;\n for (const path of result.paths) {\n const node = path.userData?.node as Element | undefined;\n const layerName = getLayerNameFromNode(node);\n if (layerName?.toLowerCase().startsWith('route-path')) continue;\n if (layerName && (isRoutePathLabel(layerName) || isRouteFolderLabel(layerName))) {\n continue;\n }\n if (layerName && suppressIds?.has(layerName)) continue;\n if (isInteractiveAncestor(node) && !layerName) continue;\n // Whole INTERACTIVE / STORES folders are owned by DB shapes.\n if (layerName && (isInteractiveGroupLabel(layerName) || isStoreFolderLabel(layerName))) {\n continue;\n }\n if (node && isInteractiveAncestor(node) && layerName && suppressIds?.has(layerName)) {\n continue;\n }\n // Skip paths inside INTERACTIVE/STORES even when not yet in DB (assignable units).\n if (node && isInteractiveAncestor(node)) continue;\n\n const shapes = SVGLoader.createShapes(path);\n if (shapes.length === 0) continue;\n\n const layerStyle = resolveLayerStyle(layerName, theme);\n const fillTransparent = isTransparentColor(layerStyle?.fill);\n const strokeTransparent = isTransparentColor(layerStyle?.stroke);\n const color = new THREE.Color();\n if (layerStyle?.fill && !fillTransparent) {\n color.set(layerStyle.fill);\n } else if (path.color && !fillTransparent) {\n color.copy(path.color);\n } else {\n color.set('#cccccc');\n }\n if (layerStyle?.stroke && !layerStyle.fill && !strokeTransparent) {\n color.set(layerStyle.stroke);\n }\n\n const opacity =\n fillTransparent || (strokeTransparent && !layerStyle?.fill)\n ? 0\n : typeof path.userData?.style?.opacity === 'number'\n ? path.userData.style.opacity\n : 1;\n const extrude =\n is3d && layerStyle?.extrudeHeight != null ? layerStyle.extrudeHeight : 0;\n\n out.push({\n key: `${layerName ?? 'path'}-${idx++}`,\n shapes,\n color,\n opacity,\n extrude,\n renderOrder: layerStyle?.renderOrder ?? 2,\n });\n }\n return out;\n }, [result, suppressIds, is3d, theme]);\n\n if (!result || meshes.length === 0) return null;\n\n return (\n <group position={[0, 0, BASE_Z]} renderOrder={-20}>\n {meshes.map((m) =>\n m.shapes.map((shape, si) => (\n <mesh\n key={`${m.key}-${si}`}\n renderOrder={m.renderOrder}\n raycast={() => {}}\n >\n {m.extrude > 0 ? (\n <extrudeGeometry\n args={[shape, { depth: m.extrude, bevelEnabled: false }]}\n />\n ) : (\n <shapeGeometry args={[shape]} />\n )}\n <meshBasicMaterial\n color={m.color}\n transparent={m.opacity < 1}\n opacity={m.opacity}\n depthWrite={false}\n toneMapped={false}\n side={THREE.DoubleSide}\n />\n </mesh>\n )),\n )}\n </group>\n );\n}\n","import {\n expandBounds,\n sceneBoundsFromBBox,\n type BBox,\n type LevelTransform,\n type SceneBounds,\n type Vec2,\n} from '../core';\n\n/**\n * Stored geometry is raw SVG user space, where Y grows downward. The scene\n * mirrors Y once so the camera can keep a conventional `up = [0, 1, 0]`.\n *\n * Do not \"fix\" orientation by setting `up = [0, -1, 0]` instead: three.js\n * derives the camera's right axis from `up × forward`, so a negative up also\n * mirrors X and the map renders rotated 180° rather than flipped.\n */\nexport const SCENE_FLIP_SCALE: [number, number, number] = [1, -1, 1];\n\n/** Stored SVG-space point → view space, matching `SCENE_FLIP_SCALE`. */\nexport function dataToViewPoint(point: Vec2): Vec2 {\n return { x: point.x, y: -point.y };\n}\n\n/** Stored SVG-space bounds → view space, for camera and controls placement. */\nexport function viewBoundsFromData(bounds: SceneBounds): SceneBounds {\n return {\n ...bounds,\n minY: -bounds.maxY,\n maxY: -bounds.minY,\n cy: -bounds.cy,\n };\n}\n\n/**\n * Fit an orthographic camera so the map fills the canvas on the limiting\n * axis (width or height) with no extra inset.\n */\nexport function fitOrthoZoom(\n viewWidth: number,\n viewHeight: number,\n worldWidth: number,\n worldHeight: number,\n): number {\n const zoomX = Math.max(viewWidth, 1) / Math.max(worldWidth, 1);\n const zoomY = Math.max(viewHeight, 1) / Math.max(worldHeight, 1);\n return Math.min(zoomX, zoomY);\n}\n\nexport function boundsExtent(bounds: SceneBounds): { width: number; height: number } {\n return {\n width: Math.max(bounds.maxX - bounds.minX, 1),\n height: Math.max(bounds.maxY - bounds.minY, 1),\n };\n}\n\nexport const VIEWER_ZOOM_ANIM_MS = 240;\n/**\n * Selection pan/zoom. v1 used 0.2s of linear travel (`CAMERA.animSpeed`).\n * Ease-in-out over 200ms bunched the motion into the last frames and looked\n * like a snap; ease-out over 400ms reads as a short, smooth glide.\n */\nexport const VIEWER_FOCUS_ANIM_MS = 400;\n\n/** Extra space around a small focused shape so it does not fill the canvas. */\nexport const FOCUS_BOUNDS_PADDING = 1;\n/**\n * Padding for a large store (extent ≥ `FOCUS_LARGE_EXTENT`).\n * 2.0 → the store occupies about a third of the frame, so neighbors stay visible.\n */\nexport const FOCUS_LARGE_PADDING = 2;\n/** World size at which padding reaches `FOCUS_LARGE_PADDING`. */\nexport const FOCUS_LARGE_EXTENT = 400;\n/**\n * Padding stays tight until this size (typical small store). Kiosks and\n * amenities below this still zoom closer via `FOCUS_MIN_EXTENT`.\n */\nexport const FOCUS_PAD_SMALL_EXTENT = 80;\n/**\n * Floor for the framed world size. Tiny amenities keep neighbors in view\n * instead of filling the canvas; anything larger frames to its own bbox.\n */\nexport const FOCUS_MIN_EXTENT = 52;\n/**\n * Click-to-focus cap vs the full-map fit. A typical store stays at a\n * neighborhood view; 64× filled the canvas on the default assign map.\n */\nexport const FOCUS_MAX_ZOOM_MULTIPLE = 8;\n/**\n * Tiny kiosks/amenities may go closer than a store so they stay readable.\n * Still far below a canvas-filling close-up.\n */\nexport const FOCUS_SMALL_MAX_ZOOM_MULTIPLE = 14;\n/** Manual +/− ceiling, independent of selection focus. */\nexport const VIEWER_MAX_ZOOM_MULTIPLE = 16;\n\n/** More margin as the store grows so a department store is not edge-to-edge. */\nexport function focusPaddingRatio(\n width: number,\n height: number,\n paddingRatio = FOCUS_BOUNDS_PADDING,\n smallExtent = FOCUS_PAD_SMALL_EXTENT,\n largePadding = FOCUS_LARGE_PADDING,\n largeExtent = FOCUS_LARGE_EXTENT,\n): number {\n const extent = Math.max(width, height);\n if (extent <= smallExtent) return paddingRatio;\n const span = Math.max(largeExtent - smallExtent, 1);\n const t = Math.min(1, (extent - smallExtent) / span);\n return paddingRatio + (largePadding - paddingRatio) * t;\n}\n\n/**\n * Expand a shape's bounds for a \"click to assign\" camera frame.\n * Small units keep a tighter frame; large stores pull the camera back.\n */\nexport function paddedFocusBounds(\n bounds: SceneBounds,\n paddingRatio = FOCUS_BOUNDS_PADDING,\n minExtent = FOCUS_MIN_EXTENT,\n): SceneBounds {\n const rawW = bounds.maxX - bounds.minX;\n const rawH = bounds.maxY - bounds.minY;\n const width = Math.max(rawW, minExtent);\n const height = Math.max(rawH, minExtent);\n const pad = focusPaddingRatio(rawW, rawH, paddingRatio);\n const halfW = (width + width * pad) / 2;\n const halfH = (height + height * pad) / 2;\n return {\n minX: bounds.cx - halfW,\n minY: bounds.cy - halfH,\n maxX: bounds.cx + halfW,\n maxY: bounds.cy + halfH,\n cx: bounds.cx,\n cy: bounds.cy,\n size: Math.max(halfW, halfH) * 2,\n };\n}\n\n/**\n * How far a click may zoom relative to the fitted map. Smaller padded\n * frames (kiosks) get more zoom; store-sized frames stay at 8×.\n */\nexport function focusMaxZoomMultiple(\n paddedWidth: number,\n paddedHeight: number,\n typicalMultiple = FOCUS_MAX_ZOOM_MULTIPLE,\n smallMultiple = FOCUS_SMALL_MAX_ZOOM_MULTIPLE,\n): number {\n const extent = Math.max(paddedWidth, paddedHeight);\n const typicalFrame = FOCUS_PAD_SMALL_EXTENT * (1 + FOCUS_BOUNDS_PADDING);\n if (extent >= typicalFrame) return typicalMultiple;\n const tinyFrame = FOCUS_MIN_EXTENT * (1 + FOCUS_BOUNDS_PADDING);\n if (extent <= tinyFrame) return smallMultiple;\n const span = Math.max(typicalFrame - tinyFrame, 1);\n const t = (extent - tinyFrame) / span;\n return smallMultiple + (typicalMultiple - smallMultiple) * t;\n}\n\nexport function clampFocusZoom(\n shapeFitZoom: number,\n mapFitZoom: number,\n maxMultiple = FOCUS_MAX_ZOOM_MULTIPLE,\n): number {\n const cap = Math.max(mapFitZoom, 0.001) * maxMultiple;\n return Math.min(shapeFitZoom, cap);\n}\n\ntype FocusLevel = {\n shapes: Array<{ id: number; bbox: BBox }>;\n transform: LevelTransform;\n};\n\n/** Stable key so adding/removing a Shift-selected shape re-frames the camera. */\nexport function selectionFocusKey(shapeIds: number[]): string | null {\n const ids = [...new Set(shapeIds.filter((id) => Number.isFinite(id)))].sort(\n (a, b) => a - b,\n );\n return ids.length > 0 ? ids.join(',') : null;\n}\n\n/** View-space frame for one or more published shapes. */\nexport function viewFocusBoundsForShapes(\n levels: FocusLevel[],\n shapeIds: number[],\n): SceneBounds | null {\n const wanted = new Set(shapeIds);\n if (wanted.size === 0) return null;\n let combined: SceneBounds | null = null;\n for (const level of levels) {\n for (const shape of level.shapes) {\n if (!wanted.has(shape.id)) continue;\n const next = sceneBoundsFromBBox(shape.bbox, level.transform);\n combined = combined ? expandBounds(combined, next) : next;\n }\n }\n return combined ? viewBoundsFromData(paddedFocusBounds(combined)) : null;\n}\n\n/** View-space frame for a published shape, ready for `CameraRig.focusBounds`. */\nexport function viewFocusBoundsForShape(\n levels: FocusLevel[],\n shapeId: number,\n): SceneBounds | null {\n return viewFocusBoundsForShapes(levels, [shapeId]);\n}\n\nexport function easeOutCubic(t: number): number {\n const x = Math.min(1, Math.max(0, t));\n return 1 - (1 - x) ** 3;\n}\n\n/** Symmetric ease so a selection pan is visible the whole way, like v1's lerp. */\nexport function easeInOutCubic(t: number): number {\n const x = Math.min(1, Math.max(0, t));\n return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;\n}\n\nexport function lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nexport interface CameraPose {\n zoom: number;\n position: [number, number, number];\n target: [number, number, number];\n}\n\n/** Interpolate zoom + pan/orbit for a smooth +/− / Reset / selection focus. */\nexport function interpolateCameraPose(\n from: CameraPose,\n to: CameraPose,\n t: number,\n ease: (t: number) => number = easeOutCubic,\n): CameraPose {\n const e = ease(t);\n return {\n zoom: lerp(from.zoom, to.zoom, e),\n position: [\n lerp(from.position[0], to.position[0], e),\n lerp(from.position[1], to.position[1], e),\n lerp(from.position[2], to.position[2], e),\n ],\n target: [\n lerp(from.target[0], to.target[0], e),\n lerp(from.target[1], to.target[1], e),\n lerp(from.target[2], to.target[2], e),\n ],\n };\n}\n\nexport function cameraPosesNear(\n a: CameraPose,\n b: CameraPose,\n epsilon = 1e-3,\n): boolean {\n return (\n Math.abs(a.zoom - b.zoom) < epsilon &&\n Math.abs(a.position[0] - b.position[0]) < epsilon &&\n Math.abs(a.position[1] - b.position[1]) < epsilon &&\n Math.abs(a.position[2] - b.position[2]) < epsilon &&\n Math.abs(a.target[0] - b.target[0]) < epsilon &&\n Math.abs(a.target[1] - b.target[1]) < epsilon &&\n Math.abs(a.target[2] - b.target[2]) < epsilon\n );\n}\n\nexport function nextOrthoZoom(\n current: number,\n direction: 1 | -1,\n step: number,\n min: number,\n max: number,\n): number {\n const factor = 1 + Math.min(Math.max(step, 0.15), 1) * 0.5;\n const next = direction > 0 ? current * factor : current / factor;\n return Math.min(max, Math.max(min, next));\n}\n\n/** three.js `MOUSE` / `TOUCH` enums — left-drag pans the 2D admin/public map. */\nconst MOUSE_ROTATE = 0;\nconst MOUSE_DOLLY = 1;\nconst MOUSE_PAN = 2;\nconst TOUCH_ROTATE = 0;\nconst TOUCH_PAN = 1;\nconst TOUCH_DOLLY_PAN = 2;\n\n/**\n * Wheel zoom keeps the pointer over the same map point (Google Maps-style).\n * Speed is three-stdlib `pow(0.95, zoomSpeed)` per event — same helper as\n * Edit Map / Wayfinding (`nextZoomFromWheel`).\n * +/− still zooms about the view centre because those buttons have no cursor.\n */\nexport const ORBIT_ZOOM_TO_CURSOR = true;\n\nexport function orbitMouseButtons(is3d: boolean): {\n LEFT: number;\n MIDDLE: number;\n RIGHT: number;\n} {\n if (is3d) {\n return { LEFT: MOUSE_ROTATE, MIDDLE: MOUSE_DOLLY, RIGHT: MOUSE_PAN };\n }\n return { LEFT: MOUSE_PAN, MIDDLE: MOUSE_DOLLY, RIGHT: MOUSE_PAN };\n}\n\nexport function orbitTouches(is3d: boolean): { ONE: number; TWO: number } {\n if (is3d) {\n return { ONE: TOUCH_ROTATE, TWO: TOUCH_DOLLY_PAN };\n }\n return { ONE: TOUCH_PAN, TWO: TOUCH_DOLLY_PAN };\n}\n","import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react';\nimport { useFrame, useThree } from '@react-three/fiber';\nimport type { OrbitControls } from 'three-stdlib';\nimport * as THREE from 'three';\nimport type { SceneBounds, ThemeDefaults } from '../../core';\nimport {\n boundsExtent,\n cameraPosesNear,\n clampFocusZoom,\n easeOutCubic,\n fitOrthoZoom,\n focusMaxZoomMultiple,\n VIEWER_MAX_ZOOM_MULTIPLE,\n interpolateCameraPose,\n lerp,\n nextOrthoZoom,\n VIEWER_FOCUS_ANIM_MS,\n VIEWER_ZOOM_ANIM_MS,\n type CameraPose,\n} from '../camera';\n\nexport interface MapCameraHandle {\n zoomIn: () => void;\n zoomOut: () => void;\n reset: () => void;\n /** View-space bounds (already Y-flipped). Animates pan + zoom onto the shape. */\n focusBounds: (focus: SceneBounds) => void;\n}\n\n/** Survives Canvas / camera remounts so Settings color tweaks keep the view. */\nexport interface CameraViewSnapshot {\n is3d: boolean;\n boundsKey: string;\n zoom: number;\n position: [number, number, number];\n target: [number, number, number];\n userAdjusted: boolean;\n focusKey?: string | number | null;\n}\n\nexport function cameraBoundsKey(bounds: SceneBounds, is3d: boolean): string {\n return [\n bounds.cx,\n bounds.cy,\n bounds.minX,\n bounds.minY,\n bounds.maxX,\n bounds.maxY,\n bounds.size,\n is3d ? '3d' : '2d',\n ].join('|');\n}\n\nexport interface CameraRigProps {\n /** View-space bounds — already Y-flipped by the scene, so up is +Y. */\n bounds: SceneBounds;\n theme: ThemeDefaults;\n is3d: boolean;\n controlsRef: React.RefObject<OrbitControls | null>;\n cameraRef?: React.Ref<MapCameraHandle | null>;\n persistedViewRef: React.MutableRefObject<CameraViewSnapshot | null>;\n /** Selection key; when it changes the camera eases onto `focusViewBounds`. */\n focusKey?: string | number | null;\n focusViewBounds?: SceneBounds | null;\n}\n\nexport function CameraRig({\n bounds,\n theme,\n is3d,\n controlsRef,\n cameraRef,\n persistedViewRef,\n focusKey = null,\n focusViewBounds = null,\n}: CameraRigProps) {\n const { camera, size, invalidate } = useThree();\n const userAdjusted = useRef(false);\n const applyingView = useRef(false);\n const zoomAnimRef = useRef<number | null>(null);\n const appliedFocusKey = useRef<string | number | null>(null);\n const focusKeyRef = useRef(focusKey);\n focusKeyRef.current = focusKey;\n const focusViewBoundsRef = useRef(focusViewBounds);\n focusViewBoundsRef.current = focusViewBounds;\n const focusAnimRef = useRef<{\n from: CameraPose;\n dest: CameraPose;\n started: number;\n lookAt: boolean;\n } | null>(null);\n const boundsKey = cameraBoundsKey(bounds, is3d);\n\n const cancelZoomAnim = useCallback(() => {\n if (zoomAnimRef.current == null) return;\n cancelAnimationFrame(zoomAnimRef.current);\n zoomAnimRef.current = null;\n }, []);\n\n const captureView = useCallback(\n (adjusted = userAdjusted.current): CameraViewSnapshot => {\n const controls = controlsRef.current;\n return {\n is3d,\n boundsKey,\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [camera.position.x, camera.position.y, camera.position.z],\n target: controls\n ? [controls.target.x, controls.target.y, controls.target.z]\n : [bounds.cx, bounds.cy, 0],\n userAdjusted: adjusted,\n focusKey: focusKeyRef.current,\n };\n },\n [bounds.cx, bounds.cy, boundsKey, camera, controlsRef, is3d],\n );\n\n const restoreView = useCallback(\n (snap: CameraViewSnapshot) => {\n applyingView.current = true;\n cancelZoomAnim();\n camera.up.set(0, 1, 0);\n camera.position.set(snap.position[0], snap.position[1], snap.position[2]);\n if (camera instanceof THREE.OrthographicCamera) {\n camera.zoom = snap.zoom;\n camera.updateProjectionMatrix();\n } else {\n camera.lookAt(snap.target[0], snap.target[1], snap.target[2]);\n }\n const controls = controlsRef.current;\n if (controls) {\n controls.target.set(snap.target[0], snap.target[1], snap.target[2]);\n controls.update();\n }\n persistedViewRef.current = { ...snap, boundsKey, is3d };\n userAdjusted.current = snap.userAdjusted;\n invalidate();\n applyingView.current = false;\n },\n [boundsKey, camera, cancelZoomAnim, controlsRef, invalidate, is3d, persistedViewRef],\n );\n\n const animateOrthoZoom = useCallback(\n (targetZoom: number) => {\n if (!(camera instanceof THREE.OrthographicCamera)) return;\n cancelZoomAnim();\n const startZoom = camera.zoom;\n if (startZoom === targetZoom) return;\n const started = performance.now();\n const step = (now: number) => {\n if (!(camera instanceof THREE.OrthographicCamera)) return;\n const t = Math.min(1, (now - started) / VIEWER_ZOOM_ANIM_MS);\n camera.zoom = lerp(startZoom, targetZoom, easeOutCubic(t));\n camera.updateProjectionMatrix();\n persistedViewRef.current = captureView();\n invalidate();\n if (t < 1) {\n zoomAnimRef.current = requestAnimationFrame(step);\n return;\n }\n zoomAnimRef.current = null;\n };\n zoomAnimRef.current = requestAnimationFrame(step);\n },\n [camera, cancelZoomAnim, captureView, invalidate, persistedViewRef],\n );\n\n const currentPose = useCallback((): CameraPose => {\n const controls = controlsRef.current;\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [camera.position.x, camera.position.y, camera.position.z],\n target: controls\n ? [controls.target.x, controls.target.y, controls.target.z]\n : [bounds.cx, bounds.cy, 0],\n };\n }, [bounds.cx, bounds.cy, camera, controlsRef]);\n\n const fitPose = useCallback((): CameraPose => {\n const { width, height } = boundsExtent(bounds);\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n return {\n zoom: fitOrthoZoom(size.width, size.height, width, height),\n position: [bounds.cx, bounds.cy, 500],\n target: [bounds.cx, bounds.cy, 0],\n };\n }\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [bounds.cx, bounds.cy - bounds.size * 0.35, bounds.size * 0.85],\n target: [bounds.cx, bounds.cy, 0],\n };\n }, [bounds, camera, is3d, size.height, size.width]);\n\n const applyPose = useCallback(\n (pose: CameraPose, lookAt: boolean) => {\n applyingView.current = true;\n camera.up.set(0, 1, 0);\n camera.position.set(pose.position[0], pose.position[1], pose.position[2]);\n if (camera instanceof THREE.OrthographicCamera) {\n camera.zoom = pose.zoom;\n camera.updateProjectionMatrix();\n }\n if (lookAt) {\n camera.lookAt(pose.target[0], pose.target[1], pose.target[2]);\n }\n const controls = controlsRef.current;\n if (controls) {\n controls.target.set(pose.target[0], pose.target[1], pose.target[2]);\n controls.update();\n }\n invalidate();\n applyingView.current = false;\n },\n [camera, controlsRef, invalidate],\n );\n\n const poseForFocusBounds = useCallback(\n (focus: SceneBounds): CameraPose => {\n const { width, height } = boundsExtent(focus);\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n const mapExtent = boundsExtent(bounds);\n const mapFit = fitOrthoZoom(\n size.width,\n size.height,\n mapExtent.width,\n mapExtent.height,\n );\n return {\n zoom: clampFocusZoom(\n fitOrthoZoom(size.width, size.height, width, height),\n mapFit,\n focusMaxZoomMultiple(width, height),\n ),\n position: [focus.cx, focus.cy, 500],\n target: [focus.cx, focus.cy, 0],\n };\n }\n const sizeHint = Math.max(focus.size, 1);\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [focus.cx, focus.cy - sizeHint * 0.35, sizeHint * 0.85],\n target: [focus.cx, focus.cy, 0],\n };\n },\n [bounds, camera, is3d, size.height, size.width],\n );\n\n const applyFit = useCallback(() => {\n cancelZoomAnim();\n focusAnimRef.current = null;\n applyPose(fitPose(), is3d);\n persistedViewRef.current = captureView(false);\n }, [applyPose, cancelZoomAnim, captureView, fitPose, is3d, persistedViewRef]);\n\n const animateFocus = useCallback(\n (focus: SceneBounds) => {\n const dest = poseForFocusBounds(focus);\n const from = currentPose();\n userAdjusted.current = true;\n appliedFocusKey.current = focusKeyRef.current;\n cancelZoomAnim();\n if (cameraPosesNear(from, dest)) {\n focusAnimRef.current = null;\n persistedViewRef.current = captureView(true);\n return;\n }\n // Drive the pan in useFrame so a later layout effect cannot snap to dest.\n focusAnimRef.current = {\n from,\n dest,\n started: performance.now(),\n lookAt: is3d,\n };\n applyingView.current = true;\n invalidate();\n },\n [\n cancelZoomAnim,\n captureView,\n currentPose,\n invalidate,\n is3d,\n persistedViewRef,\n poseForFocusBounds,\n ],\n );\n\n const animateReset = useCallback(() => {\n const dest = fitPose();\n const from = currentPose();\n focusAnimRef.current = null;\n if (cameraPosesNear(from, dest)) {\n userAdjusted.current = false;\n persistedViewRef.current = captureView(false);\n return;\n }\n cancelZoomAnim();\n const started = performance.now();\n const lookAt = is3d;\n const step = (now: number) => {\n const t = Math.min(1, (now - started) / VIEWER_ZOOM_ANIM_MS);\n applyPose(interpolateCameraPose(from, dest, t), lookAt);\n persistedViewRef.current = captureView(false);\n if (t < 1) {\n applyingView.current = true;\n zoomAnimRef.current = requestAnimationFrame(step);\n return;\n }\n zoomAnimRef.current = null;\n userAdjusted.current = false;\n applyingView.current = false;\n };\n applyingView.current = true;\n zoomAnimRef.current = requestAnimationFrame(step);\n }, [\n applyPose,\n cancelZoomAnim,\n captureView,\n currentPose,\n fitPose,\n is3d,\n persistedViewRef,\n ]);\n const applyFitRef = useRef(applyFit);\n applyFitRef.current = applyFit;\n const restoreViewRef = useRef(restoreView);\n restoreViewRef.current = restoreView;\n const animateFocusRef = useRef(animateFocus);\n animateFocusRef.current = animateFocus;\n\n const zoomBy = useCallback(\n (direction: 1 | -1) => {\n userAdjusted.current = true;\n focusAnimRef.current = null;\n const controls = controlsRef.current;\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n const { width, height } = boundsExtent(bounds);\n const fit = fitOrthoZoom(size.width, size.height, width, height);\n animateOrthoZoom(\n nextOrthoZoom(\n camera.zoom,\n direction,\n theme.ZOOM_STEP,\n fit * 0.2,\n fit * VIEWER_MAX_ZOOM_MULTIPLE,\n ),\n );\n } else if (controls) {\n const offset = camera.position.clone().sub(controls.target);\n const factor = 1 + Math.min(Math.max(theme.ZOOM_STEP, 0.15), 1) * 0.5;\n const next = direction > 0 ? offset.length() / factor : offset.length() * factor;\n offset.setLength(\n Math.min(theme.CAMERA_MAX_DISTANCE, Math.max(theme.CAMERA_MIN_DISTANCE, next)),\n );\n camera.position.copy(controls.target).add(offset);\n persistedViewRef.current = captureView();\n }\n controls?.update();\n invalidate();\n },\n [\n animateOrthoZoom,\n bounds,\n camera,\n captureView,\n controlsRef,\n invalidate,\n is3d,\n persistedViewRef,\n size.height,\n size.width,\n theme,\n ],\n );\n\n useEffect(() => () => cancelZoomAnim(), [cancelZoomAnim]);\n\n useEffect(() => {\n const controls = controlsRef.current;\n if (!controls) return;\n const onChange = () => {\n if (applyingView.current) return;\n userAdjusted.current = true;\n persistedViewRef.current = captureView(true);\n };\n const onStart = () => {\n if (applyingView.current) return;\n // Pointer drag — not OrbitControls.update() during a programmed ease.\n userAdjusted.current = true;\n focusAnimRef.current = null;\n persistedViewRef.current = captureView(true);\n };\n controls.addEventListener('change', onChange);\n controls.addEventListener('start', onStart);\n return () => {\n controls.removeEventListener('change', onChange);\n controls.removeEventListener('start', onStart);\n };\n }, [camera, captureView, controlsRef, persistedViewRef]);\n\n useImperativeHandle(\n cameraRef,\n () => ({\n zoomIn: () => {\n zoomBy(1);\n },\n zoomOut: () => {\n zoomBy(-1);\n },\n reset: () => {\n userAdjusted.current = false;\n focusAnimRef.current = null;\n appliedFocusKey.current = null;\n focusKeyRef.current = null;\n animateReset();\n },\n focusBounds: (focus) => {\n animateFocus(focus);\n },\n }),\n [animateFocus, animateReset, zoomBy],\n );\n\n useLayoutEffect(() => {\n if (size.width < 2 || size.height < 2) return;\n if (focusKey == null) {\n appliedFocusKey.current = null;\n focusAnimRef.current = null;\n }\n const snap = persistedViewRef.current;\n const focus = focusViewBoundsRef.current;\n const isNewFocus =\n focusKey != null && focus != null && appliedFocusKey.current !== focusKey;\n const snapMatchesFocus =\n snap != null &&\n snap.is3d === is3d &&\n snap.boundsKey === boundsKey &&\n snap.focusKey === focusKey;\n\n if (focusKey != null && focus != null) {\n if (snapMatchesFocus) {\n appliedFocusKey.current = focusKey;\n if (focusAnimRef.current == null) restoreViewRef.current(snap);\n return;\n }\n if (isNewFocus) {\n // Only the first map paint snaps — otherwise the unfitted camera flashes.\n // Every later selection eases from the current view, like v1.\n if (persistedViewRef.current == null) {\n appliedFocusKey.current = focusKey;\n userAdjusted.current = true;\n cancelZoomAnim();\n applyPose(poseForFocusBounds(focus), is3d);\n persistedViewRef.current = captureView(true);\n return;\n }\n if (snap && !snapMatchesFocus) restoreViewRef.current(snap);\n animateFocusRef.current(focus);\n return;\n }\n // Same selection after a remount / theme swap — keep the current view.\n // Do not snap: that cancelled the ease when this effect re-ran.\n return;\n }\n\n // Theme rebuilds can swap the drei camera or remount this rig. Keep the\n // last view when the map extents and 2D/3D mode have not changed.\n if (snap && snap.is3d === is3d && snap.boundsKey === boundsKey) {\n restoreViewRef.current(snap);\n return;\n }\n userAdjusted.current = false;\n applyFitRef.current();\n }, [\n applyPose,\n boundsKey,\n camera,\n cancelZoomAnim,\n captureView,\n focusKey,\n is3d,\n persistedViewRef,\n poseForFocusBounds,\n ]);\n\n useEffect(() => {\n if (size.width < 2 || size.height < 2 || userAdjusted.current) return;\n applyFitRef.current();\n }, [size.height, size.width]);\n\n useFrame(() => {\n const anim = focusAnimRef.current;\n if (!anim) return;\n const t = Math.min(1, (performance.now() - anim.started) / VIEWER_FOCUS_ANIM_MS);\n applyPose(\n interpolateCameraPose(anim.from, anim.dest, t, easeOutCubic),\n anim.lookAt,\n );\n persistedViewRef.current = captureView(true);\n if (t < 1) {\n invalidate();\n return;\n }\n focusAnimRef.current = null;\n });\n\n return null;\n}\n","import React, { useMemo, useRef } from 'react';\nimport { Canvas } from '@react-three/fiber';\nimport { OrthographicCamera, OrbitControls } from '@react-three/drei';\nimport type { OrbitControls as OrbitControlsImpl } from 'three-stdlib';\nimport type { PathResult, PublishedDocument, SceneBounds, ThemeDefaults } from '../../core';\nimport {\n boundsFromStackedLevels,\n isOutdoorLevel,\n isTransparentColor,\n outdoorSvgSuppressIds,\n viewerLevelStack,\n} from '../../core';\nimport { LevelMeshes } from './LevelMeshes';\nimport { RouteLine } from './RouteLine';\nimport { SvgVectorLayer } from './SvgVectorLayer';\nimport { CameraRig, type CameraViewSnapshot, type MapCameraHandle } from './CameraRig';\nimport {\n ORBIT_ZOOM_TO_CURSOR,\n SCENE_FLIP_SCALE,\n orbitMouseButtons,\n orbitTouches,\n viewBoundsFromData,\n} from '../camera';\nimport { pointerMissClearsSelection } from '../pointer';\n\nconst OUTDOOR_Z = -1;\nconst CAMERA_UP: [number, number, number] = [0, 1, 0];\nconst CANVAS_DPR: [number, number] = [1, 2];\nconst CANVAS_GL = { antialias: true };\n\nexport interface MapSceneProps {\n doc: PublishedDocument;\n theme: ThemeDefaults;\n activeLevelId: number | null;\n route: PathResult | null;\n selectedShapeId?: number | null;\n selectedShapeIds?: number[];\n hoveredShapeId?: number | null;\n focusKey?: string | number | null;\n focusViewBounds?: SceneBounds | null;\n cameraRef?: React.Ref<MapCameraHandle | null>;\n onSelectShape?: (\n shapeId: number | null,\n levelId: number,\n opts?: { additive?: boolean },\n ) => void;\n imageProxyUrl?: string | null;\n /** Keep pointer events inside the map canvas host so header/footer stay clickable. */\n eventSource?: React.RefObject<HTMLElement | null>;\n}\n\nexport function MapScene({\n doc,\n theme,\n activeLevelId,\n route,\n selectedShapeId,\n selectedShapeIds,\n hoveredShapeId = null,\n focusKey,\n focusViewBounds,\n cameraRef,\n onSelectShape,\n imageProxyUrl,\n eventSource,\n}: MapSceneProps) {\n const is3d = theme.MAP_STYLE === '3D';\n const controlsRef = useRef<OrbitControlsImpl | null>(null);\n const persistedViewRef = useRef<CameraViewSnapshot | null>(null);\n const pointerDownRef = useRef<{ x: number; y: number } | null>(null);\n\n const stacked = useMemo(\n () => viewerLevelStack(doc.levels, activeLevelId),\n [doc.levels, activeLevelId],\n );\n\n const bounds = useMemo(\n () => boundsFromStackedLevels(doc.levels, activeLevelId, doc.baseViewbox),\n [doc.levels, doc.baseViewbox, activeLevelId],\n );\n\n const view = useMemo(\n () => viewBoundsFromData(bounds),\n [\n bounds.cx,\n bounds.cy,\n bounds.maxX,\n bounds.maxY,\n bounds.minX,\n bounds.minY,\n bounds.size,\n ],\n );\n const cameraPosition = useMemo(\n () => [view.cx, view.cy, 500] as [number, number, number],\n [view.cx, view.cy],\n );\n const camera3dPosition = useMemo(\n () =>\n [view.cx, view.cy - view.size * 0.35, view.size * 0.85] as [\n number,\n number,\n number,\n ],\n [view.cx, view.cy, view.size],\n );\n const mouseButtons = useMemo(() => orbitMouseButtons(is3d), [is3d]);\n const touches = useMemo(() => orbitTouches(is3d), [is3d]);\n\n const outdoorLevel = useMemo(\n () => doc.levels.find((level) => isOutdoorLevel(level)) ?? null,\n [doc.levels],\n );\n\n const outdoorSvgUrl =\n outdoorLevel?.sourceSvgUrl ?? doc.baseSvgUrl ?? null;\n\n const suppressIds = useMemo(\n () => outdoorSvgSuppressIds(doc.levels),\n [doc.levels],\n );\n\n const showOutdoorSvg = stacked.some((level) => isOutdoorLevel(level));\n\n const outdoorTheme = useMemo(\n () => ({\n GREEN_AREA_COLOR: theme.GREEN_AREA_COLOR,\n WATER_COLOR: theme.WATER_COLOR,\n PARKING_LANE_COLOR: theme.PARKING_LANE_COLOR,\n PARKING_ICON_COLOR: theme.PARKING_ICON_COLOR,\n WALKABLE_COLOR: theme.WALKABLE_COLOR,\n }),\n [\n theme.GREEN_AREA_COLOR,\n theme.PARKING_ICON_COLOR,\n theme.PARKING_LANE_COLOR,\n theme.WALKABLE_COLOR,\n theme.WATER_COLOR,\n ],\n );\n\n return (\n <Canvas\n style={{\n width: '100%',\n height: '100%',\n background: isTransparentColor(theme.MAP_BACKGROUND_COLOR)\n ? 'transparent'\n : theme.MAP_BACKGROUND_COLOR,\n }}\n eventSource={eventSource ?? undefined}\n eventPrefix=\"offset\"\n orthographic={!is3d}\n frameloop=\"demand\"\n dpr={CANVAS_DPR}\n flat\n gl={CANVAS_GL}\n onPointerDown={(e) => {\n pointerDownRef.current = { x: e.clientX, y: e.clientY };\n }}\n onPointerMissed={(e) => {\n if (\n pointerMissClearsSelection(pointerDownRef.current, {\n x: e.clientX,\n y: e.clientY,\n button: e.button,\n })\n ) {\n onSelectShape?.(null, activeLevelId ?? 0);\n }\n }}\n camera={\n is3d\n ? {\n position: camera3dPosition,\n fov: 50,\n near: 1,\n far: 10000,\n up: CAMERA_UP,\n }\n : undefined\n }\n >\n {!is3d && (\n <OrthographicCamera\n makeDefault\n position={cameraPosition}\n up={CAMERA_UP}\n near={0.1}\n far={5000}\n />\n )}\n {isTransparentColor(theme.MAP_BACKGROUND_COLOR) ? null : (\n <color attach=\"background\" args={[theme.MAP_BACKGROUND_COLOR]} />\n )}\n <ambientLight intensity={4} color=\"#c4c4c4\" />\n <directionalLight position={[0, 400, 0]} color=\"#ffffff\" intensity={0.3} />\n <directionalLight position={[0, 0, 400]} color=\"#c4c4c4\" intensity={0.2} />\n <directionalLight position={[0, 0, -400]} color=\"#c4c4c4\" intensity={0.2} />\n\n <group scale={SCENE_FLIP_SCALE}>\n {showOutdoorSvg && outdoorSvgUrl ? (\n <SvgVectorLayer\n url={outdoorSvgUrl}\n suppressIds={suppressIds}\n imageProxyUrl={imageProxyUrl}\n is3d={is3d}\n theme={outdoorTheme}\n />\n ) : null}\n\n {stacked.map((level) => {\n const outdoor = isOutdoorLevel(level);\n const transform = level.transform;\n return (\n <group\n key={level.id}\n position={[\n transform.translateX,\n transform.translateY,\n outdoor ? OUTDOOR_Z : 0,\n ]}\n rotation={[0, 0, (transform.rotate * Math.PI) / 180]}\n scale={transform.scale || 1}\n >\n <LevelMeshes\n level={level}\n theme={theme}\n is3d={is3d}\n eventSource={eventSource}\n selectedShapeIds={selectedShapeIds}\n hoveredShapeId={hoveredShapeId}\n interactiveOnly={outdoor && Boolean(outdoorSvgUrl)}\n imageProxyUrl={imageProxyUrl}\n amenities={doc.amenities}\n onSelectShape={(shapeId, opts) =>\n onSelectShape?.(shapeId, level.id, opts)\n }\n />\n </group>\n );\n })}\n\n {route && (\n <RouteLine\n route={route}\n activeLevelId={activeLevelId}\n color={theme.ACCENT_COLOR}\n />\n )}\n </group>\n\n <OrbitControls\n ref={controlsRef}\n makeDefault\n enableDamping={false}\n enableRotate={is3d}\n enablePan\n enableZoom\n screenSpacePanning\n zoomSpeed={1}\n zoomToCursor={ORBIT_ZOOM_TO_CURSOR}\n mouseButtons={mouseButtons}\n touches={touches}\n maxDistance={theme.CAMERA_MAX_DISTANCE}\n minDistance={theme.CAMERA_MIN_DISTANCE}\n />\n <CameraRig\n bounds={view}\n theme={theme}\n is3d={is3d}\n controlsRef={controlsRef}\n cameraRef={cameraRef}\n persistedViewRef={persistedViewRef}\n focusKey={focusKey ?? selectedShapeId ?? null}\n focusViewBounds={focusViewBounds ?? null}\n />\n </Canvas>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport type {\n CmAmenityCatalogItem,\n PathResult,\n PublishedDocument,\n} from '../../core';\nimport { ModernSelect } from '../../ui/ModernSelect.tsx';\nimport { getAmenityByType, recolorMapSvg } from '../../specialIcons';\n\nexport interface RuntimeChromeProps {\n doc: PublishedDocument;\n amenities: CmAmenityCatalogItem[];\n activeLevelId: number | null;\n onActiveLevelChange: (id: number) => void;\n fromAnchorId: number | null;\n toAnchorId: number | null;\n onFromChange: (id: number | null) => void;\n onToChange: (id: number | null) => void;\n accessibleOnly: boolean;\n onAccessibleOnlyChange: (v: boolean) => void;\n route: PathResult | null;\n showSearch?: boolean;\n showAmenities?: boolean;\n}\n\ninterface ListItem {\n id: string;\n label: string;\n group: string;\n anchorId: number | null;\n levelId: number;\n kind: 'store' | 'amenity';\n amenityId: number | null;\n}\n\nfunction itemLabel(\n shape: PublishedDocument['levels'][number]['shapes'][number],\n amenityName?: string,\n): string {\n return (\n shape.assignment?.customLabel ||\n amenityName ||\n shape.label.text ||\n shape.assignment?.unitNumber ||\n shape.key\n );\n}\n\nexport function RuntimeChrome({\n doc,\n amenities,\n onActiveLevelChange,\n fromAnchorId,\n toAnchorId,\n onFromChange,\n onToChange,\n accessibleOnly,\n onAccessibleOnlyChange,\n route,\n showSearch = true,\n showAmenities = true,\n}: RuntimeChromeProps) {\n const [query, setQuery] = useState('');\n const [selectedItem, setSelectedItem] = useState<ListItem | null>(null);\n\n const items = useMemo(() => {\n const list: ListItem[] = [];\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id) ?? null;\n if (shape.kind === 'unit') {\n list.push({\n id: `store-${shape.id}`,\n label: itemLabel(shape),\n group: level.name,\n anchorId: anchor?.id ?? null,\n levelId: level.id,\n kind: 'store',\n amenityId: null,\n });\n }\n if (shape.kind === 'amenity' && shape.assignment?.amenityId) {\n const amenity = amenities.find((a) => a.id === shape.assignment!.amenityId);\n list.push({\n id: `amenity-${shape.id}`,\n label: itemLabel(shape, amenity?.name),\n group: 'Amenities',\n anchorId: anchor?.id ?? null,\n levelId: level.id,\n kind: 'amenity',\n amenityId: amenity?.id ?? shape.assignment.amenityId,\n });\n }\n }\n }\n return list;\n }, [doc, amenities]);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return items;\n return items.filter((i) => i.label.toLowerCase().includes(q));\n }, [items, query]);\n\n const grouped = useMemo(() => {\n const map = new Map<string, ListItem[]>();\n for (const item of filtered) {\n const arr = map.get(item.group) ?? [];\n arr.push(item);\n map.set(item.group, arr);\n }\n return Array.from(map.entries());\n }, [filtered]);\n\n const anchorOptions = items.filter((i) => i.anchorId != null);\n const hasQuery = query.trim().length > 0;\n\n const selectItem = (item: ListItem) => {\n setSelectedItem(item);\n if (item.anchorId != null) {\n onToChange(item.anchorId);\n onActiveLevelChange(item.levelId);\n }\n };\n\n if (!showSearch && !(showAmenities && amenities.length > 0)) {\n return null;\n }\n\n return (\n <div className=\"eyeon-map-chrome\">\n <div className=\"eyeon-map-chrome__top\">\n {showSearch && (\n <input\n type=\"search\"\n className=\"eyeon-map-chrome__search-input\"\n placeholder=\"Search...\"\n aria-label=\"Search...\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n )}\n\n {showAmenities && amenities.length > 0 && (\n <div className=\"eyeon-map-chrome__amenities\">\n {amenities.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n className=\"eyeon-map-chrome__amenity\"\n aria-label={a.name}\n onClick={() => {\n const match = items.find(\n (i) =>\n i.kind === 'amenity' &&\n i.amenityId === a.id &&\n i.anchorId != null,\n );\n if (match) selectItem(match);\n }}\n >\n {(() => {\n const amenity = getAmenityByType(a.code);\n return amenity ? (\n <span\n className=\"eyeon-map-chrome__amenity-icon\"\n dangerouslySetInnerHTML={{\n __html: recolorMapSvg(amenity.svgCode, '#334155'),\n }}\n />\n ) : (\n <span className=\"eyeon-map-chrome__amenity-label\">\n {a.name.slice(0, 2)}\n </span>\n );\n })()}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {showSearch && hasQuery && (\n <div className=\"eyeon-map-chrome__panel\">\n <div className=\"eyeon-map-chrome__groups\">\n {grouped.length === 0 ? (\n <div className=\"eyeon-map-chrome__empty\">No matching stores</div>\n ) : (\n grouped.map(([group, groupItems]) => (\n <div key={group} className=\"eyeon-map-chrome__group\">\n <div className=\"eyeon-map-chrome__group-title\">{group}</div>\n {groupItems.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n className={\n selectedItem?.id === item.id\n ? 'eyeon-map-chrome__item is-selected'\n : 'eyeon-map-chrome__item'\n }\n onClick={() => selectItem(item)}\n >\n {item.label}\n </button>\n ))}\n </div>\n ))\n )}\n </div>\n\n {selectedItem && (\n <div className=\"eyeon-map-chrome__detail\">\n <div className=\"eyeon-map-chrome__detail-title\">{selectedItem.label}</div>\n <div className=\"eyeon-map-chrome__detail-meta\">{selectedItem.group}</div>\n </div>\n )}\n\n <div className=\"eyeon-map-chrome__route\">\n <label>\n From\n <ModernSelect\n ariaLabel=\"From\"\n value={fromAnchorId != null ? String(fromAnchorId) : ''}\n placeholder=\"Select start\"\n searchable\n options={anchorOptions.map((i) => ({\n value: String(i.anchorId),\n label: `${i.label} · ${i.group}`,\n }))}\n onChange={(next) => onFromChange(next ? Number(next) : null)}\n />\n </label>\n <label>\n To\n <ModernSelect\n ariaLabel=\"To\"\n value={toAnchorId != null ? String(toAnchorId) : ''}\n placeholder=\"Select destination\"\n searchable\n options={anchorOptions.map((i) => ({\n value: String(i.anchorId),\n label: `${i.label} · ${i.group}`,\n }))}\n onChange={(next) => onToChange(next ? Number(next) : null)}\n />\n </label>\n <label className=\"eyeon-map-chrome__accessible\">\n <input\n type=\"checkbox\"\n checked={accessibleOnly}\n onChange={(e) => onAccessibleOnlyChange(e.target.checked)}\n />\n Accessible route\n </label>\n {route && (\n <div className=\"eyeon-map-chrome__route-meta\">\n {route.levelChanges.length > 0\n ? `${route.levelChanges.length} level change(s)`\n : 'Same level'}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React, { Suspense, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n CmAmenityCatalogItem,\n MapViewerHost,\n PathResult,\n PublishedDocument,\n ThemeDefaults,\n} from '../core';\nimport {\n compileGraph,\n defaultViewerLevelId,\n hasBuildingFloors,\n MAP_NO_FLOORS_MESSAGE,\n mergeTheme,\n findPath,\n normalizePublishedDocument,\n viewerChrome,\n viewerLevelIdAfterShapeSelect,\n} from '../core';\nimport { MapScene } from './components/MapScene';\nimport { isAssignAmenity } from '../specialIcons';\nimport type { MapCameraHandle } from './components/CameraRig';\nimport { RuntimeChrome } from './ui/RuntimeChrome';\nimport { MapControls } from './ui/MapControls';\nimport {\n selectionFocusKey,\n viewFocusBoundsForShape,\n viewFocusBoundsForShapes,\n} from './camera';\nimport { ensureMapFont } from '../fonts/mapFontUrl';\nimport './viewer.css';\n\nexport interface MapViewerProps {\n /** Published (or draft) document. If omitted, fetched from webApiURI. */\n document?: PublishedDocument | null;\n webApiURI?: string;\n /** Prefer fetching /v1/map/document */\n centerId?: number;\n /** Public / preview / kiosk surface. Never includes Map options (editor rail). */\n host?: MapViewerHost;\n kioskId?: number | null;\n selectedRetailerId?: number | null;\n /**\n * Media proxy base, appended with the encoded SVG URL (v1 `IMAGE_PROXY_URL`\n * contract, e.g. `/eyeon-portal/media?url=`). Needed wherever the outdoor\n * SVG origin sends no CORS headers.\n */\n imageProxyUrl?: string | null;\n themeOverrides?: Partial<ThemeDefaults>;\n onExtractedAmenities?: (codes: string[]) => void;\n onSelectShape?: (shapeId: number | null, opts?: { additive?: boolean }) => void;\n /** Zoom to this shape (PORTAL default-map assign). */\n selectedShapeId?: number | null;\n /** Extra selected shapes when Shift-selecting in PORTAL assign. */\n selectedShapeIds?: number[];\n /** Highlight from the Map options list (same fill as pointer hover). */\n hoveredShapeId?: number | null;\n /**\n * Bump when staff pick a row in the rail so the camera re-frames even if\n * the same shape is already selected.\n */\n focusNonce?: number;\n /** Controlled floor when embedded (e.g. PORTAL default). */\n activeLevelId?: number | null;\n onActiveLevelChange?: (levelId: number) => void;\n /** Click a store/amenity to route. Off when PORTAL is assigning. Default true. */\n routeOnSelect?: boolean;\n createRouteRef?: React.MutableRefObject<{\n createRouteToStore: (retailerId: number) => void;\n createRouteToAmenity: (amenityCode: string) => void;\n clearRoute: () => void;\n } | null>;\n className?: string;\n style?: React.CSSProperties;\n}\n\nasync function fetchDocument(\n webApiURI: string,\n centerId?: number,\n draft?: boolean,\n signal?: AbortSignal,\n): Promise<PublishedDocument> {\n const base = webApiURI.replace(/\\/$/, '');\n const params = new URLSearchParams();\n if (centerId != null && centerId > 0) params.set('center_id', String(centerId));\n if (draft) params.set('draft', '1');\n const qs = params.toString();\n const res = await fetch(`${base}/v1/map/document${qs ? `?${qs}` : ''}`, {\n credentials: 'include',\n signal,\n });\n if (!res.ok) {\n throw new Error(`Failed to load map document (${res.status})`);\n }\n return res.json();\n}\n\nexport function MapViewer(props: MapViewerProps) {\n ensureMapFont();\n const {\n document: documentProp,\n webApiURI,\n centerId,\n host = 'WEBSITE',\n kioskId = null,\n selectedRetailerId = null,\n themeOverrides,\n onExtractedAmenities,\n createRouteRef,\n className,\n style,\n activeLevelId: activeLevelIdProp,\n onActiveLevelChange,\n routeOnSelect = true,\n imageProxyUrl,\n selectedShapeId = null,\n selectedShapeIds,\n hoveredShapeId = null,\n focusNonce,\n } = props;\n\n const [rawDoc, setDoc] = useState<PublishedDocument | null>(documentProp ?? null);\n const doc = useMemo(\n () => (rawDoc ? normalizePublishedDocument(rawDoc) : null),\n [rawDoc],\n );\n const [error, setError] = useState<string | null>(null);\n const [route, setRoute] = useState<PathResult | null>(null);\n const [fromAnchorId, setFromAnchorId] = useState<number | null>(null);\n const [toAnchorId, setToAnchorId] = useState<number | null>(null);\n const [accessibleOnly, setAccessibleOnly] = useState(false);\n const [internalLevelId, setInternalLevelId] = useState<number | null>(() => {\n if (!documentProp) return null;\n return defaultViewerLevelId(normalizePublishedDocument(documentProp).levels);\n });\n const cameraApi = useRef<MapCameraHandle | null>(null);\n const canvasHostRef = useRef<HTMLDivElement>(null);\n const activeLevelId = activeLevelIdProp ?? internalLevelId;\n const setActiveLevelId = (id: number | null) => {\n setInternalLevelId(id);\n if (id != null) onActiveLevelChange?.(id);\n };\n\n useEffect(() => {\n if (documentProp) {\n setDoc(documentProp);\n return;\n }\n if (!webApiURI) return;\n let cancelled = false;\n const controller = new AbortController();\n const draft = viewerChrome(host).fetchDraft;\n fetchDocument(webApiURI, centerId, draft, controller.signal)\n .then((d) => {\n if (!cancelled) setDoc(d);\n })\n .catch((e) => {\n if (\n !cancelled &&\n !(e instanceof DOMException && e.name === 'AbortError')\n ) {\n setError(e instanceof Error ? e.message : String(e));\n }\n });\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [documentProp, webApiURI, centerId, host]);\n\n useEffect(() => {\n if (!doc) return;\n const ids = new Set(doc.levels.map((level) => level.id));\n if (activeLevelId == null || !ids.has(activeLevelId)) {\n setActiveLevelId(defaultViewerLevelId(doc.levels));\n }\n const codes = new Set<string>();\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.kind === 'amenity' && shape.assignment?.amenityId != null) {\n const amenity = doc.amenities.find((a) => a.id === shape.assignment!.amenityId);\n if (amenity) codes.add(amenity.code);\n }\n }\n }\n onExtractedAmenities?.(Array.from(codes));\n }, [doc, activeLevelId, onExtractedAmenities]);\n\n // Map IT / ?r= — switch to the store's floor so the highlight is visible\n useEffect(() => {\n if (!doc || selectedRetailerId == null) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.retailerId === selectedRetailerId) {\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n return;\n }\n }\n }\n }, [doc, selectedRetailerId]);\n\n const focusShapeIds = useMemo(() => {\n if (selectedShapeIds && selectedShapeIds.length > 0) return selectedShapeIds;\n return selectedShapeId != null ? [selectedShapeId] : [];\n }, [selectedShapeId, selectedShapeIds]);\n const selectionKey = selectionFocusKey(focusShapeIds);\n const focusKey =\n selectionKey == null\n ? null\n : focusNonce != null\n ? `${selectionKey}#${focusNonce}`\n : selectionKey;\n const focusViewBounds = useMemo(() => {\n if (!doc || focusShapeIds.length === 0) return null;\n // Union every selected shape so Shift-select frames the group, not the first id.\n return viewFocusBoundsForShapes(doc.levels, focusShapeIds);\n }, [doc, focusShapeIds]);\n\n // Prefill \"from\" for kiosk host\n useEffect(() => {\n if (!doc || !viewerChrome(host).kioskOrigin || kioskId == null) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (\n shape.kind === 'kiosk_screen' &&\n shape.assignment?.kioskId === kioskId\n ) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) setFromAnchorId(anchor.id);\n }\n }\n }\n }, [doc, host, kioskId]);\n\n const compiled = useMemo(() => {\n if (!doc) return null;\n return compileGraph(\n doc.graph.nodes.map((n) => ({\n id: n.id,\n levelId: n.levelId,\n shapeId: n.shapeId,\n kind: n.kind,\n x: n.x,\n y: n.y,\n connectorId: n.connectorId,\n })),\n doc.graph.edges.map((e) => ({\n id: e.id,\n mapId: doc.mapId,\n fromAnchorId: e.from,\n toAnchorId: e.to,\n weight: e.weight,\n directed: e.directed,\n accessible: e.accessible,\n kind: e.kind,\n })),\n doc.connectors,\n );\n }, [doc]);\n\n const runRoute = (fromId: number | null, toId: number | null) => {\n if (!compiled || fromId == null || toId == null) {\n setRoute(null);\n return;\n }\n const result = findPath(compiled, fromId, toId, { accessibleOnly });\n setRoute(result);\n };\n\n useEffect(() => {\n runRoute(fromAnchorId, toAnchorId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fromAnchorId, toAnchorId, accessibleOnly, compiled]);\n\n useEffect(() => {\n if (!createRouteRef || !doc) return;\n const routeApi = {\n createRouteToStore(retailerId: number) {\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.retailerId === retailerId) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) {\n setToAnchorId(anchor.id);\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n }\n }\n }\n }\n },\n createRouteToAmenity(amenityCode: string) {\n const amenity = doc.amenities.find((a) => a.code === amenityCode);\n if (!amenity) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.amenityId === amenity.id) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) {\n setToAnchorId(anchor.id);\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n return;\n }\n }\n }\n }\n },\n clearRoute() {\n setToAnchorId(null);\n setRoute(null);\n },\n };\n createRouteRef.current = routeApi;\n return () => {\n if (createRouteRef.current === routeApi) createRouteRef.current = null;\n };\n }, [activeLevelId, createRouteRef, doc]);\n\n const theme: ThemeDefaults = mergeTheme(doc?.theme, themeOverrides);\n\n if (error) {\n return (\n <div className={`eyeon-map-viewer eyeon-map-viewer--error ${className ?? ''}`} style={style}>\n <div className=\"eyeon-map-viewer__error\">{error}</div>\n </div>\n );\n }\n\n if (!doc) {\n return (\n <div className={`eyeon-map-viewer eyeon-map-viewer--loading ${className ?? ''}`} style={style}>\n <div className=\"eyeon-map-viewer__loading\">Loading map…</div>\n </div>\n );\n }\n\n const amenitiesOnMap: CmAmenityCatalogItem[] = doc.amenities.filter(\n (a) =>\n isAssignAmenity(a.code) &&\n doc.levels.some((l) =>\n l.shapes.some((s) => s.assignment?.amenityId === a.id),\n ),\n );\n const chrome = viewerChrome(host);\n const hasFloors = hasBuildingFloors(doc.levels);\n\n return (\n <div\n className={`eyeon-map-viewer eyeon-map-viewer--${host}${hasFloors ? '' : ' eyeon-map-viewer--empty'} ${className ?? ''}`}\n style={\n {\n ...style,\n ['--map-accent' as string]: theme.ACCENT_COLOR,\n ['--map-bg' as string]: theme.MAP_BACKGROUND_COLOR,\n } as React.CSSProperties\n }\n >\n {!hasFloors ? (\n <div className=\"eyeon-map-viewer__empty\">{MAP_NO_FLOORS_MESSAGE}</div>\n ) : null}\n\n {hasFloors && (chrome.search || chrome.amenities) && (\n <RuntimeChrome\n doc={doc}\n amenities={amenitiesOnMap}\n activeLevelId={activeLevelId}\n onActiveLevelChange={setActiveLevelId}\n fromAnchorId={fromAnchorId}\n toAnchorId={toAnchorId}\n onFromChange={setFromAnchorId}\n onToChange={setToAnchorId}\n accessibleOnly={accessibleOnly}\n onAccessibleOnlyChange={setAccessibleOnly}\n route={route}\n showSearch={chrome.search}\n showAmenities={chrome.amenities}\n />\n )}\n\n {hasFloors ? (\n <MapControls\n levels={doc.levels}\n activeLevelId={activeLevelId}\n onActiveLevelChange={setActiveLevelId}\n onZoomIn={() => cameraApi.current?.zoomIn()}\n onZoomOut={() => cameraApi.current?.zoomOut()}\n onReset={() => cameraApi.current?.reset()}\n showFloors={chrome.floors}\n showZoomReset={chrome.zoomReset}\n />\n ) : null}\n\n {hasFloors ? (\n <div ref={canvasHostRef} className=\"eyeon-map-viewer__canvas\">\n <Suspense fallback={null}>\n <MapScene\n doc={doc}\n theme={theme}\n activeLevelId={activeLevelId}\n route={route}\n selectedShapeId={selectedShapeId}\n selectedShapeIds={focusShapeIds}\n hoveredShapeId={hoveredShapeId}\n focusKey={focusKey}\n focusViewBounds={focusViewBounds}\n cameraRef={cameraApi}\n eventSource={canvasHostRef}\n imageProxyUrl={imageProxyUrl}\n onSelectShape={(shapeId, levelId, opts) => {\n if (shapeId == null) {\n props.onSelectShape?.(null);\n return;\n }\n if (!opts?.additive) {\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, levelId),\n );\n }\n if (routeOnSelect) {\n const level = doc.levels.find((l) => l.id === levelId);\n const anchor = level?.anchors.find((a) => a.shapeId === shapeId);\n if (anchor) setToAnchorId(anchor.id);\n }\n props.onSelectShape?.(shapeId, opts);\n if (!opts?.additive && shapeId === selectedShapeId) {\n const focus =\n viewFocusBoundsForShapes(doc.levels, focusShapeIds) ??\n viewFocusBoundsForShape(doc.levels, shapeId);\n if (focus) cameraApi.current?.focusBounds(focus);\n }\n }}\n />\n </Suspense>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default MapViewer;\n"],"names":["MapControls","levels","activeLevelId","onActiveLevelChange","onZoomIn","onZoomOut","onReset","showFloors","showZoomReset","floorOptions","alwaysShowFloors","switcher","floorSwitcherDisplayLevels","showFloorList","shouldShowFloorSwitcher","showZoom","hasBuildingFloors","jsxs","jsx","level","active","Fragment","MAP_FONT_FAMILY","MAP_LABEL_LINE_HEIGHT","SVGIcons","AllAmenities","CONNECTOR_AMENITY_TYPES","AssignAmenities","item","KioskSvg","EntranceSvg","isAssignAmenity","type","getAmenityByType","getMapSpecialSvg","id","_a","recolorMapSvg","svg","color","hex","mapSpecialSvgToDataUrl","colored","entranceIconDataUrl","amenityAssignOptions","amenityTypeFromCatalogId","amenityId","amenities","amenityCatalogIdForType","row","assignmentSpecialIconDataUrl","assignment","assignmentSpecialIconId","ASSIGNED_CONNECTOR_ICON","UNASSIGNED_CONNECTOR_ICON","connectorSpecialKind","shape","raw","connectorSpecialIconDataUrl","kind","assigned","fill","assignedConnectorShapeIds","anchors","ids","anchor","connectorMapIconKind","assignedShapeIds","mapFontUrl","MAP_FONT_URL","registered","ensureMapFont","loaded","MODERN_SELECT_SEARCH_AFTER","filterModernSelectOptions","options","query","q","o","modernSelectIsSearchable","optionCount","searchable","Chevron","ModernSelect","value","onChange","disabled","placeholder","ariaLabel","listId","useId","rootRef","useRef","triggerRef","buttonRef","menuRef","searchRef","open","setOpen","useState","setQuery","activeIndex","setActiveIndex","menuPos","setMenuPos","withSearch","selected","filtered","useMemo","close","useCallback","pick","next","updateMenuPos","el","rect","spaceBelow","spaceAbove","maxHeight","openAbove","useEffect","onDoc","e","t","_b","onKey","onMove","moveActive","delta","i","onSearchKeyDown","option","menu","createPortal","index","highlighted","target","v","polygonToThreeShape","points","THREE","polygonToThreePath","path","slabShapeWithHoles","outer","holes","hole","holesOverlappingOuter","skipRaycast","createOpeningMarkTexture","aspect","width","canvas","ctx","pad","OPENING_VOID_MARK","texture","OpeningVoidMesh","polygon","box","polygonBBox","dash","openingSpanDash","outline","first","p","geometry","material","OPENING_VOID_STROKE","line","mark","height","OPENING_VOID_FILL","bbox","span","OpeningWells","polygons","VIEWER_SELECTABLE_KINDS","isViewerSelectableKind","viewerShapeHighlighted","shapeId","hoveredShapeId","selectedShapeIds","resolvedViewerHoverId","listHoverId","pointerHoverId","viewerHoverCursor","applyViewerHoverCursor","host","cursor","viewerHoverFillOpacity","base","hovered","parseHex","h","r","g","b","n","toHex","viewerHoverFillColor","accent","amount","a","VIEWER_CLICK_DRAG_PX","pointerMissClearsSelection","down","up","dx","dy","kindColor","theme","resolvedAssignmentBgColor","polygonShape","HoverOutline","extrude","sourceGeometry","LevelMeshes","is3d","onSelectShape","hoveredShapeIdProp","eventSource","interactiveOnly","imageProxyUrl","setPointerHoverId","openings","voidPolygonsOnLevel","meshes","s","isEntranceIcon","INTERACTIVE_SHAPE_KINDS","resolveLayerStyle","radius","punch","isSlabShapeKind","threeShapes","poly","filletPolygon","labels","entranceIcons","overlays","assignmentOverlayVisible","connectorOverlays","assignedIds","layout","connectorIconLayout","url","geometryBBox","align","normalizeLabelAlign","cx","cy","tilt","Text","labelAlignX","size","DEFAULT_ENTRANCE_SIZE","AssignmentImageOverlay","fontSize","DEFAULT_ASSIGNMENT_SIZE","z","iconColor","imageKey","assignmentOverlayImageUrl","text","_c","assignmentOverlayRenderSize","rotation","x","y","selectable","baseOpacity","fillTransparent","isTransparentColor","opacity","geoShape","idx","loadCanvasTexture","signal","resolve","reject","img","cleanup","onAbort","position","setTexture","setAspect","disposed","controller","proxied","resolveFetchUrl","candidates","lastError","src","error","RouteLine","route","curve","COLOR_SPACE_SVG","SRGBColorSpace","SVGLoader","Loader","manager","onLoad","onProgress","onError","scope","loader","FileLoader","parseNode","node","style","transform","getNodeTransform","isDefsNode","parseStyle","parseCSSStylesheet","parsePathNode","parseRectNode","parsePolygonNode","parsePolylineNode","parseCircleNode","parseEllipseNode","parseLineNode","usedNodeId","usedNode","transformPath","currentTransform","paths","childNodes","transformStack","ShapePath","point","Vector2","control","firstPoint","isFirstPoint","doSetFirstPoint","d","commands","l","command","data","numbers","parseFloats","j","jl","getReflection","rx","ry","start","parseArcCommand","stylesheet","selectorList","definitions","stylesheets","x_axis_rotation","large_arc_flag","sweep_flag","end","dx2","dy2","x1p","y1p","rxs","rys","x1ps","y1ps","cr","dq","pq","cxp","cyp","theta","svgAngle","ux","uy","vx","vy","dot","len","ang","parseFloatWithUnits","w","bci","iterator","match","regex","subpath","Path","x1","y1","x2","y2","stylesheetStyles","classSelectors","addStyle","svgName","jsName","adjustFunction","clamp","positive","input","flags","stride","RE","SEP","INT","FLOAT","EXP","state","seenComma","number","exponent","result","throwSyntaxError","current","partial","newNumber","length","units","unitConversion","string","theUnit","u","scale","parseNodeTransform","Matrix3","tempTransform0","tx","ty","transformsTexts","tIndex","transformText","openParPos","closeParPos","transformType","array","angle","tempTransform1","tempTransform2","tempTransform3","scaleX","scaleY","m","transfVec2","v2","tempV3","transfEllipseGeneric","cosTheta","sinTheta","v1","Vector3","f1","f2","mF","mFInv","mQe","ed","eigenDecomposition","rt1sqrt","rt2sqrt","mDsqrt","mRT","mDRF","transformAngle","phi","cosR","sinR","isTransformFlipped","transfEllipseNoSkew","sx","getTransformScaleX","sy","getTransformScaleY","subPaths","curves","tempV2","isTransformSkewed","te","basisDot","A","B","C","rt1","rt2","cs","sn","sm","df","rt","xml","shapePath","IntersectionLocationType","classifyResult","findEdgeIntersection","a0","a1","b0","b1","x3","x4","y3","y4","nom1","nom2","denom","t1","t2","classifyPoint","edgeStart","edgeEnd","ax","ay","bx","by","sa","getIntersections","path1","path2","intersectionsRaw","intersections","path1EdgeStart","path1EdgeEnd","index2","path2EdgeStart","path2EdgeEnd","intersection","getScanlineIntersections","scanline","boundingBox","center","allIntersections","i1","i2","isHoleTo","simplePath","allPaths","scanlineMinX","scanlineMaxX","_fillRule","centerBoundingBox","scanlineIntersections","baseIntersections","otherIntersections","firstXOfPath","stack","isHole","isHoleFor","lastCWValue","identifier","simplePaths","maxY","minY","maxX","minX","ShapeUtils","Box2","sp","isAHole","shapesToReturn","Shape","lineJoin","lineCap","miterLimit","arcDivisions","minDistance","vertices","normals","uvs","BufferGeometry","Float32BufferAttribute","vertexOffset","tempV2_1","tempV2_2","tempV2_3","tempV2_4","tempV2_5","tempV2_6","tempV2_7","lastPointL","lastPointR","point0L","point0R","currentPointL","currentPointR","nextPointL","nextPointR","innerPoint","outerPoint","removeDuplicatedPoints","numPoints","isClosed","currentPoint","previousPoint","nextPoint","strokeWidth2","deltaU","u0","u1","innerSideModified","joinIsOnLeftSide","isMiter","initialJoinIsOnLeftSide","numVertices","currentCoordinate","currentCoordinateUV","getNormal","iPoint","normal1","miterSide","miterLength2","segmentLengthPrev","segmentLengthNext","makeSegmentTriangles","makeSegmentWithBevelJoin","createSegmentTrianglesWithMiddleSection","makeCircularSector","miterFraction","addVertex","addCapGeometry","lastOuter","lastInner","p1","p2","il","vl","dupPoints","newPoints","BASE_Z","getLayerNameFromNode","isInteractiveAncestor","dataName","isInteractiveGroupLabel","isStoreFolderLabel","SvgVectorLayer","suppressIds","setResult","cancelled","fetchUrl","res","inlined","inlineSvgStyles","err","out","layerName","isRoutePathLabel","isRouteFolderLabel","shapes","layerStyle","strokeTransparent","si","SCENE_FLIP_SCALE","viewBoundsFromData","bounds","fitOrthoZoom","viewWidth","viewHeight","worldWidth","worldHeight","zoomX","zoomY","boundsExtent","VIEWER_ZOOM_ANIM_MS","VIEWER_FOCUS_ANIM_MS","FOCUS_BOUNDS_PADDING","FOCUS_LARGE_PADDING","FOCUS_LARGE_EXTENT","FOCUS_PAD_SMALL_EXTENT","FOCUS_MIN_EXTENT","FOCUS_MAX_ZOOM_MULTIPLE","FOCUS_SMALL_MAX_ZOOM_MULTIPLE","VIEWER_MAX_ZOOM_MULTIPLE","focusPaddingRatio","paddingRatio","smallExtent","largePadding","largeExtent","extent","paddedFocusBounds","minExtent","rawW","rawH","halfW","halfH","focusMaxZoomMultiple","paddedWidth","paddedHeight","typicalMultiple","smallMultiple","typicalFrame","tinyFrame","clampFocusZoom","shapeFitZoom","mapFitZoom","maxMultiple","cap","selectionFocusKey","shapeIds","viewFocusBoundsForShapes","wanted","combined","sceneBoundsFromBBox","expandBounds","viewFocusBoundsForShape","easeOutCubic","lerp","interpolateCameraPose","from","to","ease","cameraPosesNear","epsilon","nextOrthoZoom","direction","step","min","max","factor","MOUSE_ROTATE","MOUSE_DOLLY","MOUSE_PAN","TOUCH_ROTATE","TOUCH_PAN","TOUCH_DOLLY_PAN","ORBIT_ZOOM_TO_CURSOR","orbitMouseButtons","orbitTouches","cameraBoundsKey","CameraRig","controlsRef","cameraRef","persistedViewRef","focusKey","focusViewBounds","camera","invalidate","useThree","userAdjusted","applyingView","zoomAnimRef","appliedFocusKey","focusKeyRef","focusViewBoundsRef","focusAnimRef","boundsKey","cancelZoomAnim","captureView","adjusted","controls","restoreView","snap","animateOrthoZoom","targetZoom","startZoom","started","now","currentPose","fitPose","applyPose","pose","lookAt","poseForFocusBounds","focus","mapExtent","mapFit","sizeHint","applyFit","animateFocus","dest","animateReset","applyFitRef","restoreViewRef","animateFocusRef","zoomBy","fit","offset","onStart","useImperativeHandle","useLayoutEffect","isNewFocus","snapMatchesFocus","useFrame","anim","OUTDOOR_Z","CAMERA_UP","CANVAS_DPR","CANVAS_GL","MapScene","doc","selectedShapeId","pointerDownRef","stacked","viewerLevelStack","boundsFromStackedLevels","view","cameraPosition","camera3dPosition","mouseButtons","touches","outdoorLevel","isOutdoorLevel","outdoorSvgUrl","outdoorSvgSuppressIds","showOutdoorSvg","outdoorTheme","Canvas","OrthographicCamera","outdoor","opts","OrbitControls","itemLabel","amenityName","RuntimeChrome","fromAnchorId","toAnchorId","onFromChange","onToChange","accessibleOnly","onAccessibleOnlyChange","showSearch","showAmenities","selectedItem","setSelectedItem","items","list","amenity","grouped","map","arr","anchorOptions","hasQuery","selectItem","group","groupItems","fetchDocument","webApiURI","centerId","draft","params","qs","MapViewer","props","documentProp","kioskId","selectedRetailerId","themeOverrides","onExtractedAmenities","createRouteRef","className","activeLevelIdProp","routeOnSelect","focusNonce","rawDoc","setDoc","normalizePublishedDocument","setError","setRoute","setFromAnchorId","setToAnchorId","setAccessibleOnly","internalLevelId","setInternalLevelId","defaultViewerLevelId","cameraApi","canvasHostRef","setActiveLevelId","viewerChrome","codes","viewerLevelIdAfterShapeSelect","focusShapeIds","selectionKey","compiled","compileGraph","runRoute","fromId","toId","findPath","routeApi","retailerId","amenityCode","mergeTheme","amenitiesOnMap","chrome","hasFloors","Suspense","levelId"],"mappings":"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","x_google_ignoreList":[15]}
|
|
1
|
+
{"version":3,"file":"MapViewer.js","sources":["../../src/viewer/ui/MapControls.tsx","../../src/fonts/mapFont.ts","../../../threejs-map/src/helpers/svgIcons.helper.ts","../../../threejs-map/src/helpers/amenities.helper.ts","../../../threejs-map/src/amenities.ts","../../src/specialIcons.ts","../../src/fonts/Montserrat-Regular.woff?url","../../src/fonts/mapFontUrl.ts","../../src/ui/selectSearch.ts","../../src/ui/ModernSelect.tsx","../../src/viewer/components/openingGeometry.ts","../../src/viewer/components/OpeningWell.tsx","../../src/viewer/pointer.ts","../../src/viewer/components/LevelMeshes.tsx","../../src/viewer/components/RouteLine.tsx","../../../../node_modules/three/examples/jsm/loaders/SVGLoader.js","../../src/viewer/components/SvgVectorLayer.tsx","../../src/viewer/camera.ts","../../src/viewer/components/CameraRig.tsx","../../src/viewer/components/MapScene.tsx","../../src/viewer/ui/RuntimeChrome.tsx","../../src/viewer/MapViewer.tsx"],"sourcesContent":["import React from 'react';\nimport type { StackLevel } from '../../core';\nimport {\n floorSwitcherDisplayLevels,\n hasBuildingFloors,\n shouldShowFloorSwitcher,\n} from '../../core';\n\nexport interface MapControlLevel {\n id: number;\n name: string;\n}\n\nexport interface MapControlsProps {\n levels: Array<MapControlLevel & Partial<StackLevel>>;\n activeLevelId: number | null;\n onActiveLevelChange: (id: number) => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onReset: () => void;\n showFloors?: boolean;\n showZoomReset?: boolean;\n /** Override the viewer building-floor list (e.g. Edit Map + Outdoor). */\n floorOptions?: MapControlLevel[];\n /** Show the floor list even when there is only one floor. */\n alwaysShowFloors?: boolean;\n}\n\nexport function MapControls({\n levels,\n activeLevelId,\n onActiveLevelChange,\n onZoomIn,\n onZoomOut,\n onReset,\n showFloors = true,\n showZoomReset = true,\n floorOptions,\n alwaysShowFloors = false,\n}: MapControlsProps) {\n const stackLevels = levels.filter(\n (level): level is MapControlLevel & StackLevel =>\n level.kind != null &&\n level.ordering != null &&\n level.levelIndex != null,\n );\n const switcher = floorOptions ?? floorSwitcherDisplayLevels(stackLevels);\n const showFloorList =\n showFloors &&\n (alwaysShowFloors\n ? switcher.length > 0\n : shouldShowFloorSwitcher(stackLevels));\n const showZoom = showZoomReset && hasBuildingFloors(stackLevels);\n if (!showFloorList && !showZoom) return null;\n\n return (\n <div className=\"eyeon-map-controls\">\n <div className=\"eyeon-map-controls__stack\">\n {showFloorList && (\n <div className=\"eyeon-map-controls__floors\" role=\"tablist\" aria-label=\"Floors\">\n {switcher.map((level) => {\n const active = level.id === activeLevelId;\n return (\n <button\n key={level.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n className={\n active\n ? 'eyeon-map-controls__floor is-active'\n : 'eyeon-map-controls__floor'\n }\n onClick={() => onActiveLevelChange(level.id)}\n >\n {level.name}\n </button>\n );\n })}\n </div>\n )}\n\n {showZoom && (\n <>\n <button\n type=\"button\"\n className=\"eyeon-map-controls__reset\"\n onClick={onReset}\n aria-label=\"Reset map\"\n >\n Reset\n </button>\n\n <div className=\"eyeon-map-controls__zoom\">\n <button\n type=\"button\"\n className=\"eyeon-map-controls__zoom-btn\"\n onClick={onZoomOut}\n aria-label=\"Zoom out\"\n >\n −\n </button>\n <button\n type=\"button\"\n className=\"eyeon-map-controls__zoom-btn\"\n onClick={onZoomIn}\n aria-label=\"Zoom in\"\n >\n +\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n","/** CSS family — same Montserrat as admin-portal / Edit Map chrome. */\nexport const MAP_FONT_FAMILY = 'Montserrat, sans-serif';\n\n/** Shared by Edit Map SVG tspans and default-map troika `<Text>`. */\nexport const MAP_LABEL_LINE_HEIGHT = 1.15;\n","const SVGIcons = {\n Entrance: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\n <path fill=\"none\" stroke=\"#444444\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8.25 3.75h8.25A3.5 3.5 0 0 1 20 7.25v9.5a3.5 3.5 0 0 1-3.5 3.5H8.25\"/>\n <path fill=\"none\" stroke=\"#444444\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.5 12h12.35M12.2 7.85 16.4 12l-4.2 4.15\"/>\n </svg>`,\n\n Kiosk: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 443.83 787.21\">\n <path fill=\"#444444\" d=\"M451,587.7V8.14H7.14V589.5H111.43V730.89H71.27L38.59,763.58v31.78H416.36V764.93l-34.05-34H345.78V587.7ZM396.91,71.23v452.7H59.85V71.23Z\" transform=\"translate(-7.14 -8.14)\" />\n </svg>`,\n\n Escalator: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 445.3\">\n <path fill=\"#444444\" d=\"M243.4,75.9c21.2,0,38.1-16.8,38.1-38S264.6,0,243.4,0c-21.2,0-38.1,16.8-38.1,38S222.1,75.9,243.4,75.9z M508.5,41.2h-88.7 c-18.5,0-41.9,7.6-56.1,21.7l-82.2,81.9V121c0-51-75.7-50.4-75.7,0v98.2l-71.3,71c-6.5,6.5-7.6,7.1-20.7,7.1H70.2 C26.1,297.2,0,336.8,0,369.9c0,33.6,26.1,75.4,74,75.4h77.9c18.5,0,40.8-7.1,58.8-24.4l228.1-226.7c4.9-4.3,7.6-5.4,15.8-5.4h56.1 c27.2,0,65.3-30.4,65.3-74.8C576.5,70.5,537.9,41.2,508.5,41.2z M504.7,150.8h-47.9c-20.1,0-29.4,2.7-41.4,14.7L185.7,394.3 c-9.3,9.2-21.2,13-36.5,13H73.5c-19.6,0-36.5-16.3-36.5-38c0-21.7,16.3-33.6,33.2-33.6H122c15.2,0,25-4.3,33.7-13L389.3,90 c9.8-9.8,19.1-10.9,35.4-10.9h80c19.6,0,32.7,21.7,32.7,34.7C537.9,126.4,528.6,150.8,504.7,150.8z\" />\n </svg>`,\n\n ATM: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 577.8 577\">\n <path fill=\"#444444\" d=\"M388.7,314c-3.7-10.3-10.3-19.8-17.7-27.2c-7.4-7.4-17.7-14-29.5-19.1c-6.6-2.9-19.2-6.6-39.1-11.8V144.2 c13.3,2.2,22.8,8.1,30.2,16.2c7.4,8.1,11.8,19.9,14,35.3l39.8-5.9c-2.9-24.3-13.3-44.1-30.2-58.1c-13.3-11-31-17.7-53.8-19.8V93.4 h-24.3v18.4c-25.8,2.2-45,9.6-58.2,21.3c-19.9,17.7-29.5,39.7-29.5,67.6c0,15.5,3.7,29.4,10.3,41.9s16.2,22,28.7,28.7 c17,9.6,33.2,16.2,49.4,20.6v121.3c-14.8-1.5-28-8.8-39.1-22.8c-7.4-9.6-13.3-25-16.2-46.3l-39.1,7.4c1.5,20.6,6.6,37.5,15.5,51.5 s19.9,23.5,31.7,30.1c12.5,6.6,28,11,47.9,13.2v39v-0.1V483h22.1v-39c28-0.7,50.1-11,67.1-28.7c17-18.4,25.8-40.4,25.8-67.6 C394.6,336,392.4,324.3,388.7,314z M278.9,145.1v107.2c-17.7-5.2-30.2-11.8-37.6-20.6s-11.1-19.8-11.1-33.1c0-14,4.4-25.7,13.3-35.3 C252.2,153.9,263.7,147.4,278.9,145.1V145h0.7C279.3,145,279.1,145,278.9,145.1z M340,394.2c-9.6,11-22.1,18.4-37.6,19.8l0,0V297.9 c20.6,5.2,34.6,11.8,42,20.6c6.6,8.1,10.3,19.8,10.3,33.8C354.8,369.2,349.6,383.1,340,394.2z\" />\n <path fill=\"#444444\" d=\"M289.8,2.5c-158.7,0-288,128-288,287.2c0,158.3,129.3,287.2,288,287.2s288-128.9,288-287.2S448.6,2.5,289.8,2.5z M289.9,533.9C155,533.9,45.2,424.3,45.2,289.8C45.2,154.5,155,45.7,289.9,45.7s244.7,109.5,244.7,244.1S424.8,533.9,289.9,533.9z\" />\n </svg>`,\n\n Management: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 414.6\">\n <path fill=\"#444444\" d=\"M371.6,180.4c66.8,0,101,58.5,121.4,121.9l16.4,50.4c2.7,8.8-7.5,16.3-16.4,16.3h-56.6l-7.5-27.2 c-17.7-53.1-45-106.2-94.8-125.9c13-8.8,23.9-21.1,30.7-35.4C366.1,180.4,368.8,180.4,371.6,180.4z M441.2,145.7 c64.8,2,98.2,59.2,118.7,121.9l15.7,49.7c2.7,8.8-7.5,17.7-16.4,17.7h-35.5l-12.3-38.1c-16.4-53.1-44.3-106.2-94.8-125.9 C426.2,162.7,434.3,155.2,441.2,145.7z M51.6,334.3H16.8c-9.6,0-19.1-8.2-16.4-17.7l15.7-49.7C35.9,204.2,70.1,147.1,134.9,145 c6.1,9.5,15,18.4,24.6,24.5c-49.8,19.7-77.8,72.8-94.8,125.9L51.6,334.3L51.6,334.3z M437.7,0c35.5,0,64.8,28.6,64.8,64.7 c0,31.3-22.5,57.2-52.5,62.6c3.4-8.8,5.5-18.4,5.5-27.9c0-39.5-27.3-71.5-62.8-81C403.6,6.8,419.3,0,437.7,0L437.7,0z M137.6,0 c17.7,0,34.1,6.8,45,18.4c-35.5,9.5-62.8,41.5-62.8,81c0,9.5,2.1,19.1,5.5,27.9C96,121.9,72.8,96,72.8,64.7 C73.5,28.6,102.1,0,137.6,0L137.6,0z M287.7,0c19.8,0,37.5,8.8,49.8,22.5c-15.7,6.8-29.3,19.1-38.2,34l-3.4,5.5c-2.7,0-5.5,0-7.5,0 c-2,0-6.1,0-8.9,0l-3.4-5.5c-9.6-15-22.5-27.2-38.2-34C250.2,8.9,267.9,0,287.7,0L287.7,0z M287.7,226c66.8,0,101,58.5,122.1,121.9 l15.7,50.4c2.7,8.8-8.2,16.3-16.4,16.3H166.2c-9.6,0-19.8-8.2-16.4-16.3l15.7-50.4C186,284.6,220.8,226,287.7,226z M287.7,81 c35.5,0,64.8,28.6,64.8,64.7s-28.7,64.7-64.8,64.7c-35.5,0-64.8-28.6-64.8-64.7S252.2,81,287.7,81z M138.3,369H82.3 c-9.6,0-19.1-8.2-16.4-16.3l15.7-50.4c21.1-63.3,55.3-121.9,122.1-121.9c2.7,0,5.5,0,7.5,0c6.1,15,17.7,27.2,30.7,35.4 c-49.8,19.7-78.5,72.8-94.8,125.9C147.1,341.8,138.3,369,138.3,369z M203.8,34.7c23.9,0,44.3,12.9,55.9,31.3 c-32.1,12.2-55.9,42.9-55.9,79c0,6.1,0.7,12.2,2.1,18.4h-2.1c-35.5,0-64.8-28.6-64.8-64.7S168.3,34.7,203.8,34.7z M371.6,34.7 c35.5,0,64.8,28.6,64.8,64.7s-29.3,64-64.8,64h-2.7c2.1-6.1,2.7-12.2,2.7-18.4c0-36.8-23.9-66.7-55.9-79 C327.2,47.7,347,34.7,371.6,34.7z\" />\n </svg>`,\n\n PlayArea: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 537.9\">\n <path fill=\"#444444\" d=\"M384.3,137c38,0,68.8-30.7,68.8-68.5S422.3,0,384.3,0s-68.8,30.7-68.8,68.5S346.4,137,384.3,137z\" />\n <path fill=\"#444444\" d=\"M283.3,96c20,26.3,35.9,53.3,67.6,64.4c31.2,11.1,60.5,11.1,83.5-5.3c22.9-16.4,34.7-46.8,54.1-87.2 c18.8-40.4,34.1-48,57-48c23.5,0,31.2,28.1,30.6,39.8s-10.6,31-40,52.7c-49.4,36.3-57.6,108.3-59.4,127.7 c-1.8,19.3-2.9,50.4,17.6,169.2c20.6,118.9-20,125.9-25.3,127.1c-5.3,0.6-21.2,8.2-31.1-16.4c-10-24.6-11.8-91.3-14.1-120 c-2.9-28.7-6.5-70.9-35.9-79c-30-8.2-40.6,39.8-51.7,76.1c-10.6,36.9-40,71.4-72.3,59.1s-29.4-50.4-10-78.5 c19.4-27.5,61.7-57.4,67.6-124.1c5.9-66.8-11.8-69.1-68.2-90.8c-55.8-22.3-60.5-33.4-67.6-48.6s7.6-46.8,31.1-52.7 C239.2,55.1,259.1,63.9,283.3,96L283.3,96z\" />\n <path fill=\"#444444\" d=\"M134.7,251.7c26.9,0,48.8-21.8,48.8-48.6s-21.8-48.6-48.8-48.6s-48.8,21.8-48.8,48.6S107.7,251.7,134.7,251.7z\" />\n <path fill=\"#444444\" d=\"M204,227.8c-15.3,17.6-28.2,35.7-51.1,41.6c-22.9,6.4-43.5,4.7-58.8-8.2c-15.3-12.9-21.7-35.1-32.9-64.4S40,161,23.5,159.8 C7.1,158.7,0,178,0,186.2c-0.6,8.2,5.9,22.3,25.3,39.2C58.2,253.5,60,305.1,60,318.5c0.6,13.5-0.6,35.7-21.7,118.3 s7.1,89.6,10.6,90.8s14.7,7,22.9-10s12.9-63.8,16.5-83.7c3.5-19.9,8.2-49.8,29.4-53.9s26.5,30.4,32.3,56.8 c5.9,26.3,24.7,52.7,47.6,45.7c22.9-7,23.5-34,11.2-54.4c-12.3-20.5-40-43.9-40.6-90.8c-0.6-47.4,12.3-48,52.9-60.3 c40.6-12.3,44.7-20.5,50.5-30.4c5.9-10-2.9-33.4-18.8-38.6C237.5,201.4,222.8,206.7,204,227.8L204,227.8z\" />\n </svg>`,\n\n RestRoom: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 533.9\">\n <path fill=\"#444444\" d=\"M282.3,533.9h9.2V0h-9.2V533.9z\" />\n <path fill=\"#444444\" d=\"M118.2,97.1c25.4-4.6,41.6-30.1,34.7-55.5C146,16.2,122.9,2.3,97.4,6.9S58.1,39.3,62.8,62.4S95.1,104,118.2,97.1z\" />\n <path fill=\"#444444\" d=\"M159.8,145.6h4.6c0,0,2.3,0,2.3,2.3L183,270.4c2.3,9.2,9.2,16.2,18.5,16.2c11.6,0,18.5-9.2,18.5-20.8l-18.5-129.4 c-2.3-13.9-13.9-23.1-27.7-23.1H44.3c-13.9,0-25.4,9.2-27.7,23.1L0.4,265.8c-2.3,11.6,6.9,20.8,18.5,20.8c9.2,0,16.2-6.9,18.5-16.2 l16.2-122.5c0,0,0-2.3,2.3-2.3h4.6c0,0,2.3,0,2.3,2.3L30.4,390.6c0,0,0,2.3,2.3,2.3h37c0,0,2.3,0,2.3,2.3v117.9 c0,9.2,6.9,16.2,16.2,16.2s16.2-6.9,16.2-16.2V393c0,0,0-2.3,2.3-2.3h11.6c0,0,2.3,0,2.3,2.3v117.9c0,9.2,6.9,16.2,16.2,16.2 c9.2,0,16.2-6.9,16.2-16.2V393c0,0,0-2.3,2.3-2.3h30.1c0,0,2.3,0,2.3-2.3l-27.7-242.7l0,0l0,0L159.8,145.6z\" />\n <path fill=\"#444444\" d=\"M497.3,76.3c13.9-23.1,4.6-50.9-16.2-62.4s-50.9-6.9-64.7,16.2c-13.9,23.1-4.6,50.9,16.2,62.4 C455.7,106.3,483.5,99.4,497.3,76.3z\" />\n <path fill=\"#444444\" d=\"M545.9,113.3h-178c-13.9,0-25.4,9.2-27.7,23.1v129.4c0,11.6,9.2,20.8,20.8,20.8s18.5-9.2,18.5-20.8V159.5c0,0,0-2.3,2.3-2.3 h2.3c0,0,2.3,0,2.3,2.3l25.4,161.8v187.2c0,11.6,9.2,20.8,20.8,20.8l0,0c11.6,0,20.8-9.2,20.8-20.8V323.6c0,0,0-2.3,2.3-2.3h6.9 c0,0,2.3,0,2.3,2.3v184.9c0,11.6,9.2,20.8,20.8,20.8l0,0c11.6,0,20.8-9.2,20.8-20.8V321.3l25.4-161.8c0,0,0-2.3,2.3-2.3h-2.3 c0,0,2.3,0,2.3,2.3v106.3c0,11.6,9.2,20.8,20.8,20.8s20.8-9.2,20.8-20.8V136.4C571.4,122.5,559.8,113.3,545.9,113.3L545.9,113.3 L545.9,113.3z\" />\n </svg>`,\n\n FamilyRestRoom: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 522.5\">\n <path fill=\"#444444\" d=\"M119.8,91.5c25-5.9,40.5-30.8,34.6-55.7c-5.9-24.9-30.9-40.4-55.9-34.5S58,32,63.9,56.9S94.8,97.3,119.8,91.5z\" />\n <path fill=\"#444444\" d=\"M160.6,139.1h4.5c0.6,0,1.3,0.6,1.3,1.3l15.3,123.1c1.3,8.9,8.9,15.9,17.8,15.9c10.8,0,19.1-9.5,17.8-20.3l-15.9-128.9 c-1.9-13.3-13.4-24.1-27.4-24.1H43.4c-14,0-25.5,10.2-27.4,24.1L0.1,259.1c-1.3,10.8,7,20.3,17.8,20.3c8.9,0,16.5-7,17.8-15.9 l15.3-123.8c0-0.6,0.6-1.3,1.3-1.3h4.5c0.6,0,1.3,0.6,1.3,1.3L29.4,384.1c0,0.6,0.6,1.3,1.3,1.3H67c0.6,0,1.3,0.6,1.3,1.3v118.1 c0,9.5,7.6,16.5,16.5,16.5c9.5,0,16.5-7.6,16.5-16.5V387.3c0-0.6,0.6-1.3,1.3-1.3h10.8c0.6,0,1.3,0.6,1.3,1.3v118.1 c0,9.5,7.6,16.5,16.5,16.5c9.5,0,16.5-7.6,16.5-16.5V387.3c0-0.6,0.6-1.3,1.3-1.3h36.3c0.6,0,1.3-0.6,1.3-1.3L158,140.3 C159.3,139.7,159.9,139.1,160.6,139.1L160.6,139.1z\" />\n <path fill=\"#444444\" d=\"M498.9,69.8c12.9-22.1,5.4-50.5-16.8-63.4c-22.2-12.9-50.6-5.4-63.6,16.7c-12.9,22.1-5.4,50.5,16.8,63.4 C457.5,99.4,486,91.9,498.9,69.8z\" />\n <path fill=\"#444444\" d=\"M547.9,106.1H369.6c-14,0-25.5,10.2-27.4,24.1v128.9c0,10.8,8.9,19.7,19.7,19.7s19.7-8.9,19.7-19.7v-106 c0-0.6,0.6-1.3,1.3-1.3h2.5c0.6,0,1.3,0.6,1.3,1.3l25.5,162.5v187.3c0,10.8,8.9,19.7,19.7,19.7h0.6c10.8,0,19.7-8.9,19.7-19.7v-186 c0-0.6,0.6-1.3,1.3-1.3h10.8c0.6,0,1.3,0.6,1.3,1.3v186c0,10.8,8.9,19.7,19.7,19.7h0.6c10.8,0,19.7-8.9,19.7-19.7V315.6l25.5-162.5 c0-0.6,0.6-1.3,1.3-1.3h2.6c0.6,0,1.3,0.6,1.3,1.3v106c0,10.8,8.9,19.7,19.7,19.7s19.7-8.9,19.7-19.7V130.2 C573.4,116.2,562,106.1,547.9,106.1L547.9,106.1z\" />\n <path fill=\"#444444\" d=\"M259.6,480l19.7-19.7L251.9,433L229,455.8c-7.6,7.6-5.7,20.3,1.3,27.3l32.5,33.6c12.7,12.7,29.3-5.1,17.2-17.1L259.6,480 L259.6,480z M288.9,347.9c19.1,0,34.4-15.2,34.4-34.3s-15.3-34.3-34.4-34.3s-34.4,15.2-34.4,34.3S269.7,347.9,288.9,347.9z M369.7,405.7l-46.5-46.3c-3.8-3.8-8.3-6.3-14.7-6.3h-41.4c-6.4,0-10.8,2.5-14,6.3l-45.9,45.7c-12.7,12.7,4.5,28.6,17.2,15.9 l28-27.9v26h72.6v-26l28.6,28.6C364.6,433.6,381.8,417.1,369.7,405.7L369.7,405.7z M324.5,433l-27.4,27.3l19.7,19.7l-20.4,20.3 c-12.1,12.1,4.5,29.2,17.2,17.1l32.5-33.6c7-7,8.9-20.3,1.3-27.3C347.4,455.9,324.5,433,324.5,433z\" />\n </svg>`,\n\n Elevator: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 576\">\n <path fill=\"#444444\" d=\"M576,145.2v268.6c-0.1,1.6-0.3,3.1-0.3,4.7c-0.3,33.3-0.6,66.6-0.8,99.9c-0.1,21.1-9.7,37.2-26.7,49 c-7.7,5.4-15.9,9.3-25.9,8c-3.8-0.5-7.7-0.1-11.5-0.1c-115.3,0.1-230.6,0.2-345.9,0.3c-1.1,0-2.2,0.2-3.3,0.3h-16.9 c-1.2-0.1-2.4-0.3-3.6-0.3c-30.2-0.3-60.4-0.6-90.7-0.8c-11.1-0.1-20.7-4.1-29.1-11.2c-8.7-7.4-15.5-16.7-19.9-27.3l-0.2-0.5 c-0.7-1.6-1.1-3.4-1.2-5.4v0C0,492.8,0,455.1,0,417.4c0-124.1,0-248.1,0-372.2c0-0.2,0-0.3,0-0.5c0-1.5,0.3-2.9,0.7-4.2l0,0.1 C8.3,22.5,20.5,8.9,38.7,1c1.2-0.5,2.6-0.9,4-0.9h0c162.8,0,325.6,0,488.4,0c1.5,0,2.8,0.4,4.1,0.9l-0.1,0c3.4,1.4,6.1,2.7,8.8,4.2 l-0.4-0.2c19.7,11.2,30.9,27.8,31.3,50.8c0.4,28.2,0.6,56.3,0.8,84.5C575.7,141.8,575.8,143.5,576,145.2L576,145.2z M536.4,288.6 h0.3c0-56.7,0-113.4,0-170c0-18.2-0.4-36.4-0.7-54.6c-0.1-8-8.4-19.8-15.9-22.7c-1-0.4-2.1-0.6-3.2-0.7h0c-3.2-0.3-6.4-0.6-9.5-0.6 c-25.5-0.4-51-0.9-76.6-1c-96.4-0.2-192.7-0.4-289.1-0.4c-22.9,0-45.8,0.1-68.7,0.3c-3.4,0-6.8,0.1-10,0.9 c-9.9,2.3-17.1,8.3-21.7,17.3c-1,1.9-2,3.9-2.1,5.9c-0.1,149.8-0.1,299.6-0.1,449.4c0,0.9-0.1,2,0.3,2.7c2.7,4.2,5.1,8.6,8.3,12.3 c5.6,6.3,13.2,8.4,21.6,8.4c23.7,0.1,47.5,0.6,71.2,0.6c123.5,0,247,0,370.5,0c0.1,0,0.2,0,0.3,0c1.1,0,2.1-0.2,3-0.6l-0.1,0 c8.3-3.5,15.4-8.4,20.2-16.3c1.2-1.8,2-4.1,2-6.5l0,0C536.4,438.2,536.4,363.4,536.4,288.6L536.4,288.6z\" />\n <path fill=\"#444444\" d=\"M307,277.5l75.9,68.4l0.9-0.2V150.9h49.7v194.8l1,0.3l78.2-67.4c0.1,1,0.2,1.7,0.3,2.4c0.3,19.9,0.6,39.8,0.8,59.7 c0,0,0,0,0,0.1c0,1.4-0.5,2.6-1.4,3.6l0,0c-34.1,32.7-68.2,65.3-102.3,97.9c-0.3,0.3-0.6,0.5-1,0.9c-0.6-0.5-1.3-1-1.9-1.5 c-32.7-30.7-65.5-61.4-98.2-92c-1.4-1.2-2.3-3-2.3-5c0-0.1,0-0.3,0-0.4v0c0.2-20.9,0.3-41.9,0.4-62.8C307,280.5,307,279.4,307,277.5 L307,277.5z\" />\n <path fill=\"#444444\" d=\"M142.2,234.5L67,301.8c-0.1-1.2-0.3-1.9-0.3-2.7c-0.3-20.7-0.7-41.5-1-62.2c0-1.3,0.5-2.5,1.3-3.4l0,0 c33.3-31.4,66.7-62.8,100.1-94.1c0.3-0.3,0.6-0.5,1-0.8c5.9,5.7,11.8,11.3,17.7,16.9c28.1,26.9,56.2,53.9,84.3,80.9 c0.9,0.8,1.4,2,1.5,3.3v0c-0.5,20.2-1.1,40.3-1.6,60.5c0,0.3-0.1,0.7-0.2,1.7l-77.4-67.1l-0.9,0.1v193.9h-48.3v-194L142.2,234.5z\" />\n </svg>`,\n\n Security: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 576 597.6\">\n <path fill=\"#444444\" d=\"M554,80.7L298.5,1.5c-6.6-2-13.2-2-19.9,0L23.2,80.7C9.3,84.7,0,97.9,0,112.4c0,352.5,178.7,436.4,274,481.9 c4.6,2,9.3,3.3,13.9,3.3c4.6,0,9.9-1.3,13.9-3.3c96-45.5,274-129.4,274-481.9C577.2,97.9,567.9,85.3,554,80.7z M288.6,527.6 C197.2,484.1,73.5,411.4,66.2,136.2l222.4-68.6L511,136.8C503.7,412.1,379.3,484.1,288.6,527.6z\" />\n <path fill=\"#444444\" d=\"M278.7,152l-26.5,87.1l-90.7-2.6c-4.6,0-8.6,2.6-9.9,7.3c-1.3,4.6,0,9.2,4,11.9l74.8,51.5L200.6,393c-1.3,4.6,0,9.2,4,11.9 c4,2.6,8.6,2.6,12.6,0l72.1-54.8l72.1,54.8c4,2.6,8.6,2.6,12.6,0c4-2.6,5.3-7.3,4-11.9l-29.8-85.8l74.8-51.5c4-2.6,5.3-7.3,4-11.9 c-1.3-4.6-5.3-7.3-9.9-7.3l-90.7,2l-26.5-87.1c-1.3-4.6-5.3-7.3-9.9-7.3C283.9,144.1,280,147.4,278.7,152L278.7,152z\" />\n </svg>`,\n\n ChildStroller: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 432 370.06\">\n <path fill=\"#444444\" d=\"M130.29,178.61l-42.67,34L33.24,254.13c-15.48,12.09-28.32-2.64-28.32-2.64-12.08-15.86,1.89-26.06,1.89-26.06l68-53.24s7.55-7.93,26.81-2.26l28.7,8.68\"/>\n <path fill=\"#444444\" d=\"M210,111A38.52,38.52,0,1,1,248.48,72.5,38.68,38.68,0,0,1,210,111\"/>\n <path fill=\"#444444\" d=\"M390.84,0a42.88,42.88,0,0,0-24.92,8.31L80.44,235.63a43.71,43.71,0,0,0-13.59,22.28,40.67,40.67,0,0,0,1.89,23.41,47.9,47.9,0,0,0-22.28,41.16A47.58,47.58,0,1,0,94,274.9,41.43,41.43,0,0,0,84.22,276a22.77,22.77,0,0,1-1.51-14.35,25.82,25.82,0,0,1,8.68-13.59l17.37-14,88,29.08a33.54,33.54,0,0,0,42.67-21.53l1.51-4.91,18.88,45.32a47.09,47.09,0,0,0-22.28,40.4,47.58,47.58,0,1,0,47.58-47.58,41.43,41.43,0,0,0-9.82,1.13l-26.43-62.68,43.8-126.12,83.08-66.08a23.7,23.7,0,0,1,15.1-5.29,25.3,25.3,0,0,1,25.3,25.3,25.72,25.72,0,0,1-10.2,20.39,8,8,0,0,0,10.58,12.08A41.37,41.37,0,0,0,390.84,0ZM93.66,301.33A20.77,20.77,0,1,1,72.89,322.1,20.71,20.71,0,0,1,93.66,301.33Zm191.07,0A20.77,20.77,0,1,1,264,322.1,20.71,20.71,0,0,1,284.73,301.33Z\"/>\n </svg>`,\n\n VendingMachine: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 594\">\n <circle fill=\"#444444\" cx=\"324\" cy=\"175.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"175.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"324\" cy=\"243\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"243\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"324\" cy=\"310.5\" r=\"13.5\"/>\n <circle fill=\"#444444\" cx=\"364.5\" cy=\"310.5\" r=\"13.5\"/>\n <path fill=\"#444444\" d=\"M216,94.5H67.5C59.4,94.5,54,99.9,54,108c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,99.9,224.1,94.5,216,94.5z\"/>\n <path fill=\"#444444\" d=\"M216,162H67.5c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,167.4,224.1,162,216,162z\"/>\n <path fill=\"#444444\" d=\"M216,229.5H67.5c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5 C229.5,234.9,224.1,229.5,216,229.5z\"/>\n <path fill=\"#444444\" d=\"M216,297H67.5c-8.1,0-13.5,5.4-13.5,13.5S59.4,324,67.5,324H216c8.1,0,13.5-5.4,13.5-13.5S224.1,297,216,297z\"/>\n <path fill=\"#444444\" d=\"M391.5,0H324c-8.1,0-13.5,5.4-13.5,13.5S315.9,27,324,27h67.5c8.1,0,13.5,5.4,13.5,13.5V567H27V40.5 C27,32.4,32.4,27,40.5,27h216v499.5c0,8.1,5.4,13.5,13.5,13.5s13.5-5.4,13.5-13.5v-513C283.5,5.4,278.1,0,270,0H40.5 C17.5,0,0,17.5,0,40.5v540c0,8.1,5.4,13.5,13.5,13.5h405c8.1,0,13.5-5.4,13.5-13.5v-540C432,17.5,414.5,0,391.5,0z\"/>\n <path fill=\"#444444\" d=\"M364.5,94.5H324c-8.1,0-13.5,5.4-13.5,13.5c0,8.1,5.4,13.5,13.5,13.5h40.5c8.1,0,13.5-5.4,13.5-13.5 C378,99.9,372.6,94.5,364.5,94.5z\"/>\n <path fill=\"#444444\" d=\"M216,432H67.5c-8.1,0-13.5,5.4-13.5,13.5V513c0,8.1,5.4,13.5,13.5,13.5H216c8.1,0,13.5-5.4,13.5-13.5v-67.5 C229.5,437.4,224.1,432,216,432z M81,499.5V459h121.5v40.5H81z\"/>\n </svg>`,\n\n Stairs: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 448.5\">\n <path fill=\"#444444\" d=\"M432,243.3h-81.7v33.1h-72.2v33.1h-72.2v33.1h-72.2v33.1H61.5v33.1H0v39.7h101.2v-33.1h72.2v-33.1h72.2v-33.1h72.2v-33.1 h72.2V283H432L432,243.3\"/>\n <path fill=\"#444444\" d=\"M99.9,109.3c12,0,21.8-9.7,21.8-21.8c0-12-9.8-21.8-21.8-21.8c-12,0-21.8,9.7-21.8,21.8C78.1,99.6,87.9,109.3,99.9,109.3\"/>\n <path fill=\"#444444\" d=\"M179.4,299.8l-56.5-47.4l11.7-82.9c12.5,14.8,20.7,33.4,22.7,53.8l17.8-4.8c-0.9-32.2-14.2-61.3-35.3-82.6 c-14.4-14.5-32.9-19.2-45.9-20.6c-0.1,0-0.2,0-0.3,0c-1.6,0-2.9,1.2-3.2,2.7c-6.5,34.7-27.7,64.2-56.9,81.9l9.3,16.1 c15.6-6.6,29.5-16.4,40.9-28.6v177.3H107l10.4-73.7l57.7,33.3L179.4,299.8\"/>\n <path fill=\"#444444\" d=\"M294.1,43.6c12,0,21.8-9.8,21.8-21.8c0-12-9.8-21.8-21.8-21.8c-12,0-21.8,9.8-21.8,21.8C272.3,33.8,282.1,43.6,294.1,43.6\" />\n <path fill=\"#444444\" d=\"M337.2,154.3l-41.8-24.1l3.9-20c1.4-7.5,2.2-15.2,2.2-23.1c0-12-1.8-23.7-5-34.6c-0.4-1.4-1.7-2.4-3.1-2.4c0,0-0.1,0-0.1,0 c-46.7,1.6-84.1,40-84.1,87.1c0,2.3,0.1,4.6,0.3,6.9l18.3,3.2c0-0.5,0-0.9,0-1.4c0-19.5,8.6-36.9,22.3-48.7l-10.5,201.1h23.3 l24.9-128l23,10.7L294.9,240l16.6,16.6l34.6-74.3c1.3-2.8,2-5.9,2-9.2C348.1,165.1,343.8,158,337.2,154.3\"/>\n </svg>`,\n\n ChargingStation: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 627.4\">\n <polygon fill=\"#444444\" points=\"314.4,282.1 133.8,467.8 188.6,334.2 114.9,334.2 225.6,148.6 314.4,148.6 236.7,282.1 \"/>\n <path fill=\"#444444\" d=\"M374.2,0H63.3C28.4,0.1,0.1,28.4,0,63.3v503.6c0,32.8,30.1,60.5,62.6,60.5h309.2c33.3,0,60.3-27,60.3-60.3V374.2l0,0V57.8 C432,25.9,406.1,0,374.2,0z M220.3,600.4c-8.3,0.2-15.2-6.4-15.4-14.7c0-0.2,0-0.5,0-0.7c0.1-8.5,6.9-15.3,15.4-15.4 c8.3-0.2,15.2,6.4,15.4,14.7c0,0.2,0,0.5,0,0.7C235.4,593.8,229.1,600.4,220.3,600.4z M391.1,544.8H44v-465h346.7v294.4l0.4,55 V544.8z\"/>\n </svg>`,\n\n WheelChair: `<svg xmlns=\"http://www.w3.org/2000/svg\" x=\"0px\" y=\"0px\" viewBox=\"0 0 432 492.2\">\n <path fill=\"#444444\" d=\"M134.7,80.1l9.5,103h104.6v33.3H146.6l3.2,30.9h147.4l66.6,157l56.3-23.8l11.9,27l-84,36.4l-69.7-163.3H118.9l-19-221.9 c-3.2-5.5-4.7-11.9-4.7-18.2C95.1,18.2,112.5,0,134.7,0c22.2,0,40.4,18.2,40.4,40.4C175.2,61.8,156.9,80.1,134.7,80.1L134.7,80.1z\" />\n <path fill=\"#444444\" d=\"M306.7,397.1c-25.3,56.3-81.6,95.1-146.6,95.1C72.1,492.2,0,420.9,0,332.1C0,268.7,37.2,214,91.1,187.9l3.2,36.5 c-36.5,22.2-61,61.8-61,107.8c0,69.8,57.1,126.8,126.8,126.8c65,0,118.1-48.3,126-110.2L306.7,397.1\"/>\n </svg>`,\n\n};\n\nexport default SVGIcons;","import SVGIcons from \"./svgIcons.helper\";\n\nexport type MapAmenityID = 'atm' | 'management' | 'playarea' | 'restroom' | 'family-restroom' | 'elevator' | 'escalator' | 'security' | 'dog-poop-station' | 'child-stroller' | 'vending-machine' | 'stairs' | 'charging-station' | 'wheelchair';\n\nexport interface MapAmenity {\n name: string;\n type: MapAmenityID;\n svgCode: string;\n}\n\nexport const AllAmenities: MapAmenity[] = [\n {\n name: \"ATM\",\n type: \"atm\",\n svgCode: SVGIcons.ATM\n },\n {\n name: \"Management\",\n type: \"management\",\n svgCode: SVGIcons.Management\n },\n {\n name: \"Kids Area\",\n type: \"playarea\",\n svgCode: SVGIcons.PlayArea\n },\n {\n name: \"Restroom\",\n type: \"restroom\",\n svgCode: SVGIcons.RestRoom\n },\n {\n name: \"Family Restroom\",\n type: \"family-restroom\",\n svgCode: SVGIcons.FamilyRestRoom\n },\n {\n name: \"Elevator\",\n type: \"elevator\",\n svgCode: SVGIcons.Elevator\n },\n {\n name: \"Security\",\n type: \"security\",\n svgCode: SVGIcons.Security\n },\n {\n name: \"Escalator\",\n type: \"escalator\",\n svgCode: SVGIcons.Escalator\n },\n {\n name: 'Child Stroller',\n type: 'child-stroller',\n svgCode: SVGIcons.ChildStroller\n },\n {\n name: 'Vending Machine',\n type: 'vending-machine',\n svgCode: SVGIcons.VendingMachine\n },\n {\n name: 'Stairs',\n type: 'stairs',\n svgCode: SVGIcons.Stairs\n },\n {\n name: 'Charging Station',\n type: 'charging-station',\n svgCode: SVGIcons.ChargingStation\n },\n {\n name: 'Wheelchair',\n type: 'wheelchair',\n svgCode: SVGIcons.WheelChair\n },\n];\n\n","/**\n * Lightweight amenity + kiosk icon catalog for every EyeOn surface.\n * Import from `@eyeon/threejs-map/amenities` (or `@eyeon/threejs-map`) —\n * do not copy these SVGs into other packages.\n */\nimport SVGIcons from './helpers/svgIcons.helper';\nimport {\n AllAmenities,\n type MapAmenity,\n type MapAmenityID,\n} from './helpers/amenities.helper';\n\nexport { AllAmenities };\nexport type { MapAmenity, MapAmenityID };\n\n/** Elevator / escalator are their own v1 modules, not amenity assignments. */\nconst CONNECTOR_AMENITY_TYPES = new Set<MapAmenityID>([\n 'elevator',\n 'escalator',\n]);\n\nexport const AssignAmenities: MapAmenity[] = AllAmenities.filter(\n (item) => !CONNECTOR_AMENITY_TYPES.has(item.type),\n);\n\nexport const KioskSvg = SVGIcons.Kiosk;\nexport const EntranceSvg = SVGIcons.Entrance;\n\nexport function isAssignAmenity(type: string): boolean {\n return AssignAmenities.some((item) => item.type === type);\n}\n\nexport function getAmenityByType(type: string): MapAmenity | undefined {\n return AssignAmenities.find((item) => item.type === type) ??\n AllAmenities.find((item) => item.type === type);\n}\n\nexport function getMapSpecialSvg(id: string): string | undefined {\n if (id === 'kiosk') return KioskSvg;\n if (id === 'entrance') return EntranceSvg;\n return getAmenityByType(id)?.svgCode;\n}\n\nexport function recolorMapSvg(svg: string, color: string): string {\n const hex = color.startsWith('#') ? color : `#${color}`;\n return svg\n .replace(/fill=\"(?!none\")[^\"]*\"/gi, `fill=\"${hex}\"`)\n .replace(/stroke=\"(?!none\")[^\"]*\"/gi, `stroke=\"${hex}\"`);\n}\n\nexport function mapSpecialSvgToDataUrl(\n svg: string,\n color?: string | null,\n): string {\n const colored = color ? recolorMapSvg(svg, color) : svg;\n return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(colored)}`;\n}\n","/**\n * v2 render helpers for amenity / kiosk icons.\n * SVG markup lives only in `@eyeon/threejs-map/amenities`.\n */\nimport {\n AllAmenities,\n AssignAmenities,\n getAmenityByType,\n getMapSpecialSvg,\n isAssignAmenity,\n mapSpecialSvgToDataUrl,\n recolorMapSvg,\n} from '@eyeon/threejs-map/amenities';\nimport type { CmAmenityCatalogItem, CmShapeAssignment } from './core';\nimport { assignmentSpecialIconId } from './core';\n\nexport {\n AllAmenities,\n AssignAmenities,\n getAmenityByType,\n isAssignAmenity,\n getMapSpecialSvg,\n mapSpecialSvgToDataUrl,\n recolorMapSvg,\n};\n\nexport function entranceIconDataUrl(color?: string | null): string | undefined {\n const svg = getMapSpecialSvg('entrance');\n if (!svg) return undefined;\n return mapSpecialSvgToDataUrl(svg, color);\n}\n\n/** v1 amenity list for the assign dropdown — elevator / escalator are separate modules. */\nexport function amenityAssignOptions(): { value: string; label: string }[] {\n return AssignAmenities.map((item) => ({\n value: item.type,\n label: item.name,\n }));\n}\n\nexport function amenityTypeFromCatalogId(\n amenityId: number | null | undefined,\n amenities: CmAmenityCatalogItem[],\n): string {\n if (amenityId == null) return '';\n return amenities.find((item) => item.id === amenityId)?.code ?? '';\n}\n\nexport function amenityCatalogIdForType(\n type: string,\n amenities: CmAmenityCatalogItem[],\n): number | null {\n const row = amenities.find(\n (item) => item.isActive !== false && item.code === type,\n );\n return row?.id ?? null;\n}\n\nexport function assignmentSpecialIconDataUrl(\n assignment: CmShapeAssignment | null | undefined,\n amenities: Array<{ id: number; code: string }>,\n color?: string | null,\n): string | undefined {\n const id = assignmentSpecialIconId(assignment, amenities);\n if (!id) return undefined;\n const svg = getMapSpecialSvg(id);\n if (!svg) return undefined;\n return mapSpecialSvgToDataUrl(svg, color);\n}\n\nexport type ConnectorSpecialKind = 'escalator' | 'elevator';\n\nconst ASSIGNED_CONNECTOR_ICON = '#0763b1';\nconst UNASSIGNED_CONNECTOR_ICON = '#94a3b8';\n\n/** Escalator / elevator SVG ids from the floor file (`escalator-5-up-start`). */\nexport function connectorSpecialKind(shape: {\n key: string;\n sourceSvgId?: string | null;\n}): ConnectorSpecialKind | null {\n const raw = (shape.sourceSvgId ?? shape.key)\n .trim()\n .toLowerCase()\n .replace(/_/g, '-');\n if (raw === 'escalator' || raw.startsWith('escalator-')) return 'escalator';\n if (raw === 'elevator' || raw.startsWith('elevator-')) return 'elevator';\n return null;\n}\n\nexport function connectorSpecialIconDataUrl(\n kind: ConnectorSpecialKind,\n assigned: boolean,\n color?: string | null,\n): string | undefined {\n const svg = getMapSpecialSvg(kind);\n if (!svg) return undefined;\n const fill = color?.trim()\n ? color.trim()\n : assigned\n ? ASSIGNED_CONNECTOR_ICON\n : UNASSIGNED_CONNECTOR_ICON;\n return mapSpecialSvgToDataUrl(svg, fill);\n}\n\n/** Landings that belong to a linked escalator ride / elevator shaft. */\nexport function assignedConnectorShapeIds(\n anchors: Array<{ shapeId?: number | null; connectorId?: number | null }>,\n): Set<number> {\n const ids = new Set<number>();\n for (const anchor of anchors) {\n if (anchor.shapeId != null && anchor.connectorId != null) {\n ids.add(anchor.shapeId);\n }\n }\n return ids;\n}\n\n/**\n * Map overlay: only a linked landing gets an icon. Unassigned escalators\n * (and elevators) stay as empty polygons so the floor is not covered in gray\n * markers.\n */\nexport function connectorMapIconKind(\n shape: {\n id: number;\n key: string;\n sourceSvgId?: string | null;\n orphanedAt?: string | Date | null;\n },\n assignedShapeIds: Set<number>,\n): ConnectorSpecialKind | null {\n if (shape.orphanedAt) return null;\n const kind = connectorSpecialKind(shape);\n if (!kind || !assignedShapeIds.has(shape.id)) return null;\n return kind;\n}\n","export default \"data:font/woff;base64,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\"","import mapFontUrl from './Montserrat-Regular.woff?url';\n\n/**\n * Troika (drei `<Text>`) cannot use CSS `font-family`; it needs a font file.\n * Latin 400 WOFF, same face as `@fontsource/montserrat` / admin-portal.\n */\nexport const MAP_FONT_URL = mapFontUrl;\n\nlet registered = false;\n\n/** Register Montserrat so SVG + canvas measurement match the 3D overlay. */\nexport function ensureMapFont(): void {\n if (registered || typeof document === 'undefined' || !('fonts' in document)) {\n return;\n }\n registered = true;\n const face = new FontFace('Montserrat', `url(${MAP_FONT_URL})`);\n void face.load().then((loaded) => {\n document.fonts.add(loaded);\n });\n}\n\nensureMapFont();\n","export interface ModernSelectOption {\n value: string;\n label: string;\n hint?: string;\n iconUrl?: string;\n iconMuted?: boolean;\n}\n\n/** Show a search field once a list is long enough to scan by eye. */\nexport const MODERN_SELECT_SEARCH_AFTER = 8;\n\nexport function filterModernSelectOptions(\n options: ModernSelectOption[],\n query: string,\n): ModernSelectOption[] {\n const q = query.trim().toLowerCase();\n if (!q) return options;\n return options.filter((o) => {\n const haystack = `${o.label} ${o.hint ?? ''}`.toLowerCase();\n return haystack.includes(q);\n });\n}\n\nexport function modernSelectIsSearchable(\n optionCount: number,\n searchable?: boolean,\n): boolean {\n return searchable ?? optionCount >= MODERN_SELECT_SEARCH_AFTER;\n}\n","import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport './modern-select.css';\nimport {\n filterModernSelectOptions,\n modernSelectIsSearchable,\n type ModernSelectOption,\n} from './selectSearch';\n\nexport type { ModernSelectOption } from './selectSearch';\nexport { filterModernSelectOptions } from './selectSearch';\n\nfunction Chevron() {\n return (\n <svg\n className=\"eyeon-map-select__chevron\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n aria-hidden\n >\n <path\n d=\"M2.5 4.5 6 8l3.5-3.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nexport function ModernSelect({\n value,\n options,\n onChange,\n disabled = false,\n placeholder = 'Select…',\n searchable,\n ariaLabel,\n}: {\n value: string;\n options: ModernSelectOption[];\n onChange: (value: string) => void;\n disabled?: boolean;\n placeholder?: string;\n searchable?: boolean;\n ariaLabel?: string;\n}) {\n const listId = useId();\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const [menuPos, setMenuPos] = useState<{\n top: number;\n left: number;\n width: number;\n maxHeight: number;\n } | null>(null);\n\n const withSearch = modernSelectIsSearchable(options.length, searchable);\n const selected = options.find((o) => o.value === value);\n const filtered = useMemo(\n () => filterModernSelectOptions(options, withSearch && open ? query : ''),\n [open, options, query, withSearch],\n );\n\n const close = useCallback(() => {\n setOpen(false);\n setQuery('');\n setActiveIndex(0);\n }, []);\n\n const pick = useCallback(\n (next: string) => {\n onChange(next);\n close();\n },\n [close, onChange],\n );\n\n const updateMenuPos = useCallback(() => {\n const el = triggerRef.current ?? buttonRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom - 8;\n const spaceAbove = rect.top - 8;\n const maxHeight = Math.min(280, Math.max(spaceBelow, spaceAbove, 120));\n const openAbove = spaceBelow < 160 && spaceAbove > spaceBelow;\n setMenuPos({\n top: openAbove ? Math.max(8, rect.top - maxHeight - 4) : rect.bottom + 4,\n left: rect.left,\n width: Math.max(rect.width, 160),\n maxHeight,\n });\n }, []);\n\n useEffect(() => {\n if (!open) {\n setMenuPos(null);\n return;\n }\n updateMenuPos();\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (rootRef.current?.contains(t) || menuRef.current?.contains(t)) return;\n close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n close();\n (withSearch ? searchRef.current : buttonRef.current)?.blur();\n }\n };\n const onMove = () => updateMenuPos();\n document.addEventListener('mousedown', onDoc);\n document.addEventListener('keydown', onKey);\n window.addEventListener('resize', onMove);\n window.addEventListener('scroll', onMove, true);\n return () => {\n document.removeEventListener('mousedown', onDoc);\n document.removeEventListener('keydown', onKey);\n window.removeEventListener('resize', onMove);\n window.removeEventListener('scroll', onMove, true);\n };\n }, [close, open, updateMenuPos, withSearch]);\n\n useEffect(() => {\n if (!open || !withSearch) return;\n requestAnimationFrame(() => searchRef.current?.focus());\n }, [open, withSearch]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query, filtered.length]);\n\n const moveActive = (delta: number) => {\n if (filtered.length === 0) return;\n setActiveIndex((i) => (i + delta + filtered.length) % filtered.length);\n };\n\n const onSearchKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!open) setOpen(true);\n else moveActive(1);\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (!open) setOpen(true);\n else moveActive(-1);\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n const option = filtered[activeIndex];\n if (open && option) pick(option.value);\n else setOpen(true);\n }\n };\n\n const menu =\n open && menuPos && !disabled\n ? createPortal(\n <div\n ref={menuRef}\n id={listId}\n className=\"eyeon-map-select__menu\"\n role=\"listbox\"\n aria-label={ariaLabel}\n style={{\n top: menuPos.top,\n left: menuPos.left,\n width: menuPos.width,\n maxHeight: menuPos.maxHeight,\n }}\n >\n <ul className=\"eyeon-map-select__list\">\n {filtered.length === 0 ? (\n <li className=\"eyeon-map-select__empty\">No matches</li>\n ) : (\n filtered.map((option, index) => {\n const active = option.value === value;\n const highlighted = index === activeIndex;\n return (\n <li\n key={option.value}\n id={`${listId}-${option.value}`}\n role=\"option\"\n aria-selected={active}\n >\n <button\n type=\"button\"\n className={[\n 'eyeon-map-select__option',\n active ? 'is-active' : '',\n highlighted ? 'is-highlight' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseDown={(e) => e.preventDefault()}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => pick(option.value)}\n >\n {option.iconUrl ? (\n <img\n className={\n option.iconMuted\n ? 'eyeon-map-select__option-icon is-muted'\n : 'eyeon-map-select__option-icon'\n }\n src={option.iconUrl}\n alt=\"\"\n />\n ) : null}\n <span className=\"eyeon-map-select__option-copy\">\n <span>{option.label}</span>\n {option.hint ? (\n <span className=\"eyeon-map-select__option-hint\">\n {option.hint}\n </span>\n ) : null}\n </span>\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>,\n document.body,\n )\n : null;\n\n return (\n <div ref={rootRef} className=\"eyeon-map-select\">\n {withSearch ? (\n <div\n ref={triggerRef}\n className={\n open\n ? 'eyeon-map-select__trigger is-open'\n : 'eyeon-map-select__trigger'\n }\n onMouseDown={(e) => {\n if (disabled) return;\n const target = e.target as HTMLElement;\n if (target.closest('.eyeon-map-select__chevron-btn')) return;\n if (target !== searchRef.current) {\n e.preventDefault();\n searchRef.current?.focus();\n }\n if (!open) setOpen(true);\n }}\n >\n <input\n ref={searchRef}\n className=\"eyeon-map-select__input\"\n type=\"text\"\n role=\"combobox\"\n aria-label={ariaLabel}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={\n open && filtered[activeIndex]\n ? `${listId}-${filtered[activeIndex].value}`\n : undefined\n }\n disabled={disabled}\n placeholder={placeholder}\n value={open ? query : (selected?.label ?? '')}\n onChange={(e) => {\n setQuery(e.target.value);\n if (!open) setOpen(true);\n }}\n onFocus={() => {\n if (!disabled) setOpen(true);\n }}\n onKeyDown={onSearchKeyDown}\n />\n <button\n type=\"button\"\n className=\"eyeon-map-select__chevron-btn\"\n tabIndex={-1}\n aria-hidden\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (disabled) return;\n setOpen((v) => !v);\n }}\n >\n <Chevron />\n </button>\n </div>\n ) : (\n <button\n ref={buttonRef}\n type=\"button\"\n className=\"eyeon-map-select__trigger\"\n aria-label={ariaLabel}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n disabled={disabled}\n onClick={() => {\n if (disabled) return;\n setOpen((v) => !v);\n }}\n >\n <span\n className={\n selected\n ? 'eyeon-map-select__value'\n : 'eyeon-map-select__placeholder'\n }\n >\n {selected?.iconUrl ? (\n <img\n className={\n selected.iconMuted\n ? 'eyeon-map-select__option-icon is-muted'\n : 'eyeon-map-select__option-icon'\n }\n src={selected.iconUrl}\n alt=\"\"\n />\n ) : null}\n {selected?.label ?? placeholder}\n </span>\n <Chevron />\n </button>\n )}\n {menu}\n </div>\n );\n}\n","import * as THREE from 'three';\nimport type { Vec2 } from '../../core';\nimport { holesOverlappingOuter } from '../../core';\n\nexport function polygonToThreeShape(points: Vec2[]): THREE.Shape | null {\n if (points.length < 3) return null;\n const shape = new THREE.Shape();\n shape.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n shape.lineTo(points[i].x, points[i].y);\n }\n shape.closePath();\n return shape;\n}\n\nexport function polygonToThreePath(points: Vec2[]): THREE.Path | null {\n if (points.length < 3) return null;\n const path = new THREE.Path();\n path.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n path.lineTo(points[i].x, points[i].y);\n }\n path.closePath();\n return path;\n}\n\n/** Punch overlapping openings out of a slab polygon. */\nexport function slabShapeWithHoles(\n outer: Vec2[],\n holes: Vec2[][],\n): THREE.Shape | null {\n const shape = polygonToThreeShape(outer);\n if (!shape) return null;\n for (const hole of holesOverlappingOuter(outer, holes)) {\n const path = polygonToThreePath(hole);\n if (path) shape.holes.push(path);\n }\n return shape;\n}\n","import React, { useEffect, useMemo } from 'react';\nimport * as THREE from 'three';\nimport type { Vec2 } from '../../core';\nimport {\n OPENING_VOID_FILL,\n OPENING_VOID_MARK,\n OPENING_VOID_STROKE,\n polygonBBox,\n} from '../../core';\nimport { polygonToThreeShape } from './openingGeometry';\n\nfunction skipRaycast() {}\n\n/** X mark in bbox UV space — ShapeGeometry clips it to the opening. */\nfunction createOpeningMarkTexture(aspect: number): THREE.CanvasTexture {\n const height = 256;\n const width = Math.max(48, Math.round(height * Math.max(aspect, 0.2)));\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new THREE.CanvasTexture(canvas);\n ctx.clearRect(0, 0, width, height);\n const pad = Math.min(width, height) * 0.14;\n ctx.strokeStyle = OPENING_VOID_MARK;\n ctx.globalAlpha = 0.82;\n ctx.lineWidth = Math.max(5, Math.min(width, height) * 0.045);\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(pad, pad);\n ctx.lineTo(width - pad, height - pad);\n ctx.moveTo(width - pad, pad);\n ctx.lineTo(pad, height - pad);\n ctx.stroke();\n const texture = new THREE.CanvasTexture(canvas);\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.anisotropy = 4;\n texture.needsUpdate = true;\n return texture;\n}\n\nfunction OpeningVoidMesh({ polygon }: { polygon: Vec2[] }) {\n const shape = useMemo(() => polygonToThreeShape(polygon), [polygon]);\n const box = useMemo(() => polygonBBox(polygon), [polygon]);\n const dash = Math.max(8, openingSpanDash(box));\n const outline = useMemo(() => {\n if (polygon.length < 2) return null;\n const first = polygon[0];\n const points = [\n ...polygon.map((p) => new THREE.Vector3(p.x, p.y, 0.05)),\n new THREE.Vector3(first.x, first.y, 0.05),\n ];\n const geometry = new THREE.BufferGeometry().setFromPoints(points);\n const material = new THREE.LineDashedMaterial({\n color: OPENING_VOID_STROKE,\n dashSize: dash,\n gapSize: dash * 0.65,\n });\n const line = new THREE.Line(geometry, material);\n line.renderOrder = 8;\n line.computeLineDistances();\n line.raycast = skipRaycast;\n return line;\n }, [dash, polygon]);\n\n useEffect(\n () => () => {\n if (!outline) return;\n outline.geometry.dispose();\n const material = outline.material;\n if (Array.isArray(material)) material.forEach((item) => item.dispose());\n else material.dispose();\n },\n [outline],\n );\n const mark = useMemo(() => {\n const width = Math.max(box.maxX - box.minX, 1);\n const height = Math.max(box.maxY - box.minY, 1);\n return createOpeningMarkTexture(width / height);\n }, [box]);\n\n useEffect(() => () => mark.dispose(), [mark]);\n\n if (!shape || !outline) return null;\n\n return (\n <group>\n <mesh\n position={[0, 0, 0.02]}\n renderOrder={6}\n onClick={(e) => e.stopPropagation()}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <shapeGeometry args={[shape]} />\n <meshBasicMaterial\n color={OPENING_VOID_FILL}\n side={THREE.DoubleSide}\n depthWrite={false}\n />\n </mesh>\n <mesh position={[0, 0, 0.03]} renderOrder={7} raycast={skipRaycast}>\n <shapeGeometry args={[shape]} />\n <meshBasicMaterial\n map={mark}\n transparent\n depthWrite={false}\n side={THREE.DoubleSide}\n toneMapped={false}\n />\n </mesh>\n {outline ? <primitive object={outline} /> : null}\n </group>\n );\n}\n\nfunction openingSpanDash(bbox: {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}): number {\n const span = Math.min(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY);\n return Math.min(18, Math.max(7, span * 0.08));\n}\n\nexport function OpeningWells({\n polygons,\n}: {\n polygons: Vec2[][];\n is3d?: boolean;\n}) {\n if (polygons.length === 0) return null;\n return (\n <group>\n {polygons.map((polygon, index) => (\n <OpeningVoidMesh key={`opening-void-${index}`} polygon={polygon} />\n ))}\n </group>\n );\n}\n","import type { ShapeKind } from '../core';\n\n/** Kinds that select (or Shift-add) on the assign / public map. */\nexport const VIEWER_SELECTABLE_KINDS: ShapeKind[] = [\n 'unit',\n 'amenity',\n 'kiosk_screen',\n 'connector',\n 'entrance',\n 'parking_zone',\n];\n\nexport function isViewerSelectableKind(kind: string): boolean {\n return (VIEWER_SELECTABLE_KINDS as readonly string[]).includes(kind);\n}\n\n/** Hover and the current selection share the same assign-map highlight. */\nexport function viewerShapeHighlighted(\n shapeId: number,\n hoveredShapeId: number | null,\n selectedShapeIds: readonly number[],\n): boolean {\n return hoveredShapeId === shapeId || selectedShapeIds.includes(shapeId);\n}\n\n/** Map pointer hover wins over a leftover list hover. */\nexport function resolvedViewerHoverId(\n listHoverId: number | null | undefined,\n pointerHoverId: number | null,\n): number | null {\n return pointerHoverId ?? listHoverId ?? null;\n}\n\nexport function viewerHoverCursor(kind: string): 'pointer' | '' {\n return isViewerSelectableKind(kind) ? 'pointer' : '';\n}\n\n/** R3F `eventSource` hosts the cursor — the WebGL canvas has pointer-events: none. */\nexport function applyViewerHoverCursor(\n host: HTMLElement | null | undefined,\n cursor: 'pointer' | '',\n): void {\n if (!host) return;\n host.classList.toggle('is-hover-shape', cursor === 'pointer');\n}\n\n/** Amenities are almost invisible; hover must still read. */\nexport function viewerHoverFillOpacity(\n kind: string,\n base: number,\n hovered: boolean,\n): number {\n if (!hovered || !isViewerSelectableKind(kind)) return base;\n if (base < 0.08) return 0.28;\n return base;\n}\n\nfunction parseHex(hex: string): [number, number, number] | null {\n const h = hex.replace('#', '').trim();\n if (h.length === 3) {\n return [\n parseInt(h[0] + h[0], 16),\n parseInt(h[1] + h[1], 16),\n parseInt(h[2] + h[2], 16),\n ];\n }\n if (h.length !== 6) return null;\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return [r, g, b];\n}\n\nfunction toHex(r: number, g: number, b: number): string {\n const hex = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\n return `#${hex(r)}${hex(g)}${hex(b)}`;\n}\n\n/** Tint a store fill toward the accent so hover matches Edit Map. */\nexport function viewerHoverFillColor(\n fill: string,\n accent: string,\n hovered: boolean,\n amount = 0.2,\n): string {\n if (!hovered) return fill;\n const a = parseHex(fill);\n const b = parseHex(accent);\n if (!a || !b) return fill;\n return toHex(\n a[0] + (b[0] - a[0]) * amount,\n a[1] + (b[1] - a[1]) * amount,\n a[2] + (b[2] - a[2]) * amount,\n );\n}\n\n/** Pan farther than this and a pointer-up on empty space is not a clear. */\nexport const VIEWER_CLICK_DRAG_PX = 5;\n\nexport function pointerMissClearsSelection(\n down: { x: number; y: number } | null,\n up: { x: number; y: number; button?: number },\n): boolean {\n if ((up.button ?? 0) !== 0) return false;\n if (!down) return true;\n const dx = up.x - down.x;\n const dy = up.y - down.y;\n return dx * dx + dy * dy <= VIEWER_CLICK_DRAG_PX * VIEWER_CLICK_DRAG_PX;\n}\n","import React, { useEffect, useMemo, useState } from 'react';\nimport * as THREE from 'three';\nimport { Text } from '@react-three/drei';\nimport type {\n CmAmenityCatalogItem,\n PublishedLevel,\n ThemeDefaults,\n ShapeKind,\n} from '../../core';\nimport {\n assignmentOverlayImageUrl,\n assignmentOverlayRenderSize,\n assignmentOverlayVisible,\n connectorIconLayout,\n DEFAULT_ASSIGNMENT_SIZE,\n DEFAULT_ENTRANCE_SIZE,\n filletPolygon,\n geometryBBox,\n INTERACTIVE_SHAPE_KINDS,\n isEntranceIcon,\n isSlabShapeKind,\n isTransparentColor,\n labelAlignX,\n normalizeLabelAlign,\n resolveFetchUrl,\n resolveLayerStyle,\n resolvedAssignmentBgColor,\n voidPolygonsOnLevel,\n} from '../../core';\nimport { polygonToThreeShape, slabShapeWithHoles } from './openingGeometry';\nimport { OpeningWells } from './OpeningWell';\nimport { MAP_LABEL_LINE_HEIGHT } from '../../fonts/mapFont';\nimport { MAP_FONT_URL } from '../../fonts/mapFontUrl';\nimport {\n applyViewerHoverCursor,\n isViewerSelectableKind,\n viewerHoverCursor,\n viewerHoverFillColor,\n viewerHoverFillOpacity,\n resolvedViewerHoverId,\n viewerShapeHighlighted,\n} from '../pointer';\nimport {\n assignedConnectorShapeIds,\n assignmentSpecialIconDataUrl,\n connectorMapIconKind,\n connectorSpecialIconDataUrl,\n entranceIconDataUrl,\n} from '../../specialIcons';\n\nfunction kindColor(\n kind: ShapeKind,\n theme: ThemeDefaults,\n fill?: string,\n assignment?: { bgColor?: string | null } | null,\n): string {\n if (kind === 'walkable') return theme.WALKABLE_COLOR;\n if (kind === 'unit') {\n return resolvedAssignmentBgColor(assignment, theme.STORE_DEFAULT_COLOR);\n }\n if (kind === 'connector' && assignment?.bgColor) {\n return resolvedAssignmentBgColor(assignment, fill || '#e2e8f0');\n }\n if (fill) return fill;\n switch (kind) {\n case 'wall':\n case 'boundary':\n return theme.WALL_COLOR;\n case 'parking_zone':\n return theme.PARKING_ZONE_COLOR;\n case 'green_area':\n return theme.GREEN_AREA_COLOR;\n case 'water':\n return theme.WATER_COLOR;\n case 'floorplate':\n return theme.BASE_COLOR;\n case 'void':\n return '#00000000';\n default:\n return '#e2e8f0';\n }\n}\n\nfunction polygonShape(points: { x: number; y: number }[]): THREE.Shape | null {\n return polygonToThreeShape(points);\n}\n\nexport interface LevelMeshesProps {\n level: PublishedLevel;\n theme: ThemeDefaults;\n is3d: boolean;\n onSelectShape?: (shapeId: number | null, opts?: { additive?: boolean }) => void;\n /** Assign-map selection — same highlight as hover so staff can see the set. */\n selectedShapeIds?: readonly number[];\n /** Rail / search hover — same darker fill as pointer hover. */\n hoveredShapeId?: number | null;\n /** Host that owns pointer events (and therefore the CSS cursor). */\n eventSource?: React.RefObject<HTMLElement | null>;\n /**\n * When true (outdoor with live SVG), only interactive shapes are drawn —\n * decoration comes from SvgVectorLayer.\n */\n interactiveOnly?: boolean;\n /** Same media proxy as outdoor SVGs — retailer logos are often cross-origin. */\n imageProxyUrl?: string | null;\n /** Published amenity catalog — used to resolve v1 amenity icons by code. */\n amenities?: CmAmenityCatalogItem[];\n}\n\nfunction HoverOutline({\n shape,\n extrude,\n color,\n}: {\n shape: THREE.Shape;\n extrude: number;\n color: string;\n}) {\n const sourceGeometry = useMemo(\n () =>\n extrude > 0\n ? new THREE.ExtrudeGeometry(shape, {\n depth: extrude,\n bevelEnabled: false,\n })\n : new THREE.ShapeGeometry(shape),\n [extrude, shape],\n );\n\n useEffect(() => () => sourceGeometry.dispose(), [sourceGeometry]);\n\n return (\n <lineSegments renderOrder={40}>\n <edgesGeometry args={[sourceGeometry]} />\n <lineBasicMaterial color={color} depthTest={false} />\n </lineSegments>\n );\n}\n\nexport function LevelMeshes({\n level,\n theme,\n is3d,\n onSelectShape,\n selectedShapeIds = [],\n hoveredShapeId: hoveredShapeIdProp = null,\n eventSource,\n interactiveOnly = false,\n imageProxyUrl = null,\n amenities = [],\n}: LevelMeshesProps) {\n const [pointerHoverId, setPointerHoverId] = useState<number | null>(null);\n const hoveredShapeId = resolvedViewerHoverId(\n hoveredShapeIdProp,\n pointerHoverId,\n );\n useEffect(\n () => () => applyViewerHoverCursor(eventSource?.current, ''),\n [eventSource],\n );\n const openings = useMemo(() => voidPolygonsOnLevel(level), [level]);\n const meshes = useMemo(() => {\n return level.shapes\n .filter((s) => s.kind !== 'void')\n .filter((s) => !(s.kind === 'label' && s.label?.text?.trim()))\n .filter((s) => !isEntranceIcon(s))\n .filter(\n (s) =>\n !interactiveOnly ||\n INTERACTIVE_SHAPE_KINDS.includes(s.kind) ||\n (s.kind === 'label' && Boolean(s.label?.text?.trim())) ||\n (s.kind === 'walkable' && !resolveLayerStyle(s.sourceSvgId)),\n )\n .filter((s) => !s.orphanedAt)\n .map((shape) => {\n const radius = shape.kind === 'unit' ? theme.STORE_RADIUS : 0;\n const punch = isSlabShapeKind(shape.kind) && openings.length > 0;\n const polys = shape.geometry.polygons.map((poly) =>\n radius > 0 ? filletPolygon(poly, radius) : poly,\n );\n const threeShapes = polys\n .map((poly) =>\n punch ? slabShapeWithHoles(poly, openings) : polygonShape(poly),\n )\n .filter((s): s is THREE.Shape => s != null);\n if (threeShapes.length === 0) return null;\n\n const color = kindColor(\n shape.kind,\n theme,\n shape.style.fill,\n shape.assignment,\n );\n const extrude =\n is3d && (shape.kind === 'unit' || shape.kind === 'wall')\n ? shape.style.extrudeHeight ??\n (shape.kind === 'unit' ? theme.STORE_HEIGHT : 2)\n : 0;\n\n return { shape, threeShapes, color, extrude };\n })\n .filter(Boolean) as Array<{\n shape: (typeof level.shapes)[number];\n threeShapes: THREE.Shape[];\n color: string;\n extrude: number;\n }>;\n }, [level, theme, is3d, interactiveOnly, openings]);\n\n const labels = useMemo(\n () =>\n level.shapes.filter(\n (s) => !s.orphanedAt && s.kind === 'label' && Boolean(s.label?.text?.trim()),\n ),\n [level.shapes],\n );\n\n const entranceIcons = useMemo(\n () => level.shapes.filter((s) => !s.orphanedAt && isEntranceIcon(s)),\n [level.shapes],\n );\n\n const overlays = useMemo(\n () =>\n level.shapes.filter(\n (s) =>\n !s.orphanedAt &&\n s.kind !== 'label' &&\n !isEntranceIcon(s) &&\n assignmentOverlayVisible(s.assignment, s.label),\n ),\n [level.shapes],\n );\n\n const connectorOverlays = useMemo(() => {\n const assignedIds = assignedConnectorShapeIds(level.anchors);\n return level.shapes.flatMap((shape) => {\n const kind = connectorMapIconKind(shape, assignedIds);\n if (!kind) return [];\n const layout = connectorIconLayout(shape);\n const url = connectorSpecialIconDataUrl(kind, true, layout.iconColor);\n if (!url) return [];\n const box = geometryBBox(shape.geometry);\n return [\n {\n shape,\n url,\n width: layout.size,\n rotation: (layout.rotate * Math.PI) / 180,\n x: (box.minX + box.maxX) / 2 + layout.offsetX,\n y: (box.minY + box.maxY) / 2 + layout.offsetY,\n },\n ];\n });\n }, [level.anchors, level.shapes]);\n\n return (\n <group>\n {labels.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const align = normalizeLabelAlign(shape.label.align);\n const cx = (box.minX + box.maxX) / 2;\n const cy = (box.minY + box.maxY) / 2;\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n return (\n <group\n key={`label-${shape.id}`}\n position={[cx, cy, 0.15]}\n rotation={[0, 0, tilt]}\n >\n <Text\n font={MAP_FONT_URL}\n position={[labelAlignX(box, align) - cx, 0, 0]}\n fontSize={shape.label.size ?? 24}\n color={shape.label.color ?? theme.STORE_TEXT_COLOR}\n anchorX={align}\n anchorY=\"middle\"\n textAlign={align}\n lineHeight={MAP_LABEL_LINE_HEIGHT}\n scale={[1, -1, 1]}\n >\n {shape.label.text}\n </Text>\n </group>\n );\n })}\n {entranceIcons.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const cx = (box.minX + box.maxX) / 2 + (shape.label.offsetX ?? 0);\n const cy = (box.minY + box.maxY) / 2 + (shape.label.offsetY ?? 0);\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n const size = shape.label.size || DEFAULT_ENTRANCE_SIZE;\n const url = entranceIconDataUrl(\n shape.label.color ?? theme.STORE_TEXT_COLOR,\n );\n if (!url) return null;\n return (\n <AssignmentImageOverlay\n key={`entrance-${shape.id}`}\n url={url}\n width={size}\n position={[cx, cy, 0.18]}\n rotation={tilt}\n />\n );\n })}\n {overlays.map((shape) => {\n const box = geometryBBox(shape.geometry);\n const cx = (box.minX + box.maxX) / 2 + (shape.label.offsetX ?? 0);\n const cy = (box.minY + box.maxY) / 2 + (shape.label.offsetY ?? 0);\n const tilt = ((shape.label.rotate ?? 0) * Math.PI) / 180;\n const fontSize = shape.label.size || shape.assignment?.size || DEFAULT_ASSIGNMENT_SIZE;\n const extrude =\n is3d && (shape.kind === 'unit' || shape.kind === 'wall')\n ? shape.style.extrudeHeight ??\n (shape.kind === 'unit' ? theme.STORE_HEIGHT : 2)\n : 0;\n const z = extrude > 0 ? extrude + 0.15 : 0.2;\n const iconColor =\n shape.label.color ??\n shape.assignment?.textColor ??\n theme.STORE_TEXT_COLOR;\n const imageKey =\n assignmentOverlayImageUrl(shape.assignment, null, shape.label) ??\n assignmentSpecialIconDataUrl(\n shape.assignment,\n amenities,\n iconColor,\n );\n const text = shape.label.text?.trim();\n const align = normalizeLabelAlign(shape.label.align);\n return imageKey ? (\n <AssignmentImageOverlay\n key={`overlay-${shape.id}`}\n url={imageKey}\n width={assignmentOverlayRenderSize(fontSize, shape.assignment)}\n position={[cx, cy, z]}\n rotation={tilt}\n imageProxyUrl={imageProxyUrl}\n />\n ) : (\n <Text\n key={`overlay-${shape.id}`}\n font={MAP_FONT_URL}\n position={[cx, cy, z]}\n rotation={[0, 0, tilt]}\n fontSize={fontSize}\n color={shape.label.color ?? theme.STORE_TEXT_COLOR}\n anchorX=\"center\"\n anchorY=\"middle\"\n textAlign={align}\n lineHeight={MAP_LABEL_LINE_HEIGHT}\n scale={[1, -1, 1]}\n raycast={skipRaycast}\n >\n {text}\n </Text>\n );\n })}\n {connectorOverlays.map(({ shape, url, width, rotation, x, y }) => (\n <AssignmentImageOverlay\n key={`connector-icon-${shape.id}`}\n url={url}\n width={width}\n position={[x, y, 0.22]}\n rotation={rotation}\n />\n ))}\n <OpeningWells polygons={openings} />\n {meshes.map(({ shape, threeShapes, color, extrude }) => {\n const selectable = isViewerSelectableKind(shape.kind);\n const hovered =\n selectable &&\n viewerShapeHighlighted(shape.id, hoveredShapeId, selectedShapeIds);\n const baseOpacity =\n shape.style.opacity ?? (shape.kind === 'amenity' ? 0.01 : 1);\n const fillTransparent = isTransparentColor(color);\n const opacity = fillTransparent\n ? hovered\n ? 0.2\n : 0\n : viewerHoverFillOpacity(\n shape.kind,\n baseOpacity,\n hovered,\n );\n const fill = fillTransparent\n ? hovered\n ? theme.ACCENT_COLOR\n : '#000000'\n : viewerHoverFillColor(color, theme.ACCENT_COLOR, hovered);\n return (\n <group key={shape.id}>\n {threeShapes.map((geoShape, idx) => (\n <mesh\n key={`${shape.id}-${idx}`}\n position={[0, 0, shape.zIndex * 0.01]}\n onPointerOver={(e) => {\n if (!selectable) return;\n e.stopPropagation();\n setPointerHoverId(shape.id);\n applyViewerHoverCursor(\n eventSource?.current,\n viewerHoverCursor(shape.kind),\n );\n }}\n onPointerOut={(e) => {\n if (!selectable) return;\n e.stopPropagation();\n setPointerHoverId((id) => (id === shape.id ? null : id));\n applyViewerHoverCursor(eventSource?.current, '');\n }}\n onPointerDown={(e) => {\n const additive = Boolean(\n e.shiftKey ||\n (e.nativeEvent as MouseEvent | undefined)?.shiftKey,\n );\n if (additive) e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n if (selectable) {\n onSelectShape?.(shape.id, {\n additive: Boolean(\n e.shiftKey ||\n (e.nativeEvent as MouseEvent | undefined)?.shiftKey,\n ),\n });\n return;\n }\n onSelectShape?.(null);\n }}\n >\n {extrude > 0 ? (\n <extrudeGeometry\n args={[\n geoShape,\n { depth: extrude, bevelEnabled: false },\n ]}\n />\n ) : (\n <shapeGeometry args={[geoShape]} />\n )}\n <meshBasicMaterial\n color={fill}\n transparent={\n shape.style.transparent ||\n shape.kind === 'amenity' ||\n opacity < 1\n }\n opacity={opacity}\n side={THREE.DoubleSide}\n />\n {hovered ? (\n <HoverOutline\n shape={geoShape}\n extrude={extrude}\n color={theme.ACCENT_COLOR}\n />\n ) : null}\n </mesh>\n ))}\n </group>\n );\n })}\n </group>\n );\n}\n\nfunction skipRaycast() {}\n\nfunction loadCanvasTexture(\n url: string,\n signal?: AbortSignal,\n): Promise<{ texture: THREE.CanvasTexture; aspect: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const cleanup = () => {\n signal?.removeEventListener('abort', onAbort);\n img.onload = null;\n img.onerror = null;\n };\n const onAbort = () => {\n cleanup();\n img.src = '';\n reject(new DOMException('Image load aborted', 'AbortError'));\n };\n if (signal?.aborted) {\n onAbort();\n return;\n }\n signal?.addEventListener('abort', onAbort, { once: true });\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n cleanup();\n const width = img.naturalWidth || img.width;\n const height = img.naturalHeight || img.height;\n if (!width || !height) {\n reject(new Error('empty image'));\n return;\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reject(new Error('canvas'));\n return;\n }\n ctx.drawImage(img, 0, 0);\n const texture = new THREE.CanvasTexture(canvas);\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.needsUpdate = true;\n resolve({ texture, aspect: height / width });\n };\n img.onerror = () => {\n cleanup();\n reject(new Error(`Failed to load ${url}`));\n };\n img.src = url;\n });\n}\n\nfunction AssignmentImageOverlay({\n url,\n width,\n position,\n rotation,\n imageProxyUrl,\n}: {\n url: string;\n width: number;\n position: [number, number, number];\n rotation: number;\n imageProxyUrl?: string | null;\n}) {\n const [texture, setTexture] = useState<THREE.CanvasTexture | null>(null);\n const [aspect, setAspect] = useState(1);\n\n useEffect(() => {\n let disposed = false;\n let loaded: THREE.CanvasTexture | null = null;\n const controller = new AbortController();\n setTexture(null);\n const proxied = resolveFetchUrl(url, imageProxyUrl);\n const candidates = proxied === url ? [url] : [proxied, url];\n const load = async () => {\n let lastError: unknown;\n for (const src of candidates) {\n try {\n const next = await loadCanvasTexture(src, controller.signal);\n if (disposed) {\n next.texture.dispose();\n return;\n }\n loaded = next.texture;\n setAspect(next.aspect);\n setTexture(next.texture);\n return;\n } catch (error) {\n if (controller.signal.aborted) return;\n lastError = error;\n }\n }\n if (!disposed) {\n setTexture(null);\n if (lastError) console.warn('Retail logo failed to load', url, lastError);\n }\n };\n void load();\n return () => {\n disposed = true;\n controller.abort();\n loaded?.dispose();\n };\n }, [url, imageProxyUrl]);\n\n if (!texture || width <= 0) return null;\n\n return (\n <mesh\n position={position}\n rotation={[0, 0, rotation]}\n scale={[1, -1, 1]}\n renderOrder={30}\n raycast={skipRaycast}\n >\n <planeGeometry args={[width, width * aspect]} />\n <meshBasicMaterial\n map={texture}\n transparent\n depthTest={false}\n depthWrite={false}\n side={THREE.DoubleSide}\n toneMapped={false}\n />\n </mesh>\n );\n}\n","import React, { useMemo } from 'react';\nimport * as THREE from 'three';\nimport type { PathResult } from '../../core';\n\nexport function RouteLine({\n route,\n activeLevelId,\n color,\n}: {\n route: PathResult;\n activeLevelId: number | null;\n color: string;\n}) {\n const points = useMemo(() => {\n return route.points\n .filter((p) => activeLevelId == null || p.levelId === activeLevelId)\n .map((p) => new THREE.Vector3(p.x, p.y, 2));\n }, [route, activeLevelId]);\n const curve = useMemo(\n () => (points.length >= 2 ? new THREE.CatmullRomCurve3(points) : null),\n [points],\n );\n\n if (!curve) return null;\n\n return (\n <mesh>\n <tubeGeometry args={[curve, Math.max(points.length * 4, 8), 1.5, 8, false]} />\n <meshBasicMaterial color={color} />\n </mesh>\n );\n}\n","import {\n\tBox2,\n\tBufferGeometry,\n\tFileLoader,\n\tFloat32BufferAttribute,\n\tLoader,\n\tMatrix3,\n\tPath,\n\tShape,\n\tShapePath,\n\tShapeUtils,\n\tSRGBColorSpace,\n\tVector2,\n\tVector3\n} from 'three';\n\nconst COLOR_SPACE_SVG = SRGBColorSpace;\n\n/**\n * A loader for the SVG format.\n *\n * Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics\n * with support for interactivity and animation.\n *\n * ```js\n * const loader = new SVGLoader();\n * const data = await loader.loadAsync( 'data/svgSample.svg' );\n *\n * const paths = data.paths;\n * const group = new THREE.Group();\n *\n * for ( let i = 0; i < paths.length; i ++ ) {\n *\n * \tconst path = paths[ i ];\n * \tconst material = new THREE.MeshBasicMaterial( {\n * \t\tcolor: path.color,\n * \t\tside: THREE.DoubleSide,\n * \t\tdepthWrite: false\n * \t} );\n *\n * \tconst shapes = SVGLoader.createShapes( path );\n *\n * \tfor ( let j = 0; j < shapes.length; j ++ ) {\n *\n * \t\tconst shape = shapes[ j ];\n * \t\tconst geometry = new THREE.ShapeGeometry( shape );\n * \t\tconst mesh = new THREE.Mesh( geometry, material );\n * \t\tgroup.add( mesh );\n *\n * \t}\n *\n * }\n *\n * scene.add( group );\n * ```\n *\n * @augments Loader\n * @three_import import { SVGLoader } from 'three/addons/loaders/SVGLoader.js';\n */\nclass SVGLoader extends Loader {\n\n\t/**\n\t * Constructs a new SVG loader.\n\t *\n\t * @param {LoadingManager} [manager] - The loading manager.\n\t */\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\t/**\n\t\t * Default dots per inch.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 90\n\t\t */\n\t\tthis.defaultDPI = 90;\n\n\t\t/**\n\t\t * Default unit.\n\t\t *\n\t\t * @type {('mm'|'cm'|'in'|'pt'|'pc'|'px')}\n\t\t * @default 'px'\n\t\t */\n\t\tthis.defaultUnit = 'px';\n\n\t}\n\n\t/**\n\t * Starts loading from the given URL and passes the loaded SVG asset\n\t * to the `onLoad()` callback.\n\t *\n\t * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.\n\t * @param {function({paths:Array<ShapePath>,xml:string})} onLoad - Executed when the loading process has been finished.\n\t * @param {onProgressCallback} onProgress - Executed while the loading is in progress.\n\t * @param {onErrorCallback} onError - Executed when errors occur.\n\t */\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( scope.manager );\n\t\tloader.setPath( scope.path );\n\t\tloader.setRequestHeader( scope.requestHeader );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( text ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\t/**\n\t * Parses the given SVG data and returns the resulting data.\n\t *\n\t * @param {string} text - The raw SVG data as a string.\n\t * @return {{paths:Array<ShapePath>,xml:string}} An object holding an array of shape paths and the\n\t * SVG XML document.\n\t */\n\tparse( text ) {\n\n\t\tconst scope = this;\n\n\t\tfunction parseNode( node, style ) {\n\n\t\t\tif ( node.nodeType !== 1 ) return;\n\n\t\t\tconst transform = getNodeTransform( node );\n\n\t\t\tlet isDefsNode = false;\n\n\t\t\tlet path = null;\n\n\t\t\tswitch ( node.nodeName ) {\n\n\t\t\t\tcase 'svg':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'style':\n\t\t\t\t\tparseCSSStylesheet( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'g':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'path':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tif ( node.hasAttribute( 'd' ) ) path = parsePathNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'rect':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseRectNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'polygon':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parsePolygonNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'polyline':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parsePolylineNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'circle':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseCircleNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'ellipse':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseEllipseNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'line':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\t\t\t\t\tpath = parseLineNode( node );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'defs':\n\t\t\t\t\tisDefsNode = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'use':\n\t\t\t\t\tstyle = parseStyle( node, style );\n\n\t\t\t\t\tconst href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || '';\n\t\t\t\t\tconst usedNodeId = href.substring( 1 );\n\t\t\t\t\tconst usedNode = node.viewportElement.getElementById( usedNodeId );\n\t\t\t\t\tif ( usedNode ) {\n\n\t\t\t\t\t\tparseNode( usedNode, style );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'SVGLoader: \\'use node\\' references non-existent node id: ' + usedNodeId );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t// console.log( node );\n\n\t\t\t}\n\n\t\t\tif ( path ) {\n\n\t\t\t\tif ( style.fill !== undefined && style.fill !== 'none' ) {\n\n\t\t\t\t\tpath.color.setStyle( style.fill, COLOR_SPACE_SVG );\n\n\t\t\t\t}\n\n\t\t\t\ttransformPath( path, currentTransform );\n\n\t\t\t\tpaths.push( path );\n\n\t\t\t\tpath.userData = { node: node, style: style };\n\n\t\t\t}\n\n\t\t\tconst childNodes = node.childNodes;\n\n\t\t\tfor ( let i = 0; i < childNodes.length; i ++ ) {\n\n\t\t\t\tconst node = childNodes[ i ];\n\n\t\t\t\tif ( isDefsNode && node.nodeName !== 'style' && node.nodeName !== 'defs' ) {\n\n\t\t\t\t\t// Ignore everything in defs except CSS style definitions\n\t\t\t\t\t// and nested defs, because it is OK by the standard to have\n\t\t\t\t\t// <style/> there.\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tparseNode( node, style );\n\n\t\t\t}\n\n\n\t\t\tif ( transform ) {\n\n\t\t\t\ttransformStack.pop();\n\n\t\t\t\tif ( transformStack.length > 0 ) {\n\n\t\t\t\t\tcurrentTransform.copy( transformStack[ transformStack.length - 1 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcurrentTransform.identity();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction parsePathNode( node ) {\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tconst point = new Vector2();\n\t\t\tconst control = new Vector2();\n\n\t\t\tconst firstPoint = new Vector2();\n\t\t\tlet isFirstPoint = true;\n\t\t\tlet doSetFirstPoint = false;\n\n\t\t\tconst d = node.getAttribute( 'd' );\n\n\t\t\tif ( d === '' || d === 'none' ) return null;\n\n\t\t\t// console.log( d );\n\n\t\t\tconst commands = d.match( /[a-df-z][^a-df-z]*/ig );\n\n\t\t\tfor ( let i = 0, l = commands.length; i < l; i ++ ) {\n\n\t\t\t\tconst command = commands[ i ];\n\n\t\t\t\tconst type = command.charAt( 0 );\n\t\t\t\tconst data = command.slice( 1 ).trim();\n\n\t\t\t\tif ( isFirstPoint === true ) {\n\n\t\t\t\t\tdoSetFirstPoint = true;\n\t\t\t\t\tisFirstPoint = false;\n\n\t\t\t\t}\n\n\t\t\t\tlet numbers;\n\n\t\t\t\tswitch ( type ) {\n\n\t\t\t\t\tcase 'M':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\n\t\t\t\t\t\t\tif ( j === 0 ) {\n\n\t\t\t\t\t\t\t\tpath.moveTo( point.x, point.y );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( j === 0 ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'H':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'V':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.y = numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'L':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'C':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 4 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 5 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 3 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 4 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 5 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'S':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tgetReflection( point.x, control.x ),\n\t\t\t\t\t\t\t\tgetReflection( point.y, control.y ),\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Q':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 2 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'T':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tconst rx = getReflection( point.x, control.x );\n\t\t\t\t\t\t\tconst ry = getReflection( point.y, control.y );\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\trx,\n\t\t\t\t\t\t\t\try,\n\t\t\t\t\t\t\t\tnumbers[ j + 0 ],\n\t\t\t\t\t\t\t\tnumbers[ j + 1 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = rx;\n\t\t\t\t\t\t\tcontrol.y = ry;\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 1 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'A':\n\t\t\t\t\t\tnumbers = parseFloats( data, [ 3, 4 ], 7 );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {\n\n\t\t\t\t\t\t\t// skip command if start point == end point\n\t\t\t\t\t\t\tif ( numbers[ j + 5 ] == point.x && numbers[ j + 6 ] == point.y ) continue;\n\n\t\t\t\t\t\t\tconst start = point.clone();\n\t\t\t\t\t\t\tpoint.x = numbers[ j + 5 ];\n\t\t\t\t\t\t\tpoint.y = numbers[ j + 6 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tparseArcCommand(\n\t\t\t\t\t\t\t\tpath, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'm':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\n\t\t\t\t\t\t\tif ( j === 0 ) {\n\n\t\t\t\t\t\t\t\tpath.moveTo( point.x, point.y );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( j === 0 ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'h':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'v':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\tpoint.y += numbers[ j ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'l':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 1 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tpath.lineTo( point.x, point.y );\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'c':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 6 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 4 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 5 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 2 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 3 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 4 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 5 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 's':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\t\t\t\tgetReflection( point.x, control.x ),\n\t\t\t\t\t\t\t\tgetReflection( point.y, control.y ),\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 4 ) {\n\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ],\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 2 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 3 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tcontrol.y = point.y + numbers[ j + 1 ];\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 2 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 3 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 't':\n\t\t\t\t\t\tnumbers = parseFloats( data );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 2 ) {\n\n\t\t\t\t\t\t\tconst rx = getReflection( point.x, control.x );\n\t\t\t\t\t\t\tconst ry = getReflection( point.y, control.y );\n\t\t\t\t\t\t\tpath.quadraticCurveTo(\n\t\t\t\t\t\t\t\trx,\n\t\t\t\t\t\t\t\try,\n\t\t\t\t\t\t\t\tpoint.x + numbers[ j + 0 ],\n\t\t\t\t\t\t\t\tpoint.y + numbers[ j + 1 ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontrol.x = rx;\n\t\t\t\t\t\t\tcontrol.y = ry;\n\t\t\t\t\t\t\tpoint.x = point.x + numbers[ j + 0 ];\n\t\t\t\t\t\t\tpoint.y = point.y + numbers[ j + 1 ];\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'a':\n\t\t\t\t\t\tnumbers = parseFloats( data, [ 3, 4 ], 7 );\n\n\t\t\t\t\t\tfor ( let j = 0, jl = numbers.length; j < jl; j += 7 ) {\n\n\t\t\t\t\t\t\t// skip command if no displacement\n\t\t\t\t\t\t\tif ( numbers[ j + 5 ] == 0 && numbers[ j + 6 ] == 0 ) continue;\n\n\t\t\t\t\t\t\tconst start = point.clone();\n\t\t\t\t\t\t\tpoint.x += numbers[ j + 5 ];\n\t\t\t\t\t\t\tpoint.y += numbers[ j + 6 ];\n\t\t\t\t\t\t\tcontrol.x = point.x;\n\t\t\t\t\t\t\tcontrol.y = point.y;\n\t\t\t\t\t\t\tparseArcCommand(\n\t\t\t\t\t\t\t\tpath, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\tcase 'z':\n\t\t\t\t\t\tpath.currentPath.autoClose = true;\n\n\t\t\t\t\t\tif ( path.currentPath.curves.length > 0 ) {\n\n\t\t\t\t\t\t\t// Reset point to beginning of Path\n\t\t\t\t\t\t\tpoint.copy( firstPoint );\n\t\t\t\t\t\t\tpath.currentPath.currentPoint.copy( point );\n\t\t\t\t\t\t\tisFirstPoint = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tconsole.warn( command );\n\n\t\t\t\t}\n\n\t\t\t\t// console.log( type, parseFloats( data ), parseFloats( data ).length )\n\n\t\t\t\tdoSetFirstPoint = false;\n\n\t\t\t}\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseCSSStylesheet( node ) {\n\n\t\t\tif ( ! node.sheet || ! node.sheet.cssRules || ! node.sheet.cssRules.length ) return;\n\n\t\t\tfor ( let i = 0; i < node.sheet.cssRules.length; i ++ ) {\n\n\t\t\t\tconst stylesheet = node.sheet.cssRules[ i ];\n\n\t\t\t\tif ( stylesheet.type !== 1 ) continue;\n\n\t\t\t\tconst selectorList = stylesheet.selectorText\n\t\t\t\t\t.split( /,/gm )\n\t\t\t\t\t.filter( Boolean )\n\t\t\t\t\t.map( i => i.trim() );\n\n\t\t\t\tfor ( let j = 0; j < selectorList.length; j ++ ) {\n\n\t\t\t\t\t// Remove empty rules\n\t\t\t\t\tconst definitions = Object.fromEntries(\n\t\t\t\t\t\tObject.entries( stylesheet.style ).filter( ( [ , v ] ) => v !== '' )\n\t\t\t\t\t);\n\n\t\t\t\t\tstylesheets[ selectorList[ j ] ] = Object.assign(\n\t\t\t\t\t\tstylesheets[ selectorList[ j ] ] || {},\n\t\t\t\t\t\tdefinitions\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/**\n\t\t * https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes\n\t\t * https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ Appendix: Endpoint to center arc conversion\n\t\t * From\n\t\t * rx ry x-axis-rotation large-arc-flag sweep-flag x y\n\t\t * To\n\t\t * aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation\n\t\t */\n\n\t\tfunction parseArcCommand( path, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, start, end ) {\n\n\t\t\tif ( rx == 0 || ry == 0 ) {\n\n\t\t\t\t// draw a line if either of the radii == 0\n\t\t\t\tpath.lineTo( end.x, end.y );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tx_axis_rotation = x_axis_rotation * Math.PI / 180;\n\n\t\t\t// Ensure radii are positive\n\t\t\trx = Math.abs( rx );\n\t\t\try = Math.abs( ry );\n\n\t\t\t// Compute (x1', y1')\n\t\t\tconst dx2 = ( start.x - end.x ) / 2.0;\n\t\t\tconst dy2 = ( start.y - end.y ) / 2.0;\n\t\t\tconst x1p = Math.cos( x_axis_rotation ) * dx2 + Math.sin( x_axis_rotation ) * dy2;\n\t\t\tconst y1p = - Math.sin( x_axis_rotation ) * dx2 + Math.cos( x_axis_rotation ) * dy2;\n\n\t\t\t// Compute (cx', cy')\n\t\t\tlet rxs = rx * rx;\n\t\t\tlet rys = ry * ry;\n\t\t\tconst x1ps = x1p * x1p;\n\t\t\tconst y1ps = y1p * y1p;\n\n\t\t\t// Ensure radii are large enough\n\t\t\tconst cr = x1ps / rxs + y1ps / rys;\n\n\t\t\tif ( cr > 1 ) {\n\n\t\t\t\t// scale up rx,ry equally so cr == 1\n\t\t\t\tconst s = Math.sqrt( cr );\n\t\t\t\trx = s * rx;\n\t\t\t\try = s * ry;\n\t\t\t\trxs = rx * rx;\n\t\t\t\trys = ry * ry;\n\n\t\t\t}\n\n\t\t\tconst dq = ( rxs * y1ps + rys * x1ps );\n\t\t\tconst pq = ( rxs * rys - dq ) / dq;\n\t\t\tlet q = Math.sqrt( Math.max( 0, pq ) );\n\t\t\tif ( large_arc_flag === sweep_flag ) q = - q;\n\t\t\tconst cxp = q * rx * y1p / ry;\n\t\t\tconst cyp = - q * ry * x1p / rx;\n\n\t\t\t// Step 3: Compute (cx, cy) from (cx', cy')\n\t\t\tconst cx = Math.cos( x_axis_rotation ) * cxp - Math.sin( x_axis_rotation ) * cyp + ( start.x + end.x ) / 2;\n\t\t\tconst cy = Math.sin( x_axis_rotation ) * cxp + Math.cos( x_axis_rotation ) * cyp + ( start.y + end.y ) / 2;\n\n\t\t\t// Step 4: Compute θ1 and Δθ\n\t\t\tconst theta = svgAngle( 1, 0, ( x1p - cxp ) / rx, ( y1p - cyp ) / ry );\n\t\t\tconst delta = svgAngle( ( x1p - cxp ) / rx, ( y1p - cyp ) / ry, ( - x1p - cxp ) / rx, ( - y1p - cyp ) / ry ) % ( Math.PI * 2 );\n\n\t\t\tpath.currentPath.absellipse( cx, cy, rx, ry, theta, theta + delta, sweep_flag === 0, x_axis_rotation );\n\n\t\t}\n\n\t\tfunction svgAngle( ux, uy, vx, vy ) {\n\n\t\t\tconst dot = ux * vx + uy * vy;\n\t\t\tconst len = Math.sqrt( ux * ux + uy * uy ) * Math.sqrt( vx * vx + vy * vy );\n\t\t\tlet ang = Math.acos( Math.max( - 1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear\n\t\t\tif ( ( ux * vy - uy * vx ) < 0 ) ang = - ang;\n\t\t\treturn ang;\n\n\t\t}\n\n\t\t/*\n\t\t* According to https://www.w3.org/TR/SVG/shapes.html#RectElementRXAttribute\n\t\t* rounded corner should be rendered to elliptical arc, but bezier curve does the job well enough\n\t\t*/\n\n\t\tfunction parseRectNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'x' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'y' ) || 0 );\n\t\t\tconst rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || node.getAttribute( 'ry' ) || 0 );\n\t\t\tconst ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || node.getAttribute( 'rx' ) || 0 );\n\t\t\tconst w = parseFloatWithUnits( node.getAttribute( 'width' ) );\n\t\t\tconst h = parseFloatWithUnits( node.getAttribute( 'height' ) );\n\n\t\t\t// Ellipse arc to Bezier approximation Coefficient (Inversed). See:\n\t\t\t// https://spencermortensen.com/articles/bezier-circle/\n\t\t\tconst bci = 1 - 0.551915024494;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\t// top left\n\t\t\tpath.moveTo( x + rx, y );\n\n\t\t\t// top right\n\t\t\tpath.lineTo( x + w - rx, y );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + w - rx * bci,\n\t\t\t\t\ty,\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + ry * bci,\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + ry\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// bottom right\n\t\t\tpath.lineTo( x + w, y + h - ry );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + w,\n\t\t\t\t\ty + h - ry * bci,\n\t\t\t\t\tx + w - rx * bci,\n\t\t\t\t\ty + h,\n\t\t\t\t\tx + w - rx,\n\t\t\t\t\ty + h\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// bottom left\n\t\t\tpath.lineTo( x + rx, y + h );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo(\n\t\t\t\t\tx + rx * bci,\n\t\t\t\t\ty + h,\n\t\t\t\t\tx,\n\t\t\t\t\ty + h - ry * bci,\n\t\t\t\t\tx,\n\t\t\t\t\ty + h - ry\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// back to top left\n\t\t\tpath.lineTo( x, y + ry );\n\t\t\tif ( rx !== 0 || ry !== 0 ) {\n\n\t\t\t\tpath.bezierCurveTo( x, y + ry * bci, x + rx * bci, y, x + rx, y );\n\n\t\t\t}\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parsePolygonNode( node ) {\n\n\t\t\tfunction iterator( match, a, b ) {\n\n\t\t\t\tconst x = parseFloatWithUnits( a );\n\t\t\t\tconst y = parseFloatWithUnits( b );\n\n\t\t\t\tif ( index === 0 ) {\n\n\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t}\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tconst regex = /([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)(?:,|\\s)([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)/g;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tlet index = 0;\n\n\t\t\tnode.getAttribute( 'points' ).replace( regex, iterator );\n\n\t\t\tpath.currentPath.autoClose = true;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parsePolylineNode( node ) {\n\n\t\t\tfunction iterator( match, a, b ) {\n\n\t\t\t\tconst x = parseFloatWithUnits( a );\n\t\t\t\tconst y = parseFloatWithUnits( b );\n\n\t\t\t\tif ( index === 0 ) {\n\n\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t}\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tconst regex = /([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)(?:,|\\s)([+-]?\\d*\\.?\\d+(?:e[+-]?\\d+)?)/g;\n\n\t\t\tconst path = new ShapePath();\n\n\t\t\tlet index = 0;\n\n\t\t\tnode.getAttribute( 'points' ).replace( regex, iterator );\n\n\t\t\tpath.currentPath.autoClose = false;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseCircleNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'cx' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'cy' ) || 0 );\n\t\t\tconst r = parseFloatWithUnits( node.getAttribute( 'r' ) || 0 );\n\n\t\t\tconst subpath = new Path();\n\t\t\tsubpath.absarc( x, y, r, 0, Math.PI * 2 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.subPaths.push( subpath );\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseEllipseNode( node ) {\n\n\t\t\tconst x = parseFloatWithUnits( node.getAttribute( 'cx' ) || 0 );\n\t\t\tconst y = parseFloatWithUnits( node.getAttribute( 'cy' ) || 0 );\n\t\t\tconst rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || 0 );\n\t\t\tconst ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || 0 );\n\n\t\t\tconst subpath = new Path();\n\t\t\tsubpath.absellipse( x, y, rx, ry, 0, Math.PI * 2 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.subPaths.push( subpath );\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\tfunction parseLineNode( node ) {\n\n\t\t\tconst x1 = parseFloatWithUnits( node.getAttribute( 'x1' ) || 0 );\n\t\t\tconst y1 = parseFloatWithUnits( node.getAttribute( 'y1' ) || 0 );\n\t\t\tconst x2 = parseFloatWithUnits( node.getAttribute( 'x2' ) || 0 );\n\t\t\tconst y2 = parseFloatWithUnits( node.getAttribute( 'y2' ) || 0 );\n\n\t\t\tconst path = new ShapePath();\n\t\t\tpath.moveTo( x1, y1 );\n\t\t\tpath.lineTo( x2, y2 );\n\t\t\tpath.currentPath.autoClose = false;\n\n\t\t\treturn path;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction parseStyle( node, style ) {\n\n\t\t\tstyle = Object.assign( {}, style ); // clone style\n\n\t\t\tlet stylesheetStyles = {};\n\n\t\t\tif ( node.hasAttribute( 'class' ) ) {\n\n\t\t\t\tconst classSelectors = node.getAttribute( 'class' )\n\t\t\t\t\t.split( /\\s/ )\n\t\t\t\t\t.filter( Boolean )\n\t\t\t\t\t.map( i => i.trim() );\n\n\t\t\t\tfor ( let i = 0; i < classSelectors.length; i ++ ) {\n\n\t\t\t\t\tstylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '.' + classSelectors[ i ] ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( node.hasAttribute( 'id' ) ) {\n\n\t\t\t\tstylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '#' + node.getAttribute( 'id' ) ] );\n\n\t\t\t}\n\n\t\t\tfunction addStyle( svgName, jsName, adjustFunction ) {\n\n\t\t\t\tif ( adjustFunction === undefined ) adjustFunction = function copy( v ) {\n\n\t\t\t\t\tif ( v.startsWith( 'url' ) ) console.warn( 'SVGLoader: url access in attributes is not implemented.' );\n\n\t\t\t\t\treturn v;\n\n\t\t\t\t};\n\n\t\t\t\tif ( node.hasAttribute( svgName ) ) style[ jsName ] = adjustFunction( node.getAttribute( svgName ) );\n\t\t\t\tif ( stylesheetStyles[ svgName ] ) style[ jsName ] = adjustFunction( stylesheetStyles[ svgName ] );\n\t\t\t\tif ( node.style && node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] );\n\n\t\t\t}\n\n\t\t\tfunction clamp( v ) {\n\n\t\t\t\treturn Math.max( 0, Math.min( 1, parseFloatWithUnits( v ) ) );\n\n\t\t\t}\n\n\t\t\tfunction positive( v ) {\n\n\t\t\t\treturn Math.max( 0, parseFloatWithUnits( v ) );\n\n\t\t\t}\n\n\t\t\taddStyle( 'fill', 'fill' );\n\t\t\taddStyle( 'fill-opacity', 'fillOpacity', clamp );\n\t\t\taddStyle( 'fill-rule', 'fillRule' );\n\t\t\taddStyle( 'opacity', 'opacity', clamp );\n\t\t\taddStyle( 'stroke', 'stroke' );\n\t\t\taddStyle( 'stroke-opacity', 'strokeOpacity', clamp );\n\t\t\taddStyle( 'stroke-width', 'strokeWidth', positive );\n\t\t\taddStyle( 'stroke-linejoin', 'strokeLineJoin' );\n\t\t\taddStyle( 'stroke-linecap', 'strokeLineCap' );\n\t\t\taddStyle( 'stroke-miterlimit', 'strokeMiterLimit', positive );\n\t\t\taddStyle( 'visibility', 'visibility' );\n\n\t\t\treturn style;\n\n\t\t}\n\n\t\t// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes\n\n\t\tfunction getReflection( a, b ) {\n\n\t\t\treturn a - ( b - a );\n\n\t\t}\n\n\t\t// from https://github.com/ppvg/svg-numbers (MIT License)\n\n\t\tfunction parseFloats( input, flags, stride ) {\n\n\t\t\tif ( typeof input !== 'string' ) {\n\n\t\t\t\tthrow new TypeError( 'Invalid input: ' + typeof input );\n\n\t\t\t}\n\n\t\t\t// Character groups\n\t\t\tconst RE = {\n\t\t\t\tSEPARATOR: /[ \\t\\r\\n\\,.\\-+]/,\n\t\t\t\tWHITESPACE: /[ \\t\\r\\n]/,\n\t\t\t\tDIGIT: /[\\d]/,\n\t\t\t\tSIGN: /[-+]/,\n\t\t\t\tPOINT: /\\./,\n\t\t\t\tCOMMA: /,/,\n\t\t\t\tEXP: /e/i,\n\t\t\t\tFLAGS: /[01]/\n\t\t\t};\n\n\t\t\t// States\n\t\t\tconst SEP = 0;\n\t\t\tconst INT = 1;\n\t\t\tconst FLOAT = 2;\n\t\t\tconst EXP = 3;\n\n\t\t\tlet state = SEP;\n\t\t\tlet seenComma = true;\n\t\t\tlet number = '', exponent = '';\n\t\t\tconst result = [];\n\n\t\t\tfunction throwSyntaxError( current, i, partial ) {\n\n\t\t\t\tconst error = new SyntaxError( 'Unexpected character \"' + current + '\" at index ' + i + '.' );\n\t\t\t\terror.partial = partial;\n\t\t\t\tthrow error;\n\n\t\t\t}\n\n\t\t\tfunction newNumber() {\n\n\t\t\t\tif ( number !== '' ) {\n\n\t\t\t\t\tif ( exponent === '' ) result.push( Number( number ) );\n\t\t\t\t\telse result.push( Number( number ) * Math.pow( 10, Number( exponent ) ) );\n\n\t\t\t\t}\n\n\t\t\t\tnumber = '';\n\t\t\t\texponent = '';\n\n\t\t\t}\n\n\t\t\tlet current;\n\t\t\tconst length = input.length;\n\n\t\t\tfor ( let i = 0; i < length; i ++ ) {\n\n\t\t\t\tcurrent = input[ i ];\n\n\t\t\t\t// check for flags\n\t\t\t\tif ( Array.isArray( flags ) && flags.includes( result.length % stride ) && RE.FLAGS.test( current ) ) {\n\n\t\t\t\t\tstate = INT;\n\t\t\t\t\tnumber = current;\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\t// parse until next number\n\t\t\t\tif ( state === SEP ) {\n\n\t\t\t\t\t// eat whitespace\n\t\t\t\t\tif ( RE.WHITESPACE.test( current ) ) {\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// start new number\n\t\t\t\t\tif ( RE.DIGIT.test( current ) || RE.SIGN.test( current ) ) {\n\n\t\t\t\t\t\tstate = INT;\n\t\t\t\t\t\tnumber = current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\t\tnumber = current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double commas (e.g. \"1, , 2\")\n\t\t\t\t\tif ( RE.COMMA.test( current ) ) {\n\n\t\t\t\t\t\tif ( seenComma ) {\n\n\t\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tseenComma = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse integer part\n\t\t\t\tif ( state === INT ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.EXP.test( current ) ) {\n\n\t\t\t\t\t\tstate = EXP;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double signs (\"-+1\"), but not on sign as separator (\"-1-2\")\n\t\t\t\t\tif ( RE.SIGN.test( current )\n\t\t\t\t\t\t\t&& number.length === 1\n\t\t\t\t\t\t\t&& RE.SIGN.test( number[ 0 ] ) ) {\n\n\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse decimal part\n\t\t\t\tif ( state === FLOAT ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\tnumber += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.EXP.test( current ) ) {\n\n\t\t\t\t\t\tstate = EXP;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// throw on double decimal points (e.g. \"1..2\")\n\t\t\t\t\tif ( RE.POINT.test( current ) && number[ number.length - 1 ] === '.' ) {\n\n\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// parse exponent part\n\t\t\t\tif ( state === EXP ) {\n\n\t\t\t\t\tif ( RE.DIGIT.test( current ) ) {\n\n\t\t\t\t\t\texponent += current;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( RE.SIGN.test( current ) ) {\n\n\t\t\t\t\t\tif ( exponent === '' ) {\n\n\t\t\t\t\t\t\texponent += current;\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( exponent.length === 1 && RE.SIGN.test( exponent ) ) {\n\n\t\t\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t\t// end of number\n\t\t\t\tif ( RE.WHITESPACE.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = SEP;\n\t\t\t\t\tseenComma = false;\n\n\t\t\t\t} else if ( RE.COMMA.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = SEP;\n\t\t\t\t\tseenComma = true;\n\n\t\t\t\t} else if ( RE.SIGN.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = INT;\n\t\t\t\t\tnumber = current;\n\n\t\t\t\t} else if ( RE.POINT.test( current ) ) {\n\n\t\t\t\t\tnewNumber();\n\t\t\t\t\tstate = FLOAT;\n\t\t\t\t\tnumber = current;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrowSyntaxError( current, i, result );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add the last number found (if any)\n\t\t\tnewNumber();\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\t// Units\n\n\t\tconst units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ];\n\n\t\t// Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent)\n\t\tconst unitConversion = {\n\n\t\t\t'mm': {\n\t\t\t\t'mm': 1,\n\t\t\t\t'cm': 0.1,\n\t\t\t\t'in': 1 / 25.4,\n\t\t\t\t'pt': 72 / 25.4,\n\t\t\t\t'pc': 6 / 25.4,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'cm': {\n\t\t\t\t'mm': 10,\n\t\t\t\t'cm': 1,\n\t\t\t\t'in': 1 / 2.54,\n\t\t\t\t'pt': 72 / 2.54,\n\t\t\t\t'pc': 6 / 2.54,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'in': {\n\t\t\t\t'mm': 25.4,\n\t\t\t\t'cm': 2.54,\n\t\t\t\t'in': 1,\n\t\t\t\t'pt': 72,\n\t\t\t\t'pc': 6,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'pt': {\n\t\t\t\t'mm': 25.4 / 72,\n\t\t\t\t'cm': 2.54 / 72,\n\t\t\t\t'in': 1 / 72,\n\t\t\t\t'pt': 1,\n\t\t\t\t'pc': 6 / 72,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'pc': {\n\t\t\t\t'mm': 25.4 / 6,\n\t\t\t\t'cm': 2.54 / 6,\n\t\t\t\t'in': 1 / 6,\n\t\t\t\t'pt': 72 / 6,\n\t\t\t\t'pc': 1,\n\t\t\t\t'px': - 1\n\t\t\t},\n\t\t\t'px': {\n\t\t\t\t'px': 1\n\t\t\t}\n\n\t\t};\n\n\t\tfunction parseFloatWithUnits( string ) {\n\n\t\t\tlet theUnit = 'px';\n\n\t\t\tif ( typeof string === 'string' || string instanceof String ) {\n\n\t\t\t\tfor ( let i = 0, n = units.length; i < n; i ++ ) {\n\n\t\t\t\t\tconst u = units[ i ];\n\n\t\t\t\t\tif ( string.endsWith( u ) ) {\n\n\t\t\t\t\t\ttheUnit = u;\n\t\t\t\t\t\tstring = string.substring( 0, string.length - u.length );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlet scale = undefined;\n\n\t\t\tif ( theUnit === 'px' && scope.defaultUnit !== 'px' ) {\n\n\t\t\t\t// Conversion scale from pixels to inches, then to default units\n\n\t\t\t\tscale = unitConversion[ 'in' ][ scope.defaultUnit ] / scope.defaultDPI;\n\n\t\t\t} else {\n\n\t\t\t\tscale = unitConversion[ theUnit ][ scope.defaultUnit ];\n\n\t\t\t\tif ( scale < 0 ) {\n\n\t\t\t\t\t// Conversion scale to pixels\n\n\t\t\t\t\tscale = unitConversion[ theUnit ][ 'in' ] * scope.defaultDPI;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn scale * parseFloat( string );\n\n\t\t}\n\n\t\t// Transforms\n\n\t\tfunction getNodeTransform( node ) {\n\n\t\t\tif ( ! ( node.hasAttribute( 'transform' ) || ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) ) ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tconst transform = parseNodeTransform( node );\n\n\t\t\tif ( transformStack.length > 0 ) {\n\n\t\t\t\ttransform.premultiply( transformStack[ transformStack.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tcurrentTransform.copy( transform );\n\t\t\ttransformStack.push( transform );\n\n\t\t\treturn transform;\n\n\t\t}\n\n\t\tfunction parseNodeTransform( node ) {\n\n\t\t\tconst transform = new Matrix3();\n\t\t\tconst currentTransform = tempTransform0;\n\n\t\t\tif ( node.nodeName === 'use' && ( node.hasAttribute( 'x' ) || node.hasAttribute( 'y' ) ) ) {\n\n\t\t\t\tconst tx = parseFloatWithUnits( node.getAttribute( 'x' ) );\n\t\t\t\tconst ty = parseFloatWithUnits( node.getAttribute( 'y' ) );\n\n\t\t\t\ttransform.translate( tx, ty );\n\n\t\t\t}\n\n\t\t\tif ( node.hasAttribute( 'transform' ) ) {\n\n\t\t\t\tconst transformsTexts = node.getAttribute( 'transform' ).split( ')' );\n\n\t\t\t\tfor ( let tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) {\n\n\t\t\t\t\tconst transformText = transformsTexts[ tIndex ].trim();\n\n\t\t\t\t\tif ( transformText === '' ) continue;\n\n\t\t\t\t\tconst openParPos = transformText.indexOf( '(' );\n\t\t\t\t\tconst closeParPos = transformText.length;\n\n\t\t\t\t\tif ( openParPos > 0 && openParPos < closeParPos ) {\n\n\t\t\t\t\t\tconst transformType = transformText.slice( 0, openParPos );\n\n\t\t\t\t\t\tconst array = parseFloats( transformText.slice( openParPos + 1 ) );\n\n\t\t\t\t\t\tcurrentTransform.identity();\n\n\t\t\t\t\t\tswitch ( transformType ) {\n\n\t\t\t\t\t\t\tcase 'translate':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tconst tx = array[ 0 ];\n\t\t\t\t\t\t\t\t\tlet ty = 0;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 2 ) {\n\n\t\t\t\t\t\t\t\t\t\tty = array[ 1 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.translate( tx, ty );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'rotate':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tlet angle = 0;\n\t\t\t\t\t\t\t\t\tlet cx = 0;\n\t\t\t\t\t\t\t\t\tlet cy = 0;\n\n\t\t\t\t\t\t\t\t\t// Angle\n\t\t\t\t\t\t\t\t\tangle = array[ 0 ] * Math.PI / 180;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 3 ) {\n\n\t\t\t\t\t\t\t\t\t\t// Center x, y\n\t\t\t\t\t\t\t\t\t\tcx = array[ 1 ];\n\t\t\t\t\t\t\t\t\t\tcy = array[ 2 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Rotate around center (cx, cy)\n\t\t\t\t\t\t\t\t\ttempTransform1.makeTranslation( - cx, - cy );\n\t\t\t\t\t\t\t\t\ttempTransform2.makeRotation( angle );\n\t\t\t\t\t\t\t\t\ttempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );\n\t\t\t\t\t\t\t\t\ttempTransform1.makeTranslation( cx, cy );\n\t\t\t\t\t\t\t\t\tcurrentTransform.multiplyMatrices( tempTransform1, tempTransform3 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'scale':\n\n\t\t\t\t\t\t\t\tif ( array.length >= 1 ) {\n\n\t\t\t\t\t\t\t\t\tconst scaleX = array[ 0 ];\n\t\t\t\t\t\t\t\t\tlet scaleY = scaleX;\n\n\t\t\t\t\t\t\t\t\tif ( array.length >= 2 ) {\n\n\t\t\t\t\t\t\t\t\t\tscaleY = array[ 1 ];\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.scale( scaleX, scaleY );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'skewX':\n\n\t\t\t\t\t\t\t\tif ( array.length === 1 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\t1, Math.tan( array[ 0 ] * Math.PI / 180 ), 0,\n\t\t\t\t\t\t\t\t\t\t0, 1, 0,\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'skewY':\n\n\t\t\t\t\t\t\t\tif ( array.length === 1 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\t1, 0, 0,\n\t\t\t\t\t\t\t\t\t\tMath.tan( array[ 0 ] * Math.PI / 180 ), 1, 0,\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'matrix':\n\n\t\t\t\t\t\t\t\tif ( array.length === 6 ) {\n\n\t\t\t\t\t\t\t\t\tcurrentTransform.set(\n\t\t\t\t\t\t\t\t\t\tarray[ 0 ], array[ 2 ], array[ 4 ],\n\t\t\t\t\t\t\t\t\t\tarray[ 1 ], array[ 3 ], array[ 5 ],\n\t\t\t\t\t\t\t\t\t\t0, 0, 1\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttransform.premultiply( currentTransform );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn transform;\n\n\t\t}\n\n\t\tfunction transformPath( path, m ) {\n\n\t\t\tfunction transfVec2( v2 ) {\n\n\t\t\t\ttempV3.set( v2.x, v2.y, 1 ).applyMatrix3( m );\n\n\t\t\t\tv2.set( tempV3.x, tempV3.y );\n\n\t\t\t}\n\n\t\t\tfunction transfEllipseGeneric( curve ) {\n\n\t\t\t\t// For math description see:\n\t\t\t\t// https://math.stackexchange.com/questions/4544164\n\n\t\t\t\tconst a = curve.xRadius;\n\t\t\t\tconst b = curve.yRadius;\n\n\t\t\t\tconst cosTheta = Math.cos( curve.aRotation );\n\t\t\t\tconst sinTheta = Math.sin( curve.aRotation );\n\n\t\t\t\tconst v1 = new Vector3( a * cosTheta, a * sinTheta, 0 );\n\t\t\t\tconst v2 = new Vector3( - b * sinTheta, b * cosTheta, 0 );\n\n\t\t\t\tconst f1 = v1.applyMatrix3( m );\n\t\t\t\tconst f2 = v2.applyMatrix3( m );\n\n\t\t\t\tconst mF = tempTransform0.set(\n\t\t\t\t\tf1.x, f2.x, 0,\n\t\t\t\t\tf1.y, f2.y, 0,\n\t\t\t\t\t0, 0, 1,\n\t\t\t\t);\n\n\t\t\t\tconst mFInv = tempTransform1.copy( mF ).invert();\n\t\t\t\tconst mFInvT = tempTransform2.copy( mFInv ).transpose();\n\t\t\t\tconst mQ = mFInvT.multiply( mFInv );\n\t\t\t\tconst mQe = mQ.elements;\n\n\t\t\t\tconst ed = eigenDecomposition( mQe[ 0 ], mQe[ 1 ], mQe[ 4 ] );\n\t\t\t\tconst rt1sqrt = Math.sqrt( ed.rt1 );\n\t\t\t\tconst rt2sqrt = Math.sqrt( ed.rt2 );\n\n\t\t\t\tcurve.xRadius = 1 / rt1sqrt;\n\t\t\t\tcurve.yRadius = 1 / rt2sqrt;\n\t\t\t\tcurve.aRotation = Math.atan2( ed.sn, ed.cs );\n\n\t\t\t\tconst isFullEllipse =\n\t\t\t\t\t( curve.aEndAngle - curve.aStartAngle ) % ( 2 * Math.PI ) < Number.EPSILON;\n\n\t\t\t\t// Do not touch angles of a full ellipse because after transformation they\n\t\t\t\t// would converge to a single value effectively removing the whole curve\n\n\t\t\t\tif ( ! isFullEllipse ) {\n\n\t\t\t\t\tconst mDsqrt = tempTransform1.set(\n\t\t\t\t\t\trt1sqrt, 0, 0,\n\t\t\t\t\t\t0, rt2sqrt, 0,\n\t\t\t\t\t\t0, 0, 1,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst mRT = tempTransform2.set(\n\t\t\t\t\t\ted.cs, ed.sn, 0,\n\t\t\t\t\t\t- ed.sn, ed.cs, 0,\n\t\t\t\t\t\t0, 0, 1,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst mDRF = mDsqrt.multiply( mRT ).multiply( mF );\n\n\t\t\t\t\tconst transformAngle = phi => {\n\n\t\t\t\t\t\tconst { x: cosR, y: sinR } =\n\t\t\t\t\t\t\tnew Vector3( Math.cos( phi ), Math.sin( phi ), 0 ).applyMatrix3( mDRF );\n\n\t\t\t\t\t\treturn Math.atan2( sinR, cosR );\n\n\t\t\t\t\t};\n\n\t\t\t\t\tcurve.aStartAngle = transformAngle( curve.aStartAngle );\n\t\t\t\t\tcurve.aEndAngle = transformAngle( curve.aEndAngle );\n\n\t\t\t\t\tif ( isTransformFlipped( m ) ) {\n\n\t\t\t\t\t\tcurve.aClockwise = ! curve.aClockwise;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction transfEllipseNoSkew( curve ) {\n\n\t\t\t\t// Faster shortcut if no skew is applied\n\t\t\t\t// (e.g, a euclidean transform of a group containing the ellipse)\n\n\t\t\t\tconst sx = getTransformScaleX( m );\n\t\t\t\tconst sy = getTransformScaleY( m );\n\n\t\t\t\tcurve.xRadius *= sx;\n\t\t\t\tcurve.yRadius *= sy;\n\n\t\t\t\t// Extract rotation angle from the matrix of form:\n\t\t\t\t//\n\t\t\t\t// | cosθ sx -sinθ sy |\n\t\t\t\t// | sinθ sx cosθ sy |\n\t\t\t\t//\n\t\t\t\t// Remembering that tanθ = sinθ / cosθ; and that\n\t\t\t\t// `sx`, `sy`, or both might be zero.\n\t\t\t\tconst theta =\n\t\t\t\t\tsx > Number.EPSILON\n\t\t\t\t\t\t? Math.atan2( m.elements[ 1 ], m.elements[ 0 ] )\n\t\t\t\t\t\t: Math.atan2( - m.elements[ 3 ], m.elements[ 4 ] );\n\n\t\t\t\tcurve.aRotation += theta;\n\n\t\t\t\tif ( isTransformFlipped( m ) ) {\n\n\t\t\t\t\tcurve.aStartAngle *= - 1;\n\t\t\t\t\tcurve.aEndAngle *= - 1;\n\t\t\t\t\tcurve.aClockwise = ! curve.aClockwise;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst subPaths = path.subPaths;\n\n\t\t\tfor ( let i = 0, n = subPaths.length; i < n; i ++ ) {\n\n\t\t\t\tconst subPath = subPaths[ i ];\n\t\t\t\tconst curves = subPath.curves;\n\n\t\t\t\tfor ( let j = 0; j < curves.length; j ++ ) {\n\n\t\t\t\t\tconst curve = curves[ j ];\n\n\t\t\t\t\tif ( curve.isLineCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\n\t\t\t\t\t} else if ( curve.isCubicBezierCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v0 );\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\t\t\t\t\t\ttransfVec2( curve.v3 );\n\n\t\t\t\t\t} else if ( curve.isQuadraticBezierCurve ) {\n\n\t\t\t\t\t\ttransfVec2( curve.v0 );\n\t\t\t\t\t\ttransfVec2( curve.v1 );\n\t\t\t\t\t\ttransfVec2( curve.v2 );\n\n\t\t\t\t\t} else if ( curve.isEllipseCurve ) {\n\n\t\t\t\t\t\t// Transform ellipse center point\n\n\t\t\t\t\t\ttempV2.set( curve.aX, curve.aY );\n\t\t\t\t\t\ttransfVec2( tempV2 );\n\t\t\t\t\t\tcurve.aX = tempV2.x;\n\t\t\t\t\t\tcurve.aY = tempV2.y;\n\n\t\t\t\t\t\t// Transform ellipse shape parameters\n\n\t\t\t\t\t\tif ( isTransformSkewed( m ) ) {\n\n\t\t\t\t\t\t\ttransfEllipseGeneric( curve );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttransfEllipseNoSkew( curve );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction isTransformFlipped( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn te[ 0 ] * te[ 4 ] - te[ 1 ] * te[ 3 ] < 0;\n\n\t\t}\n\n\t\tfunction isTransformSkewed( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\tconst basisDot = te[ 0 ] * te[ 3 ] + te[ 1 ] * te[ 4 ];\n\n\t\t\t// Shortcut for trivial rotations and transformations\n\t\t\tif ( basisDot === 0 ) return false;\n\n\t\t\tconst sx = getTransformScaleX( m );\n\t\t\tconst sy = getTransformScaleY( m );\n\n\t\t\treturn Math.abs( basisDot / ( sx * sy ) ) > Number.EPSILON;\n\n\t\t}\n\n\t\tfunction getTransformScaleX( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn Math.sqrt( te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] );\n\n\t\t}\n\n\t\tfunction getTransformScaleY( m ) {\n\n\t\t\tconst te = m.elements;\n\t\t\treturn Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] );\n\n\t\t}\n\n\t\t// Calculates the eigensystem of a real symmetric 2x2 matrix\n\t\t// [ A B ]\n\t\t// [ B C ]\n\t\t// in the form\n\t\t// [ A B ] = [ cs -sn ] [ rt1 0 ] [ cs sn ]\n\t\t// [ B C ] [ sn cs ] [ 0 rt2 ] [ -sn cs ]\n\t\t// where rt1 >= rt2.\n\t\t//\n\t\t// Adapted from: https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html\n\t\t// -> Algorithms for real symmetric matrices -> Analytical (2x2 symmetric)\n\t\tfunction eigenDecomposition( A, B, C ) {\n\n\t\t\tlet rt1, rt2, cs, sn, t;\n\t\t\tconst sm = A + C;\n\t\t\tconst df = A - C;\n\t\t\tconst rt = Math.sqrt( df * df + 4 * B * B );\n\n\t\t\tif ( sm > 0 ) {\n\n\t\t\t\trt1 = 0.5 * ( sm + rt );\n\t\t\t\tt = 1 / rt1;\n\t\t\t\trt2 = A * t * C - B * t * B;\n\n\t\t\t} else if ( sm < 0 ) {\n\n\t\t\t\trt2 = 0.5 * ( sm - rt );\n\n\t\t\t} else {\n\n\t\t\t\t// This case needs to be treated separately to avoid div by 0\n\n\t\t\t\trt1 = 0.5 * rt;\n\t\t\t\trt2 = - 0.5 * rt;\n\n\t\t\t}\n\n\t\t\t// Calculate eigenvectors\n\n\t\t\tif ( df > 0 ) {\n\n\t\t\t\tcs = df + rt;\n\n\t\t\t} else {\n\n\t\t\t\tcs = df - rt;\n\n\t\t\t}\n\n\t\t\tif ( Math.abs( cs ) > 2 * Math.abs( B ) ) {\n\n\t\t\t\tt = - 2 * B / cs;\n\t\t\t\tsn = 1 / Math.sqrt( 1 + t * t );\n\t\t\t\tcs = t * sn;\n\n\t\t\t} else if ( Math.abs( B ) === 0 ) {\n\n\t\t\t\tcs = 1;\n\t\t\t\tsn = 0;\n\n\t\t\t} else {\n\n\t\t\t\tt = - 0.5 * cs / B;\n\t\t\t\tcs = 1 / Math.sqrt( 1 + t * t );\n\t\t\t\tsn = t * cs;\n\n\t\t\t}\n\n\t\t\tif ( df > 0 ) {\n\n\t\t\t\tt = cs;\n\t\t\t\tcs = - sn;\n\t\t\t\tsn = t;\n\n\t\t\t}\n\n\t\t\treturn { rt1, rt2, cs, sn };\n\n\t\t}\n\n\t\t//\n\n\t\tconst paths = [];\n\t\tconst stylesheets = {};\n\n\t\tconst transformStack = [];\n\n\t\tconst tempTransform0 = new Matrix3();\n\t\tconst tempTransform1 = new Matrix3();\n\t\tconst tempTransform2 = new Matrix3();\n\t\tconst tempTransform3 = new Matrix3();\n\t\tconst tempV2 = new Vector2();\n\t\tconst tempV3 = new Vector3();\n\n\t\tconst currentTransform = new Matrix3();\n\n\t\tconst xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml\n\n\t\tparseNode( xml.documentElement, {\n\t\t\tfill: '#000',\n\t\t\tfillOpacity: 1,\n\t\t\tstrokeOpacity: 1,\n\t\t\tstrokeWidth: 1,\n\t\t\tstrokeLineJoin: 'miter',\n\t\t\tstrokeLineCap: 'butt',\n\t\t\tstrokeMiterLimit: 4\n\t\t} );\n\n\t\tconst data = { paths: paths, xml: xml.documentElement };\n\n\t\t// console.log( paths );\n\t\treturn data;\n\n\t}\n\n\t/**\n\t * Creates from the given shape path and array of shapes.\n\t *\n\t * @param {ShapePath} shapePath - The shape path.\n\t * @return {Array<Shape>} An array of shapes.\n\t */\n\tstatic createShapes( shapePath ) {\n\n\t\tconst BIGNUMBER = 999999999;\n\n\t\tconst IntersectionLocationType = {\n\t\t\tORIGIN: 0,\n\t\t\tDESTINATION: 1,\n\t\t\tBETWEEN: 2,\n\t\t\tLEFT: 3,\n\t\t\tRIGHT: 4,\n\t\t\tBEHIND: 5,\n\t\t\tBEYOND: 6\n\t\t};\n\n\t\tconst classifyResult = {\n\t\t\tloc: IntersectionLocationType.ORIGIN,\n\t\t\tt: 0\n\t\t};\n\n\t\tfunction findEdgeIntersection( a0, a1, b0, b1 ) {\n\n\t\t\tconst x1 = a0.x;\n\t\t\tconst x2 = a1.x;\n\t\t\tconst x3 = b0.x;\n\t\t\tconst x4 = b1.x;\n\t\t\tconst y1 = a0.y;\n\t\t\tconst y2 = a1.y;\n\t\t\tconst y3 = b0.y;\n\t\t\tconst y4 = b1.y;\n\t\t\tconst nom1 = ( x4 - x3 ) * ( y1 - y3 ) - ( y4 - y3 ) * ( x1 - x3 );\n\t\t\tconst nom2 = ( x2 - x1 ) * ( y1 - y3 ) - ( y2 - y1 ) * ( x1 - x3 );\n\t\t\tconst denom = ( y4 - y3 ) * ( x2 - x1 ) - ( x4 - x3 ) * ( y2 - y1 );\n\t\t\tconst t1 = nom1 / denom;\n\t\t\tconst t2 = nom2 / denom;\n\n\t\t\tif ( ( ( denom === 0 ) && ( nom1 !== 0 ) ) || ( t1 <= 0 ) || ( t1 >= 1 ) || ( t2 < 0 ) || ( t2 > 1 ) ) {\n\n\t\t\t\t//1. lines are parallel or edges don't intersect\n\n\t\t\t\treturn null;\n\n\t\t\t} else if ( ( nom1 === 0 ) && ( denom === 0 ) ) {\n\n\t\t\t\t//2. lines are colinear\n\n\t\t\t\t//check if endpoints of edge2 (b0-b1) lies on edge1 (a0-a1)\n\t\t\t\tfor ( let i = 0; i < 2; i ++ ) {\n\n\t\t\t\t\tclassifyPoint( i === 0 ? b0 : b1, a0, a1 );\n\t\t\t\t\t//find position of this endpoints relatively to edge1\n\t\t\t\t\tif ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {\n\n\t\t\t\t\t\tconst point = ( i === 0 ? b0 : b1 );\n\t\t\t\t\t\treturn { x: point.x, y: point.y, t: classifyResult.t };\n\n\t\t\t\t\t} else if ( classifyResult.loc == IntersectionLocationType.BETWEEN ) {\n\n\t\t\t\t\t\tconst x = + ( ( x1 + classifyResult.t * ( x2 - x1 ) ).toPrecision( 10 ) );\n\t\t\t\t\t\tconst y = + ( ( y1 + classifyResult.t * ( y2 - y1 ) ).toPrecision( 10 ) );\n\t\t\t\t\t\treturn { x: x, y: y, t: classifyResult.t, };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t} else {\n\n\t\t\t\t//3. edges intersect\n\n\t\t\t\tfor ( let i = 0; i < 2; i ++ ) {\n\n\t\t\t\t\tclassifyPoint( i === 0 ? b0 : b1, a0, a1 );\n\n\t\t\t\t\tif ( classifyResult.loc == IntersectionLocationType.ORIGIN ) {\n\n\t\t\t\t\t\tconst point = ( i === 0 ? b0 : b1 );\n\t\t\t\t\t\treturn { x: point.x, y: point.y, t: classifyResult.t };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconst x = + ( ( x1 + t1 * ( x2 - x1 ) ).toPrecision( 10 ) );\n\t\t\t\tconst y = + ( ( y1 + t1 * ( y2 - y1 ) ).toPrecision( 10 ) );\n\t\t\t\treturn { x: x, y: y, t: t1 };\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction classifyPoint( p, edgeStart, edgeEnd ) {\n\n\t\t\tconst ax = edgeEnd.x - edgeStart.x;\n\t\t\tconst ay = edgeEnd.y - edgeStart.y;\n\t\t\tconst bx = p.x - edgeStart.x;\n\t\t\tconst by = p.y - edgeStart.y;\n\t\t\tconst sa = ax * by - bx * ay;\n\n\t\t\tif ( ( p.x === edgeStart.x ) && ( p.y === edgeStart.y ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.ORIGIN;\n\t\t\t\tclassifyResult.t = 0;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( ( p.x === edgeEnd.x ) && ( p.y === edgeEnd.y ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.DESTINATION;\n\t\t\t\tclassifyResult.t = 1;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( sa < - Number.EPSILON ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.LEFT;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( sa > Number.EPSILON ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.RIGHT;\n\t\t\t\treturn;\n\n\n\t\t\t}\n\n\t\t\tif ( ( ( ax * bx ) < 0 ) || ( ( ay * by ) < 0 ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.BEHIND;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( ( Math.sqrt( ax * ax + ay * ay ) ) < ( Math.sqrt( bx * bx + by * by ) ) ) {\n\n\t\t\t\tclassifyResult.loc = IntersectionLocationType.BEYOND;\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tlet t;\n\n\t\t\tif ( ax !== 0 ) {\n\n\t\t\t\tt = bx / ax;\n\n\t\t\t} else {\n\n\t\t\t\tt = by / ay;\n\n\t\t\t}\n\n\t\t\tclassifyResult.loc = IntersectionLocationType.BETWEEN;\n\t\t\tclassifyResult.t = t;\n\n\t\t}\n\n\t\tfunction getIntersections( path1, path2 ) {\n\n\t\t\tconst intersectionsRaw = [];\n\t\t\tconst intersections = [];\n\n\t\t\tfor ( let index = 1; index < path1.length; index ++ ) {\n\n\t\t\t\tconst path1EdgeStart = path1[ index - 1 ];\n\t\t\t\tconst path1EdgeEnd = path1[ index ];\n\n\t\t\t\tfor ( let index2 = 1; index2 < path2.length; index2 ++ ) {\n\n\t\t\t\t\tconst path2EdgeStart = path2[ index2 - 1 ];\n\t\t\t\t\tconst path2EdgeEnd = path2[ index2 ];\n\n\t\t\t\t\tconst intersection = findEdgeIntersection( path1EdgeStart, path1EdgeEnd, path2EdgeStart, path2EdgeEnd );\n\n\t\t\t\t\tif ( intersection !== null && intersectionsRaw.find( i => i.t <= intersection.t + Number.EPSILON && i.t >= intersection.t - Number.EPSILON ) === undefined ) {\n\n\t\t\t\t\t\tintersectionsRaw.push( intersection );\n\t\t\t\t\t\tintersections.push( new Vector2( intersection.x, intersection.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn intersections;\n\n\t\t}\n\n\t\tfunction getScanlineIntersections( scanline, boundingBox, paths ) {\n\n\t\t\tconst center = new Vector2();\n\t\t\tboundingBox.getCenter( center );\n\n\t\t\tconst allIntersections = [];\n\n\t\t\tpaths.forEach( path => {\n\n\t\t\t\t// check if the center of the bounding box is in the bounding box of the paths.\n\t\t\t\t// this is a pruning method to limit the search of intersections in paths that can't envelop of the current path.\n\t\t\t\t// if a path envelops another path. The center of that other path, has to be inside the bounding box of the enveloping path.\n\t\t\t\tif ( path.boundingBox.containsPoint( center ) ) {\n\n\t\t\t\t\tconst intersections = getIntersections( scanline, path.points );\n\n\t\t\t\t\tintersections.forEach( p => {\n\n\t\t\t\t\t\tallIntersections.push( { identifier: path.identifier, isCW: path.isCW, point: p } );\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tallIntersections.sort( ( i1, i2 ) => {\n\n\t\t\t\treturn i1.point.x - i2.point.x;\n\n\t\t\t} );\n\n\t\t\treturn allIntersections;\n\n\t\t}\n\n\t\tfunction isHoleTo( simplePath, allPaths, scanlineMinX, scanlineMaxX, _fillRule ) {\n\n\t\t\tif ( _fillRule === null || _fillRule === undefined || _fillRule === '' ) {\n\n\t\t\t\t_fillRule = 'nonzero';\n\n\t\t\t}\n\n\t\t\tconst centerBoundingBox = new Vector2();\n\t\t\tsimplePath.boundingBox.getCenter( centerBoundingBox );\n\n\t\t\tconst scanline = [ new Vector2( scanlineMinX, centerBoundingBox.y ), new Vector2( scanlineMaxX, centerBoundingBox.y ) ];\n\n\t\t\tconst scanlineIntersections = getScanlineIntersections( scanline, simplePath.boundingBox, allPaths );\n\n\t\t\tscanlineIntersections.sort( ( i1, i2 ) => {\n\n\t\t\t\treturn i1.point.x - i2.point.x;\n\n\t\t\t} );\n\n\t\t\tconst baseIntersections = [];\n\t\t\tconst otherIntersections = [];\n\n\t\t\tscanlineIntersections.forEach( i => {\n\n\t\t\t\tif ( i.identifier === simplePath.identifier ) {\n\n\t\t\t\t\tbaseIntersections.push( i );\n\n\t\t\t\t} else {\n\n\t\t\t\t\totherIntersections.push( i );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tconst firstXOfPath = baseIntersections[ 0 ].point.x;\n\n\t\t\t// build up the path hierarchy\n\t\t\tconst stack = [];\n\t\t\tlet i = 0;\n\n\t\t\twhile ( i < otherIntersections.length && otherIntersections[ i ].point.x < firstXOfPath ) {\n\n\t\t\t\tif ( stack.length > 0 && stack[ stack.length - 1 ] === otherIntersections[ i ].identifier ) {\n\n\t\t\t\t\tstack.pop();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstack.push( otherIntersections[ i ].identifier );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\tstack.push( simplePath.identifier );\n\n\t\t\tif ( _fillRule === 'evenodd' ) {\n\n\t\t\t\tconst isHole = stack.length % 2 === 0 ? true : false;\n\t\t\t\tconst isHoleFor = stack[ stack.length - 2 ];\n\n\t\t\t\treturn { identifier: simplePath.identifier, isHole: isHole, for: isHoleFor };\n\n\t\t\t} else if ( _fillRule === 'nonzero' ) {\n\n\t\t\t\t// check if path is a hole by counting the amount of paths with alternating rotations it has to cross.\n\t\t\t\tlet isHole = true;\n\t\t\t\tlet isHoleFor = null;\n\t\t\t\tlet lastCWValue = null;\n\n\t\t\t\tfor ( let i = 0; i < stack.length; i ++ ) {\n\n\t\t\t\t\tconst identifier = stack[ i ];\n\t\t\t\t\tif ( isHole ) {\n\n\t\t\t\t\t\tlastCWValue = allPaths[ identifier ].isCW;\n\t\t\t\t\t\tisHole = false;\n\t\t\t\t\t\tisHoleFor = identifier;\n\n\t\t\t\t\t} else if ( lastCWValue !== allPaths[ identifier ].isCW ) {\n\n\t\t\t\t\t\tlastCWValue = allPaths[ identifier ].isCW;\n\t\t\t\t\t\tisHole = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { identifier: simplePath.identifier, isHole: isHole, for: isHoleFor };\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'fill-rule: \"' + _fillRule + '\" is currently not implemented.' );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// check for self intersecting paths\n\t\t// TODO\n\n\t\t// check intersecting paths\n\t\t// TODO\n\n\t\t// prepare paths for hole detection\n\t\tlet scanlineMinX = BIGNUMBER;\n\t\tlet scanlineMaxX = - BIGNUMBER;\n\n\t\tlet simplePaths = shapePath.subPaths.map( p => {\n\n\t\t\tconst points = p.getPoints();\n\t\t\tlet maxY = - BIGNUMBER;\n\t\t\tlet minY = BIGNUMBER;\n\t\t\tlet maxX = - BIGNUMBER;\n\t\t\tlet minX = BIGNUMBER;\n\n\t \t//points.forEach(p => p.y *= -1);\n\n\t\t\tfor ( let i = 0; i < points.length; i ++ ) {\n\n\t\t\t\tconst p = points[ i ];\n\n\t\t\t\tif ( p.y > maxY ) {\n\n\t\t\t\t\tmaxY = p.y;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.y < minY ) {\n\n\t\t\t\t\tminY = p.y;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.x > maxX ) {\n\n\t\t\t\t\tmaxX = p.x;\n\n\t\t\t\t}\n\n\t\t\t\tif ( p.x < minX ) {\n\n\t\t\t\t\tminX = p.x;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\t\t\tif ( scanlineMaxX <= maxX ) {\n\n\t\t\t\tscanlineMaxX = maxX + 1;\n\n\t\t\t}\n\n\t\t\tif ( scanlineMinX >= minX ) {\n\n\t\t\t\tscanlineMinX = minX - 1;\n\n\t\t\t}\n\n\t\t\treturn { curves: p.curves, points: points, isCW: ShapeUtils.isClockWise( points ), identifier: - 1, boundingBox: new Box2( new Vector2( minX, minY ), new Vector2( maxX, maxY ) ) };\n\n\t\t} );\n\n\t\tsimplePaths = simplePaths.filter( sp => sp.points.length > 1 );\n\n\t\tfor ( let identifier = 0; identifier < simplePaths.length; identifier ++ ) {\n\n\t\t\tsimplePaths[ identifier ].identifier = identifier;\n\n\t\t}\n\n\t\t// check if path is solid or a hole\n\t\tconst isAHole = simplePaths.map( p => isHoleTo( p, simplePaths, scanlineMinX, scanlineMaxX, ( shapePath.userData ? shapePath.userData.style.fillRule : undefined ) ) );\n\n\n\t\tconst shapesToReturn = [];\n\t\tsimplePaths.forEach( p => {\n\n\t\t\tconst amIAHole = isAHole[ p.identifier ];\n\n\t\t\tif ( ! amIAHole.isHole ) {\n\n\t\t\t\tconst shape = new Shape();\n\t\t\t\tshape.curves = p.curves;\n\t\t\t\tconst holes = isAHole.filter( h => h.isHole && h.for === p.identifier );\n\t\t\t\tholes.forEach( h => {\n\n\t\t\t\t\tconst hole = simplePaths[ h.identifier ];\n\t\t\t\t\tconst path = new Path();\n\t\t\t\t\tpath.curves = hole.curves;\n\t\t\t\t\tshape.holes.push( path );\n\n\t\t\t\t} );\n\t\t\t\tshapesToReturn.push( shape );\n\n\t\t\t}\n\n\t\t} );\n\n\t\treturn shapesToReturn;\n\n\t}\n\n\t/**\n\t * Returns a stroke style object from the given parameters.\n\t *\n\t * @param {number} [width=1] - The stroke width.\n\t * @param {string} [color='#000'] - The stroke color, as returned by {@link Color#getStyle}.\n\t * @param {'round'|'bevel'|'miter'|'miter-limit'} [lineJoin='miter'] - The line join style.\n\t * @param {'round'|'square'|'butt'} [lineCap='butt'] - The line cap style.\n\t * @param {number} [miterLimit=4] - Maximum join length, in multiples of the `width` parameter (join is truncated if it exceeds that distance).\n\t * @return {Object} The style object.\n\t */\n\tstatic getStrokeStyle( width, color, lineJoin, lineCap, miterLimit ) {\n\n\t\twidth = width !== undefined ? width : 1;\n\t\tcolor = color !== undefined ? color : '#000';\n\t\tlineJoin = lineJoin !== undefined ? lineJoin : 'miter';\n\t\tlineCap = lineCap !== undefined ? lineCap : 'butt';\n\t\tmiterLimit = miterLimit !== undefined ? miterLimit : 4;\n\n\t\treturn {\n\t\t\tstrokeColor: color,\n\t\t\tstrokeWidth: width,\n\t\t\tstrokeLineJoin: lineJoin,\n\t\t\tstrokeLineCap: lineCap,\n\t\t\tstrokeMiterLimit: miterLimit\n\t\t};\n\n\t}\n\n\t/**\n\t * Creates a stroke from an array of points.\n\t *\n\t * @param {Array<Vector2>} points - The points in 2D space. Minimum 2 points. The path can be open or closed (last point equals to first point).\n\t * @param {Object} style - Object with SVG properties as returned by `SVGLoader.getStrokeStyle()`, or `SVGLoader.parse()` in the `path.userData.style` object.\n\t * @param {number} [arcDivisions=12] - Arc divisions for round joins and endcaps.\n\t * @param {number} [minDistance=0.001] - Points closer to this distance will be merged.\n\t * @return {?BufferGeometry} The stroke geometry. UV coordinates are generated ('u' along path. 'v' across it, from left to right).\n\t * Returns `null` if not geometry was generated.\n\t */\n\tstatic pointsToStroke( points, style, arcDivisions, minDistance ) {\n\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tif ( SVGLoader.pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs ) === 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tgeometry.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\treturn geometry;\n\n\t}\n\n\t/**\n\t * Creates a stroke from an array of points.\n\t *\n\t * @param {Array<Vector2>} points - The points in 2D space. Minimum 2 points.\n\t * @param {Object} style - Object with SVG properties as returned by `SVGLoader.getStrokeStyle()`, or `SVGLoader.parse()` in the `path.userData.style` object.\n\t * @param {number} [arcDivisions=12] - Arc divisions for round joins and endcaps.\n\t * @param {number} [minDistance=0.001] - Points closer to this distance will be merged.\n\t * @param {Array<number>} vertices - An array holding vertices.\n\t * @param {Array<number>} normals - An array holding normals.\n\t * @param {Array<number>} uvs - An array holding uvs.\n\t * @param {number} [vertexOffset=0] - The vertex offset.\n\t * @return {number} The number of vertices.\n\t */\n\tstatic pointsToStrokeWithBuffers( points, style, arcDivisions, minDistance, vertices, normals, uvs, vertexOffset ) {\n\n\t\t// This function can be called to update existing arrays or buffers.\n\t\t// Accepts same parameters as pointsToStroke, plus the buffers and optional offset.\n\t\t// Param vertexOffset: Offset vertices to start writing in the buffers (3 elements/vertex for vertices and normals, and 2 elements/vertex for uvs)\n\t\t// Returns number of written vertices / normals / uvs pairs\n\t\t// if 'vertices' parameter is undefined no triangles will be generated, but the returned vertices count will still be valid (useful to preallocate the buffers)\n\t\t// 'normals' and 'uvs' buffers are optional\n\n\t\tconst tempV2_1 = new Vector2();\n\t\tconst tempV2_2 = new Vector2();\n\t\tconst tempV2_3 = new Vector2();\n\t\tconst tempV2_4 = new Vector2();\n\t\tconst tempV2_5 = new Vector2();\n\t\tconst tempV2_6 = new Vector2();\n\t\tconst tempV2_7 = new Vector2();\n\t\tconst lastPointL = new Vector2();\n\t\tconst lastPointR = new Vector2();\n\t\tconst point0L = new Vector2();\n\t\tconst point0R = new Vector2();\n\t\tconst currentPointL = new Vector2();\n\t\tconst currentPointR = new Vector2();\n\t\tconst nextPointL = new Vector2();\n\t\tconst nextPointR = new Vector2();\n\t\tconst innerPoint = new Vector2();\n\t\tconst outerPoint = new Vector2();\n\n\t\tarcDivisions = arcDivisions !== undefined ? arcDivisions : 12;\n\t\tminDistance = minDistance !== undefined ? minDistance : 0.001;\n\t\tvertexOffset = vertexOffset !== undefined ? vertexOffset : 0;\n\n\t\t// First ensure there are no duplicated points\n\t\tpoints = removeDuplicatedPoints( points );\n\n\t\tconst numPoints = points.length;\n\n\t\tif ( numPoints < 2 ) return 0;\n\n\t\tconst isClosed = points[ 0 ].equals( points[ numPoints - 1 ] );\n\n\t\tlet currentPoint;\n\t\tlet previousPoint = points[ 0 ];\n\t\tlet nextPoint;\n\n\t\tconst strokeWidth2 = style.strokeWidth / 2;\n\n\t\tconst deltaU = 1 / ( numPoints - 1 );\n\t\tlet u0 = 0, u1;\n\n\t\tlet innerSideModified;\n\t\tlet joinIsOnLeftSide;\n\t\tlet isMiter;\n\t\tlet initialJoinIsOnLeftSide = false;\n\n\t\tlet numVertices = 0;\n\t\tlet currentCoordinate = vertexOffset * 3;\n\t\tlet currentCoordinateUV = vertexOffset * 2;\n\n\t\t// Get initial left and right stroke points\n\t\tgetNormal( points[ 0 ], points[ 1 ], tempV2_1 ).multiplyScalar( strokeWidth2 );\n\t\tlastPointL.copy( points[ 0 ] ).sub( tempV2_1 );\n\t\tlastPointR.copy( points[ 0 ] ).add( tempV2_1 );\n\t\tpoint0L.copy( lastPointL );\n\t\tpoint0R.copy( lastPointR );\n\n\t\tfor ( let iPoint = 1; iPoint < numPoints; iPoint ++ ) {\n\n\t\t\tcurrentPoint = points[ iPoint ];\n\n\t\t\t// Get next point\n\t\t\tif ( iPoint === numPoints - 1 ) {\n\n\t\t\t\tif ( isClosed ) {\n\n\t\t\t\t\t// Skip duplicated initial point\n\t\t\t\t\tnextPoint = points[ 1 ];\n\n\t\t\t\t} else nextPoint = undefined;\n\n\t\t\t} else {\n\n\t\t\t\tnextPoint = points[ iPoint + 1 ];\n\n\t\t\t}\n\n\t\t\t// Normal of previous segment in tempV2_1\n\t\t\tconst normal1 = tempV2_1;\n\t\t\tgetNormal( previousPoint, currentPoint, normal1 );\n\n\t\t\ttempV2_3.copy( normal1 ).multiplyScalar( strokeWidth2 );\n\t\t\tcurrentPointL.copy( currentPoint ).sub( tempV2_3 );\n\t\t\tcurrentPointR.copy( currentPoint ).add( tempV2_3 );\n\n\t\t\tu1 = u0 + deltaU;\n\n\t\t\tinnerSideModified = false;\n\n\t\t\tif ( nextPoint !== undefined ) {\n\n\t\t\t\t// Normal of next segment in tempV2_2\n\t\t\t\tgetNormal( currentPoint, nextPoint, tempV2_2 );\n\n\t\t\t\ttempV2_3.copy( tempV2_2 ).multiplyScalar( strokeWidth2 );\n\t\t\t\tnextPointL.copy( currentPoint ).sub( tempV2_3 );\n\t\t\t\tnextPointR.copy( currentPoint ).add( tempV2_3 );\n\n\t\t\t\tjoinIsOnLeftSide = true;\n\t\t\t\ttempV2_3.subVectors( nextPoint, previousPoint );\n\t\t\t\tif ( normal1.dot( tempV2_3 ) < 0 ) {\n\n\t\t\t\t\tjoinIsOnLeftSide = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( iPoint === 1 ) initialJoinIsOnLeftSide = joinIsOnLeftSide;\n\n\t\t\t\ttempV2_3.subVectors( nextPoint, currentPoint );\n\t\t\t\ttempV2_3.normalize();\n\t\t\t\tconst dot = Math.abs( normal1.dot( tempV2_3 ) );\n\n\t\t\t\t// If path is straight, don't create join\n\t\t\t\tif ( dot > Number.EPSILON ) {\n\n\t\t\t\t\t// Compute inner and outer segment intersections\n\t\t\t\t\tconst miterSide = strokeWidth2 / dot;\n\t\t\t\t\ttempV2_3.multiplyScalar( - miterSide );\n\t\t\t\t\ttempV2_4.subVectors( currentPoint, previousPoint );\n\t\t\t\t\ttempV2_5.copy( tempV2_4 ).setLength( miterSide ).add( tempV2_3 );\n\t\t\t\t\tinnerPoint.copy( tempV2_5 ).negate();\n\t\t\t\t\tconst miterLength2 = tempV2_5.length();\n\t\t\t\t\tconst segmentLengthPrev = tempV2_4.length();\n\t\t\t\t\ttempV2_4.divideScalar( segmentLengthPrev );\n\t\t\t\t\ttempV2_6.subVectors( nextPoint, currentPoint );\n\t\t\t\t\tconst segmentLengthNext = tempV2_6.length();\n\t\t\t\t\ttempV2_6.divideScalar( segmentLengthNext );\n\t\t\t\t\t// Check that previous and next segments doesn't overlap with the innerPoint of intersection\n\t\t\t\t\tif ( tempV2_4.dot( innerPoint ) < segmentLengthPrev && tempV2_6.dot( innerPoint ) < segmentLengthNext ) {\n\n\t\t\t\t\t\tinnerSideModified = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\touterPoint.copy( tempV2_5 ).add( currentPoint );\n\t\t\t\t\tinnerPoint.add( currentPoint );\n\n\t\t\t\t\tisMiter = false;\n\n\t\t\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\tnextPointR.copy( innerPoint );\n\t\t\t\t\t\t\tcurrentPointR.copy( innerPoint );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tnextPointL.copy( innerPoint );\n\t\t\t\t\t\t\tcurrentPointL.copy( innerPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// The segment triangles are generated here if there was overlapping\n\n\t\t\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch ( style.strokeLineJoin ) {\n\n\t\t\t\t\t\tcase 'bevel':\n\n\t\t\t\t\t\t\tmakeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'round':\n\n\t\t\t\t\t\t\t// Segment triangles\n\n\t\t\t\t\t\t\tcreateSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );\n\n\t\t\t\t\t\t\t// Join triangles\n\n\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\tmakeCircularSector( currentPoint, currentPointL, nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tmakeCircularSector( currentPoint, nextPointR, currentPointR, u1, 1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'miter':\n\t\t\t\t\t\tcase 'miter-clip':\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconst miterFraction = ( strokeWidth2 * style.strokeMiterLimit ) / miterLength2;\n\n\t\t\t\t\t\t\tif ( miterFraction < 1 ) {\n\n\t\t\t\t\t\t\t\t// The join miter length exceeds the miter limit\n\n\t\t\t\t\t\t\t\tif ( style.strokeLineJoin !== 'miter-clip' ) {\n\n\t\t\t\t\t\t\t\t\tmakeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t// Segment triangles\n\n\t\t\t\t\t\t\t\t\tcreateSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified );\n\n\t\t\t\t\t\t\t\t\t// Miter-clip join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\ttempV2_6.subVectors( outerPoint, currentPointL ).multiplyScalar( miterFraction ).add( currentPointL );\n\t\t\t\t\t\t\t\t\t\ttempV2_7.subVectors( outerPoint, nextPointL ).multiplyScalar( miterFraction ).add( nextPointL );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\ttempV2_6.subVectors( outerPoint, currentPointR ).multiplyScalar( miterFraction ).add( currentPointR );\n\t\t\t\t\t\t\t\t\t\ttempV2_7.subVectors( outerPoint, nextPointR ).multiplyScalar( miterFraction ).add( nextPointR );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_6, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( tempV2_7, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointR, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Miter join segment triangles\n\n\t\t\t\t\t\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t\t\t\t\t\t// Optimized segment + join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\tnextPointL.copy( outerPoint );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tnextPointR.copy( outerPoint );\n\n\t\t\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t// Add extra miter join triangles\n\n\t\t\t\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 0 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointL, u1, 0 );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\t\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\t\t\t\t\t\taddVertex( outerPoint, u1, 1 );\n\t\t\t\t\t\t\t\t\t\taddVertex( nextPointR, u1, 1 );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tisMiter = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// The segment triangles are generated here when two consecutive points are collinear\n\n\t\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// The segment triangles are generated here if it is the ending segment\n\n\t\t\t\tmakeSegmentTriangles();\n\n\t\t\t}\n\n\t\t\tif ( ! isClosed && iPoint === numPoints - 1 ) {\n\n\t\t\t\t// Start line endcap\n\t\t\t\taddCapGeometry( points[ 0 ], point0L, point0R, joinIsOnLeftSide, true, u0 );\n\n\t\t\t}\n\n\t\t\t// Increment loop variables\n\n\t\t\tu0 = u1;\n\n\t\t\tpreviousPoint = currentPoint;\n\n\t\t\tlastPointL.copy( nextPointL );\n\t\t\tlastPointR.copy( nextPointR );\n\n\t\t}\n\n\t\tif ( ! isClosed ) {\n\n\t\t\t// Ending line endcap\n\t\t\taddCapGeometry( currentPoint, currentPointL, currentPointR, joinIsOnLeftSide, false, u1 );\n\n\t\t} else if ( innerSideModified && vertices ) {\n\n\t\t\t// Modify path first segment vertices to adjust to the segments inner and outer intersections\n\n\t\t\tlet lastOuter = outerPoint;\n\t\t\tlet lastInner = innerPoint;\n\n\t\t\tif ( initialJoinIsOnLeftSide !== joinIsOnLeftSide ) {\n\n\t\t\t\tlastOuter = innerPoint;\n\t\t\t\tlastInner = outerPoint;\n\n\t\t\t}\n\n\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\tif ( isMiter || initialJoinIsOnLeftSide ) {\n\n\t\t\t\t\tlastInner.toArray( vertices, 0 * 3 );\n\t\t\t\t\tlastInner.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\tif ( isMiter ) {\n\n\t\t\t\t\t\tlastOuter.toArray( vertices, 1 * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( isMiter || ! initialJoinIsOnLeftSide ) {\n\n\t\t\t\t\tlastInner.toArray( vertices, 1 * 3 );\n\t\t\t\t\tlastInner.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\tif ( isMiter ) {\n\n\t\t\t\t\t\tlastOuter.toArray( vertices, 0 * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn numVertices;\n\n\t\t// -- End of algorithm\n\n\t\t// -- Functions\n\n\t\tfunction getNormal( p1, p2, result ) {\n\n\t\t\tresult.subVectors( p2, p1 );\n\t\t\treturn result.set( - result.y, result.x ).normalize();\n\n\t\t}\n\n\t\tfunction addVertex( position, u, v ) {\n\n\t\t\tif ( vertices ) {\n\n\t\t\t\tvertices[ currentCoordinate ] = position.x;\n\t\t\t\tvertices[ currentCoordinate + 1 ] = position.y;\n\t\t\t\tvertices[ currentCoordinate + 2 ] = 0;\n\n\t\t\t\tif ( normals ) {\n\n\t\t\t\t\tnormals[ currentCoordinate ] = 0;\n\t\t\t\t\tnormals[ currentCoordinate + 1 ] = 0;\n\t\t\t\t\tnormals[ currentCoordinate + 2 ] = 1;\n\n\t\t\t\t}\n\n\t\t\t\tcurrentCoordinate += 3;\n\n\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\tuvs[ currentCoordinateUV ] = u;\n\t\t\t\t\tuvs[ currentCoordinateUV + 1 ] = v;\n\n\t\t\t\t\tcurrentCoordinateUV += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tnumVertices += 3;\n\n\t\t}\n\n\t\tfunction makeCircularSector( center, p1, p2, u, v ) {\n\n\t\t\t// param p1, p2: Points in the circle arc.\n\t\t\t// p1 and p2 are in clockwise direction.\n\n\t\t\ttempV2_1.copy( p1 ).sub( center ).normalize();\n\t\t\ttempV2_2.copy( p2 ).sub( center ).normalize();\n\n\t\t\tlet angle = Math.PI;\n\t\t\tconst dot = tempV2_1.dot( tempV2_2 );\n\t\t\tif ( Math.abs( dot ) < 1 ) angle = Math.abs( Math.acos( dot ) );\n\n\t\t\tangle /= arcDivisions;\n\n\t\t\ttempV2_3.copy( p1 );\n\n\t\t\tfor ( let i = 0, il = arcDivisions - 1; i < il; i ++ ) {\n\n\t\t\t\ttempV2_4.copy( tempV2_3 ).rotateAround( center, angle );\n\n\t\t\t\taddVertex( tempV2_3, u, v );\n\t\t\t\taddVertex( tempV2_4, u, v );\n\t\t\t\taddVertex( center, u, 0.5 );\n\n\t\t\t\ttempV2_3.copy( tempV2_4 );\n\n\t\t\t}\n\n\t\t\taddVertex( tempV2_4, u, v );\n\t\t\taddVertex( p2, u, v );\n\t\t\taddVertex( center, u, 0.5 );\n\n\t\t}\n\n\t\tfunction makeSegmentTriangles() {\n\n\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t}\n\n\t\tfunction makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u ) {\n\n\t\t\tif ( innerSideModified ) {\n\n\t\t\t\t// Optimized segment + bevel triangles\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t// Path segments triangles\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\t// Bevel join triangle\n\n\t\t\t\t\taddVertex( currentPointL, u, 0 );\n\t\t\t\t\taddVertex( nextPointL, u, 0 );\n\t\t\t\t\taddVertex( innerPoint, u, 0.5 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Path segments triangles\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\t// Bevel join triangle\n\n\t\t\t\t\taddVertex( currentPointR, u, 1 );\n\t\t\t\t\taddVertex( innerPoint, u, 0 );\n\t\t\t\t\taddVertex( nextPointR, u, 1 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bevel join triangle. The segment triangles are done in the main loop\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\taddVertex( currentPointL, u, 0 );\n\t\t\t\t\taddVertex( nextPointL, u, 0 );\n\t\t\t\t\taddVertex( currentPoint, u, 0.5 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\taddVertex( currentPointR, u, 1 );\n\t\t\t\t\taddVertex( nextPointR, u, 0 );\n\t\t\t\t\taddVertex( currentPoint, u, 0.5 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createSegmentTrianglesWithMiddleSection( joinIsOnLeftSide, innerSideModified ) {\n\n\t\t\tif ( innerSideModified ) {\n\n\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( currentPointL, u1, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( nextPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 1 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\taddVertex( lastPointR, u0, 1 );\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( lastPointL, u0, 0 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPointR, u1, 1 );\n\n\t\t\t\t\taddVertex( currentPointR, u0, 1 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\n\t\t\t\t\taddVertex( currentPoint, u1, 0.5 );\n\t\t\t\t\taddVertex( innerPoint, u1, 0 );\n\t\t\t\t\taddVertex( nextPointR, u0, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction addCapGeometry( center, p1, p2, joinIsOnLeftSide, start, u ) {\n\n\t\t\t// param center: End point of the path\n\t\t\t// param p1, p2: Left and right cap points\n\n\t\t\tswitch ( style.strokeLineCap ) {\n\n\t\t\t\tcase 'round':\n\n\t\t\t\t\tif ( start ) {\n\n\t\t\t\t\t\tmakeCircularSector( center, p2, p1, u, 0.5 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tmakeCircularSector( center, p1, p2, u, 0.5 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'square':\n\n\t\t\t\t\tif ( start ) {\n\n\t\t\t\t\t\ttempV2_1.subVectors( p1, center );\n\t\t\t\t\t\ttempV2_2.set( tempV2_1.y, - tempV2_1.x );\n\n\t\t\t\t\t\ttempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );\n\t\t\t\t\t\ttempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );\n\n\t\t\t\t\t\t// Modify already existing vertices\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 0 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 3 * 3 );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, 1 * 3 );\n\t\t\t\t\t\t\t// using tempV2_4 to update 3rd vertex if the uv.y of 3rd vertex is 1\n\t\t\t\t\t\t\tuvs[ 3 * 2 + 1 ] === 1 ? tempV2_4.toArray( vertices, 3 * 3 ) : tempV2_3.toArray( vertices, 3 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, 0 * 3 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttempV2_1.subVectors( p2, center );\n\t\t\t\t\t\ttempV2_2.set( tempV2_1.y, - tempV2_1.x );\n\n\t\t\t\t\t\ttempV2_3.addVectors( tempV2_1, tempV2_2 ).add( center );\n\t\t\t\t\t\ttempV2_4.subVectors( tempV2_2, tempV2_1 ).add( center );\n\n\t\t\t\t\t\tconst vl = vertices.length;\n\n\t\t\t\t\t\t// Modify already existing vertices\n\t\t\t\t\t\tif ( joinIsOnLeftSide ) {\n\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, vl - 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 2 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 4 * 3 );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 2 * 3 );\n\t\t\t\t\t\t\ttempV2_3.toArray( vertices, vl - 1 * 3 );\n\t\t\t\t\t\t\ttempV2_4.toArray( vertices, vl - 4 * 3 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'butt':\n\t\t\t\tdefault:\n\n\t\t\t\t\t// Nothing to do here\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeDuplicatedPoints( points ) {\n\n\t\t\t// Creates a new array if necessary with duplicated points removed.\n\t\t\t// This does not remove duplicated initial and ending points of a closed path.\n\n\t\t\tlet dupPoints = false;\n\t\t\tfor ( let i = 1, n = points.length - 1; i < n; i ++ ) {\n\n\t\t\t\tif ( points[ i ].distanceTo( points[ i + 1 ] ) < minDistance ) {\n\n\t\t\t\t\tdupPoints = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! dupPoints ) return points;\n\n\t\t\tconst newPoints = [];\n\t\t\tnewPoints.push( points[ 0 ] );\n\n\t\t\tfor ( let i = 1, n = points.length - 1; i < n; i ++ ) {\n\n\t\t\t\tif ( points[ i ].distanceTo( points[ i + 1 ] ) >= minDistance ) {\n\n\t\t\t\t\tnewPoints.push( points[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tnewPoints.push( points[ points.length - 1 ] );\n\n\t\t\treturn newPoints;\n\n\t\t}\n\n\t}\n\n\n}\n\nexport { SVGLoader };\n","import React, { useEffect, useMemo, useState } from 'react';\nimport * as THREE from 'three';\nimport { SVGLoader, type SVGResult } from 'three/examples/jsm/loaders/SVGLoader.js';\nimport {\n inlineSvgStyles,\n isInteractiveGroupLabel,\n isRouteFolderLabel,\n isRoutePathLabel,\n isStoreFolderLabel,\n isTransparentColor,\n resolveFetchUrl,\n resolveLayerStyle,\n} from '../../core';\n\nexport { resolveFetchUrl };\n\nconst BASE_Z = -2;\n\nfunction getLayerNameFromNode(node: Element | undefined): string | undefined {\n if (!node || node.nodeType !== 1) return undefined;\n let current: Element | null = node;\n while (current) {\n const id = current.getAttribute('id');\n if (id) return id;\n current = current.parentElement;\n }\n return undefined;\n}\n\nfunction isInteractiveAncestor(node: Element | undefined): boolean {\n if (!node) return false;\n let current: Element | null = node;\n while (current) {\n const id = current.getAttribute('id') ?? '';\n const dataName = current.getAttribute('data-name') ?? '';\n if (isInteractiveGroupLabel(id) || isInteractiveGroupLabel(dataName)) return true;\n if (isStoreFolderLabel(id) || isStoreFolderLabel(dataName)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\nexport interface SvgVectorLayerProps {\n url: string;\n /** sourceSvgId values held in cm_shapes — skip drawing these (DB owns them). */\n suppressIds?: ReadonlySet<string>;\n imageProxyUrl?: string | null;\n is3d?: boolean;\n /** Settings overrides for house outdoor colors. */\n theme?: Partial<Record<string, string>> | null;\n}\n\ninterface PreparedMesh {\n key: string;\n shapes: THREE.Shape[];\n color: THREE.Color;\n opacity: number;\n extrude: number;\n renderOrder: number;\n}\n\n/**\n * Live outdoor SVG as real vector geometry (not a raster texture).\n * Applies house-style colors for reserved layer names; otherwise keeps\n * Illustrator fills. Skips route-path* and interactive ids owned by the DB.\n * Coordinates stay in SVG user space — `MapScene` flips the whole scene.\n */\nexport function SvgVectorLayer({\n url,\n suppressIds,\n imageProxyUrl,\n is3d = false,\n theme,\n}: SvgVectorLayerProps) {\n const [result, setResult] = useState<SVGResult | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n const controller = new AbortController();\n const fetchUrl = resolveFetchUrl(url, imageProxyUrl);\n fetch(fetchUrl, { signal: controller.signal })\n .then((res) => {\n if (!res.ok) throw new Error(`SVG fetch ${res.status}`);\n return res.text();\n })\n .then((text) => {\n if (cancelled) return;\n const inlined = inlineSvgStyles(text);\n const loader = new SVGLoader();\n setResult(loader.parse(inlined));\n })\n .catch((err) => {\n if (cancelled) return;\n if (err instanceof DOMException && err.name === 'AbortError') return;\n setResult(null);\n // Silence here used to hide CORS failures as \"outdoor has no decoration\".\n console.warn(\n `[eyeon-map] Outdoor SVG failed to load from ${fetchUrl}. ` +\n 'If this is a cross-origin error, pass `imageProxyUrl` to MapViewer.',\n err,\n );\n });\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [url, imageProxyUrl]);\n\n const meshes = useMemo(() => {\n if (!result) return [] as PreparedMesh[];\n const out: PreparedMesh[] = [];\n let idx = 0;\n for (const path of result.paths) {\n const node = path.userData?.node as Element | undefined;\n const layerName = getLayerNameFromNode(node);\n if (layerName?.toLowerCase().startsWith('route-path')) continue;\n if (layerName && (isRoutePathLabel(layerName) || isRouteFolderLabel(layerName))) {\n continue;\n }\n if (layerName && suppressIds?.has(layerName)) continue;\n if (isInteractiveAncestor(node) && !layerName) continue;\n // Whole INTERACTIVE / STORES folders are owned by DB shapes.\n if (layerName && (isInteractiveGroupLabel(layerName) || isStoreFolderLabel(layerName))) {\n continue;\n }\n if (node && isInteractiveAncestor(node) && layerName && suppressIds?.has(layerName)) {\n continue;\n }\n // Skip paths inside INTERACTIVE/STORES even when not yet in DB (assignable units).\n if (node && isInteractiveAncestor(node)) continue;\n\n const shapes = SVGLoader.createShapes(path);\n if (shapes.length === 0) continue;\n\n const layerStyle = resolveLayerStyle(layerName, theme);\n const fillTransparent = isTransparentColor(layerStyle?.fill);\n const strokeTransparent = isTransparentColor(layerStyle?.stroke);\n const color = new THREE.Color();\n if (layerStyle?.fill && !fillTransparent) {\n color.set(layerStyle.fill);\n } else if (path.color && !fillTransparent) {\n color.copy(path.color);\n } else {\n color.set('#cccccc');\n }\n if (layerStyle?.stroke && !layerStyle.fill && !strokeTransparent) {\n color.set(layerStyle.stroke);\n }\n\n const opacity =\n fillTransparent || (strokeTransparent && !layerStyle?.fill)\n ? 0\n : typeof path.userData?.style?.opacity === 'number'\n ? path.userData.style.opacity\n : 1;\n const extrude =\n is3d && layerStyle?.extrudeHeight != null ? layerStyle.extrudeHeight : 0;\n\n out.push({\n key: `${layerName ?? 'path'}-${idx++}`,\n shapes,\n color,\n opacity,\n extrude,\n renderOrder: layerStyle?.renderOrder ?? 2,\n });\n }\n return out;\n }, [result, suppressIds, is3d, theme]);\n\n if (!result || meshes.length === 0) return null;\n\n return (\n <group position={[0, 0, BASE_Z]} renderOrder={-20}>\n {meshes.map((m) =>\n m.shapes.map((shape, si) => (\n <mesh\n key={`${m.key}-${si}`}\n renderOrder={m.renderOrder}\n raycast={() => {}}\n >\n {m.extrude > 0 ? (\n <extrudeGeometry\n args={[shape, { depth: m.extrude, bevelEnabled: false }]}\n />\n ) : (\n <shapeGeometry args={[shape]} />\n )}\n <meshBasicMaterial\n color={m.color}\n transparent={m.opacity < 1}\n opacity={m.opacity}\n depthWrite={false}\n toneMapped={false}\n side={THREE.DoubleSide}\n />\n </mesh>\n )),\n )}\n </group>\n );\n}\n","import {\n expandBounds,\n sceneBoundsFromBBox,\n type BBox,\n type LevelTransform,\n type SceneBounds,\n type Vec2,\n} from '../core';\n\n/**\n * Stored geometry is raw SVG user space, where Y grows downward. The scene\n * mirrors Y once so the camera can keep a conventional `up = [0, 1, 0]`.\n *\n * Do not \"fix\" orientation by setting `up = [0, -1, 0]` instead: three.js\n * derives the camera's right axis from `up × forward`, so a negative up also\n * mirrors X and the map renders rotated 180° rather than flipped.\n */\nexport const SCENE_FLIP_SCALE: [number, number, number] = [1, -1, 1];\n\n/** Stored SVG-space point → view space, matching `SCENE_FLIP_SCALE`. */\nexport function dataToViewPoint(point: Vec2): Vec2 {\n return { x: point.x, y: -point.y };\n}\n\n/** Stored SVG-space bounds → view space, for camera and controls placement. */\nexport function viewBoundsFromData(bounds: SceneBounds): SceneBounds {\n return {\n ...bounds,\n minY: -bounds.maxY,\n maxY: -bounds.minY,\n cy: -bounds.cy,\n };\n}\n\n/**\n * Fit an orthographic camera so the map fills the canvas on the limiting\n * axis (width or height) with no extra inset.\n */\nexport function fitOrthoZoom(\n viewWidth: number,\n viewHeight: number,\n worldWidth: number,\n worldHeight: number,\n): number {\n const zoomX = Math.max(viewWidth, 1) / Math.max(worldWidth, 1);\n const zoomY = Math.max(viewHeight, 1) / Math.max(worldHeight, 1);\n return Math.min(zoomX, zoomY);\n}\n\nexport function boundsExtent(bounds: SceneBounds): { width: number; height: number } {\n return {\n width: Math.max(bounds.maxX - bounds.minX, 1),\n height: Math.max(bounds.maxY - bounds.minY, 1),\n };\n}\n\nexport const VIEWER_ZOOM_ANIM_MS = 240;\n/**\n * Selection pan/zoom. v1 used 0.2s of linear travel (`CAMERA.animSpeed`).\n * Ease-in-out over 200ms bunched the motion into the last frames and looked\n * like a snap; ease-out over 400ms reads as a short, smooth glide.\n */\nexport const VIEWER_FOCUS_ANIM_MS = 400;\n\n/** Extra space around a small focused shape so it does not fill the canvas. */\nexport const FOCUS_BOUNDS_PADDING = 1;\n/**\n * Padding for a large store (extent ≥ `FOCUS_LARGE_EXTENT`).\n * 2.0 → the store occupies about a third of the frame, so neighbors stay visible.\n */\nexport const FOCUS_LARGE_PADDING = 2;\n/** World size at which padding reaches `FOCUS_LARGE_PADDING`. */\nexport const FOCUS_LARGE_EXTENT = 400;\n/**\n * Padding stays tight until this size (typical small store). Kiosks and\n * amenities below this still zoom closer via `FOCUS_MIN_EXTENT`.\n */\nexport const FOCUS_PAD_SMALL_EXTENT = 80;\n/**\n * Floor for the framed world size. Tiny amenities keep neighbors in view\n * instead of filling the canvas; anything larger frames to its own bbox.\n */\nexport const FOCUS_MIN_EXTENT = 52;\n/**\n * Click-to-focus cap vs the full-map fit. A typical store stays at a\n * neighborhood view; 64× filled the canvas on the default assign map.\n */\nexport const FOCUS_MAX_ZOOM_MULTIPLE = 8;\n/**\n * Tiny kiosks/amenities may go closer than a store so they stay readable.\n * Still far below a canvas-filling close-up.\n */\nexport const FOCUS_SMALL_MAX_ZOOM_MULTIPLE = 14;\n/** Manual +/− ceiling, independent of selection focus. */\nexport const VIEWER_MAX_ZOOM_MULTIPLE = 16;\n\n/** More margin as the store grows so a department store is not edge-to-edge. */\nexport function focusPaddingRatio(\n width: number,\n height: number,\n paddingRatio = FOCUS_BOUNDS_PADDING,\n smallExtent = FOCUS_PAD_SMALL_EXTENT,\n largePadding = FOCUS_LARGE_PADDING,\n largeExtent = FOCUS_LARGE_EXTENT,\n): number {\n const extent = Math.max(width, height);\n if (extent <= smallExtent) return paddingRatio;\n const span = Math.max(largeExtent - smallExtent, 1);\n const t = Math.min(1, (extent - smallExtent) / span);\n return paddingRatio + (largePadding - paddingRatio) * t;\n}\n\n/**\n * Expand a shape's bounds for a \"click to assign\" camera frame.\n * Small units keep a tighter frame; large stores pull the camera back.\n */\nexport function paddedFocusBounds(\n bounds: SceneBounds,\n paddingRatio = FOCUS_BOUNDS_PADDING,\n minExtent = FOCUS_MIN_EXTENT,\n): SceneBounds {\n const rawW = bounds.maxX - bounds.minX;\n const rawH = bounds.maxY - bounds.minY;\n const width = Math.max(rawW, minExtent);\n const height = Math.max(rawH, minExtent);\n const pad = focusPaddingRatio(rawW, rawH, paddingRatio);\n const halfW = (width + width * pad) / 2;\n const halfH = (height + height * pad) / 2;\n return {\n minX: bounds.cx - halfW,\n minY: bounds.cy - halfH,\n maxX: bounds.cx + halfW,\n maxY: bounds.cy + halfH,\n cx: bounds.cx,\n cy: bounds.cy,\n size: Math.max(halfW, halfH) * 2,\n };\n}\n\n/**\n * How far a click may zoom relative to the fitted map. Smaller padded\n * frames (kiosks) get more zoom; store-sized frames stay at 8×.\n */\nexport function focusMaxZoomMultiple(\n paddedWidth: number,\n paddedHeight: number,\n typicalMultiple = FOCUS_MAX_ZOOM_MULTIPLE,\n smallMultiple = FOCUS_SMALL_MAX_ZOOM_MULTIPLE,\n): number {\n const extent = Math.max(paddedWidth, paddedHeight);\n const typicalFrame = FOCUS_PAD_SMALL_EXTENT * (1 + FOCUS_BOUNDS_PADDING);\n if (extent >= typicalFrame) return typicalMultiple;\n const tinyFrame = FOCUS_MIN_EXTENT * (1 + FOCUS_BOUNDS_PADDING);\n if (extent <= tinyFrame) return smallMultiple;\n const span = Math.max(typicalFrame - tinyFrame, 1);\n const t = (extent - tinyFrame) / span;\n return smallMultiple + (typicalMultiple - smallMultiple) * t;\n}\n\nexport function clampFocusZoom(\n shapeFitZoom: number,\n mapFitZoom: number,\n maxMultiple = FOCUS_MAX_ZOOM_MULTIPLE,\n): number {\n const cap = Math.max(mapFitZoom, 0.001) * maxMultiple;\n return Math.min(shapeFitZoom, cap);\n}\n\ntype FocusLevel = {\n shapes: Array<{ id: number; bbox: BBox }>;\n transform: LevelTransform;\n};\n\n/** Stable key so adding/removing a Shift-selected shape re-frames the camera. */\nexport function selectionFocusKey(shapeIds: number[]): string | null {\n const ids = [...new Set(shapeIds.filter((id) => Number.isFinite(id)))].sort(\n (a, b) => a - b,\n );\n return ids.length > 0 ? ids.join(',') : null;\n}\n\n/** View-space frame for one or more published shapes. */\nexport function viewFocusBoundsForShapes(\n levels: FocusLevel[],\n shapeIds: number[],\n): SceneBounds | null {\n const wanted = new Set(shapeIds);\n if (wanted.size === 0) return null;\n let combined: SceneBounds | null = null;\n for (const level of levels) {\n for (const shape of level.shapes) {\n if (!wanted.has(shape.id)) continue;\n const next = sceneBoundsFromBBox(shape.bbox, level.transform);\n combined = combined ? expandBounds(combined, next) : next;\n }\n }\n return combined ? viewBoundsFromData(paddedFocusBounds(combined)) : null;\n}\n\n/** View-space frame for a published shape, ready for `CameraRig.focusBounds`. */\nexport function viewFocusBoundsForShape(\n levels: FocusLevel[],\n shapeId: number,\n): SceneBounds | null {\n return viewFocusBoundsForShapes(levels, [shapeId]);\n}\n\nexport function easeOutCubic(t: number): number {\n const x = Math.min(1, Math.max(0, t));\n return 1 - (1 - x) ** 3;\n}\n\n/** Symmetric ease so a selection pan is visible the whole way, like v1's lerp. */\nexport function easeInOutCubic(t: number): number {\n const x = Math.min(1, Math.max(0, t));\n return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;\n}\n\nexport function lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nexport interface CameraPose {\n zoom: number;\n position: [number, number, number];\n target: [number, number, number];\n}\n\n/** Interpolate zoom + pan/orbit for a smooth +/− / Reset / selection focus. */\nexport function interpolateCameraPose(\n from: CameraPose,\n to: CameraPose,\n t: number,\n ease: (t: number) => number = easeOutCubic,\n): CameraPose {\n const e = ease(t);\n return {\n zoom: lerp(from.zoom, to.zoom, e),\n position: [\n lerp(from.position[0], to.position[0], e),\n lerp(from.position[1], to.position[1], e),\n lerp(from.position[2], to.position[2], e),\n ],\n target: [\n lerp(from.target[0], to.target[0], e),\n lerp(from.target[1], to.target[1], e),\n lerp(from.target[2], to.target[2], e),\n ],\n };\n}\n\nexport function cameraPosesNear(\n a: CameraPose,\n b: CameraPose,\n epsilon = 1e-3,\n): boolean {\n return (\n Math.abs(a.zoom - b.zoom) < epsilon &&\n Math.abs(a.position[0] - b.position[0]) < epsilon &&\n Math.abs(a.position[1] - b.position[1]) < epsilon &&\n Math.abs(a.position[2] - b.position[2]) < epsilon &&\n Math.abs(a.target[0] - b.target[0]) < epsilon &&\n Math.abs(a.target[1] - b.target[1]) < epsilon &&\n Math.abs(a.target[2] - b.target[2]) < epsilon\n );\n}\n\nexport function nextOrthoZoom(\n current: number,\n direction: 1 | -1,\n step: number,\n min: number,\n max: number,\n): number {\n const factor = 1 + Math.min(Math.max(step, 0.15), 1) * 0.5;\n const next = direction > 0 ? current * factor : current / factor;\n return Math.min(max, Math.max(min, next));\n}\n\n/** three.js `MOUSE` / `TOUCH` enums — left-drag pans the 2D admin/public map. */\nconst MOUSE_ROTATE = 0;\nconst MOUSE_DOLLY = 1;\nconst MOUSE_PAN = 2;\nconst TOUCH_ROTATE = 0;\nconst TOUCH_PAN = 1;\nconst TOUCH_DOLLY_PAN = 2;\n\n/**\n * Wheel zoom keeps the pointer over the same map point (Google Maps-style).\n * Speed is three-stdlib `pow(0.95, zoomSpeed)` per event — same helper as\n * Edit Map / Wayfinding (`nextZoomFromWheel`).\n * +/− still zooms about the view centre because those buttons have no cursor.\n */\nexport const ORBIT_ZOOM_TO_CURSOR = true;\n\nexport function orbitMouseButtons(is3d: boolean): {\n LEFT: number;\n MIDDLE: number;\n RIGHT: number;\n} {\n if (is3d) {\n return { LEFT: MOUSE_ROTATE, MIDDLE: MOUSE_DOLLY, RIGHT: MOUSE_PAN };\n }\n return { LEFT: MOUSE_PAN, MIDDLE: MOUSE_DOLLY, RIGHT: MOUSE_PAN };\n}\n\nexport function orbitTouches(is3d: boolean): { ONE: number; TWO: number } {\n if (is3d) {\n return { ONE: TOUCH_ROTATE, TWO: TOUCH_DOLLY_PAN };\n }\n return { ONE: TOUCH_PAN, TWO: TOUCH_DOLLY_PAN };\n}\n","import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react';\nimport { useFrame, useThree } from '@react-three/fiber';\nimport type { OrbitControls } from 'three-stdlib';\nimport * as THREE from 'three';\nimport type { SceneBounds, ThemeDefaults } from '../../core';\nimport {\n boundsExtent,\n cameraPosesNear,\n clampFocusZoom,\n easeOutCubic,\n fitOrthoZoom,\n focusMaxZoomMultiple,\n VIEWER_MAX_ZOOM_MULTIPLE,\n interpolateCameraPose,\n lerp,\n nextOrthoZoom,\n VIEWER_FOCUS_ANIM_MS,\n VIEWER_ZOOM_ANIM_MS,\n type CameraPose,\n} from '../camera';\n\nexport interface MapCameraHandle {\n zoomIn: () => void;\n zoomOut: () => void;\n reset: () => void;\n /** View-space bounds (already Y-flipped). Animates pan + zoom onto the shape. */\n focusBounds: (focus: SceneBounds) => void;\n}\n\n/** Survives Canvas / camera remounts so Settings color tweaks keep the view. */\nexport interface CameraViewSnapshot {\n is3d: boolean;\n boundsKey: string;\n zoom: number;\n position: [number, number, number];\n target: [number, number, number];\n userAdjusted: boolean;\n focusKey?: string | number | null;\n}\n\nexport function cameraBoundsKey(bounds: SceneBounds, is3d: boolean): string {\n return [\n bounds.cx,\n bounds.cy,\n bounds.minX,\n bounds.minY,\n bounds.maxX,\n bounds.maxY,\n bounds.size,\n is3d ? '3d' : '2d',\n ].join('|');\n}\n\nexport interface CameraRigProps {\n /** View-space bounds — already Y-flipped by the scene, so up is +Y. */\n bounds: SceneBounds;\n theme: ThemeDefaults;\n is3d: boolean;\n controlsRef: React.RefObject<OrbitControls | null>;\n cameraRef?: React.Ref<MapCameraHandle | null>;\n persistedViewRef: React.MutableRefObject<CameraViewSnapshot | null>;\n /** Selection key; when it changes the camera eases onto `focusViewBounds`. */\n focusKey?: string | number | null;\n focusViewBounds?: SceneBounds | null;\n}\n\nexport function CameraRig({\n bounds,\n theme,\n is3d,\n controlsRef,\n cameraRef,\n persistedViewRef,\n focusKey = null,\n focusViewBounds = null,\n}: CameraRigProps) {\n const { camera, size, invalidate } = useThree();\n const userAdjusted = useRef(false);\n const applyingView = useRef(false);\n const zoomAnimRef = useRef<number | null>(null);\n const appliedFocusKey = useRef<string | number | null>(null);\n const focusKeyRef = useRef(focusKey);\n focusKeyRef.current = focusKey;\n const focusViewBoundsRef = useRef(focusViewBounds);\n focusViewBoundsRef.current = focusViewBounds;\n const focusAnimRef = useRef<{\n from: CameraPose;\n dest: CameraPose;\n started: number;\n lookAt: boolean;\n } | null>(null);\n const boundsKey = cameraBoundsKey(bounds, is3d);\n\n const cancelZoomAnim = useCallback(() => {\n if (zoomAnimRef.current == null) return;\n cancelAnimationFrame(zoomAnimRef.current);\n zoomAnimRef.current = null;\n }, []);\n\n const captureView = useCallback(\n (adjusted = userAdjusted.current): CameraViewSnapshot => {\n const controls = controlsRef.current;\n return {\n is3d,\n boundsKey,\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [camera.position.x, camera.position.y, camera.position.z],\n target: controls\n ? [controls.target.x, controls.target.y, controls.target.z]\n : [bounds.cx, bounds.cy, 0],\n userAdjusted: adjusted,\n focusKey: focusKeyRef.current,\n };\n },\n [bounds.cx, bounds.cy, boundsKey, camera, controlsRef, is3d],\n );\n\n const restoreView = useCallback(\n (snap: CameraViewSnapshot) => {\n applyingView.current = true;\n cancelZoomAnim();\n camera.up.set(0, 1, 0);\n camera.position.set(snap.position[0], snap.position[1], snap.position[2]);\n if (camera instanceof THREE.OrthographicCamera) {\n camera.zoom = snap.zoom;\n camera.updateProjectionMatrix();\n } else {\n camera.lookAt(snap.target[0], snap.target[1], snap.target[2]);\n }\n const controls = controlsRef.current;\n if (controls) {\n controls.target.set(snap.target[0], snap.target[1], snap.target[2]);\n controls.update();\n }\n persistedViewRef.current = { ...snap, boundsKey, is3d };\n userAdjusted.current = snap.userAdjusted;\n invalidate();\n applyingView.current = false;\n },\n [boundsKey, camera, cancelZoomAnim, controlsRef, invalidate, is3d, persistedViewRef],\n );\n\n const animateOrthoZoom = useCallback(\n (targetZoom: number) => {\n if (!(camera instanceof THREE.OrthographicCamera)) return;\n cancelZoomAnim();\n const startZoom = camera.zoom;\n if (startZoom === targetZoom) return;\n const started = performance.now();\n const step = (now: number) => {\n if (!(camera instanceof THREE.OrthographicCamera)) return;\n const t = Math.min(1, (now - started) / VIEWER_ZOOM_ANIM_MS);\n camera.zoom = lerp(startZoom, targetZoom, easeOutCubic(t));\n camera.updateProjectionMatrix();\n persistedViewRef.current = captureView();\n invalidate();\n if (t < 1) {\n zoomAnimRef.current = requestAnimationFrame(step);\n return;\n }\n zoomAnimRef.current = null;\n };\n zoomAnimRef.current = requestAnimationFrame(step);\n },\n [camera, cancelZoomAnim, captureView, invalidate, persistedViewRef],\n );\n\n const currentPose = useCallback((): CameraPose => {\n const controls = controlsRef.current;\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [camera.position.x, camera.position.y, camera.position.z],\n target: controls\n ? [controls.target.x, controls.target.y, controls.target.z]\n : [bounds.cx, bounds.cy, 0],\n };\n }, [bounds.cx, bounds.cy, camera, controlsRef]);\n\n const fitPose = useCallback((): CameraPose => {\n const { width, height } = boundsExtent(bounds);\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n return {\n zoom: fitOrthoZoom(size.width, size.height, width, height),\n position: [bounds.cx, bounds.cy, 500],\n target: [bounds.cx, bounds.cy, 0],\n };\n }\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [bounds.cx, bounds.cy - bounds.size * 0.35, bounds.size * 0.85],\n target: [bounds.cx, bounds.cy, 0],\n };\n }, [bounds, camera, is3d, size.height, size.width]);\n\n const applyPose = useCallback(\n (pose: CameraPose, lookAt: boolean) => {\n applyingView.current = true;\n camera.up.set(0, 1, 0);\n camera.position.set(pose.position[0], pose.position[1], pose.position[2]);\n if (camera instanceof THREE.OrthographicCamera) {\n camera.zoom = pose.zoom;\n camera.updateProjectionMatrix();\n }\n if (lookAt) {\n camera.lookAt(pose.target[0], pose.target[1], pose.target[2]);\n }\n const controls = controlsRef.current;\n if (controls) {\n controls.target.set(pose.target[0], pose.target[1], pose.target[2]);\n controls.update();\n }\n invalidate();\n applyingView.current = false;\n },\n [camera, controlsRef, invalidate],\n );\n\n const poseForFocusBounds = useCallback(\n (focus: SceneBounds): CameraPose => {\n const { width, height } = boundsExtent(focus);\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n const mapExtent = boundsExtent(bounds);\n const mapFit = fitOrthoZoom(\n size.width,\n size.height,\n mapExtent.width,\n mapExtent.height,\n );\n return {\n zoom: clampFocusZoom(\n fitOrthoZoom(size.width, size.height, width, height),\n mapFit,\n focusMaxZoomMultiple(width, height),\n ),\n position: [focus.cx, focus.cy, 500],\n target: [focus.cx, focus.cy, 0],\n };\n }\n const sizeHint = Math.max(focus.size, 1);\n return {\n zoom: camera instanceof THREE.OrthographicCamera ? camera.zoom : 1,\n position: [focus.cx, focus.cy - sizeHint * 0.35, sizeHint * 0.85],\n target: [focus.cx, focus.cy, 0],\n };\n },\n [bounds, camera, is3d, size.height, size.width],\n );\n\n const applyFit = useCallback(() => {\n cancelZoomAnim();\n focusAnimRef.current = null;\n applyPose(fitPose(), is3d);\n persistedViewRef.current = captureView(false);\n }, [applyPose, cancelZoomAnim, captureView, fitPose, is3d, persistedViewRef]);\n\n const animateFocus = useCallback(\n (focus: SceneBounds) => {\n const dest = poseForFocusBounds(focus);\n const from = currentPose();\n userAdjusted.current = true;\n appliedFocusKey.current = focusKeyRef.current;\n cancelZoomAnim();\n if (cameraPosesNear(from, dest)) {\n focusAnimRef.current = null;\n persistedViewRef.current = captureView(true);\n return;\n }\n // Drive the pan in useFrame so a later layout effect cannot snap to dest.\n focusAnimRef.current = {\n from,\n dest,\n started: performance.now(),\n lookAt: is3d,\n };\n applyingView.current = true;\n invalidate();\n },\n [\n cancelZoomAnim,\n captureView,\n currentPose,\n invalidate,\n is3d,\n persistedViewRef,\n poseForFocusBounds,\n ],\n );\n\n const animateReset = useCallback(() => {\n const dest = fitPose();\n const from = currentPose();\n focusAnimRef.current = null;\n if (cameraPosesNear(from, dest)) {\n userAdjusted.current = false;\n persistedViewRef.current = captureView(false);\n return;\n }\n cancelZoomAnim();\n const started = performance.now();\n const lookAt = is3d;\n const step = (now: number) => {\n const t = Math.min(1, (now - started) / VIEWER_ZOOM_ANIM_MS);\n applyPose(interpolateCameraPose(from, dest, t), lookAt);\n persistedViewRef.current = captureView(false);\n if (t < 1) {\n applyingView.current = true;\n zoomAnimRef.current = requestAnimationFrame(step);\n return;\n }\n zoomAnimRef.current = null;\n userAdjusted.current = false;\n applyingView.current = false;\n };\n applyingView.current = true;\n zoomAnimRef.current = requestAnimationFrame(step);\n }, [\n applyPose,\n cancelZoomAnim,\n captureView,\n currentPose,\n fitPose,\n is3d,\n persistedViewRef,\n ]);\n const applyFitRef = useRef(applyFit);\n applyFitRef.current = applyFit;\n const restoreViewRef = useRef(restoreView);\n restoreViewRef.current = restoreView;\n const animateFocusRef = useRef(animateFocus);\n animateFocusRef.current = animateFocus;\n\n const zoomBy = useCallback(\n (direction: 1 | -1) => {\n userAdjusted.current = true;\n focusAnimRef.current = null;\n const controls = controlsRef.current;\n if (camera instanceof THREE.OrthographicCamera && !is3d) {\n const { width, height } = boundsExtent(bounds);\n const fit = fitOrthoZoom(size.width, size.height, width, height);\n animateOrthoZoom(\n nextOrthoZoom(\n camera.zoom,\n direction,\n theme.ZOOM_STEP,\n fit * 0.2,\n fit * VIEWER_MAX_ZOOM_MULTIPLE,\n ),\n );\n } else if (controls) {\n const offset = camera.position.clone().sub(controls.target);\n const factor = 1 + Math.min(Math.max(theme.ZOOM_STEP, 0.15), 1) * 0.5;\n const next = direction > 0 ? offset.length() / factor : offset.length() * factor;\n offset.setLength(\n Math.min(theme.CAMERA_MAX_DISTANCE, Math.max(theme.CAMERA_MIN_DISTANCE, next)),\n );\n camera.position.copy(controls.target).add(offset);\n persistedViewRef.current = captureView();\n }\n controls?.update();\n invalidate();\n },\n [\n animateOrthoZoom,\n bounds,\n camera,\n captureView,\n controlsRef,\n invalidate,\n is3d,\n persistedViewRef,\n size.height,\n size.width,\n theme,\n ],\n );\n\n useEffect(() => () => cancelZoomAnim(), [cancelZoomAnim]);\n\n useEffect(() => {\n const controls = controlsRef.current;\n if (!controls) return;\n const onChange = () => {\n if (applyingView.current) return;\n userAdjusted.current = true;\n persistedViewRef.current = captureView(true);\n };\n const onStart = () => {\n if (applyingView.current) return;\n // Pointer drag — not OrbitControls.update() during a programmed ease.\n userAdjusted.current = true;\n focusAnimRef.current = null;\n persistedViewRef.current = captureView(true);\n };\n controls.addEventListener('change', onChange);\n controls.addEventListener('start', onStart);\n return () => {\n controls.removeEventListener('change', onChange);\n controls.removeEventListener('start', onStart);\n };\n }, [camera, captureView, controlsRef, persistedViewRef]);\n\n useImperativeHandle(\n cameraRef,\n () => ({\n zoomIn: () => {\n zoomBy(1);\n },\n zoomOut: () => {\n zoomBy(-1);\n },\n reset: () => {\n userAdjusted.current = false;\n focusAnimRef.current = null;\n appliedFocusKey.current = null;\n focusKeyRef.current = null;\n animateReset();\n },\n focusBounds: (focus) => {\n animateFocus(focus);\n },\n }),\n [animateFocus, animateReset, zoomBy],\n );\n\n useLayoutEffect(() => {\n if (size.width < 2 || size.height < 2) return;\n if (focusKey == null) {\n appliedFocusKey.current = null;\n focusAnimRef.current = null;\n }\n const snap = persistedViewRef.current;\n const focus = focusViewBoundsRef.current;\n const isNewFocus =\n focusKey != null && focus != null && appliedFocusKey.current !== focusKey;\n const snapMatchesFocus =\n snap != null &&\n snap.is3d === is3d &&\n snap.boundsKey === boundsKey &&\n snap.focusKey === focusKey;\n\n if (focusKey != null && focus != null) {\n if (snapMatchesFocus) {\n appliedFocusKey.current = focusKey;\n if (focusAnimRef.current == null) restoreViewRef.current(snap);\n return;\n }\n if (isNewFocus) {\n // Only the first map paint snaps — otherwise the unfitted camera flashes.\n // Every later selection eases from the current view, like v1.\n if (persistedViewRef.current == null) {\n appliedFocusKey.current = focusKey;\n userAdjusted.current = true;\n cancelZoomAnim();\n applyPose(poseForFocusBounds(focus), is3d);\n persistedViewRef.current = captureView(true);\n return;\n }\n if (snap && !snapMatchesFocus) restoreViewRef.current(snap);\n animateFocusRef.current(focus);\n return;\n }\n // Same selection after a remount / theme swap — keep the current view.\n // Do not snap: that cancelled the ease when this effect re-ran.\n return;\n }\n\n // Theme rebuilds can swap the drei camera or remount this rig. Keep the\n // last view when the map extents and 2D/3D mode have not changed.\n if (snap && snap.is3d === is3d && snap.boundsKey === boundsKey) {\n restoreViewRef.current(snap);\n return;\n }\n userAdjusted.current = false;\n applyFitRef.current();\n }, [\n applyPose,\n boundsKey,\n camera,\n cancelZoomAnim,\n captureView,\n focusKey,\n is3d,\n persistedViewRef,\n poseForFocusBounds,\n ]);\n\n useEffect(() => {\n if (size.width < 2 || size.height < 2 || userAdjusted.current) return;\n applyFitRef.current();\n }, [size.height, size.width]);\n\n useFrame(() => {\n const anim = focusAnimRef.current;\n if (!anim) return;\n const t = Math.min(1, (performance.now() - anim.started) / VIEWER_FOCUS_ANIM_MS);\n applyPose(\n interpolateCameraPose(anim.from, anim.dest, t, easeOutCubic),\n anim.lookAt,\n );\n persistedViewRef.current = captureView(true);\n if (t < 1) {\n invalidate();\n return;\n }\n focusAnimRef.current = null;\n });\n\n return null;\n}\n","import React, { useMemo, useRef } from 'react';\nimport { Canvas } from '@react-three/fiber';\nimport { OrthographicCamera, OrbitControls } from '@react-three/drei';\nimport type { OrbitControls as OrbitControlsImpl } from 'three-stdlib';\nimport type { PathResult, PublishedDocument, SceneBounds, ThemeDefaults } from '../../core';\nimport {\n boundsFromStackedLevels,\n isOutdoorLevel,\n isTransparentColor,\n outdoorSvgSuppressIds,\n viewerLevelStack,\n} from '../../core';\nimport { LevelMeshes } from './LevelMeshes';\nimport { RouteLine } from './RouteLine';\nimport { SvgVectorLayer } from './SvgVectorLayer';\nimport { CameraRig, type CameraViewSnapshot, type MapCameraHandle } from './CameraRig';\nimport {\n ORBIT_ZOOM_TO_CURSOR,\n SCENE_FLIP_SCALE,\n orbitMouseButtons,\n orbitTouches,\n viewBoundsFromData,\n} from '../camera';\nimport { pointerMissClearsSelection } from '../pointer';\n\nconst OUTDOOR_Z = -1;\nconst CAMERA_UP: [number, number, number] = [0, 1, 0];\nconst CANVAS_DPR: [number, number] = [1, 2];\nconst CANVAS_GL = { antialias: true };\n\nexport interface MapSceneProps {\n doc: PublishedDocument;\n theme: ThemeDefaults;\n activeLevelId: number | null;\n route: PathResult | null;\n selectedShapeId?: number | null;\n selectedShapeIds?: number[];\n hoveredShapeId?: number | null;\n focusKey?: string | number | null;\n focusViewBounds?: SceneBounds | null;\n cameraRef?: React.Ref<MapCameraHandle | null>;\n onSelectShape?: (\n shapeId: number | null,\n levelId: number,\n opts?: { additive?: boolean },\n ) => void;\n imageProxyUrl?: string | null;\n /** Keep pointer events inside the map canvas host so header/footer stay clickable. */\n eventSource?: React.RefObject<HTMLElement | null>;\n}\n\nexport function MapScene({\n doc,\n theme,\n activeLevelId,\n route,\n selectedShapeId,\n selectedShapeIds,\n hoveredShapeId = null,\n focusKey,\n focusViewBounds,\n cameraRef,\n onSelectShape,\n imageProxyUrl,\n eventSource,\n}: MapSceneProps) {\n const is3d = theme.MAP_STYLE === '3D';\n const controlsRef = useRef<OrbitControlsImpl | null>(null);\n const persistedViewRef = useRef<CameraViewSnapshot | null>(null);\n const pointerDownRef = useRef<{ x: number; y: number } | null>(null);\n\n const stacked = useMemo(\n () => viewerLevelStack(doc.levels, activeLevelId),\n [doc.levels, activeLevelId],\n );\n\n const bounds = useMemo(\n () => boundsFromStackedLevels(doc.levels, activeLevelId, doc.baseViewbox),\n [doc.levels, doc.baseViewbox, activeLevelId],\n );\n\n const view = useMemo(\n () => viewBoundsFromData(bounds),\n [\n bounds.cx,\n bounds.cy,\n bounds.maxX,\n bounds.maxY,\n bounds.minX,\n bounds.minY,\n bounds.size,\n ],\n );\n const cameraPosition = useMemo(\n () => [view.cx, view.cy, 500] as [number, number, number],\n [view.cx, view.cy],\n );\n const camera3dPosition = useMemo(\n () =>\n [view.cx, view.cy - view.size * 0.35, view.size * 0.85] as [\n number,\n number,\n number,\n ],\n [view.cx, view.cy, view.size],\n );\n const mouseButtons = useMemo(() => orbitMouseButtons(is3d), [is3d]);\n const touches = useMemo(() => orbitTouches(is3d), [is3d]);\n\n const outdoorLevel = useMemo(\n () => doc.levels.find((level) => isOutdoorLevel(level)) ?? null,\n [doc.levels],\n );\n\n const outdoorSvgUrl =\n outdoorLevel?.sourceSvgUrl ?? doc.baseSvgUrl ?? null;\n\n const suppressIds = useMemo(\n () => outdoorSvgSuppressIds(doc.levels),\n [doc.levels],\n );\n\n const showOutdoorSvg = stacked.some((level) => isOutdoorLevel(level));\n\n const outdoorTheme = useMemo(\n () => ({\n GREEN_AREA_COLOR: theme.GREEN_AREA_COLOR,\n WATER_COLOR: theme.WATER_COLOR,\n PARKING_LANE_COLOR: theme.PARKING_LANE_COLOR,\n PARKING_ICON_COLOR: theme.PARKING_ICON_COLOR,\n WALKABLE_COLOR: theme.WALKABLE_COLOR,\n }),\n [\n theme.GREEN_AREA_COLOR,\n theme.PARKING_ICON_COLOR,\n theme.PARKING_LANE_COLOR,\n theme.WALKABLE_COLOR,\n theme.WATER_COLOR,\n ],\n );\n\n return (\n <Canvas\n style={{\n width: '100%',\n height: '100%',\n background: isTransparentColor(theme.MAP_BACKGROUND_COLOR)\n ? 'transparent'\n : theme.MAP_BACKGROUND_COLOR,\n }}\n eventSource={eventSource as React.RefObject<HTMLElement> | undefined}\n eventPrefix=\"offset\"\n orthographic={!is3d}\n frameloop=\"demand\"\n dpr={CANVAS_DPR}\n flat\n gl={CANVAS_GL}\n onPointerDown={(e) => {\n pointerDownRef.current = { x: e.clientX, y: e.clientY };\n }}\n onPointerMissed={(e) => {\n if (\n pointerMissClearsSelection(pointerDownRef.current, {\n x: e.clientX,\n y: e.clientY,\n button: e.button,\n })\n ) {\n onSelectShape?.(null, activeLevelId ?? 0);\n }\n }}\n camera={\n is3d\n ? {\n position: camera3dPosition,\n fov: 50,\n near: 1,\n far: 10000,\n up: CAMERA_UP,\n }\n : undefined\n }\n >\n {!is3d && (\n <OrthographicCamera\n makeDefault\n position={cameraPosition}\n up={CAMERA_UP}\n near={0.1}\n far={5000}\n />\n )}\n {isTransparentColor(theme.MAP_BACKGROUND_COLOR) ? null : (\n <color attach=\"background\" args={[theme.MAP_BACKGROUND_COLOR]} />\n )}\n <ambientLight intensity={4} color=\"#c4c4c4\" />\n <directionalLight position={[0, 400, 0]} color=\"#ffffff\" intensity={0.3} />\n <directionalLight position={[0, 0, 400]} color=\"#c4c4c4\" intensity={0.2} />\n <directionalLight position={[0, 0, -400]} color=\"#c4c4c4\" intensity={0.2} />\n\n <group scale={SCENE_FLIP_SCALE}>\n {showOutdoorSvg && outdoorSvgUrl ? (\n <SvgVectorLayer\n url={outdoorSvgUrl}\n suppressIds={suppressIds}\n imageProxyUrl={imageProxyUrl}\n is3d={is3d}\n theme={outdoorTheme}\n />\n ) : null}\n\n {stacked.map((level) => {\n const outdoor = isOutdoorLevel(level);\n const transform = level.transform;\n return (\n <group\n key={level.id}\n position={[\n transform.translateX,\n transform.translateY,\n outdoor ? OUTDOOR_Z : 0,\n ]}\n rotation={[0, 0, (transform.rotate * Math.PI) / 180]}\n scale={transform.scale || 1}\n >\n <LevelMeshes\n level={level}\n theme={theme}\n is3d={is3d}\n eventSource={eventSource}\n selectedShapeIds={selectedShapeIds}\n hoveredShapeId={hoveredShapeId}\n interactiveOnly={outdoor && Boolean(outdoorSvgUrl)}\n imageProxyUrl={imageProxyUrl}\n amenities={doc.amenities}\n onSelectShape={(shapeId, opts) =>\n onSelectShape?.(shapeId, level.id, opts)\n }\n />\n </group>\n );\n })}\n\n {route && (\n <RouteLine\n route={route}\n activeLevelId={activeLevelId}\n color={theme.ACCENT_COLOR}\n />\n )}\n </group>\n\n <OrbitControls\n ref={controlsRef}\n makeDefault\n enableDamping={false}\n enableRotate={is3d}\n enablePan\n enableZoom\n screenSpacePanning\n zoomSpeed={1}\n zoomToCursor={ORBIT_ZOOM_TO_CURSOR}\n mouseButtons={mouseButtons}\n touches={touches}\n maxDistance={theme.CAMERA_MAX_DISTANCE}\n minDistance={theme.CAMERA_MIN_DISTANCE}\n />\n <CameraRig\n bounds={view}\n theme={theme}\n is3d={is3d}\n controlsRef={controlsRef}\n cameraRef={cameraRef}\n persistedViewRef={persistedViewRef}\n focusKey={focusKey ?? selectedShapeId ?? null}\n focusViewBounds={focusViewBounds ?? null}\n />\n </Canvas>\n );\n}\n","import React, { useMemo, useState } from 'react';\nimport type {\n CmAmenityCatalogItem,\n PathResult,\n PublishedDocument,\n} from '../../core';\nimport { ModernSelect } from '../../ui/ModernSelect';\nimport { getAmenityByType, recolorMapSvg } from '../../specialIcons';\n\nexport interface RuntimeChromeProps {\n doc: PublishedDocument;\n amenities: CmAmenityCatalogItem[];\n activeLevelId: number | null;\n onActiveLevelChange: (id: number) => void;\n fromAnchorId: number | null;\n toAnchorId: number | null;\n onFromChange: (id: number | null) => void;\n onToChange: (id: number | null) => void;\n accessibleOnly: boolean;\n onAccessibleOnlyChange: (v: boolean) => void;\n route: PathResult | null;\n showSearch?: boolean;\n showAmenities?: boolean;\n}\n\ninterface ListItem {\n id: string;\n label: string;\n group: string;\n anchorId: number | null;\n levelId: number;\n kind: 'store' | 'amenity';\n amenityId: number | null;\n}\n\nfunction itemLabel(\n shape: PublishedDocument['levels'][number]['shapes'][number],\n amenityName?: string,\n): string {\n return (\n shape.assignment?.customLabel ||\n amenityName ||\n shape.label.text ||\n shape.assignment?.unitNumber ||\n shape.key\n );\n}\n\nexport function RuntimeChrome({\n doc,\n amenities,\n onActiveLevelChange,\n fromAnchorId,\n toAnchorId,\n onFromChange,\n onToChange,\n accessibleOnly,\n onAccessibleOnlyChange,\n route,\n showSearch = true,\n showAmenities = true,\n}: RuntimeChromeProps) {\n const [query, setQuery] = useState('');\n const [selectedItem, setSelectedItem] = useState<ListItem | null>(null);\n\n const items = useMemo(() => {\n const list: ListItem[] = [];\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id) ?? null;\n if (shape.kind === 'unit') {\n list.push({\n id: `store-${shape.id}`,\n label: itemLabel(shape),\n group: level.name,\n anchorId: anchor?.id ?? null,\n levelId: level.id,\n kind: 'store',\n amenityId: null,\n });\n }\n if (shape.kind === 'amenity' && shape.assignment?.amenityId) {\n const amenity = amenities.find((a) => a.id === shape.assignment!.amenityId);\n list.push({\n id: `amenity-${shape.id}`,\n label: itemLabel(shape, amenity?.name),\n group: 'Amenities',\n anchorId: anchor?.id ?? null,\n levelId: level.id,\n kind: 'amenity',\n amenityId: amenity?.id ?? shape.assignment.amenityId,\n });\n }\n }\n }\n return list;\n }, [doc, amenities]);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return items;\n return items.filter((i) => i.label.toLowerCase().includes(q));\n }, [items, query]);\n\n const grouped = useMemo(() => {\n const map = new Map<string, ListItem[]>();\n for (const item of filtered) {\n const arr = map.get(item.group) ?? [];\n arr.push(item);\n map.set(item.group, arr);\n }\n return Array.from(map.entries());\n }, [filtered]);\n\n const anchorOptions = items.filter((i) => i.anchorId != null);\n const hasQuery = query.trim().length > 0;\n\n const selectItem = (item: ListItem) => {\n setSelectedItem(item);\n if (item.anchorId != null) {\n onToChange(item.anchorId);\n onActiveLevelChange(item.levelId);\n }\n };\n\n if (!showSearch && !(showAmenities && amenities.length > 0)) {\n return null;\n }\n\n return (\n <div className=\"eyeon-map-chrome\">\n <div className=\"eyeon-map-chrome__top\">\n {showSearch && (\n <input\n type=\"search\"\n className=\"eyeon-map-chrome__search-input\"\n placeholder=\"Search...\"\n aria-label=\"Search...\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n )}\n\n {showAmenities && amenities.length > 0 && (\n <div className=\"eyeon-map-chrome__amenities\">\n {amenities.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n className=\"eyeon-map-chrome__amenity\"\n aria-label={a.name}\n onClick={() => {\n const match = items.find(\n (i) =>\n i.kind === 'amenity' &&\n i.amenityId === a.id &&\n i.anchorId != null,\n );\n if (match) selectItem(match);\n }}\n >\n {(() => {\n const amenity = getAmenityByType(a.code);\n return amenity ? (\n <span\n className=\"eyeon-map-chrome__amenity-icon\"\n dangerouslySetInnerHTML={{\n __html: recolorMapSvg(amenity.svgCode, '#334155'),\n }}\n />\n ) : (\n <span className=\"eyeon-map-chrome__amenity-label\">\n {a.name.slice(0, 2)}\n </span>\n );\n })()}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {showSearch && hasQuery && (\n <div className=\"eyeon-map-chrome__panel\">\n <div className=\"eyeon-map-chrome__groups\">\n {grouped.length === 0 ? (\n <div className=\"eyeon-map-chrome__empty\">No matching stores</div>\n ) : (\n grouped.map(([group, groupItems]) => (\n <div key={group} className=\"eyeon-map-chrome__group\">\n <div className=\"eyeon-map-chrome__group-title\">{group}</div>\n {groupItems.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n className={\n selectedItem?.id === item.id\n ? 'eyeon-map-chrome__item is-selected'\n : 'eyeon-map-chrome__item'\n }\n onClick={() => selectItem(item)}\n >\n {item.label}\n </button>\n ))}\n </div>\n ))\n )}\n </div>\n\n {selectedItem && (\n <div className=\"eyeon-map-chrome__detail\">\n <div className=\"eyeon-map-chrome__detail-title\">{selectedItem.label}</div>\n <div className=\"eyeon-map-chrome__detail-meta\">{selectedItem.group}</div>\n </div>\n )}\n\n <div className=\"eyeon-map-chrome__route\">\n <label>\n From\n <ModernSelect\n ariaLabel=\"From\"\n value={fromAnchorId != null ? String(fromAnchorId) : ''}\n placeholder=\"Select start\"\n searchable\n options={anchorOptions.map((i) => ({\n value: String(i.anchorId),\n label: `${i.label} · ${i.group}`,\n }))}\n onChange={(next) => onFromChange(next ? Number(next) : null)}\n />\n </label>\n <label>\n To\n <ModernSelect\n ariaLabel=\"To\"\n value={toAnchorId != null ? String(toAnchorId) : ''}\n placeholder=\"Select destination\"\n searchable\n options={anchorOptions.map((i) => ({\n value: String(i.anchorId),\n label: `${i.label} · ${i.group}`,\n }))}\n onChange={(next) => onToChange(next ? Number(next) : null)}\n />\n </label>\n <label className=\"eyeon-map-chrome__accessible\">\n <input\n type=\"checkbox\"\n checked={accessibleOnly}\n onChange={(e) => onAccessibleOnlyChange(e.target.checked)}\n />\n Accessible route\n </label>\n {route && (\n <div className=\"eyeon-map-chrome__route-meta\">\n {route.levelChanges.length > 0\n ? `${route.levelChanges.length} level change(s)`\n : 'Same level'}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React, { Suspense, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n CmAmenityCatalogItem,\n MapViewerHost,\n PathResult,\n PublishedDocument,\n ThemeDefaults,\n} from '../core';\nimport {\n compileGraph,\n defaultViewerLevelId,\n hasBuildingFloors,\n MAP_NO_FLOORS_MESSAGE,\n mergeTheme,\n findPath,\n normalizePublishedDocument,\n viewerChrome,\n viewerLevelIdAfterShapeSelect,\n} from '../core';\nimport { MapScene } from './components/MapScene';\nimport { isAssignAmenity } from '../specialIcons';\nimport type { MapCameraHandle } from './components/CameraRig';\nimport { RuntimeChrome } from './ui/RuntimeChrome';\nimport { MapControls } from './ui/MapControls';\nimport {\n selectionFocusKey,\n viewFocusBoundsForShape,\n viewFocusBoundsForShapes,\n} from './camera';\nimport { ensureMapFont } from '../fonts/mapFontUrl';\nimport './viewer.css';\n\nexport interface MapViewerProps {\n /** Published (or draft) document. If omitted, fetched from webApiURI. */\n document?: PublishedDocument | null;\n webApiURI?: string;\n /** Prefer fetching /v1/map/document */\n centerId?: number;\n /** Public / preview / kiosk surface. Never includes Map options (editor rail). */\n host?: MapViewerHost;\n kioskId?: number | null;\n selectedRetailerId?: number | null;\n /**\n * Media proxy base, appended with the encoded SVG URL (v1 `IMAGE_PROXY_URL`\n * contract, e.g. `/eyeon-portal/media?url=`). Needed wherever the outdoor\n * SVG origin sends no CORS headers.\n */\n imageProxyUrl?: string | null;\n themeOverrides?: Partial<ThemeDefaults>;\n onExtractedAmenities?: (codes: string[]) => void;\n onSelectShape?: (shapeId: number | null, opts?: { additive?: boolean }) => void;\n /** Zoom to this shape (PORTAL default-map assign). */\n selectedShapeId?: number | null;\n /** Extra selected shapes when Shift-selecting in PORTAL assign. */\n selectedShapeIds?: number[];\n /** Highlight from the Map options list (same fill as pointer hover). */\n hoveredShapeId?: number | null;\n /**\n * Bump when staff pick a row in the rail so the camera re-frames even if\n * the same shape is already selected.\n */\n focusNonce?: number;\n /** Controlled floor when embedded (e.g. PORTAL default). */\n activeLevelId?: number | null;\n onActiveLevelChange?: (levelId: number) => void;\n /** Click a store/amenity to route. Off when PORTAL is assigning. Default true. */\n routeOnSelect?: boolean;\n createRouteRef?: React.MutableRefObject<{\n createRouteToStore: (retailerId: number) => void;\n createRouteToAmenity: (amenityCode: string) => void;\n clearRoute: () => void;\n } | null>;\n className?: string;\n style?: React.CSSProperties;\n}\n\nasync function fetchDocument(\n webApiURI: string,\n centerId?: number,\n draft?: boolean,\n signal?: AbortSignal,\n): Promise<PublishedDocument> {\n const base = webApiURI.replace(/\\/$/, '');\n const params = new URLSearchParams();\n if (centerId != null && centerId > 0) params.set('center_id', String(centerId));\n if (draft) params.set('draft', '1');\n const qs = params.toString();\n const res = await fetch(`${base}/v1/map/document${qs ? `?${qs}` : ''}`, {\n credentials: 'include',\n signal,\n });\n if (!res.ok) {\n throw new Error(`Failed to load map document (${res.status})`);\n }\n return res.json();\n}\n\nexport function MapViewer(props: MapViewerProps) {\n ensureMapFont();\n const {\n document: documentProp,\n webApiURI,\n centerId,\n host = 'WEBSITE',\n kioskId = null,\n selectedRetailerId = null,\n themeOverrides,\n onExtractedAmenities,\n createRouteRef,\n className,\n style,\n activeLevelId: activeLevelIdProp,\n onActiveLevelChange,\n routeOnSelect = true,\n imageProxyUrl,\n selectedShapeId = null,\n selectedShapeIds,\n hoveredShapeId = null,\n focusNonce,\n } = props;\n\n const [rawDoc, setDoc] = useState<PublishedDocument | null>(documentProp ?? null);\n const doc = useMemo(\n () => (rawDoc ? normalizePublishedDocument(rawDoc) : null),\n [rawDoc],\n );\n const [error, setError] = useState<string | null>(null);\n const [route, setRoute] = useState<PathResult | null>(null);\n const [fromAnchorId, setFromAnchorId] = useState<number | null>(null);\n const [toAnchorId, setToAnchorId] = useState<number | null>(null);\n const [accessibleOnly, setAccessibleOnly] = useState(false);\n const [internalLevelId, setInternalLevelId] = useState<number | null>(() => {\n if (!documentProp) return null;\n return defaultViewerLevelId(normalizePublishedDocument(documentProp).levels);\n });\n const cameraApi = useRef<MapCameraHandle | null>(null);\n const canvasHostRef = useRef<HTMLDivElement>(null);\n const activeLevelId = activeLevelIdProp ?? internalLevelId;\n const setActiveLevelId = (id: number | null) => {\n setInternalLevelId(id);\n if (id != null) onActiveLevelChange?.(id);\n };\n\n useEffect(() => {\n if (documentProp) {\n setDoc(documentProp);\n return;\n }\n if (!webApiURI) return;\n let cancelled = false;\n const controller = new AbortController();\n const draft = viewerChrome(host).fetchDraft;\n fetchDocument(webApiURI, centerId, draft, controller.signal)\n .then((d) => {\n if (!cancelled) setDoc(d);\n })\n .catch((e) => {\n if (\n !cancelled &&\n !(e instanceof DOMException && e.name === 'AbortError')\n ) {\n setError(e instanceof Error ? e.message : String(e));\n }\n });\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [documentProp, webApiURI, centerId, host]);\n\n useEffect(() => {\n if (!doc) return;\n const ids = new Set(doc.levels.map((level) => level.id));\n if (activeLevelId == null || !ids.has(activeLevelId)) {\n setActiveLevelId(defaultViewerLevelId(doc.levels));\n }\n const codes = new Set<string>();\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.kind === 'amenity' && shape.assignment?.amenityId != null) {\n const amenity = doc.amenities.find((a) => a.id === shape.assignment!.amenityId);\n if (amenity) codes.add(amenity.code);\n }\n }\n }\n onExtractedAmenities?.(Array.from(codes));\n }, [doc, activeLevelId, onExtractedAmenities]);\n\n // Map IT / ?r= — switch to the store's floor so the highlight is visible\n useEffect(() => {\n if (!doc || selectedRetailerId == null) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.retailerId === selectedRetailerId) {\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n return;\n }\n }\n }\n }, [doc, selectedRetailerId]);\n\n const focusShapeIds = useMemo(() => {\n if (selectedShapeIds && selectedShapeIds.length > 0) return selectedShapeIds;\n return selectedShapeId != null ? [selectedShapeId] : [];\n }, [selectedShapeId, selectedShapeIds]);\n const selectionKey = selectionFocusKey(focusShapeIds);\n const focusKey =\n selectionKey == null\n ? null\n : focusNonce != null\n ? `${selectionKey}#${focusNonce}`\n : selectionKey;\n const focusViewBounds = useMemo(() => {\n if (!doc || focusShapeIds.length === 0) return null;\n // Union every selected shape so Shift-select frames the group, not the first id.\n return viewFocusBoundsForShapes(doc.levels, focusShapeIds);\n }, [doc, focusShapeIds]);\n\n // Prefill \"from\" for kiosk host\n useEffect(() => {\n if (!doc || !viewerChrome(host).kioskOrigin || kioskId == null) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (\n shape.kind === 'kiosk_screen' &&\n shape.assignment?.kioskId === kioskId\n ) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) setFromAnchorId(anchor.id);\n }\n }\n }\n }, [doc, host, kioskId]);\n\n const compiled = useMemo(() => {\n if (!doc) return null;\n return compileGraph(\n doc.graph.nodes.map((n) => ({\n id: n.id,\n levelId: n.levelId,\n shapeId: n.shapeId,\n kind: n.kind,\n x: n.x,\n y: n.y,\n connectorId: n.connectorId,\n })),\n doc.graph.edges.map((e) => ({\n id: e.id,\n mapId: doc.mapId,\n fromAnchorId: e.from,\n toAnchorId: e.to,\n weight: e.weight,\n directed: e.directed,\n accessible: e.accessible,\n kind: e.kind,\n })),\n doc.connectors,\n );\n }, [doc]);\n\n const runRoute = (fromId: number | null, toId: number | null) => {\n if (!compiled || fromId == null || toId == null) {\n setRoute(null);\n return;\n }\n const result = findPath(compiled, fromId, toId, { accessibleOnly });\n setRoute(result);\n };\n\n useEffect(() => {\n runRoute(fromAnchorId, toAnchorId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fromAnchorId, toAnchorId, accessibleOnly, compiled]);\n\n useEffect(() => {\n if (!createRouteRef || !doc) return;\n const routeApi = {\n createRouteToStore(retailerId: number) {\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.retailerId === retailerId) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) {\n setToAnchorId(anchor.id);\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n }\n }\n }\n }\n },\n createRouteToAmenity(amenityCode: string) {\n const amenity = doc.amenities.find((a) => a.code === amenityCode);\n if (!amenity) return;\n for (const level of doc.levels) {\n for (const shape of level.shapes) {\n if (shape.assignment?.amenityId === amenity.id) {\n const anchor = level.anchors.find((a) => a.shapeId === shape.id);\n if (anchor) {\n setToAnchorId(anchor.id);\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, level.id),\n );\n return;\n }\n }\n }\n }\n },\n clearRoute() {\n setToAnchorId(null);\n setRoute(null);\n },\n };\n createRouteRef.current = routeApi;\n return () => {\n if (createRouteRef.current === routeApi) createRouteRef.current = null;\n };\n }, [activeLevelId, createRouteRef, doc]);\n\n const theme: ThemeDefaults = mergeTheme(doc?.theme, themeOverrides);\n\n if (error) {\n return (\n <div className={`eyeon-map-viewer eyeon-map-viewer--error ${className ?? ''}`} style={style}>\n <div className=\"eyeon-map-viewer__error\">{error}</div>\n </div>\n );\n }\n\n if (!doc) {\n return (\n <div className={`eyeon-map-viewer eyeon-map-viewer--loading ${className ?? ''}`} style={style}>\n <div className=\"eyeon-map-viewer__loading\">Loading map…</div>\n </div>\n );\n }\n\n const amenitiesOnMap: CmAmenityCatalogItem[] = doc.amenities.filter(\n (a) =>\n isAssignAmenity(a.code) &&\n doc.levels.some((l) =>\n l.shapes.some((s) => s.assignment?.amenityId === a.id),\n ),\n );\n const chrome = viewerChrome(host);\n const hasFloors = hasBuildingFloors(doc.levels);\n\n return (\n <div\n className={`eyeon-map-viewer eyeon-map-viewer--${host}${hasFloors ? '' : ' eyeon-map-viewer--empty'} ${className ?? ''}`}\n style={\n {\n ...style,\n ['--map-accent' as string]: theme.ACCENT_COLOR,\n ['--map-bg' as string]: theme.MAP_BACKGROUND_COLOR,\n } as React.CSSProperties\n }\n >\n {!hasFloors ? (\n <div className=\"eyeon-map-viewer__empty\">{MAP_NO_FLOORS_MESSAGE}</div>\n ) : null}\n\n {hasFloors && (chrome.search || chrome.amenities) && (\n <RuntimeChrome\n doc={doc}\n amenities={amenitiesOnMap}\n activeLevelId={activeLevelId}\n onActiveLevelChange={setActiveLevelId}\n fromAnchorId={fromAnchorId}\n toAnchorId={toAnchorId}\n onFromChange={setFromAnchorId}\n onToChange={setToAnchorId}\n accessibleOnly={accessibleOnly}\n onAccessibleOnlyChange={setAccessibleOnly}\n route={route}\n showSearch={chrome.search}\n showAmenities={chrome.amenities}\n />\n )}\n\n {hasFloors ? (\n <MapControls\n levels={doc.levels}\n activeLevelId={activeLevelId}\n onActiveLevelChange={setActiveLevelId}\n onZoomIn={() => cameraApi.current?.zoomIn()}\n onZoomOut={() => cameraApi.current?.zoomOut()}\n onReset={() => cameraApi.current?.reset()}\n showFloors={chrome.floors}\n showZoomReset={chrome.zoomReset}\n />\n ) : null}\n\n {hasFloors ? (\n <div ref={canvasHostRef} className=\"eyeon-map-viewer__canvas\">\n <Suspense fallback={null}>\n <MapScene\n doc={doc}\n theme={theme}\n activeLevelId={activeLevelId}\n route={route}\n selectedShapeId={selectedShapeId}\n selectedShapeIds={focusShapeIds}\n hoveredShapeId={hoveredShapeId}\n focusKey={focusKey}\n focusViewBounds={focusViewBounds}\n cameraRef={cameraApi}\n eventSource={canvasHostRef}\n imageProxyUrl={imageProxyUrl}\n onSelectShape={(shapeId, levelId, opts) => {\n if (shapeId == null) {\n props.onSelectShape?.(null);\n return;\n }\n if (!opts?.additive) {\n setActiveLevelId(\n viewerLevelIdAfterShapeSelect(doc.levels, activeLevelId, levelId),\n );\n }\n if (routeOnSelect) {\n const level = doc.levels.find((l) => l.id === levelId);\n const anchor = level?.anchors.find((a) => a.shapeId === shapeId);\n if (anchor) setToAnchorId(anchor.id);\n }\n props.onSelectShape?.(shapeId, opts);\n if (!opts?.additive && shapeId === selectedShapeId) {\n const focus =\n viewFocusBoundsForShapes(doc.levels, focusShapeIds) ??\n viewFocusBoundsForShape(doc.levels, shapeId);\n if (focus) cameraApi.current?.focusBounds(focus);\n }\n }}\n />\n </Suspense>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default MapViewer;\n"],"names":["MapControls","levels","activeLevelId","onActiveLevelChange","onZoomIn","onZoomOut","onReset","showFloors","showZoomReset","floorOptions","alwaysShowFloors","stackLevels","level","switcher","floorSwitcherDisplayLevels","showFloorList","shouldShowFloorSwitcher","showZoom","hasBuildingFloors","jsxs","jsx","active","Fragment","MAP_FONT_FAMILY","MAP_LABEL_LINE_HEIGHT","SVGIcons","AllAmenities","CONNECTOR_AMENITY_TYPES","AssignAmenities","item","KioskSvg","EntranceSvg","isAssignAmenity","type","getAmenityByType","getMapSpecialSvg","id","_a","recolorMapSvg","svg","color","hex","mapSpecialSvgToDataUrl","colored","entranceIconDataUrl","amenityAssignOptions","amenityTypeFromCatalogId","amenityId","amenities","amenityCatalogIdForType","row","assignmentSpecialIconDataUrl","assignment","assignmentSpecialIconId","ASSIGNED_CONNECTOR_ICON","UNASSIGNED_CONNECTOR_ICON","connectorSpecialKind","shape","raw","connectorSpecialIconDataUrl","kind","assigned","fill","assignedConnectorShapeIds","anchors","ids","anchor","connectorMapIconKind","assignedShapeIds","mapFontUrl","MAP_FONT_URL","registered","ensureMapFont","loaded","MODERN_SELECT_SEARCH_AFTER","filterModernSelectOptions","options","query","q","o","modernSelectIsSearchable","optionCount","searchable","Chevron","ModernSelect","value","onChange","disabled","placeholder","ariaLabel","listId","useId","rootRef","useRef","triggerRef","buttonRef","menuRef","searchRef","open","setOpen","useState","setQuery","activeIndex","setActiveIndex","menuPos","setMenuPos","withSearch","selected","filtered","useMemo","close","useCallback","pick","next","updateMenuPos","el","rect","spaceBelow","spaceAbove","maxHeight","openAbove","useEffect","onDoc","e","t","_b","onKey","onMove","moveActive","delta","i","onSearchKeyDown","option","menu","createPortal","index","highlighted","target","v","polygonToThreeShape","points","THREE","polygonToThreePath","path","slabShapeWithHoles","outer","holes","hole","holesOverlappingOuter","skipRaycast","createOpeningMarkTexture","aspect","width","canvas","ctx","pad","OPENING_VOID_MARK","texture","OpeningVoidMesh","polygon","box","polygonBBox","dash","openingSpanDash","outline","first","p","geometry","material","OPENING_VOID_STROKE","line","mark","height","OPENING_VOID_FILL","bbox","span","OpeningWells","polygons","VIEWER_SELECTABLE_KINDS","isViewerSelectableKind","viewerShapeHighlighted","shapeId","hoveredShapeId","selectedShapeIds","resolvedViewerHoverId","listHoverId","pointerHoverId","viewerHoverCursor","applyViewerHoverCursor","host","cursor","viewerHoverFillOpacity","base","hovered","parseHex","h","r","g","b","n","toHex","viewerHoverFillColor","accent","amount","a","VIEWER_CLICK_DRAG_PX","pointerMissClearsSelection","down","up","dx","dy","kindColor","theme","resolvedAssignmentBgColor","polygonShape","HoverOutline","extrude","sourceGeometry","LevelMeshes","is3d","onSelectShape","hoveredShapeIdProp","eventSource","interactiveOnly","imageProxyUrl","setPointerHoverId","openings","voidPolygonsOnLevel","meshes","s","isEntranceIcon","INTERACTIVE_SHAPE_KINDS","resolveLayerStyle","radius","punch","isSlabShapeKind","threeShapes","poly","filletPolygon","labels","entranceIcons","overlays","assignmentOverlayVisible","connectorOverlays","assignedIds","layout","connectorIconLayout","url","geometryBBox","align","normalizeLabelAlign","cx","cy","tilt","Text","labelAlignX","size","DEFAULT_ENTRANCE_SIZE","AssignmentImageOverlay","fontSize","DEFAULT_ASSIGNMENT_SIZE","z","iconColor","imageKey","assignmentOverlayImageUrl","text","_c","assignmentOverlayRenderSize","rotation","x","y","selectable","baseOpacity","fillTransparent","isTransparentColor","opacity","geoShape","idx","loadCanvasTexture","signal","resolve","reject","img","cleanup","onAbort","position","setTexture","setAspect","disposed","controller","proxied","resolveFetchUrl","candidates","lastError","src","error","RouteLine","route","curve","COLOR_SPACE_SVG","SRGBColorSpace","SVGLoader","Loader","manager","onLoad","onProgress","onError","scope","loader","FileLoader","parseNode","node","style","transform","getNodeTransform","isDefsNode","parseStyle","parseCSSStylesheet","parsePathNode","parseRectNode","parsePolygonNode","parsePolylineNode","parseCircleNode","parseEllipseNode","parseLineNode","usedNodeId","usedNode","transformPath","currentTransform","paths","childNodes","transformStack","ShapePath","point","Vector2","control","firstPoint","isFirstPoint","doSetFirstPoint","d","commands","l","command","data","numbers","parseFloats","j","jl","getReflection","rx","ry","start","parseArcCommand","stylesheet","selectorList","definitions","stylesheets","x_axis_rotation","large_arc_flag","sweep_flag","end","dx2","dy2","x1p","y1p","rxs","rys","x1ps","y1ps","cr","dq","pq","cxp","cyp","theta","svgAngle","ux","uy","vx","vy","dot","len","ang","parseFloatWithUnits","w","bci","iterator","match","regex","subpath","Path","x1","y1","x2","y2","stylesheetStyles","classSelectors","addStyle","svgName","jsName","adjustFunction","clamp","positive","input","flags","stride","RE","SEP","INT","FLOAT","EXP","state","seenComma","number","exponent","result","throwSyntaxError","current","partial","newNumber","length","units","unitConversion","string","theUnit","u","scale","parseNodeTransform","Matrix3","tempTransform0","tx","ty","transformsTexts","tIndex","transformText","openParPos","closeParPos","transformType","array","angle","tempTransform1","tempTransform2","tempTransform3","scaleX","scaleY","m","transfVec2","v2","tempV3","transfEllipseGeneric","cosTheta","sinTheta","v1","Vector3","f1","f2","mF","mFInv","mQe","ed","eigenDecomposition","rt1sqrt","rt2sqrt","mDsqrt","mRT","mDRF","transformAngle","phi","cosR","sinR","isTransformFlipped","transfEllipseNoSkew","sx","getTransformScaleX","sy","getTransformScaleY","subPaths","curves","tempV2","isTransformSkewed","te","basisDot","A","B","C","rt1","rt2","cs","sn","sm","df","rt","xml","shapePath","IntersectionLocationType","classifyResult","findEdgeIntersection","a0","a1","b0","b1","x3","x4","y3","y4","nom1","nom2","denom","t1","t2","classifyPoint","edgeStart","edgeEnd","ax","ay","bx","by","sa","getIntersections","path1","path2","intersectionsRaw","intersections","path1EdgeStart","path1EdgeEnd","index2","path2EdgeStart","path2EdgeEnd","intersection","getScanlineIntersections","scanline","boundingBox","center","allIntersections","i1","i2","isHoleTo","simplePath","allPaths","scanlineMinX","scanlineMaxX","_fillRule","centerBoundingBox","scanlineIntersections","baseIntersections","otherIntersections","firstXOfPath","stack","isHole","isHoleFor","lastCWValue","identifier","simplePaths","maxY","minY","maxX","minX","ShapeUtils","Box2","sp","isAHole","shapesToReturn","Shape","lineJoin","lineCap","miterLimit","arcDivisions","minDistance","vertices","normals","uvs","BufferGeometry","Float32BufferAttribute","vertexOffset","tempV2_1","tempV2_2","tempV2_3","tempV2_4","tempV2_5","tempV2_6","tempV2_7","lastPointL","lastPointR","point0L","point0R","currentPointL","currentPointR","nextPointL","nextPointR","innerPoint","outerPoint","removeDuplicatedPoints","numPoints","isClosed","currentPoint","previousPoint","nextPoint","strokeWidth2","deltaU","u0","u1","innerSideModified","joinIsOnLeftSide","isMiter","initialJoinIsOnLeftSide","numVertices","currentCoordinate","currentCoordinateUV","getNormal","iPoint","normal1","miterSide","miterLength2","segmentLengthPrev","segmentLengthNext","makeSegmentTriangles","makeSegmentWithBevelJoin","createSegmentTrianglesWithMiddleSection","makeCircularSector","miterFraction","addVertex","addCapGeometry","lastOuter","lastInner","p1","p2","il","vl","dupPoints","newPoints","BASE_Z","getLayerNameFromNode","isInteractiveAncestor","dataName","isInteractiveGroupLabel","isStoreFolderLabel","SvgVectorLayer","suppressIds","setResult","cancelled","fetchUrl","res","inlined","inlineSvgStyles","err","out","layerName","isRoutePathLabel","isRouteFolderLabel","shapes","layerStyle","strokeTransparent","si","SCENE_FLIP_SCALE","viewBoundsFromData","bounds","fitOrthoZoom","viewWidth","viewHeight","worldWidth","worldHeight","zoomX","zoomY","boundsExtent","VIEWER_ZOOM_ANIM_MS","VIEWER_FOCUS_ANIM_MS","FOCUS_BOUNDS_PADDING","FOCUS_LARGE_PADDING","FOCUS_LARGE_EXTENT","FOCUS_PAD_SMALL_EXTENT","FOCUS_MIN_EXTENT","FOCUS_MAX_ZOOM_MULTIPLE","FOCUS_SMALL_MAX_ZOOM_MULTIPLE","VIEWER_MAX_ZOOM_MULTIPLE","focusPaddingRatio","paddingRatio","smallExtent","largePadding","largeExtent","extent","paddedFocusBounds","minExtent","rawW","rawH","halfW","halfH","focusMaxZoomMultiple","paddedWidth","paddedHeight","typicalMultiple","smallMultiple","typicalFrame","tinyFrame","clampFocusZoom","shapeFitZoom","mapFitZoom","maxMultiple","cap","selectionFocusKey","shapeIds","viewFocusBoundsForShapes","wanted","combined","sceneBoundsFromBBox","expandBounds","viewFocusBoundsForShape","easeOutCubic","lerp","interpolateCameraPose","from","to","ease","cameraPosesNear","epsilon","nextOrthoZoom","direction","step","min","max","factor","MOUSE_ROTATE","MOUSE_DOLLY","MOUSE_PAN","TOUCH_ROTATE","TOUCH_PAN","TOUCH_DOLLY_PAN","ORBIT_ZOOM_TO_CURSOR","orbitMouseButtons","orbitTouches","cameraBoundsKey","CameraRig","controlsRef","cameraRef","persistedViewRef","focusKey","focusViewBounds","camera","invalidate","useThree","userAdjusted","applyingView","zoomAnimRef","appliedFocusKey","focusKeyRef","focusViewBoundsRef","focusAnimRef","boundsKey","cancelZoomAnim","captureView","adjusted","controls","restoreView","snap","animateOrthoZoom","targetZoom","startZoom","started","now","currentPose","fitPose","applyPose","pose","lookAt","poseForFocusBounds","focus","mapExtent","mapFit","sizeHint","applyFit","animateFocus","dest","animateReset","applyFitRef","restoreViewRef","animateFocusRef","zoomBy","fit","offset","onStart","useImperativeHandle","useLayoutEffect","isNewFocus","snapMatchesFocus","useFrame","anim","OUTDOOR_Z","CAMERA_UP","CANVAS_DPR","CANVAS_GL","MapScene","doc","selectedShapeId","pointerDownRef","stacked","viewerLevelStack","boundsFromStackedLevels","view","cameraPosition","camera3dPosition","mouseButtons","touches","outdoorLevel","isOutdoorLevel","outdoorSvgUrl","outdoorSvgSuppressIds","showOutdoorSvg","outdoorTheme","Canvas","OrthographicCamera","outdoor","opts","OrbitControls","itemLabel","amenityName","RuntimeChrome","fromAnchorId","toAnchorId","onFromChange","onToChange","accessibleOnly","onAccessibleOnlyChange","showSearch","showAmenities","selectedItem","setSelectedItem","items","list","amenity","grouped","map","arr","anchorOptions","hasQuery","selectItem","group","groupItems","fetchDocument","webApiURI","centerId","draft","params","qs","MapViewer","props","documentProp","kioskId","selectedRetailerId","themeOverrides","onExtractedAmenities","createRouteRef","className","activeLevelIdProp","routeOnSelect","focusNonce","rawDoc","setDoc","normalizePublishedDocument","setError","setRoute","setFromAnchorId","setToAnchorId","setAccessibleOnly","internalLevelId","setInternalLevelId","defaultViewerLevelId","cameraApi","canvasHostRef","setActiveLevelId","viewerChrome","codes","viewerLevelIdAfterShapeSelect","focusShapeIds","selectionKey","compiled","compileGraph","runRoute","fromId","toId","findPath","routeApi","retailerId","amenityCode","mergeTheme","amenitiesOnMap","chrome","hasFloors","Suspense","levelId"],"mappings":"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","x_google_ignoreList":[15]}
|