@ifc-lite/viewer 1.17.6 → 1.19.0

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 (156) hide show
  1. package/.turbo/turbo-build.log +20 -15
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/CHANGELOG.md +949 -0
  4. package/dist/assets/{basketViewActivator-86rgogji.js → basketViewActivator-RZy5c3Td.js} +1 -1
  5. package/dist/assets/decode-worker-Collf_X_.js +1320 -0
  6. package/dist/assets/{exporters-CcPS9MK5.js → exporters-BraHBeoi.js} +4194 -3025
  7. package/dist/assets/{geometry.worker-BFUYA08u.js → geometry.worker-DQEZB2rB.js} +1 -1
  8. package/dist/assets/ifc-lite_bg-4yUkDRD8.wasm +0 -0
  9. package/dist/assets/index-0XpVr_S5.css +1 -0
  10. package/dist/assets/{index-Bfms9I4A.js → index-BOi3BuUI.js} +46423 -31181
  11. package/dist/assets/index-XwKzDuw6.js +22 -0
  12. package/dist/assets/{native-bridge-DUyLCMZS.js → native-bridge-CpBeOPQa.js} +1 -1
  13. package/dist/assets/sandbox-Baez7n-t.js +9682 -0
  14. package/dist/assets/{server-client-BuZK7OST.js → server-client-BB6cMAXE.js} +1 -1
  15. package/dist/assets/{wasm-bridge-JsqEGDV8.js → wasm-bridge-CAYCUHbE.js} +1 -1
  16. package/dist/index.html +6 -6
  17. package/package.json +11 -10
  18. package/src/apache-arrow.d.ts +30 -0
  19. package/src/components/viewer/AddElementPanel.tsx +758 -0
  20. package/src/components/viewer/BulkPropertyEditor.tsx +7 -0
  21. package/src/components/viewer/ChatPanel.tsx +64 -2
  22. package/src/components/viewer/CommandPalette.tsx +56 -7
  23. package/src/components/viewer/EntityContextMenu.tsx +168 -4
  24. package/src/components/viewer/ExportChangesButton.tsx +25 -5
  25. package/src/components/viewer/ExportDialog.tsx +19 -1
  26. package/src/components/viewer/MainToolbar.tsx +73 -12
  27. package/src/components/viewer/PointCloudPanel.tsx +174 -0
  28. package/src/components/viewer/PropertiesPanel.tsx +222 -22
  29. package/src/components/viewer/SearchInline.tsx +669 -0
  30. package/src/components/viewer/SearchModal.filter.builder.tsx +766 -0
  31. package/src/components/viewer/SearchModal.filter.tsx +514 -0
  32. package/src/components/viewer/SearchModal.text.tsx +388 -0
  33. package/src/components/viewer/SearchModal.tsx +235 -0
  34. package/src/components/viewer/ToolOverlays.tsx +5 -0
  35. package/src/components/viewer/ViewerLayout.tsx +24 -4
  36. package/src/components/viewer/Viewport.tsx +29 -2
  37. package/src/components/viewer/ViewportContainer.tsx +45 -5
  38. package/src/components/viewer/ViewportOverlays.tsx +13 -2
  39. package/src/components/viewer/annotations/AnnotationDropInput.tsx +203 -0
  40. package/src/components/viewer/annotations/AnnotationLayer.tsx +287 -0
  41. package/src/components/viewer/annotations/AnnotationPin.tsx +90 -0
  42. package/src/components/viewer/annotations/AnnotationPopover.tsx +296 -0
  43. package/src/components/viewer/bcf/BCFTopicDetail.tsx +1 -1
  44. package/src/components/viewer/lists/ListPanel.tsx +14 -21
  45. package/src/components/viewer/properties/RawStepCard.tsx +332 -0
  46. package/src/components/viewer/properties/RawStepRow.tsx +261 -0
  47. package/src/components/viewer/properties/ScheduleCard.tsx +224 -0
  48. package/src/components/viewer/properties/TaskEditCard.tsx +510 -0
  49. package/src/components/viewer/properties/raw-step-format.ts +193 -0
  50. package/src/components/viewer/schedule/AnimationSettingsPopover.tsx +542 -0
  51. package/src/components/viewer/schedule/GanttDependencyArrows.tsx +89 -0
  52. package/src/components/viewer/schedule/GanttDragTooltip.tsx +48 -0
  53. package/src/components/viewer/schedule/GanttEmptyState.tsx +97 -0
  54. package/src/components/viewer/schedule/GanttPanel.tsx +295 -0
  55. package/src/components/viewer/schedule/GanttTaskBar.tsx +199 -0
  56. package/src/components/viewer/schedule/GanttTaskTree.tsx +250 -0
  57. package/src/components/viewer/schedule/GanttTimeline.tsx +305 -0
  58. package/src/components/viewer/schedule/GanttToolbar.tsx +406 -0
  59. package/src/components/viewer/schedule/GenerateAdvancedPanel.tsx +147 -0
  60. package/src/components/viewer/schedule/GenerateScheduleDialog.tsx +392 -0
  61. package/src/components/viewer/schedule/HeightStrategyPanel.tsx +120 -0
  62. package/src/components/viewer/schedule/generate-schedule.test.ts +439 -0
  63. package/src/components/viewer/schedule/generate-schedule.ts +648 -0
  64. package/src/components/viewer/schedule/schedule-animator.test.ts +452 -0
  65. package/src/components/viewer/schedule/schedule-animator.ts +488 -0
  66. package/src/components/viewer/schedule/schedule-selection.test.ts +148 -0
  67. package/src/components/viewer/schedule/schedule-selection.ts +163 -0
  68. package/src/components/viewer/schedule/schedule-utils.ts +223 -0
  69. package/src/components/viewer/schedule/useConstructionSequence.ts +156 -0
  70. package/src/components/viewer/schedule/useGanttBarDrag.test.ts +90 -0
  71. package/src/components/viewer/schedule/useGanttBarDrag.ts +305 -0
  72. package/src/components/viewer/schedule/useGanttSelection3DHighlight.ts +152 -0
  73. package/src/components/viewer/schedule/useOverlayCompositor.ts +108 -0
  74. package/src/components/viewer/selectionHandlers.ts +446 -0
  75. package/src/components/viewer/tools/AddElementOverlay.tsx +581 -0
  76. package/src/components/viewer/useDuplicateShortcut.ts +77 -0
  77. package/src/components/viewer/useMouseControls.ts +9 -1
  78. package/src/components/viewer/usePointCloudLifecycle.ts +64 -0
  79. package/src/components/viewer/usePointCloudSync.ts +98 -0
  80. package/src/hooks/ingest/pointCloudIngest.ts +391 -0
  81. package/src/hooks/ingest/viewerModelIngest.ts +32 -3
  82. package/src/hooks/useIfcFederation.ts +72 -3
  83. package/src/hooks/useIfcLoader.ts +89 -13
  84. package/src/hooks/useKeyboardShortcuts.ts +25 -0
  85. package/src/hooks/useSandbox.ts +1 -1
  86. package/src/hooks/useSearchIndex.ts +125 -0
  87. package/src/index.css +66 -0
  88. package/src/lib/llm/system-prompt.test.ts +14 -0
  89. package/src/lib/llm/system-prompt.ts +102 -1
  90. package/src/lib/llm/types.ts +6 -0
  91. package/src/lib/recent-files.ts +38 -4
  92. package/src/lib/scripts/templates/bim-globals.d.ts +136 -114
  93. package/src/lib/scripts/templates/construction-schedule.ts +223 -0
  94. package/src/lib/scripts/templates.ts +7 -0
  95. package/src/lib/search/common-ifc-types.ts +36 -0
  96. package/src/lib/search/filter-evaluate.test.ts +537 -0
  97. package/src/lib/search/filter-evaluate.ts +610 -0
  98. package/src/lib/search/filter-rules.test.ts +119 -0
  99. package/src/lib/search/filter-rules.ts +198 -0
  100. package/src/lib/search/filter-schema.test.ts +233 -0
  101. package/src/lib/search/filter-schema.ts +146 -0
  102. package/src/lib/search/recent-searches.test.ts +116 -0
  103. package/src/lib/search/recent-searches.ts +93 -0
  104. package/src/lib/search/result-export.test.ts +101 -0
  105. package/src/lib/search/result-export.ts +104 -0
  106. package/src/lib/search/saved-filters.test.ts +118 -0
  107. package/src/lib/search/saved-filters.ts +154 -0
  108. package/src/lib/search/tier0-scan.test.ts +196 -0
  109. package/src/lib/search/tier0-scan.ts +237 -0
  110. package/src/lib/search/tier1-index.test.ts +242 -0
  111. package/src/lib/search/tier1-index.ts +448 -0
  112. package/src/sdk/adapters/export-adapter.test.ts +434 -1
  113. package/src/sdk/adapters/export-adapter.ts +404 -1
  114. package/src/sdk/adapters/export-schedule-splice.test.ts +127 -0
  115. package/src/sdk/adapters/export-schedule-splice.ts +87 -0
  116. package/src/sdk/adapters/model-compat.ts +8 -2
  117. package/src/sdk/adapters/schedule-adapter.ts +73 -0
  118. package/src/sdk/adapters/store-adapter.ts +201 -0
  119. package/src/sdk/adapters/visibility-adapter.ts +3 -0
  120. package/src/sdk/local-backend.ts +16 -8
  121. package/src/services/desktop-export.ts +3 -1
  122. package/src/services/desktop-native-metadata.ts +41 -18
  123. package/src/services/file-dialog.ts +8 -3
  124. package/src/services/tauri-modules.d.ts +25 -0
  125. package/src/store/basketVisibleSet.ts +3 -0
  126. package/src/store/globalId.ts +4 -1
  127. package/src/store/index.ts +79 -1
  128. package/src/store/slices/addElementMeshes.ts +365 -0
  129. package/src/store/slices/addElementSlice.ts +275 -0
  130. package/src/store/slices/annotationsSlice.test.ts +133 -0
  131. package/src/store/slices/annotationsSlice.ts +251 -0
  132. package/src/store/slices/dataSlice.test.ts +23 -4
  133. package/src/store/slices/dataSlice.ts +1 -1
  134. package/src/store/slices/modelSlice.test.ts +67 -9
  135. package/src/store/slices/modelSlice.ts +39 -7
  136. package/src/store/slices/mutationSlice.ts +964 -3
  137. package/src/store/slices/overlayCompositor.test.ts +164 -0
  138. package/src/store/slices/overlaySlice.test.ts +93 -0
  139. package/src/store/slices/overlaySlice.ts +151 -0
  140. package/src/store/slices/pinboardSlice.test.ts +6 -1
  141. package/src/store/slices/playbackSlice.ts +128 -0
  142. package/src/store/slices/pointCloudSlice.ts +102 -0
  143. package/src/store/slices/schedule-edit-helpers.test.ts +97 -0
  144. package/src/store/slices/schedule-edit-helpers.ts +179 -0
  145. package/src/store/slices/scheduleSlice.test.ts +694 -0
  146. package/src/store/slices/scheduleSlice.ts +1330 -0
  147. package/src/store/slices/searchSlice.test.ts +342 -0
  148. package/src/store/slices/searchSlice.ts +341 -0
  149. package/src/store/slices/selectionSlice.test.ts +46 -0
  150. package/src/store/slices/selectionSlice.ts +20 -0
  151. package/src/store/types.ts +7 -0
  152. package/src/store.ts +14 -0
  153. package/vite.config.ts +1 -0
  154. package/dist/assets/ifc-lite_bg-BINvzoCP.wasm +0 -0
  155. package/dist/assets/index-_bfZsDCC.css +0 -1
  156. package/dist/assets/sandbox-C8575tul.js +0 -5951
