@eyeon/map 2.0.3 → 2.0.4

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.
Files changed (149) hide show
  1. package/dist/assets/MapViewer.css +1 -1
  2. package/dist/assets/index.css +1 -1
  3. package/dist/chunks/MapViewer.js +2557 -1432
  4. package/dist/chunks/MapViewer.js.map +1 -1
  5. package/dist/chunks/stacking.js +1263 -745
  6. package/dist/chunks/stacking.js.map +1 -1
  7. package/dist/chunks/wheelZoom.js +259 -0
  8. package/dist/chunks/wheelZoom.js.map +1 -0
  9. package/dist/core/assignment.d.ts +97 -0
  10. package/dist/core/assignment.d.ts.map +1 -0
  11. package/dist/core/color.d.ts +5 -0
  12. package/dist/core/color.d.ts.map +1 -0
  13. package/dist/core/entranceIcon.d.ts +12 -0
  14. package/dist/core/entranceIcon.d.ts.map +1 -0
  15. package/dist/core/hostChrome.d.ts +2 -4
  16. package/dist/core/hostChrome.d.ts.map +1 -1
  17. package/dist/core/index.d.ts +6 -0
  18. package/dist/core/index.d.ts.map +1 -1
  19. package/dist/core/index.js +161 -89
  20. package/dist/core/labelAlign.d.ts +7 -0
  21. package/dist/core/labelAlign.d.ts.map +1 -0
  22. package/dist/core/layerStyles.d.ts +40 -7
  23. package/dist/core/layerStyles.d.ts.map +1 -1
  24. package/dist/core/outdoorDecoration.d.ts +1 -1
  25. package/dist/core/outdoorDecoration.d.ts.map +1 -1
  26. package/dist/core/publish/index.d.ts +6 -4
  27. package/dist/core/publish/index.d.ts.map +1 -1
  28. package/dist/core/stacking.d.ts +50 -3
  29. package/dist/core/stacking.d.ts.map +1 -1
  30. package/dist/core/types.d.ts +29 -1
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/core/voids.d.ts +41 -0
  33. package/dist/core/voids.d.ts.map +1 -0
  34. package/dist/core/wheelZoom.d.ts +30 -0
  35. package/dist/core/wheelZoom.d.ts.map +1 -0
  36. package/dist/editor/FieldResetButton.d.ts +7 -0
  37. package/dist/editor/FieldResetButton.d.ts.map +1 -0
  38. package/dist/editor/MapEditor.d.ts +12 -2
  39. package/dist/editor/MapEditor.d.ts.map +1 -1
  40. package/dist/editor/canvas/EditorCanvas.d.ts +6 -2
  41. package/dist/editor/canvas/EditorCanvas.d.ts.map +1 -1
  42. package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts +2 -1
  43. package/dist/editor/canvas/OutdoorSvgUnderlay.d.ts.map +1 -1
  44. package/dist/editor/canvas/coords.d.ts +26 -3
  45. package/dist/editor/canvas/coords.d.ts.map +1 -1
  46. package/dist/editor/canvas/editorFill.d.ts +3 -1
  47. package/dist/editor/canvas/editorFill.d.ts.map +1 -1
  48. package/dist/editor/canvas/editorHover.d.ts +4 -0
  49. package/dist/editor/canvas/editorHover.d.ts.map +1 -1
  50. package/dist/editor/canvas/underlayHint.d.ts +8 -0
  51. package/dist/editor/canvas/underlayHint.d.ts.map +1 -1
  52. package/dist/editor/connectorAssignments.d.ts +61 -0
  53. package/dist/editor/connectorAssignments.d.ts.map +1 -1
  54. package/dist/editor/draftOps.d.ts +8 -0
  55. package/dist/editor/draftOps.d.ts.map +1 -1
  56. package/dist/editor/editorSectionReturn.d.ts.map +1 -1
  57. package/dist/editor/ellipseDraw.d.ts +12 -0
  58. package/dist/editor/ellipseDraw.d.ts.map +1 -0
  59. package/dist/editor/entranceIcon.d.ts +15 -0
  60. package/dist/editor/entranceIcon.d.ts.map +1 -0
  61. package/dist/editor/hexColor.d.ts +2 -0
  62. package/dist/editor/hexColor.d.ts.map +1 -1
  63. package/dist/editor/index.css +824 -72
  64. package/dist/editor/index.d.ts +2 -0
  65. package/dist/editor/index.d.ts.map +1 -1
  66. package/dist/editor/index.js +6700 -4160
  67. package/dist/editor/index.js.map +1 -1
  68. package/dist/editor/labelText.d.ts +12 -2
  69. package/dist/editor/labelText.d.ts.map +1 -1
  70. package/dist/editor/labels.d.ts +8 -0
  71. package/dist/editor/labels.d.ts.map +1 -1
  72. package/dist/editor/panels/AssignForm.d.ts +17 -0
  73. package/dist/editor/panels/AssignForm.d.ts.map +1 -0
  74. package/dist/editor/panels/AssignmentStyleFields.d.ts +14 -0
  75. package/dist/editor/panels/AssignmentStyleFields.d.ts.map +1 -0
  76. package/dist/editor/panels/BulkAssignForm.d.ts +11 -0
  77. package/dist/editor/panels/BulkAssignForm.d.ts.map +1 -0
  78. package/dist/editor/panels/CatalogKioskForm.d.ts +18 -0
  79. package/dist/editor/panels/CatalogKioskForm.d.ts.map +1 -0
  80. package/dist/editor/panels/ConnectorAssign.d.ts +6 -2
  81. package/dist/editor/panels/ConnectorAssign.d.ts.map +1 -1
  82. package/dist/editor/panels/CopyToLevelButton.d.ts +10 -0
  83. package/dist/editor/panels/CopyToLevelButton.d.ts.map +1 -0
  84. package/dist/editor/panels/EntranceIconForm.d.ts +11 -0
  85. package/dist/editor/panels/EntranceIconForm.d.ts.map +1 -0
  86. package/dist/editor/panels/Inspector.d.ts +24 -3
  87. package/dist/editor/panels/Inspector.d.ts.map +1 -1
  88. package/dist/editor/panels/LeftRail.d.ts +17 -6
  89. package/dist/editor/panels/LeftRail.d.ts.map +1 -1
  90. package/dist/editor/panels/PreviewOverlay.d.ts +9 -3
  91. package/dist/editor/panels/PreviewOverlay.d.ts.map +1 -1
  92. package/dist/editor/panels/TextLabelForm.d.ts +11 -0
  93. package/dist/editor/panels/TextLabelForm.d.ts.map +1 -0
  94. package/dist/editor/panels/formRows.d.ts +41 -0
  95. package/dist/editor/panels/formRows.d.ts.map +1 -0
  96. package/dist/editor/portalSurface.d.ts +10 -2
  97. package/dist/editor/portalSurface.d.ts.map +1 -1
  98. package/dist/editor/previewDocument.d.ts +2 -1
  99. package/dist/editor/previewDocument.d.ts.map +1 -1
  100. package/dist/editor/railAssignments.d.ts +9 -2
  101. package/dist/editor/railAssignments.d.ts.map +1 -1
  102. package/dist/editor/railKiosks.d.ts +27 -0
  103. package/dist/editor/railKiosks.d.ts.map +1 -0
  104. package/dist/editor/railListCopy.d.ts +31 -0
  105. package/dist/editor/railListCopy.d.ts.map +1 -0
  106. package/dist/editor/routeStubs.d.ts +1 -1
  107. package/dist/editor/routeStubs.d.ts.map +1 -1
  108. package/dist/editor/shapeCopy.d.ts +40 -0
  109. package/dist/editor/shapeCopy.d.ts.map +1 -0
  110. package/dist/editor/shapeSelection.d.ts +6 -0
  111. package/dist/editor/shapeSelection.d.ts.map +1 -0
  112. package/dist/editor/tools.d.ts +12 -2
  113. package/dist/editor/tools.d.ts.map +1 -1
  114. package/dist/fonts/assets.d.ts +4 -0
  115. package/dist/fonts/mapFont.d.ts +5 -0
  116. package/dist/fonts/mapFont.d.ts.map +1 -0
  117. package/dist/fonts/mapFontUrl.d.ts +8 -0
  118. package/dist/fonts/mapFontUrl.d.ts.map +1 -0
  119. package/dist/specialIcons.d.ts +39 -0
  120. package/dist/specialIcons.d.ts.map +1 -0
  121. package/dist/ui/ModernSelect.d.ts.map +1 -1
  122. package/dist/ui/selectSearch.d.ts +3 -0
  123. package/dist/ui/selectSearch.d.ts.map +1 -1
  124. package/dist/viewer/MapViewer.d.ts +14 -1
  125. package/dist/viewer/MapViewer.d.ts.map +1 -1
  126. package/dist/viewer/camera.d.ts +82 -1
  127. package/dist/viewer/camera.d.ts.map +1 -1
  128. package/dist/viewer/components/CameraRig.d.ts +18 -1
  129. package/dist/viewer/components/CameraRig.d.ts.map +1 -1
  130. package/dist/viewer/components/LevelMeshes.d.ts +15 -4
  131. package/dist/viewer/components/LevelMeshes.d.ts.map +1 -1
  132. package/dist/viewer/components/MapScene.d.ts +10 -4
  133. package/dist/viewer/components/MapScene.d.ts.map +1 -1
  134. package/dist/viewer/components/OpeningWell.d.ts +7 -0
  135. package/dist/viewer/components/OpeningWell.d.ts.map +1 -0
  136. package/dist/viewer/components/RouteLine.d.ts.map +1 -1
  137. package/dist/viewer/components/SvgVectorLayer.d.ts +3 -1
  138. package/dist/viewer/components/SvgVectorLayer.d.ts.map +1 -1
  139. package/dist/viewer/components/openingGeometry.d.ts +7 -0
  140. package/dist/viewer/components/openingGeometry.d.ts.map +1 -0
  141. package/dist/viewer/index.css +151 -19
  142. package/dist/viewer/index.js +3 -3
  143. package/dist/viewer/pointer.d.ts +26 -0
  144. package/dist/viewer/pointer.d.ts.map +1 -0
  145. package/dist/viewer/ui/MapControls.d.ts.map +1 -1
  146. package/dist/viewer/ui/RuntimeChrome.d.ts.map +1 -1
  147. package/package.json +4 -2
  148. package/dist/chunks/graph-tools.js +0 -246
  149. package/dist/chunks/graph-tools.js.map +0 -1
