@twinfinity/printing 6.0.1-ci.28952-beta → 6.0.2-beta
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/README.md +3 -3
- package/dist/BuildInfo.js +3 -3
- package/dist/BuildInfo.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/analyzeTemplate.js.map +1 -1
- package/dist/layout/clipUtils.js.map +1 -1
- package/dist/layout/colorConstants.js.map +1 -1
- package/dist/layout/elementKinds.js.map +1 -1
- package/dist/layout/exportDrawing.js.map +1 -1
- package/dist/layout/filters.js.map +1 -1
- package/dist/layout/geometryConstants.js.map +1 -1
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/itemBuilders.js.map +1 -1
- package/dist/layout/labelsRender.js.map +1 -1
- package/dist/layout/legendConstants.js.map +1 -1
- package/dist/layout/legendRender.js.map +1 -1
- package/dist/layout/legendRows.js.map +1 -1
- package/dist/layout/legendUtils.js.map +1 -1
- package/dist/layout/metadata.js.map +1 -1
- package/dist/layout/model.js.map +1 -1
- package/dist/layout/options.js.map +1 -1
- package/dist/layout/presets.js.map +1 -1
- package/dist/layout/qrRender.js.map +1 -1
- package/dist/layout/renderDrawing.js.map +1 -1
- package/dist/layout/renderUtils.js.map +1 -1
- package/dist/layout/sectionValidation.js.map +1 -1
- package/dist/layout/templateVariables.js.map +1 -1
- package/dist/layout/typeGuards.js.map +1 -1
- package/dist/layout/types.js.map +1 -1
- package/dist/layout/utils.js.map +1 -1
- package/dist/layout/validation.js.map +1 -1
- package/dist/layout/validationHelpers.js.map +1 -1
- package/dist/layout/validationUtils.js.map +1 -1
- package/dist/layout/viewportPrep.js.map +1 -1
- package/dist/layout/viewportRender.js.map +1 -1
- package/dist/layout/viewportUtils.js.map +1 -1
- package/dist/layout/warnings.js.map +1 -1
- package/dist/printToPdf.js.map +1 -1
- package/dist/printToSvg.js.map +1 -1
- package/dist/sections.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/BuildInfo.ts +41 -41
- package/src/index.ts +10 -10
- package/src/layout/analyzeTemplate.ts +218 -218
- package/src/layout/clipUtils.ts +193 -193
- package/src/layout/colorConstants.ts +16 -16
- package/src/layout/elementKinds.ts +35 -35
- package/src/layout/exportDrawing.ts +206 -206
- package/src/layout/filters.ts +80 -80
- package/src/layout/geometryConstants.ts +11 -11
- package/src/layout/index.ts +671 -671
- package/src/layout/itemBuilders.ts +159 -159
- package/src/layout/labelsRender.ts +170 -170
- package/src/layout/legendConstants.ts +11 -11
- package/src/layout/legendRender.ts +543 -543
- package/src/layout/legendRows.ts +62 -62
- package/src/layout/legendUtils.ts +144 -144
- package/src/layout/metadata.ts +210 -210
- package/src/layout/model.ts +372 -372
- package/src/layout/options.ts +17 -17
- package/src/layout/presets.ts +51 -51
- package/src/layout/qrRender.ts +126 -126
- package/src/layout/qrcode.d.ts +2 -2
- package/src/layout/renderDrawing.ts +710 -710
- package/src/layout/renderUtils.ts +138 -138
- package/src/layout/sectionValidation.ts +2 -2
- package/src/layout/templateVariables.ts +317 -317
- package/src/layout/typeGuards.ts +9 -9
- package/src/layout/types.ts +835 -835
- package/src/layout/utils.ts +85 -85
- package/src/layout/validation.ts +392 -392
- package/src/layout/validationHelpers.ts +59 -59
- package/src/layout/validationUtils.ts +6 -6
- package/src/layout/viewportPrep.ts +351 -351
- package/src/layout/viewportRender.ts +442 -442
- package/src/layout/viewportUtils.ts +50 -50
- package/src/layout/warnings.ts +3 -3
- package/src/printToPdf.ts +108 -108
- package/src/printToSvg.ts +188 -188
- package/src/sections.ts +1019 -1019
- package/src/types.ts +49 -49
|
@@ -1,218 +1,218 @@
|
|
|
1
|
-
import { normalizeClass } from './filters';
|
|
2
|
-
import type {
|
|
3
|
-
LayoutTemplate,
|
|
4
|
-
LayoutElement,
|
|
5
|
-
ViewportElement,
|
|
6
|
-
TextElement,
|
|
7
|
-
ImageElement,
|
|
8
|
-
QrElement,
|
|
9
|
-
LabelsElement,
|
|
10
|
-
LegendElement,
|
|
11
|
-
GroupElement,
|
|
12
|
-
ScaleBarElement,
|
|
13
|
-
WhereCondition
|
|
14
|
-
} from './types';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Describes the input requirements inferred from a layout template.
|
|
18
|
-
* Use `analyzeTemplate()` to scan a template and discover what data it needs.
|
|
19
|
-
*/
|
|
20
|
-
export interface TemplateRequirements {
|
|
21
|
-
/** Viewport IDs the template declares. */
|
|
22
|
-
viewportIds: string[];
|
|
23
|
-
|
|
24
|
-
/** Property paths referenced by legends, where-filters, and labels.
|
|
25
|
-
* Short-path format: "SetName.propName" (e.g. "BIP.spacename"). */
|
|
26
|
-
propertyPaths: string[];
|
|
27
|
-
|
|
28
|
-
/** Class filters referenced (e.g. "space", "walls"). Already lowercase. */
|
|
29
|
-
classFilters: string[];
|
|
30
|
-
|
|
31
|
-
/** Asset IDs referenced by image/northArrow elements. */
|
|
32
|
-
assetIds: string[];
|
|
33
|
-
|
|
34
|
-
/** Text interpolation variables (e.g. "viewport.main.scaleText"). */
|
|
35
|
-
interpolationVars: string[];
|
|
36
|
-
|
|
37
|
-
/** Whether the template references remote (http/https) asset URLs. */
|
|
38
|
-
usesRemoteAssets: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const INTERPOLATION_RE = /\{\{\s*([^}]+?)\s*\}\}/g;
|
|
42
|
-
|
|
43
|
-
/** Extract `{{path}}` tokens from a template string. */
|
|
44
|
-
function extractInterpolationVars(text: string): string[] {
|
|
45
|
-
const vars: string[] = [];
|
|
46
|
-
let m: RegExpExecArray | null;
|
|
47
|
-
INTERPOLATION_RE.lastIndex = 0;
|
|
48
|
-
while ((m = INTERPOLATION_RE.exec(text)) !== null) {
|
|
49
|
-
vars.push(m[1]);
|
|
50
|
-
}
|
|
51
|
-
return vars;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Collect keys from a WhereCondition (each key is a property short-path). */
|
|
55
|
-
function collectWherePaths(where: WhereCondition | undefined, out: Set<string>): void {
|
|
56
|
-
if (!where || typeof where !== 'object') return;
|
|
57
|
-
for (const key of Object.keys(where)) {
|
|
58
|
-
out.add(key);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Collect class filter values, normalizing to lowercase. */
|
|
63
|
-
function collectClassFilter(classFilter: string | string[] | undefined, out: Set<string>): void {
|
|
64
|
-
if (!classFilter) return;
|
|
65
|
-
const classes = Array.isArray(classFilter) ? classFilter : [classFilter];
|
|
66
|
-
for (const c of classes) {
|
|
67
|
-
const normalized = normalizeClass(c);
|
|
68
|
-
if (normalized) out.add(normalized);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Scan a layout template and return its input requirements.
|
|
74
|
-
*
|
|
75
|
-
* This is a pure, read-only analysis — it does not modify the template or
|
|
76
|
-
* perform any rendering. Use the result to validate inputs before calling
|
|
77
|
-
* `renderDrawing()` or `renderLayout()`.
|
|
78
|
-
*/
|
|
79
|
-
export function analyzeTemplate(template: LayoutTemplate): TemplateRequirements {
|
|
80
|
-
const viewportIds = new Set<string>();
|
|
81
|
-
const propertyPaths = new Set<string>();
|
|
82
|
-
const classFilters = new Set<string>();
|
|
83
|
-
const assetIds = new Set<string>();
|
|
84
|
-
const interpolationVars = new Set<string>();
|
|
85
|
-
let usesRemoteAssets = false;
|
|
86
|
-
|
|
87
|
-
// Check assets for remote URLs
|
|
88
|
-
if (template.assets) {
|
|
89
|
-
for (const asset of template.assets) {
|
|
90
|
-
if (asset.src && /^https?:\/\//i.test(asset.src)) {
|
|
91
|
-
usesRemoteAssets = true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Walk all elements (recursing into groups)
|
|
97
|
-
const walk = (elements: LayoutElement[]): void => {
|
|
98
|
-
for (const el of elements) {
|
|
99
|
-
switch (el.kind) {
|
|
100
|
-
case 'viewport': {
|
|
101
|
-
const vp = el as ViewportElement;
|
|
102
|
-
viewportIds.add(vp.id);
|
|
103
|
-
|
|
104
|
-
// Clip filter
|
|
105
|
-
if (vp.clip) {
|
|
106
|
-
collectClassFilter(vp.clip.class, classFilters);
|
|
107
|
-
collectWherePaths(vp.clip.where, propertyPaths);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Highlight filter
|
|
111
|
-
if (vp.highlight) {
|
|
112
|
-
collectClassFilter(vp.highlight.class, classFilters);
|
|
113
|
-
collectWherePaths(vp.highlight.where, propertyPaths);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// includeClasses
|
|
117
|
-
if (vp.includeClasses) {
|
|
118
|
-
if (Array.isArray(vp.includeClasses)) {
|
|
119
|
-
for (const c of vp.includeClasses) {
|
|
120
|
-
const normalized = normalizeClass(c);
|
|
121
|
-
if (normalized) classFilters.add(normalized);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Preset references are resolved at render time, nothing to collect
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// North arrow asset
|
|
128
|
-
if (vp.northArrow?.assetId) {
|
|
129
|
-
assetIds.add(vp.northArrow.assetId);
|
|
130
|
-
}
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
case 'text': {
|
|
135
|
-
const txt = el as TextElement;
|
|
136
|
-
if (txt.text) {
|
|
137
|
-
for (const v of extractInterpolationVars(txt.text)) {
|
|
138
|
-
interpolationVars.add(v);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
case 'image': {
|
|
145
|
-
const img = el as ImageElement;
|
|
146
|
-
if (img.assetId) assetIds.add(img.assetId);
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
case 'qr': {
|
|
151
|
-
const qr = el as QrElement;
|
|
152
|
-
if (qr.dataTemplate) {
|
|
153
|
-
for (const v of extractInterpolationVars(qr.dataTemplate)) {
|
|
154
|
-
interpolationVars.add(v);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
case 'labels': {
|
|
161
|
-
const sl = el as LabelsElement;
|
|
162
|
-
collectClassFilter(sl.class, classFilters);
|
|
163
|
-
collectWherePaths(sl.where, propertyPaths);
|
|
164
|
-
|
|
165
|
-
// Extract property paths from text interpolation (skip viewport.* which are computed)
|
|
166
|
-
if (sl.text) {
|
|
167
|
-
for (const v of extractInterpolationVars(sl.text)) {
|
|
168
|
-
if (!v.startsWith('viewport.')) {
|
|
169
|
-
propertyPaths.add(v);
|
|
170
|
-
} else {
|
|
171
|
-
interpolationVars.add(v);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
case 'legend': {
|
|
179
|
-
const leg = el as LegendElement;
|
|
180
|
-
collectClassFilter(leg.class, classFilters);
|
|
181
|
-
collectWherePaths(leg.where, propertyPaths);
|
|
182
|
-
|
|
183
|
-
// Column property paths
|
|
184
|
-
if (leg.columns) {
|
|
185
|
-
for (const col of leg.columns) {
|
|
186
|
-
if (col.property) propertyPaths.add(col.property);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
case 'scaleBar': {
|
|
193
|
-
// scaleBar references a viewport by ID (informational)
|
|
194
|
-
const sb = el as ScaleBarElement;
|
|
195
|
-
if (sb.viewport) viewportIds.add(sb.viewport);
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
case 'group': {
|
|
200
|
-
const grp = el as GroupElement;
|
|
201
|
-
if (grp.children) walk(grp.children);
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
walk(template.elements);
|
|
209
|
-
|
|
210
|
-
return {
|
|
211
|
-
viewportIds: [...viewportIds],
|
|
212
|
-
propertyPaths: [...propertyPaths],
|
|
213
|
-
classFilters: [...classFilters],
|
|
214
|
-
assetIds: [...assetIds],
|
|
215
|
-
interpolationVars: [...interpolationVars],
|
|
216
|
-
usesRemoteAssets
|
|
217
|
-
};
|
|
218
|
-
}
|
|
1
|
+
import { normalizeClass } from './filters';
|
|
2
|
+
import type {
|
|
3
|
+
LayoutTemplate,
|
|
4
|
+
LayoutElement,
|
|
5
|
+
ViewportElement,
|
|
6
|
+
TextElement,
|
|
7
|
+
ImageElement,
|
|
8
|
+
QrElement,
|
|
9
|
+
LabelsElement,
|
|
10
|
+
LegendElement,
|
|
11
|
+
GroupElement,
|
|
12
|
+
ScaleBarElement,
|
|
13
|
+
WhereCondition
|
|
14
|
+
} from './types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Describes the input requirements inferred from a layout template.
|
|
18
|
+
* Use `analyzeTemplate()` to scan a template and discover what data it needs.
|
|
19
|
+
*/
|
|
20
|
+
export interface TemplateRequirements {
|
|
21
|
+
/** Viewport IDs the template declares. */
|
|
22
|
+
viewportIds: string[];
|
|
23
|
+
|
|
24
|
+
/** Property paths referenced by legends, where-filters, and labels.
|
|
25
|
+
* Short-path format: "SetName.propName" (e.g. "BIP.spacename"). */
|
|
26
|
+
propertyPaths: string[];
|
|
27
|
+
|
|
28
|
+
/** Class filters referenced (e.g. "space", "walls"). Already lowercase. */
|
|
29
|
+
classFilters: string[];
|
|
30
|
+
|
|
31
|
+
/** Asset IDs referenced by image/northArrow elements. */
|
|
32
|
+
assetIds: string[];
|
|
33
|
+
|
|
34
|
+
/** Text interpolation variables (e.g. "viewport.main.scaleText"). */
|
|
35
|
+
interpolationVars: string[];
|
|
36
|
+
|
|
37
|
+
/** Whether the template references remote (http/https) asset URLs. */
|
|
38
|
+
usesRemoteAssets: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const INTERPOLATION_RE = /\{\{\s*([^}]+?)\s*\}\}/g;
|
|
42
|
+
|
|
43
|
+
/** Extract `{{path}}` tokens from a template string. */
|
|
44
|
+
function extractInterpolationVars(text: string): string[] {
|
|
45
|
+
const vars: string[] = [];
|
|
46
|
+
let m: RegExpExecArray | null;
|
|
47
|
+
INTERPOLATION_RE.lastIndex = 0;
|
|
48
|
+
while ((m = INTERPOLATION_RE.exec(text)) !== null) {
|
|
49
|
+
vars.push(m[1]);
|
|
50
|
+
}
|
|
51
|
+
return vars;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Collect keys from a WhereCondition (each key is a property short-path). */
|
|
55
|
+
function collectWherePaths(where: WhereCondition | undefined, out: Set<string>): void {
|
|
56
|
+
if (!where || typeof where !== 'object') return;
|
|
57
|
+
for (const key of Object.keys(where)) {
|
|
58
|
+
out.add(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Collect class filter values, normalizing to lowercase. */
|
|
63
|
+
function collectClassFilter(classFilter: string | string[] | undefined, out: Set<string>): void {
|
|
64
|
+
if (!classFilter) return;
|
|
65
|
+
const classes = Array.isArray(classFilter) ? classFilter : [classFilter];
|
|
66
|
+
for (const c of classes) {
|
|
67
|
+
const normalized = normalizeClass(c);
|
|
68
|
+
if (normalized) out.add(normalized);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Scan a layout template and return its input requirements.
|
|
74
|
+
*
|
|
75
|
+
* This is a pure, read-only analysis — it does not modify the template or
|
|
76
|
+
* perform any rendering. Use the result to validate inputs before calling
|
|
77
|
+
* `renderDrawing()` or `renderLayout()`.
|
|
78
|
+
*/
|
|
79
|
+
export function analyzeTemplate(template: LayoutTemplate): TemplateRequirements {
|
|
80
|
+
const viewportIds = new Set<string>();
|
|
81
|
+
const propertyPaths = new Set<string>();
|
|
82
|
+
const classFilters = new Set<string>();
|
|
83
|
+
const assetIds = new Set<string>();
|
|
84
|
+
const interpolationVars = new Set<string>();
|
|
85
|
+
let usesRemoteAssets = false;
|
|
86
|
+
|
|
87
|
+
// Check assets for remote URLs
|
|
88
|
+
if (template.assets) {
|
|
89
|
+
for (const asset of template.assets) {
|
|
90
|
+
if (asset.src && /^https?:\/\//i.test(asset.src)) {
|
|
91
|
+
usesRemoteAssets = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Walk all elements (recursing into groups)
|
|
97
|
+
const walk = (elements: LayoutElement[]): void => {
|
|
98
|
+
for (const el of elements) {
|
|
99
|
+
switch (el.kind) {
|
|
100
|
+
case 'viewport': {
|
|
101
|
+
const vp = el as ViewportElement;
|
|
102
|
+
viewportIds.add(vp.id);
|
|
103
|
+
|
|
104
|
+
// Clip filter
|
|
105
|
+
if (vp.clip) {
|
|
106
|
+
collectClassFilter(vp.clip.class, classFilters);
|
|
107
|
+
collectWherePaths(vp.clip.where, propertyPaths);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Highlight filter
|
|
111
|
+
if (vp.highlight) {
|
|
112
|
+
collectClassFilter(vp.highlight.class, classFilters);
|
|
113
|
+
collectWherePaths(vp.highlight.where, propertyPaths);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// includeClasses
|
|
117
|
+
if (vp.includeClasses) {
|
|
118
|
+
if (Array.isArray(vp.includeClasses)) {
|
|
119
|
+
for (const c of vp.includeClasses) {
|
|
120
|
+
const normalized = normalizeClass(c);
|
|
121
|
+
if (normalized) classFilters.add(normalized);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Preset references are resolved at render time, nothing to collect
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// North arrow asset
|
|
128
|
+
if (vp.northArrow?.assetId) {
|
|
129
|
+
assetIds.add(vp.northArrow.assetId);
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
case 'text': {
|
|
135
|
+
const txt = el as TextElement;
|
|
136
|
+
if (txt.text) {
|
|
137
|
+
for (const v of extractInterpolationVars(txt.text)) {
|
|
138
|
+
interpolationVars.add(v);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
case 'image': {
|
|
145
|
+
const img = el as ImageElement;
|
|
146
|
+
if (img.assetId) assetIds.add(img.assetId);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
case 'qr': {
|
|
151
|
+
const qr = el as QrElement;
|
|
152
|
+
if (qr.dataTemplate) {
|
|
153
|
+
for (const v of extractInterpolationVars(qr.dataTemplate)) {
|
|
154
|
+
interpolationVars.add(v);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
case 'labels': {
|
|
161
|
+
const sl = el as LabelsElement;
|
|
162
|
+
collectClassFilter(sl.class, classFilters);
|
|
163
|
+
collectWherePaths(sl.where, propertyPaths);
|
|
164
|
+
|
|
165
|
+
// Extract property paths from text interpolation (skip viewport.* which are computed)
|
|
166
|
+
if (sl.text) {
|
|
167
|
+
for (const v of extractInterpolationVars(sl.text)) {
|
|
168
|
+
if (!v.startsWith('viewport.')) {
|
|
169
|
+
propertyPaths.add(v);
|
|
170
|
+
} else {
|
|
171
|
+
interpolationVars.add(v);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case 'legend': {
|
|
179
|
+
const leg = el as LegendElement;
|
|
180
|
+
collectClassFilter(leg.class, classFilters);
|
|
181
|
+
collectWherePaths(leg.where, propertyPaths);
|
|
182
|
+
|
|
183
|
+
// Column property paths
|
|
184
|
+
if (leg.columns) {
|
|
185
|
+
for (const col of leg.columns) {
|
|
186
|
+
if (col.property) propertyPaths.add(col.property);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
case 'scaleBar': {
|
|
193
|
+
// scaleBar references a viewport by ID (informational)
|
|
194
|
+
const sb = el as ScaleBarElement;
|
|
195
|
+
if (sb.viewport) viewportIds.add(sb.viewport);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
case 'group': {
|
|
200
|
+
const grp = el as GroupElement;
|
|
201
|
+
if (grp.children) walk(grp.children);
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
walk(template.elements);
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
viewportIds: [...viewportIds],
|
|
212
|
+
propertyPaths: [...propertyPaths],
|
|
213
|
+
classFilters: [...classFilters],
|
|
214
|
+
assetIds: [...assetIds],
|
|
215
|
+
interpolationVars: [...interpolationVars],
|
|
216
|
+
usesRemoteAssets
|
|
217
|
+
};
|
|
218
|
+
}
|