@@ -0,0 +1,193 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ /**
6
+ * Display + parse helpers for the Raw STEP tab.
7
+ *
8
+ * The serialization layer in `@ifc-lite/export` (`serializeStepValue`)
9
+ * is the source of truth for what gets written to disk. The helpers here
10
+ * mirror it on the read side (display) and inverse it on the write side
11
+ * (parse user input) so the round-trip stays predictable for anyone who
12
+ * has seen STEP literals before.
13
+ *
14
+ * Conventions (mirrors the SDK / `StoreEditor` doc-comments):
15
+ * $ / null / empty → JS `null`
16
+ * .T. / .F. → JS `true` / `false`
17
+ * 123 / 1.5 / 1e3 → JS `number`
18
+ * #42 → JS string `"#42"` (STEP exporter writes as-is)
19
+ * .AREA. → JS string `".AREA."`
20
+ * 'foo' → JS string `'foo'` (quotes added by the serializer)
21
+ * (a,b,c) → JS array, recursively
22
+ */
23
+
24
+ import type { IfcAttributeValue } from '@ifc-lite/mutations';
25
+
26
+ /**
27
+ * Tokenize the inside of a STEP entity body (`,`-separated arguments)
28
+ * with awareness of nested parens and quoted strings. Same semantics
29
+ * as `splitTopLevelArgs` in `@ifc-lite/export` (kept inline here to
30
+ * avoid leaking a private util across the package boundary).
31
+ */
32
+ function splitTopLevelArgs(text: string): string[] {
33
+ const parts: string[] = [];
34
+ let current = '';
35
+ let depth = 0;
36
+ let inString = false;
37
+
38
+ for (let i = 0; i < text.length; i++) {
39
+ const ch = text[i];
40
+ if (inString) {
41
+ current += ch;
42
+ if (ch === "'") {
43
+ // STEP escapes a single quote by doubling it (`''`).
44
+ if (text[i + 1] === "'") {
45
+ current += text[i + 1];
46
+ i++;
47
+ } else {
48
+ inString = false;
49
+ }
50
+ }
51
+ } else if (ch === "'") {
52
+ inString = true;
53
+ current += ch;
54
+ } else if (ch === '(') {
55
+ depth++;
56
+ current += ch;
57
+ } else if (ch === ')') {
58
+ depth--;
59
+ current += ch;
60
+ } else if (ch === ',' && depth === 0) {
61
+ parts.push(current.trim());
62
+ current = '';
63
+ } else {
64
+ current += ch;
65
+ }
66
+ }
67
+ if (current.trim() || parts.length > 0) parts.push(current.trim());
68
+ return parts;
69
+ }
70
+
71
+ /**
72
+ * Read raw positional argument tokens directly from the STEP source
73
+ * buffer for an entity. Returns `null` if the entity body can't be
74
+ * parsed (mismatched parens, no source bytes, …).
75
+ *
76
+ * Each token is the verbatim on-disk literal — `#42` for refs,
77
+ * `.AREA.` for enums, `'My Column'` for strings, `1.5` for numbers.
78
+ * This is the most faithful representation for the "Raw STEP" view
79
+ * and it side-steps the need to round-trip references through the
80
+ * EntityExtractor (which strips the `#` prefix when it parses them
81
+ * into JS numbers).
82
+ */
83
+ export function extractRawStepTokens(
84
+ buffer: Uint8Array,
85
+ byteOffset: number,
86
+ byteLength: number,
87
+ ): string[] | null {
88
+ if (byteLength <= 0) return null;
89
+ const text = new TextDecoder().decode(
90
+ buffer.subarray(byteOffset, byteOffset + byteLength),
91
+ );
92
+ // Match #N=TYPE( ... ) — the trailing `;` is optional in case the
93
+ // ref slice doesn't include it.
94
+ const match = text.match(/^#\d+\s*=\s*[A-Z0-9_]+\(([\s\S]*)\)\s*;?\s*$/i);
95
+ if (!match) return null;
96
+ return splitTopLevelArgs(match[1]);
97
+ }
98
+
99
+ /**
100
+ * Serialize an overlay attribute value to the canonical STEP token
101
+ * form. Mirrors `serializeStepValue` in `@ifc-lite/export` for the
102
+ * conventions the StoreEditor / setPositionalAttribute API document.
103
+ *
104
+ * Used to render the displayed value when a positional override
105
+ * exists — the override is held as a JS value (number / string /
106
+ * null / array), but the row UI needs a STEP literal to look right
107
+ * next to the unmodified base tokens.
108
+ */
109
+ export function serializeStepToken(value: IfcAttributeValue): string {
110
+ if (value === null || value === undefined) return '$';
111
+ if (typeof value === 'boolean') return value ? '.T.' : '.F.';
112
+ if (typeof value === 'number') {
113
+ if (!Number.isFinite(value)) return '$';
114
+ return String(value);
115
+ }
116
+ if (typeof value === 'string') {
117
+ const trimmed = value.trim();
118
+ // Strings tagged as references / enums / wildcards pass through
119
+ // unchanged — the StoreEditor's input convention already keeps
120
+ // them in canonical form.
121
+ if (trimmed === '$' || trimmed === '*') return trimmed;
122
+ if (/^#\d+$/.test(trimmed)) return trimmed;
123
+ if (/^\.[A-Z0-9_]+\.$/i.test(trimmed)) return trimmed.toUpperCase();
124
+ return `'${value.replace(/'/g, "''")}'`;
125
+ }
126
+ if (Array.isArray(value)) {
127
+ return `(${value.map(serializeStepToken).join(',')})`;
128
+ }
129
+ return String(value);
130
+ }
131
+
132
+ /**
133
+ * Coarse classifier for "is this token safe to inline-edit?" Lists
134
+ * (`(...)`) and typed values (`IFCLABEL(...)`) are display-only —
135
+ * the row UI hides the pen icon for them and tells the user to
136
+ * reach for the script panel.
137
+ */
138
+ export function isInlineEditableToken(token: string): boolean {
139
+ const t = token.trim();
140
+ if (!t) return true;
141
+ if (t.startsWith('(')) return false;
142
+ if (/^[A-Z][A-Z0-9_]*\(/i.test(t)) return false;
143
+ return true;
144
+ }
145
+
146
+ /**
147
+ * Parse a user-typed value from the inline editor into the shape
148
+ * expected by `StoreEditor.setPositionalAttribute()`. Mirrors the
149
+ * conventions documented at the top of this file.
150
+ *
151
+ * Returns either `{ value: ... }` on success or `{ error: '...' }` on
152
+ * a clearly-invalid input. Most strings are accepted — this keeps the
153
+ * editor permissive (so e.g. an arbitrary identifier still lands as a
154
+ * quoted STEP string).
155
+ */
156
+ export function parseRawStepInput(input: string): { value: IfcAttributeValue } | { error: string } {
157
+ const trimmed = input.trim();
158
+
159
+ if (trimmed === '' || trimmed === '$' || trimmed.toLowerCase() === 'null') {
160
+ return { value: null };
161
+ }
162
+ if (trimmed === '.T.' || trimmed === '.t.') return { value: true };
163
+ if (trimmed === '.F.' || trimmed === '.f.') return { value: false };
164
+
165
+ // Reference: keep as-is, the serializer recognises the `#N` prefix.
166
+ if (/^#\d+$/.test(trimmed)) return { value: trimmed };
167
+
168
+ // Enum: normalise to upper-case dot-form.
169
+ if (/^\.[A-Za-z0-9_]+\.$/.test(trimmed)) return { value: trimmed.toUpperCase() };
170
+
171
+ // Number — accept both integer and real notation, including scientific.
172
+ if (/^-?\d+$/.test(trimmed)) return { value: Number.parseInt(trimmed, 10) };
173
+ if (/^-?\d*\.\d+([eE][+-]?\d+)?$/.test(trimmed) || /^-?\d+\.\d*([eE][+-]?\d+)?$/.test(trimmed) || /^-?\d+[eE][+-]?\d+$/.test(trimmed)) {
174
+ const n = Number.parseFloat(trimmed);
175
+ if (Number.isFinite(n)) return { value: n };
176
+ }
177
+
178
+ // Quoted string: strip the wrapping quotes — `serializeStepValue`
179
+ // re-adds them on export.
180
+ if (trimmed.startsWith("'") && trimmed.endsWith("'") && trimmed.length >= 2) {
181
+ return { value: trimmed.slice(1, -1).replace(/''/g, "'") };
182
+ }
183
+
184
+ // Lists / typed values: refuse for now. The pen icon is hidden for
185
+ // these anyway, but if a power user pastes a list literal we should
186
+ // flag rather than silently corrupt.
187
+ if (trimmed.startsWith('(') || /^[A-Z][A-Z0-9_]*\(/i.test(trimmed)) {
188
+ return { error: 'Lists and typed values must be edited from the script panel' };
189
+ }
190
+
191
+ // Fallback: treat as a plain string. The serializer will quote it.
192
+ return { value: trimmed };
193
+ }