@@ -5,8 +5,7 @@
5
5
  min-height: 320px;
6
6
  overflow: hidden;
7
7
  background: var(--map-bg, #FFFFFF);
8
- /* Inherit the host application's font; hosts may override with the variable. */
9
- font-family: var(--eyeon-map-font-family, inherit);
8
+ font-family: var(--eyeon-map-font-family, 'Montserrat', sans-serif);
10
9
  font-size: 13px;
11
10
  color: #0f172a;
12
11
  }
@@ -22,19 +21,40 @@
22
21
  position: absolute;
23
22
  inset: 0;
24
23
  cursor: grab;
24
+ touch-action: none;
25
+ overscroll-behavior: none;
25
26
  }
26
27
 
27
28
  .eyeon-map-viewer__canvas:active {
28
29
  cursor: grabbing;
29
30
  }
30
31
 
32
+ .eyeon-map-viewer__canvas.is-hover-shape,
33
+ .eyeon-map-viewer__canvas.is-hover-shape:active {
34
+ cursor: pointer;
35
+ }
36
+
31
37
  .eyeon-map-viewer__loading,
32
- .eyeon-map-viewer__error {
38
+ .eyeon-map-viewer__error,
39
+ .eyeon-map-viewer__empty {
33
40
  display: flex;
34
41
  align-items: center;
35
42
  justify-content: center;
36
43
  height: 100%;
37
- padding: 1rem;
44
+ padding: 1.5rem;
45
+ text-align: center;
46
+ }
47
+
48
+ .eyeon-map-viewer--empty {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ }
53
+
54
+ .eyeon-map-viewer__empty {
55
+ color: #64748b;
56
+ font-size: 14px;
57
+ line-height: 1.45;
38
58
  }
39
59
 
40
60
  .eyeon-map-chrome {
@@ -100,6 +120,17 @@
100
120
  font-weight: 600;
101
121
  }
102
122
 
123
+ .eyeon-map-chrome__amenity-icon {
124
+ display: flex;
125
+ width: 22px;
126
+ height: 22px;
127
+ }
128
+
129
+ .eyeon-map-chrome__amenity-icon svg {
130
+ width: 100%;
131
+ height: 100%;
132
+ }
133
+
103
134
  .eyeon-map-chrome__panel {
104
135
  background: #fff;
105
136
  border-radius: 12px;
@@ -297,17 +328,28 @@
297
328
 
298
329
  .eyeon-map-select {
299
330
  position: relative;
331
+ display: block;
332
+ box-sizing: border-box;
300
333
  width: 100%;
301
334
  min-width: 0;
302
335
  }
303
336
 
337
+ .eyeon-map-select *,
338
+ .eyeon-map-select *::before,
339
+ .eyeon-map-select *::after {
340
+ box-sizing: border-box;
341
+ }
342
+
304
343
  .eyeon-map-select__trigger {
344
+ position: relative;
305
345
  display: flex;
306
346
  align-items: center;
307
347
  justify-content: space-between;
308
348
  gap: 8px;
309
349
  width: 100%;
310
- min-height: 32px;
350
+ min-width: 0;
351
+ min-height: 34px;
352
+ margin: 0;
311
353
  padding: 6px 8px;
312
354
  border: 1px solid #e2e8f0;
313
355
  border-radius: 6px;
@@ -316,25 +358,84 @@
316
358
  font: inherit;
317
359
  font-size: 12px;
318
360
  font-weight: 500;
361
+ line-height: 1.3;
319
362
  text-align: left;
320
363
  cursor: pointer;
321
364
  }
322
365
 
323
- .eyeon-map-select__trigger:disabled {
366
+ .eyeon-map-select__trigger:has(.eyeon-map-select__input) {
367
+ display: block;
368
+ padding: 0;
369
+ }
370
+
371
+ .eyeon-map-select__trigger:disabled,
372
+ .eyeon-map-select__trigger:has(.eyeon-map-select__input:disabled) {
324
373
  opacity: 0.55;
325
374
  cursor: not-allowed;
326
375
  }
327
376
 
328
- .eyeon-map-select__trigger:not(:disabled):hover {
377
+ .eyeon-map-select__trigger:not(:disabled):hover,
378
+ .eyeon-map-select__trigger:not(:has(.eyeon-map-select__input:disabled)):hover {
329
379
  border-color: #cbd5e1;
330
380
  }
331
381
 
382
+ .eyeon-map-select__trigger.is-open {
383
+ border-color: #0763b1;
384
+ }
385
+
332
386
  .eyeon-map-select__trigger span {
333
387
  overflow: hidden;
334
388
  text-overflow: ellipsis;
335
389
  white-space: nowrap;
336
390
  }
337
391
 
392
+ .eyeon-map-select input.eyeon-map-select__input {
393
+ display: block;
394
+ width: 100%;
395
+ max-width: none;
396
+ min-width: 0;
397
+ height: 100%;
398
+ min-height: 34px;
399
+ margin: 0;
400
+ padding: 7px 30px 7px 10px;
401
+ border: 0;
402
+ border-radius: inherit;
403
+ background: transparent;
404
+ color: inherit;
405
+ font: inherit;
406
+ font-size: 12px;
407
+ font-weight: 500;
408
+ line-height: 1.3;
409
+ outline: none;
410
+ appearance: none;
411
+ -webkit-appearance: none;
412
+ box-shadow: none;
413
+ cursor: text;
414
+ }
415
+
416
+ .eyeon-map-select__input::placeholder {
417
+ color: #94a3b8;
418
+ font-weight: 400;
419
+ }
420
+
421
+ .eyeon-map-select__chevron-btn {
422
+ position: absolute;
423
+ top: 0;
424
+ right: 0;
425
+ bottom: 0;
426
+ z-index: 1;
427
+ display: inline-flex;
428
+ align-items: center;
429
+ justify-content: center;
430
+ width: 28px;
431
+ margin: 0;
432
+ padding: 0;
433
+ border: 0;
434
+ background: transparent;
435
+ color: inherit;
436
+ cursor: pointer;
437
+ }
438
+
338
439
  .eyeon-map-select__placeholder {
339
440
  color: #94a3b8;
340
441
  font-weight: 400;
@@ -346,7 +447,8 @@
346
447
  opacity: 0.7;
347
448
  }
348
449
 
349
- .eyeon-map-select__trigger[aria-expanded='true'] .eyeon-map-select__chevron {
450
+ .eyeon-map-select__trigger[aria-expanded='true'] .eyeon-map-select__chevron,
451
+ .eyeon-map-select__trigger.is-open .eyeon-map-select__chevron {
350
452
  transform: rotate(180deg);
351
453
  }
352
454
 
@@ -362,16 +464,6 @@
362
464
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14);
363
465
  }
364
466
 
365
- .eyeon-map-select__search {
366
- flex-shrink: 0;
367
- margin: 6px 6px 0;
368
- padding: 6px 8px;
369
- border: 1px solid #e2e8f0;
370
- border-radius: 6px;
371
- font: inherit;
372
- font-size: 12px;
373
- }
374
-
375
467
  .eyeon-map-select__list {
376
468
  margin: 0;
377
469
  padding: 4px;
@@ -379,8 +471,17 @@
379
471
  list-style: none;
380
472
  }
381
473
 
474
+ .eyeon-map-select__value {
475
+ display: inline-flex;
476
+ align-items: center;
477
+ gap: 8px;
478
+ min-width: 0;
479
+ }
480
+
382
481
  .eyeon-map-select__option {
383
- display: block;
482
+ display: flex;
483
+ align-items: center;
484
+ gap: 8px;
384
485
  width: 100%;
385
486
  padding: 7px 10px;
386
487
  border: 0;
@@ -393,6 +494,33 @@
393
494
  cursor: pointer;
394
495
  }
395
496
 
497
+ .eyeon-map-select__option-icon {
498
+ width: 18px;
499
+ height: 18px;
500
+ flex-shrink: 0;
501
+ object-fit: contain;
502
+ }
503
+
504
+ .eyeon-map-select__option-icon.is-muted {
505
+ opacity: 0.45;
506
+ }
507
+
508
+ .eyeon-map-select__option-copy {
509
+ display: flex;
510
+ align-items: baseline;
511
+ justify-content: space-between;
512
+ gap: 8px;
513
+ min-width: 0;
514
+ flex: 1;
515
+ }
516
+
517
+ .eyeon-map-select__option-hint {
518
+ color: #64748b;
519
+ font-size: 11px;
520
+ font-weight: 600;
521
+ flex-shrink: 0;
522
+ }
523
+
396
524
  .eyeon-map-select__option:hover {
397
525
  background: #f1f5f9;
398
526
  }
@@ -402,6 +530,10 @@
402
530
  font-weight: 600;
403
531
  }
404
532
 
533
+ .eyeon-map-select__option.is-highlight:not(.is-active) {
534
+ background: #f1f5f9;
535
+ }
536
+
405
537
  .eyeon-map-select__empty {
406
538
  padding: 8px 10px;
407
539
  color: #94a3b8;
@@ -1,12 +1,12 @@
1
1
  import { M as r, a as s, b as o, R as p } from "../chunks/MapViewer.js";
2
- import { O as i, V as t, al as M } from "../chunks/stacking.js";
2
+ import { at as t, aG as i, bn as M } from "../chunks/stacking.js";
3
3
  export {
4
4
  r as MapControls,
5
5
  s as MapScene,
6
6
  o as MapViewer,
7
7
  p as RuntimeChrome,
8
- i as isMapViewerHost,
9
- t as mapSurface,
8
+ t as isMapViewerHost,
9
+ i as mapSurface,
10
10
  M as viewerChrome
11
11
  };
12
12
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,26 @@
1
+ import { ShapeKind } from '../core';
2
+ /** Kinds that select (or Shift-add) on the assign / public map. */
3
+ export declare const VIEWER_SELECTABLE_KINDS: ShapeKind[];
4
+ export declare function isViewerSelectableKind(kind: string): boolean;
5
+ /** Hover and the current selection share the same assign-map highlight. */
6
+ export declare function viewerShapeHighlighted(shapeId: number, hoveredShapeId: number | null, selectedShapeIds: readonly number[]): boolean;
7
+ /** Map pointer hover wins over a leftover list hover. */
8
+ export declare function resolvedViewerHoverId(listHoverId: number | null | undefined, pointerHoverId: number | null): number | null;
9
+ export declare function viewerHoverCursor(kind: string): 'pointer' | '';
10
+ /** R3F `eventSource` hosts the cursor — the WebGL canvas has pointer-events: none. */
11
+ export declare function applyViewerHoverCursor(host: HTMLElement | null | undefined, cursor: 'pointer' | ''): void;
12
+ /** Amenities are almost invisible; hover must still read. */
13
+ export declare function viewerHoverFillOpacity(kind: string, base: number, hovered: boolean): number;
14
+ /** Tint a store fill toward the accent so hover matches Edit Map. */
15
+ export declare function viewerHoverFillColor(fill: string, accent: string, hovered: boolean, amount?: number): string;
16
+ /** Pan farther than this and a pointer-up on empty space is not a clear. */
17
+ export declare const VIEWER_CLICK_DRAG_PX = 5;
18
+ export declare function pointerMissClearsSelection(down: {
19
+ x: number;
20
+ y: number;
21
+ } | null, up: {
22
+ x: number;
23
+ y: number;
24
+ button?: number;
25
+ }): boolean;
26
+ //# sourceMappingURL=pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/viewer/pointer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,EAAE,SAAS,EAO9C,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,OAAO,CAET;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CAEf;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,EAAE,CAE9D;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EACpC,MAAM,EAAE,SAAS,GAAG,EAAE,GACrB,IAAI,CAGN;AAED,6DAA6D;AAC7D,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,MAAM,CAIR;AA2BD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,MAAM,SAAM,GACX,MAAM,CAUR;AAED,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,wBAAgB,0BAA0B,CACxC,IAAI,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EACrC,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAMT"}
@@ -1 +1 @@
1
- {"version":3,"file":"MapControls.d.ts","sourceRoot":"","sources":["../../../src/viewer/ui/MapControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,UAAiB,EACjB,aAAoB,EACpB,YAAY,EACZ,gBAAwB,GACzB,EAAE,gBAAgB,4BAoElB"}
1
+ {"version":3,"file":"MapControls.d.ts","sourceRoot":"","sources":["../../../src/viewer/ui/MapControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,UAAiB,EACjB,aAAoB,EACpB,YAAY,EACZ,gBAAwB,GACzB,EAAE,gBAAgB,4BAqElB"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeChrome.d.ts","sourceRoot":"","sources":["../../../src/viewer/ui/RuntimeChrome.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,iBAAiB,CAAC;IACvB,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyBD,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,KAAK,EACL,UAAiB,EACjB,aAAoB,GACrB,EAAE,kBAAkB,4BAmMpB"}
1
+ {"version":3,"file":"RuntimeChrome.d.ts","sourceRoot":"","sources":["../../../src/viewer/ui/RuntimeChrome.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,iBAAiB,CAAC;IACvB,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyBD,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,KAAK,EACL,UAAiB,EACjB,aAAoB,GACrB,EAAE,kBAAkB,4BA6MpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeon/map",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "EyeOn Center Map v2 — core, viewer, and editor",
5
5
  "author": "EyeOn LLC",
6
6
  "license": "UNLICENSED",
@@ -42,7 +42,9 @@
42
42
  "README.md"
43
43
  ],
44
44
  "sideEffects": [
45
- "**/*.css"
45
+ "**/*.css",
46
+ "**/*.woff",
47
+ "**/mapFontUrl.js"
46
48
  ],
47
49
  "scripts": {
48
50
  "build": "vite build",
@@ -1,246 +0,0 @@
1
- import { a3 as M, T as E, R as L, M as $, U as b, ac as R, a as k, d as T, _ as S, v as y, a8 as x, a6 as _ } from "./stacking.js";
2
- function j(o, u) {
3
- var t, e, c, a;
4
- const f = M(o), s = [];
5
- for (const i of f.elements) {
6
- if (!i.d || i.interactive || u != null && u.has(i.id) || i.id.toLowerCase().startsWith("route-path") || E(i.id) || L(i.id) || $(i.id) || b(i.id)) continue;
7
- const n = R(i.id), l = (n == null ? void 0 : n.fill) ?? ((t = i.style) == null ? void 0 : t.fill), p = (n == null ? void 0 : n.stroke) ?? ((e = i.style) == null ? void 0 : e.stroke), I = (n == null ? void 0 : n.strokeWidth) ?? ((c = i.style) == null ? void 0 : c.strokeWidth);
8
- s.push({
9
- id: i.id,
10
- d: i.d,
11
- fill: l && l !== "none" ? l : void 0,
12
- stroke: p && p !== "none" ? p : void 0,
13
- strokeWidth: I,
14
- opacity: (a = i.style) == null ? void 0 : a.opacity
15
- });
16
- }
17
- return s;
18
- }
19
- function C(o, u, f, s = k) {
20
- const t = o.filter((n) => f.includes(n.id));
21
- if (t.length < 2) return null;
22
- const e = t.reduce((n, l) => l.id < n.id ? l : n), c = [];
23
- for (const n of t)
24
- n.id !== e.id && y(n, e) <= s && c.push(n.id);
25
- if (c.length === 0) return null;
26
- const a = new Set(c), i = [];
27
- for (const n of u) {
28
- let l = !1;
29
- if (a.has(n.fromAnchorId) && (n.fromAnchorId = e.id, l = !0), a.has(n.toAnchorId) && (n.toAnchorId = e.id, l = !0), n.fromAnchorId === n.toAnchorId) {
30
- i.push(n.id);
31
- continue;
32
- }
33
- l && i.push(n.id);
34
- }
35
- return {
36
- survivingAnchorId: e.id,
37
- removedAnchorIds: c,
38
- rewiredEdgeIds: i
39
- };
40
- }
41
- function F(o, u = k) {
42
- const f = [], s = /* @__PURE__ */ new Set();
43
- for (let t = 0; t < o.length; t++) {
44
- if (s.has(o[t].id)) continue;
45
- const e = [o[t].id];
46
- for (let c = t + 1; c < o.length; c++)
47
- s.has(o[c].id) || o[t].levelId === o[c].levelId && y(o[t], o[c]) <= u && (e.push(o[c].id), s.add(o[c].id));
48
- e.length > 1 && (s.add(o[t].id), f.push(e));
49
- }
50
- return f;
51
- }
52
- function K(o, u, f = k) {
53
- const s = o.slice(), t = u.map((n) => ({ ...n })), e = /* @__PURE__ */ new Set();
54
- for (const n of F(s, f)) {
55
- const l = C(s, t, n, f);
56
- if (l)
57
- for (const p of l.removedAnchorIds) e.add(p);
58
- }
59
- const c = s.filter((n) => !e.has(n.id)), a = /* @__PURE__ */ new Set(), i = [];
60
- for (const n of t) {
61
- if (e.has(n.fromAnchorId) || e.has(n.toAnchorId) || n.fromAnchorId === n.toAnchorId) continue;
62
- const l = Math.min(n.fromAnchorId, n.toAnchorId), p = Math.max(n.fromAnchorId, n.toAnchorId), I = `${l}|${p}`;
63
- a.has(I) || (a.add(I), i.push(n));
64
- }
65
- return { anchors: c, edges: i };
66
- }
67
- function N(o, u, f, s = k) {
68
- let t = null;
69
- for (const c of u) {
70
- const a = S(o, c);
71
- a && (!t || a.distance < t.distance) && (t = { point: a.point, distance: a.distance });
72
- }
73
- if (!t) return null;
74
- const e = f.find(
75
- (c) => c.levelId === o.levelId && y(c, t.point) <= s
76
- );
77
- return {
78
- unitAnchorId: o.id,
79
- junctionAnchor: e ? { x: e.x, y: e.y, existingId: e.id } : { x: t.point.x, y: t.point.y },
80
- edge: {
81
- fromAnchorId: o.id,
82
- toAnchorId: e == null ? void 0 : e.id
83
- }
84
- };
85
- }
86
- function U(o, u, f, s) {
87
- if (f.length === 0) return null;
88
- const t = f.flat();
89
- if (t.length === 0) return null;
90
- let e = 0, c = 0;
91
- for (const n of t)
92
- e += n.x, c += n.y;
93
- const a = { x: e / t.length, y: c / t.length }, i = x(a, f) ? a : t[0];
94
- return {
95
- id: s,
96
- levelId: u,
97
- shapeId: o,
98
- kind: "unit",
99
- x: i.x,
100
- y: i.y,
101
- connectorId: null
102
- };
103
- }
104
- function G(o, u, f = 20) {
105
- if (o.length === 0)
106
- return { anchors: [], edges: [] };
107
- let s = 1 / 0, t = 1 / 0, e = -1 / 0, c = -1 / 0;
108
- for (const d of o)
109
- for (const r of d)
110
- s = Math.min(s, r.x), t = Math.min(t, r.y), e = Math.max(e, r.x), c = Math.max(c, r.y);
111
- const a = Math.max(1, Math.ceil((e - s) / f)), i = Math.max(1, Math.ceil((c - t) / f)), n = [];
112
- for (let d = 0; d < i; d++)
113
- for (let r = 0; r < a; r++) {
114
- const m = s + (r + 0.5) * f, g = t + (d + 0.5) * f, A = { x: m, y: g };
115
- x(A, o) && (u.length > 0 && x(A, u) || n.push({ key: `${r},${d}`, x: m, y: g, col: r, row: d }));
116
- }
117
- const l = new Map(n.map((d) => [d.key, d])), p = n.map((d) => ({
118
- tempId: d.key,
119
- x: d.x,
120
- y: d.y,
121
- kind: "junction"
122
- })), I = [], h = /* @__PURE__ */ new Set();
123
- for (const d of n) {
124
- const r = [
125
- [d.col + 1, d.row],
126
- [d.col, d.row + 1]
127
- ];
128
- for (const [m, g] of r) {
129
- const A = `${m},${g}`;
130
- if (!l.has(A)) continue;
131
- const v = d.key < A ? `${d.key}|${A}` : `${A}|${d.key}`;
132
- h.has(v) || (h.add(v), I.push({ fromTempId: d.key, toTempId: A }));
133
- }
134
- }
135
- return { anchors: p, edges: I };
136
- }
137
- function X(o, u, f, s, t = k) {
138
- const e = [], c = [];
139
- let a = s;
140
- const i = (l, p) => {
141
- const I = e.find(
142
- (d) => y(d, { x: l, y: p }) <= t
143
- );
144
- if (I) return I.id;
145
- const h = a++;
146
- return e.push({
147
- id: h,
148
- levelId: u,
149
- shapeId: null,
150
- kind: "junction",
151
- x: l,
152
- y: p,
153
- connectorId: null
154
- }), h;
155
- };
156
- for (const l of o) {
157
- const p = _(l);
158
- for (const I of p)
159
- for (let h = 0; h < I.length - 1; h++) {
160
- const d = i(I[h].x, I[h].y), r = i(I[h + 1].x, I[h + 1].y);
161
- d === r || c.some(
162
- (g) => g.fromAnchorId === d && g.toAnchorId === r || g.fromAnchorId === r && g.toAnchorId === d
163
- ) || c.push({
164
- id: a++,
165
- mapId: f,
166
- fromAnchorId: d,
167
- toAnchorId: r,
168
- weight: null,
169
- directed: !1,
170
- accessible: !0,
171
- kind: "walk"
172
- });
173
- }
174
- }
175
- const n = K(e, c, t);
176
- return { anchors: n.anchors, edges: n.edges, nextId: a };
177
- }
178
- function W(o) {
179
- return o === "entrance" ? "entrance" : o === "connector" ? "connector" : "unit";
180
- }
181
- function D(o) {
182
- return o === "entrance" ? "entrance_link" : "unit_link";
183
- }
184
- function P(o, u, f) {
185
- if (x(o, u)) return "inside";
186
- for (const s of u) {
187
- if (s.length < 2) continue;
188
- const t = [...s, s[0]], e = S(o, t);
189
- if (e && e.distance <= f) return "near";
190
- }
191
- return null;
192
- }
193
- function w(o, u, f) {
194
- if (o.length === 0) return null;
195
- const s = o.filter((e) => (u.get(e.id) ?? 0) <= 1);
196
- return [...s.length > 0 ? s : o].sort((e, c) => y(e, f) - y(c, f))[0] ?? null;
197
- }
198
- function Y(o, u, f, s = k * 3) {
199
- const t = /* @__PURE__ */ new Map();
200
- for (const i of u)
201
- t.set(i.fromAnchorId, (t.get(i.fromAnchorId) ?? 0) + 1), t.set(i.toAnchorId, (t.get(i.toAnchorId) ?? 0) + 1);
202
- const e = o.filter((i) => i.shapeId == null), c = /* @__PURE__ */ new Set();
203
- let a = 0;
204
- for (const i of f) {
205
- if (!T.includes(i.kind)) continue;
206
- const n = i.geometry.polygons ?? [];
207
- if (n.length === 0) continue;
208
- const l = e.filter((r) => !c.has(r.id)).map((r) => ({
209
- anchor: r,
210
- hit: P(r, n, s)
211
- })).filter(
212
- (r) => r.hit != null
213
- );
214
- if (l.length === 0) continue;
215
- const p = n.flat(), I = {
216
- x: p.reduce((r, m) => r + m.x, 0) / p.length,
217
- y: p.reduce((r, m) => r + m.y, 0) / p.length
218
- }, h = w(
219
- l.filter((r) => r.hit === "inside").map((r) => r.anchor),
220
- t,
221
- I
222
- ) ?? w(
223
- l.filter((r) => r.hit === "near").map((r) => r.anchor),
224
- t,
225
- I
226
- );
227
- if (!h || (h.shapeId = i.id, h.kind = W(i.kind), c.add(h.id), a += 1, (t.get(h.id) ?? 0) > 1)) continue;
228
- const d = D(h.kind);
229
- for (const r of u)
230
- (r.fromAnchorId === h.id || r.toAnchorId === h.id) && (r.kind = d);
231
- }
232
- return a;
233
- }
234
- export {
235
- Y as a,
236
- N as b,
237
- G as c,
238
- K as d,
239
- F as f,
240
- X as i,
241
- j as o,
242
- W as r,
243
- U as u,
244
- C as w
245
- };
246
- //# sourceMappingURL=graph-tools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-tools.js","sources":["../../src/core/outdoorDecoration.ts","../../src/core/routing/graph-tools.ts"],"sourcesContent":["import {\n parseSvgString,\n isInteractiveGroupLabel,\n isRouteFolderLabel,\n isRoutePathLabel,\n isStoreFolderLabel,\n} from './import';\nimport { resolveLayerStyle } from './layerStyles';\n\nexport interface OutdoorDecorationPath {\n id: string;\n d: string;\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n}\n\n/**\n * Paths the assign viewer draws from the live outdoor SVG: house-style\n * decoration (green area, parking lanes, icons) and any other\n * non-interactive art. Interactive / store folders stay out — those are\n * `cm_shapes` rows.\n */\nexport function outdoorDecorationFromSvg(\n svgText: string,\n suppressIds?: ReadonlySet<string>,\n): OutdoorDecorationPath[] {\n const parsed = parseSvgString(svgText);\n const out: OutdoorDecorationPath[] = [];\n for (const el of parsed.elements) {\n if (!el.d) continue;\n if (el.interactive) continue;\n if (suppressIds?.has(el.id)) continue;\n if (el.id.toLowerCase().startsWith('route-path')) continue;\n if (isRoutePathLabel(el.id) || isRouteFolderLabel(el.id)) continue;\n if (isInteractiveGroupLabel(el.id) || isStoreFolderLabel(el.id)) continue;\n\n const layer = resolveLayerStyle(el.id);\n const fill = layer?.fill ?? el.style?.fill;\n const stroke = layer?.stroke ?? el.style?.stroke;\n const strokeWidth = layer?.strokeWidth ?? el.style?.strokeWidth;\n out.push({\n id: el.id,\n d: el.d,\n fill: fill && fill !== 'none' ? fill : undefined,\n stroke: stroke && stroke !== 'none' ? stroke : undefined,\n strokeWidth,\n opacity: el.style?.opacity,\n });\n }\n return out;\n}\n","import type {\n AnchorKind,\n AutoConnectResult,\n CmAnchor,\n CmRouteEdge,\n ShapeGeometry,\n ShapeKind,\n SkeletonSuggestion,\n Vec2,\n WeldResult,\n} from '../types';\nimport { DEFAULT_WELD_TOLERANCE, INTERACTIVE_SHAPE_KINDS } from '../types';\nimport {\n distance,\n nearestPointOnPolyline,\n pathToPolygons,\n pointInPolygons,\n} from '../geometry';\n\nexport interface AnchorLike {\n id: number;\n x: number;\n y: number;\n levelId: number;\n shapeId?: number | null;\n kind?: string;\n}\n\nexport interface EdgeLike {\n id: number;\n fromAnchorId: number;\n toAnchorId: number;\n}\n\n/**\n * Weld anchors within tolerance into the surviving (lowest id) anchor.\n * Rewires edges that referenced removed anchors.\n */\nexport function weldAnchors(\n anchors: AnchorLike[],\n edges: EdgeLike[],\n candidateIds: number[],\n tolerance = DEFAULT_WELD_TOLERANCE,\n): WeldResult | null {\n const candidates = anchors.filter((a) => candidateIds.includes(a.id));\n if (candidates.length < 2) return null;\n\n // Cluster by proximity from the first candidate's position centroid of group\n const surviving = candidates.reduce((min, a) => (a.id < min.id ? a : min));\n const removed: number[] = [];\n\n for (const a of candidates) {\n if (a.id === surviving.id) continue;\n if (distance(a, surviving) <= tolerance) {\n removed.push(a.id);\n }\n }\n\n if (removed.length === 0) return null;\n\n const removedSet = new Set(removed);\n const rewired: number[] = [];\n\n for (const edge of edges) {\n let changed = false;\n if (removedSet.has(edge.fromAnchorId)) {\n edge.fromAnchorId = surviving.id;\n changed = true;\n }\n if (removedSet.has(edge.toAnchorId)) {\n edge.toAnchorId = surviving.id;\n changed = true;\n }\n // Drop self-loops\n if (edge.fromAnchorId === edge.toAnchorId) {\n rewired.push(edge.id);\n continue;\n }\n if (changed) rewired.push(edge.id);\n }\n\n return {\n survivingAnchorId: surviving.id,\n removedAnchorIds: removed,\n rewiredEdgeIds: rewired,\n };\n}\n\n/**\n * Find all pairs of anchors within tolerance that should be welded.\n */\nexport function findWeldCandidates(\n anchors: AnchorLike[],\n tolerance = DEFAULT_WELD_TOLERANCE,\n): number[][] {\n const groups: number[][] = [];\n const used = new Set<number>();\n\n for (let i = 0; i < anchors.length; i++) {\n if (used.has(anchors[i].id)) continue;\n const group = [anchors[i].id];\n for (let j = i + 1; j < anchors.length; j++) {\n if (used.has(anchors[j].id)) continue;\n if (\n anchors[i].levelId === anchors[j].levelId &&\n distance(anchors[i], anchors[j]) <= tolerance\n ) {\n group.push(anchors[j].id);\n used.add(anchors[j].id);\n }\n }\n if (group.length > 1) {\n used.add(anchors[i].id);\n groups.push(group);\n }\n }\n return groups;\n}\n\n/**\n * Merge coincident anchors and drop overlapping undirected edges.\n * Two SVG imports of the same ROUTES layer stack a second copy on top of\n * the first — dragging one junction then leaves the twin behind.\n */\nexport function collapseDuplicateRouteGraph<\n A extends AnchorLike,\n E extends EdgeLike,\n>(\n anchors: A[],\n edges: E[],\n tolerance = DEFAULT_WELD_TOLERANCE,\n): { anchors: A[]; edges: E[] } {\n const nextAnchors = anchors.slice();\n const nextEdges = edges.map((edge) => ({ ...edge }));\n const removed = new Set<number>();\n for (const group of findWeldCandidates(nextAnchors, tolerance)) {\n const result = weldAnchors(nextAnchors, nextEdges, group, tolerance);\n if (!result) continue;\n for (const id of result.removedAnchorIds) removed.add(id);\n }\n const alive = nextAnchors.filter((anchor) => !removed.has(anchor.id));\n const seen = new Set<string>();\n const uniqueEdges: E[] = [];\n for (const edge of nextEdges) {\n if (removed.has(edge.fromAnchorId) || removed.has(edge.toAnchorId)) continue;\n if (edge.fromAnchorId === edge.toAnchorId) continue;\n const lo = Math.min(edge.fromAnchorId, edge.toAnchorId);\n const hi = Math.max(edge.fromAnchorId, edge.toAnchorId);\n const key = `${lo}|${hi}`;\n if (seen.has(key)) continue;\n seen.add(key);\n uniqueEdges.push(edge);\n }\n return { anchors: alive, edges: uniqueEdges };\n}\n\n/**\n * Auto-connect a unit anchor to the nearest walkable segment via perpendicular projection.\n */\nexport function autoConnectUnitAnchor(\n unitAnchor: AnchorLike,\n walkablePolylines: Vec2[][],\n existingJunctions: AnchorLike[],\n weldTolerance = DEFAULT_WELD_TOLERANCE,\n): AutoConnectResult | null {\n let best: { point: Vec2; distance: number } | null = null;\n\n for (const line of walkablePolylines) {\n const hit = nearestPointOnPolyline(unitAnchor, line);\n if (hit && (!best || hit.distance < best.distance)) {\n best = { point: hit.point, distance: hit.distance };\n }\n }\n\n if (!best) return null;\n\n // Reuse existing junction if within weld tolerance\n const existing = existingJunctions.find(\n (j) =>\n j.levelId === unitAnchor.levelId &&\n distance(j, best!.point) <= weldTolerance,\n );\n\n return {\n unitAnchorId: unitAnchor.id,\n junctionAnchor: existing\n ? { x: existing.x, y: existing.y, existingId: existing.id }\n : { x: best.point.x, y: best.point.y },\n edge: {\n fromAnchorId: unitAnchor.id,\n toAnchorId: existing?.id,\n },\n };\n}\n\n/**\n * Place a unit anchor at the centroid of a shape's polygons, if the point lies inside.\n */\nexport function unitAnchorFromShape(\n shapeId: number,\n levelId: number,\n polygons: Vec2[][],\n tempId: number,\n): CmAnchor | null {\n if (polygons.length === 0) return null;\n const flat = polygons.flat();\n if (flat.length === 0) return null;\n\n let sx = 0;\n let sy = 0;\n for (const p of flat) {\n sx += p.x;\n sy += p.y;\n }\n const c = { x: sx / flat.length, y: sy / flat.length };\n\n // Prefer centroid if inside; otherwise use first polygon's average of extremes\n const point = pointInPolygons(c, polygons) ? c : flat[0];\n\n return {\n id: tempId,\n levelId,\n shapeId,\n kind: 'unit',\n x: point.x,\n y: point.y,\n connectorId: null,\n };\n}\n\n/**\n * Build a simple medial-axis-ish skeleton from walkable polygons minus voids.\n * This is a pragmatic approximation: sample a grid inside walkable, reject void cells,\n * connect adjacent free cells into a sparse graph, then prune to a polyline network.\n */\nexport function buildAutoSkeleton(\n walkablePolygons: Vec2[][],\n voidPolygons: Vec2[][],\n cellSize = 20,\n): SkeletonSuggestion {\n if (walkablePolygons.length === 0) {\n return { anchors: [], edges: [] };\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const poly of walkablePolygons) {\n for (const p of poly) {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n }\n\n const cols = Math.max(1, Math.ceil((maxX - minX) / cellSize));\n const rows = Math.max(1, Math.ceil((maxY - minY) / cellSize));\n const free: Array<{ key: string; x: number; y: number; col: number; row: number }> = [];\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n const x = minX + (col + 0.5) * cellSize;\n const y = minY + (row + 0.5) * cellSize;\n const pt = { x, y };\n if (!pointInPolygons(pt, walkablePolygons)) continue;\n if (voidPolygons.length > 0 && pointInPolygons(pt, voidPolygons)) continue;\n free.push({ key: `${col},${row}`, x, y, col, row });\n }\n }\n\n const byKey = new Map(free.map((c) => [c.key, c]));\n const anchors = free.map((c) => ({\n tempId: c.key,\n x: c.x,\n y: c.y,\n kind: 'junction' as const,\n }));\n\n const edges: Array<{ fromTempId: string; toTempId: string }> = [];\n const seen = new Set<string>();\n\n for (const cell of free) {\n const neighbors = [\n [cell.col + 1, cell.row],\n [cell.col, cell.row + 1],\n ];\n for (const [nc, nr] of neighbors) {\n const nk = `${nc},${nr}`;\n if (!byKey.has(nk)) continue;\n const edgeKey = cell.key < nk ? `${cell.key}|${nk}` : `${nk}|${cell.key}`;\n if (seen.has(edgeKey)) continue;\n seen.add(edgeKey);\n edges.push({ fromTempId: cell.key, toTempId: nk });\n }\n }\n\n return { anchors, edges };\n}\n\n/**\n * Convert route-path SVG line endpoints into welded anchors + edges.\n * This is the key converter step that repairs coincident-but-disconnected joins.\n *\n * Anchors land in raw SVG user space (Y down), the same space as shape\n * geometry. There is intentionally no viewbox-height flip here — mirroring\n * routes without mirroring shapes would silently desynchronise the two.\n */\nexport function importRoutePaths(\n pathDs: string[],\n levelId: number,\n mapId: number,\n startId: number,\n weldTolerance = DEFAULT_WELD_TOLERANCE,\n): { anchors: CmAnchor[]; edges: CmRouteEdge[]; nextId: number } {\n const anchors: CmAnchor[] = [];\n const edges: CmRouteEdge[] = [];\n let nextId = startId;\n\n const findOrCreate = (x: number, y: number): number => {\n const existing = anchors.find(\n (a) => distance(a, { x, y }) <= weldTolerance,\n );\n if (existing) return existing.id;\n const id = nextId++;\n anchors.push({\n id,\n levelId,\n shapeId: null,\n kind: 'junction',\n x,\n y,\n connectorId: null,\n });\n return id;\n };\n\n for (const d of pathDs) {\n const polys = pathToPolygons(d);\n for (const poly of polys) {\n for (let i = 0; i < poly.length - 1; i++) {\n const a = findOrCreate(poly[i].x, poly[i].y);\n const b = findOrCreate(poly[i + 1].x, poly[i + 1].y);\n if (a === b) continue;\n // Avoid duplicate edges\n const dup = edges.some(\n (e) =>\n (e.fromAnchorId === a && e.toAnchorId === b) ||\n (e.fromAnchorId === b && e.toAnchorId === a),\n );\n if (dup) continue;\n edges.push({\n id: nextId++,\n mapId,\n fromAnchorId: a,\n toAnchorId: b,\n weight: null,\n directed: false,\n accessible: true,\n kind: 'walk',\n });\n }\n }\n }\n\n const collapsed = collapseDuplicateRouteGraph(anchors, edges, weldTolerance);\n return { anchors: collapsed.anchors, edges: collapsed.edges, nextId };\n}\n\nexport function routeAnchorKindForShape(kind: ShapeKind): AnchorKind {\n if (kind === 'entrance') return 'entrance';\n if (kind === 'connector') return 'connector';\n return 'unit';\n}\n\nfunction routeLinkKind(kind: AnchorKind): CmRouteEdge['kind'] {\n return kind === 'entrance' ? 'entrance_link' : 'unit_link';\n}\n\n/** `inside` matches v1's store-mesh hit; `near` is a door-step fallback. */\nfunction pointOnPolygons(\n point: Vec2,\n polygons: Vec2[][],\n tolerance: number,\n): 'inside' | 'near' | null {\n if (pointInPolygons(point, polygons)) return 'inside';\n for (const poly of polygons) {\n if (poly.length < 2) continue;\n const closed = [...poly, poly[0]];\n const hit = nearestPointOnPolyline(point, closed);\n if (hit && hit.distance <= tolerance) return 'near';\n }\n return null;\n}\n\nfunction pickImportedShapeAnchor(\n candidates: CmAnchor[],\n degree: Map<number, number>,\n center: Vec2,\n): CmAnchor | null {\n if (candidates.length === 0) return null;\n const leaves = candidates.filter((anchor) => (degree.get(anchor.id) ?? 0) <= 1);\n const pool = leaves.length > 0 ? leaves : candidates;\n return [...pool].sort((a, b) => distance(a, center) - distance(b, center))[0] ?? null;\n}\n\nexport interface AttachableImportShape {\n id: number;\n kind: ShapeKind;\n geometry: Pick<ShapeGeometry, 'polygons'>;\n}\n\n/**\n * Same rule as v1 `assign_route_nodes_to_stores`: a route vertex that sits\n * inside (or on) an interactive shape is that store / amenity / entrance's\n * destination. Prefer a dedicated spur leaf; otherwise take the closest\n * vertex. Corridor through-points keep `walk` edges so the path stays joined.\n */\nexport function attachImportedRouteAnchors(\n anchors: CmAnchor[],\n edges: CmRouteEdge[],\n shapes: AttachableImportShape[],\n insideTolerance = DEFAULT_WELD_TOLERANCE * 3,\n): number {\n const degree = new Map<number, number>();\n for (const edge of edges) {\n degree.set(edge.fromAnchorId, (degree.get(edge.fromAnchorId) ?? 0) + 1);\n degree.set(edge.toAnchorId, (degree.get(edge.toAnchorId) ?? 0) + 1);\n }\n\n const free = anchors.filter((anchor) => anchor.shapeId == null);\n const used = new Set<number>();\n let attached = 0;\n\n for (const shape of shapes) {\n if (!INTERACTIVE_SHAPE_KINDS.includes(shape.kind)) continue;\n const polys = shape.geometry.polygons ?? [];\n if (polys.length === 0) continue;\n const hits = free\n .filter((anchor) => !used.has(anchor.id))\n .map((anchor) => ({\n anchor,\n hit: pointOnPolygons(anchor, polys, insideTolerance),\n }))\n .filter((row): row is { anchor: CmAnchor; hit: 'inside' | 'near' } =>\n row.hit != null,\n );\n if (hits.length === 0) continue;\n const verts = polys.flat();\n const center = {\n x: verts.reduce((s, p) => s + p.x, 0) / verts.length,\n y: verts.reduce((s, p) => s + p.y, 0) / verts.length,\n };\n const pick =\n pickImportedShapeAnchor(\n hits.filter((row) => row.hit === 'inside').map((row) => row.anchor),\n degree,\n center,\n ) ??\n pickImportedShapeAnchor(\n hits.filter((row) => row.hit === 'near').map((row) => row.anchor),\n degree,\n center,\n );\n if (!pick) continue;\n pick.shapeId = shape.id;\n pick.kind = routeAnchorKindForShape(shape.kind);\n used.add(pick.id);\n attached += 1;\n if ((degree.get(pick.id) ?? 0) > 1) continue;\n const linkKind = routeLinkKind(pick.kind);\n for (const edge of edges) {\n if (edge.fromAnchorId === pick.id || edge.toAnchorId === pick.id) {\n edge.kind = linkKind;\n }\n }\n }\n\n return attached;\n}\n"],"names":["outdoorDecorationFromSvg","svgText","suppressIds","parsed","parseSvgString","out","el","isRoutePathLabel","isRouteFolderLabel","isInteractiveGroupLabel","isStoreFolderLabel","layer","resolveLayerStyle","fill","_a","stroke","_b","strokeWidth","_c","_d","weldAnchors","anchors","edges","candidateIds","tolerance","DEFAULT_WELD_TOLERANCE","candidates","a","surviving","min","removed","distance","removedSet","rewired","edge","changed","findWeldCandidates","groups","used","i","group","j","collapseDuplicateRouteGraph","nextAnchors","nextEdges","result","id","alive","anchor","seen","uniqueEdges","lo","hi","key","autoConnectUnitAnchor","unitAnchor","walkablePolylines","existingJunctions","weldTolerance","best","line","hit","nearestPointOnPolyline","existing","unitAnchorFromShape","shapeId","levelId","polygons","tempId","flat","sx","sy","p","c","point","pointInPolygons","buildAutoSkeleton","walkablePolygons","voidPolygons","cellSize","minX","minY","maxX","maxY","poly","cols","rows","free","row","col","x","y","pt","byKey","cell","neighbors","nc","nr","nk","edgeKey","importRoutePaths","pathDs","mapId","startId","nextId","findOrCreate","d","polys","pathToPolygons","b","e","collapsed","routeAnchorKindForShape","kind","routeLinkKind","pointOnPolygons","closed","pickImportedShapeAnchor","degree","center","leaves","attachImportedRouteAnchors","shapes","insideTolerance","attached","shape","INTERACTIVE_SHAPE_KINDS","hits","verts","s","pick","linkKind"],"mappings":"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"}