@twinfinity/printing 5.0.3-ci.28538-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.
Files changed (209) hide show
  1. package/README.md +208 -0
  2. package/dist/BuildInfo.d.ts +25 -0
  3. package/dist/BuildInfo.d.ts.map +1 -0
  4. package/dist/BuildInfo.js +15 -0
  5. package/dist/BuildInfo.js.map +1 -0
  6. package/dist/index.d.ts +7 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +9 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/layout/analyzeTemplate.d.ts +29 -0
  11. package/dist/layout/analyzeTemplate.d.ts.map +1 -0
  12. package/dist/layout/analyzeTemplate.js +168 -0
  13. package/dist/layout/analyzeTemplate.js.map +1 -0
  14. package/dist/layout/clipUtils.d.ts +18 -0
  15. package/dist/layout/clipUtils.d.ts.map +1 -0
  16. package/dist/layout/clipUtils.js +165 -0
  17. package/dist/layout/clipUtils.js.map +1 -0
  18. package/dist/layout/colorConstants.d.ts +11 -0
  19. package/dist/layout/colorConstants.d.ts.map +1 -0
  20. package/dist/layout/colorConstants.js +14 -0
  21. package/dist/layout/colorConstants.js.map +1 -0
  22. package/dist/layout/elementKinds.d.ts +21 -0
  23. package/dist/layout/elementKinds.d.ts.map +1 -0
  24. package/dist/layout/elementKinds.js +17 -0
  25. package/dist/layout/elementKinds.js.map +1 -0
  26. package/dist/layout/exportDrawing.d.ts +143 -0
  27. package/dist/layout/exportDrawing.d.ts.map +1 -0
  28. package/dist/layout/exportDrawing.js +146 -0
  29. package/dist/layout/exportDrawing.js.map +1 -0
  30. package/dist/layout/filters.d.ts +33 -0
  31. package/dist/layout/filters.d.ts.map +1 -0
  32. package/dist/layout/filters.js +77 -0
  33. package/dist/layout/filters.js.map +1 -0
  34. package/dist/layout/geometryConstants.d.ts +8 -0
  35. package/dist/layout/geometryConstants.d.ts.map +1 -0
  36. package/dist/layout/geometryConstants.js +10 -0
  37. package/dist/layout/geometryConstants.js.map +1 -0
  38. package/dist/layout/index.d.ts +86 -0
  39. package/dist/layout/index.d.ts.map +1 -0
  40. package/dist/layout/index.js +363 -0
  41. package/dist/layout/index.js.map +1 -0
  42. package/dist/layout/itemBuilders.d.ts +29 -0
  43. package/dist/layout/itemBuilders.d.ts.map +1 -0
  44. package/dist/layout/itemBuilders.js +135 -0
  45. package/dist/layout/itemBuilders.js.map +1 -0
  46. package/dist/layout/labelsRender.d.ts +29 -0
  47. package/dist/layout/labelsRender.d.ts.map +1 -0
  48. package/dist/layout/labelsRender.js +109 -0
  49. package/dist/layout/labelsRender.js.map +1 -0
  50. package/dist/layout/legendConstants.d.ts +12 -0
  51. package/dist/layout/legendConstants.d.ts.map +1 -0
  52. package/dist/layout/legendConstants.js +12 -0
  53. package/dist/layout/legendConstants.js.map +1 -0
  54. package/dist/layout/legendRender.d.ts +13 -0
  55. package/dist/layout/legendRender.d.ts.map +1 -0
  56. package/dist/layout/legendRender.js +424 -0
  57. package/dist/layout/legendRender.js.map +1 -0
  58. package/dist/layout/legendRows.d.ts +26 -0
  59. package/dist/layout/legendRows.d.ts.map +1 -0
  60. package/dist/layout/legendRows.js +45 -0
  61. package/dist/layout/legendRows.js.map +1 -0
  62. package/dist/layout/legendUtils.d.ts +21 -0
  63. package/dist/layout/legendUtils.d.ts.map +1 -0
  64. package/dist/layout/legendUtils.js +110 -0
  65. package/dist/layout/legendUtils.js.map +1 -0
  66. package/dist/layout/metadata.d.ts +43 -0
  67. package/dist/layout/metadata.d.ts.map +1 -0
  68. package/dist/layout/metadata.js +191 -0
  69. package/dist/layout/metadata.js.map +1 -0
  70. package/dist/layout/model.d.ts +15 -0
  71. package/dist/layout/model.d.ts.map +1 -0
  72. package/dist/layout/model.js +310 -0
  73. package/dist/layout/model.js.map +1 -0
  74. package/dist/layout/options.d.ts +17 -0
  75. package/dist/layout/options.d.ts.map +1 -0
  76. package/dist/layout/options.js +2 -0
  77. package/dist/layout/options.js.map +1 -0
  78. package/dist/layout/presets.d.ts +23 -0
  79. package/dist/layout/presets.d.ts.map +1 -0
  80. package/dist/layout/presets.js +41 -0
  81. package/dist/layout/presets.js.map +1 -0
  82. package/dist/layout/qrRender.d.ts +13 -0
  83. package/dist/layout/qrRender.d.ts.map +1 -0
  84. package/dist/layout/qrRender.js +97 -0
  85. package/dist/layout/qrRender.js.map +1 -0
  86. package/dist/layout/renderDrawing.d.ts +62 -0
  87. package/dist/layout/renderDrawing.d.ts.map +1 -0
  88. package/dist/layout/renderDrawing.js +555 -0
  89. package/dist/layout/renderDrawing.js.map +1 -0
  90. package/dist/layout/renderUtils.d.ts +36 -0
  91. package/dist/layout/renderUtils.d.ts.map +1 -0
  92. package/dist/layout/renderUtils.js +117 -0
  93. package/dist/layout/renderUtils.js.map +1 -0
  94. package/dist/layout/sectionValidation.d.ts +3 -0
  95. package/dist/layout/sectionValidation.d.ts.map +1 -0
  96. package/dist/layout/sectionValidation.js +2 -0
  97. package/dist/layout/sectionValidation.js.map +1 -0
  98. package/dist/layout/templateVariables.d.ts +137 -0
  99. package/dist/layout/templateVariables.d.ts.map +1 -0
  100. package/dist/layout/templateVariables.js +295 -0
  101. package/dist/layout/templateVariables.js.map +1 -0
  102. package/dist/layout/typeGuards.d.ts +5 -0
  103. package/dist/layout/typeGuards.d.ts.map +1 -0
  104. package/dist/layout/typeGuards.js +9 -0
  105. package/dist/layout/typeGuards.js.map +1 -0
  106. package/dist/layout/types.d.ts +816 -0
  107. package/dist/layout/types.d.ts.map +1 -0
  108. package/dist/layout/types.js +2 -0
  109. package/dist/layout/types.js.map +1 -0
  110. package/dist/layout/utils.d.ts +9 -0
  111. package/dist/layout/utils.d.ts.map +1 -0
  112. package/dist/layout/utils.js +84 -0
  113. package/dist/layout/utils.js.map +1 -0
  114. package/dist/layout/validation.d.ts +7 -0
  115. package/dist/layout/validation.d.ts.map +1 -0
  116. package/dist/layout/validation.js +352 -0
  117. package/dist/layout/validation.js.map +1 -0
  118. package/dist/layout/validationHelpers.d.ts +15 -0
  119. package/dist/layout/validationHelpers.d.ts.map +1 -0
  120. package/dist/layout/validationHelpers.js +43 -0
  121. package/dist/layout/validationHelpers.js.map +1 -0
  122. package/dist/layout/validationUtils.d.ts +5 -0
  123. package/dist/layout/validationUtils.d.ts.map +1 -0
  124. package/dist/layout/validationUtils.js +5 -0
  125. package/dist/layout/validationUtils.js.map +1 -0
  126. package/dist/layout/viewportPrep.d.ts +47 -0
  127. package/dist/layout/viewportPrep.d.ts.map +1 -0
  128. package/dist/layout/viewportPrep.js +275 -0
  129. package/dist/layout/viewportPrep.js.map +1 -0
  130. package/dist/layout/viewportRender.d.ts +42 -0
  131. package/dist/layout/viewportRender.d.ts.map +1 -0
  132. package/dist/layout/viewportRender.js +337 -0
  133. package/dist/layout/viewportRender.js.map +1 -0
  134. package/dist/layout/viewportUtils.d.ts +9 -0
  135. package/dist/layout/viewportUtils.d.ts.map +1 -0
  136. package/dist/layout/viewportUtils.js +40 -0
  137. package/dist/layout/viewportUtils.js.map +1 -0
  138. package/dist/layout/warnings.d.ts +2 -0
  139. package/dist/layout/warnings.d.ts.map +1 -0
  140. package/dist/layout/warnings.js +4 -0
  141. package/dist/layout/warnings.js.map +1 -0
  142. package/dist/printToPdf.d.ts +38 -0
  143. package/dist/printToPdf.d.ts.map +1 -0
  144. package/dist/printToPdf.js +79 -0
  145. package/dist/printToPdf.js.map +1 -0
  146. package/dist/printToSvg.d.ts +11 -0
  147. package/dist/printToSvg.d.ts.map +1 -0
  148. package/dist/printToSvg.js +168 -0
  149. package/dist/printToSvg.js.map +1 -0
  150. package/dist/sections.d.ts +118 -0
  151. package/dist/sections.d.ts.map +1 -0
  152. package/dist/sections.js +839 -0
  153. package/dist/sections.js.map +1 -0
  154. package/dist/templates/default-template.json +137 -0
  155. package/dist/types.d.ts +54 -0
  156. package/dist/types.d.ts.map +1 -0
  157. package/dist/types.js +11 -0
  158. package/dist/types.js.map +1 -0
  159. package/package.json +47 -0
  160. package/src/BuildInfo.ts +41 -0
  161. package/src/index.ts +10 -0
  162. package/src/layout/analyzeTemplate.ts +218 -0
  163. package/src/layout/clipUtils.ts +193 -0
  164. package/src/layout/colorConstants.ts +16 -0
  165. package/src/layout/elementKinds.ts +35 -0
  166. package/src/layout/exportDrawing.ts +206 -0
  167. package/src/layout/filters.ts +80 -0
  168. package/src/layout/geometryConstants.ts +11 -0
  169. package/src/layout/index.ts +671 -0
  170. package/src/layout/itemBuilders.ts +159 -0
  171. package/src/layout/labelsRender.ts +170 -0
  172. package/src/layout/legendConstants.ts +11 -0
  173. package/src/layout/legendRender.ts +543 -0
  174. package/src/layout/legendRows.ts +62 -0
  175. package/src/layout/legendUtils.ts +144 -0
  176. package/src/layout/metadata.ts +210 -0
  177. package/src/layout/model.ts +372 -0
  178. package/src/layout/options.ts +17 -0
  179. package/src/layout/presets.ts +51 -0
  180. package/src/layout/qrRender.ts +126 -0
  181. package/src/layout/qrcode.d.ts +2 -0
  182. package/src/layout/renderDrawing.ts +710 -0
  183. package/src/layout/renderUtils.ts +138 -0
  184. package/src/layout/sectionValidation.ts +2 -0
  185. package/src/layout/templateVariables.ts +317 -0
  186. package/src/layout/typeGuards.ts +9 -0
  187. package/src/layout/types.ts +835 -0
  188. package/src/layout/utils.ts +85 -0
  189. package/src/layout/validation.ts +392 -0
  190. package/src/layout/validationHelpers.ts +59 -0
  191. package/src/layout/validationUtils.ts +6 -0
  192. package/src/layout/viewportPrep.ts +351 -0
  193. package/src/layout/viewportRender.ts +442 -0
  194. package/src/layout/viewportUtils.ts +50 -0
  195. package/src/layout/warnings.ts +3 -0
  196. package/src/printToPdf.ts +108 -0
  197. package/src/printToSvg.ts +188 -0
  198. package/src/sections.ts +1019 -0
  199. package/src/templates/default-template.json +137 -0
  200. package/src/types.ts +49 -0
  201. package/templates/default-a0-landscape.json +209 -0
  202. package/templates/default-a0-portrait.json +195 -0
  203. package/templates/default-a1-landscape.json +167 -0
  204. package/templates/default-a1-portrait.json +153 -0
  205. package/templates/default-a3-landscape.json +111 -0
  206. package/templates/default-a3-portrait.json +125 -0
  207. package/templates/default-a4-landscape.json +97 -0
  208. package/templates/default-a4-portrait.json +97 -0
  209. package/templates/template-schema.json +1395 -0
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # @twinfinity/printing
2
+
3
+ Template-driven page composition, section SVG building, and PDF/SVG export for BIM drawings.
4
+
5
+ This package consolidates layout composition (formerly `@measurement-tools/print-layout`), PDF/SVG export (formerly `@measurement-tools/printing`), and section SVG building (formerly `@measurement-tools/sections`) into a single package.
6
+
7
+ ## Quick Start
8
+
9
+ ### Build a section render state
10
+
11
+ ```typescript
12
+ import { createSectionSvg } from '@twinfinity/printing';
13
+
14
+ // entries = from computePlaneSectionsForProducts() in @twinfinity/geometry
15
+ const sectionState = createSectionSvg(entries);
16
+
17
+ // sectionState.paths — SVG path data with fill/stroke info
18
+ // sectionState.transform — viewport dimensions
19
+ // sectionState.labels — positioned text labels
20
+ ```
21
+
22
+ ### Compose a drawing page from a template
23
+
24
+ ```typescript
25
+ import { renderDrawing } from '@twinfinity/printing';
26
+
27
+ const { svg, viewportScales } = await renderDrawing({
28
+ template,
29
+ sectionState,
30
+ });
31
+
32
+ // svg is a complete page SVG with title block, legend, scale bar, QR codes, etc.
33
+ // viewportScales['main-viewport'].denom tells you the scale (e.g. 100 = 1:100)
34
+ ```
35
+
36
+ ### Export to PDF
37
+
38
+ ```typescript
39
+ import { exportToPdf } from '@twinfinity/printing';
40
+
41
+ await exportToPdf(svg, {
42
+ fileName: 'drawing.pdf',
43
+ pageFormat: 'a3',
44
+ orientation: 'landscape',
45
+ });
46
+ ```
47
+
48
+ ### Quick PDF without a template
49
+
50
+ ```typescript
51
+ import { exportSectionToPdf } from '@twinfinity/printing';
52
+
53
+ await exportSectionToPdf({
54
+ state: sectionState,
55
+ fileName: 'section.pdf',
56
+ pageFormat: 'a3',
57
+ orientation: 'landscape',
58
+ });
59
+ ```
60
+
61
+ ### End-to-end: BIM model to PDF
62
+
63
+ ```typescript
64
+ import { SlabSection } from '@twinfinity/product-geometry';
65
+ import { computePlaneSectionsForProducts } from '@twinfinity/geometry';
66
+ import { createSectionSvg, renderDrawing, exportToPdf } from '@twinfinity/printing';
67
+ import { planeFromPointAndNormal } from '@twinfinity/geometry';
68
+
69
+ // 1. Compute section geometry
70
+ const section = new SlabSection(scene, { cutHeight: 1.5, depth: { above: 2, below: 0.3 } });
71
+ const geometry = await section.compute(products);
72
+
73
+ // 2. Build section state
74
+ const plane = planeFromPointAndNormal([0, 1.5, 0], [0, 1, 0]);
75
+ const entries = await computePlaneSectionsForProducts(products, plane);
76
+ const sectionState = createSectionSvg(entries);
77
+
78
+ // 3. Compose drawing page from template
79
+ const { svg } = await renderDrawing({ template, sectionState });
80
+
81
+ // 4. Export to PDF
82
+ await exportToPdf(svg, { fileName: 'drawing.pdf', pageFormat: 'a3', orientation: 'landscape' });
83
+ ```
84
+
85
+ ## Template-based layout composition
86
+
87
+ ### Validation and rendering
88
+
89
+ ```typescript
90
+ import {
91
+ renderLayout,
92
+ validateLayoutTemplate,
93
+ preflight,
94
+ buildViewportItems,
95
+ sectionStateToModelView,
96
+ type LayoutTemplate,
97
+ type ProductFieldPaths,
98
+ } from '@twinfinity/printing';
99
+
100
+ // Validate template
101
+ const vt = validateLayoutTemplate(tmpl);
102
+ if (!vt.ok) throw new Error(vt.errors.map(e => `${e.path}: ${e.message}`).join('; '));
103
+
104
+ // Build viewport items
105
+ const productFields: ProductFieldPaths = {
106
+ idPath: 'propertySets.BIP.hyresobjektsnummer.value',
107
+ namePath: 'propertySets.BIP.spacename.value',
108
+ areaPath: 'propertySets.BIP.area.value',
109
+ classPath: 'propertySets.BIP.ifcClass.value',
110
+ };
111
+ const items = buildViewportItems(rawProducts, { productFields });
112
+
113
+ // Preflight check
114
+ const pf = preflight(tmpl, { viewports: { main: { items } } }, ['main'], sectionState);
115
+ if (!pf.ok) {
116
+ const msgs = [
117
+ ...(pf.templateErrors ?? []).map(e => `${e.path}: ${e.message}`),
118
+ ...(pf.dataErrors ?? []),
119
+ ...(pf.sectionErrors ?? []),
120
+ ];
121
+ throw new Error(msgs.join('; '));
122
+ }
123
+
124
+ // Render
125
+ const { svg } = await renderLayout(tmpl, { viewports: { main: { items } } }, models);
126
+ ```
127
+
128
+ ### Advanced section state
129
+
130
+ ```typescript
131
+ import {
132
+ buildSectionStateForEntries,
133
+ extractViewWindow,
134
+ strokeWidthForWindow,
135
+ } from '@twinfinity/printing';
136
+
137
+ const state = buildSectionStateForEntries(entries, {
138
+ viewport: { viewMinX: -10, viewMaxX: 30, viewMinZ: -5, viewMaxZ: 25 },
139
+ strokeWidth: 0.15,
140
+ fills: [
141
+ { class: 'ifcspace', fillOpacity: 0.35 },
142
+ { class: ['ifcwall', 'ifcslab'], fillOpacity: 0 },
143
+ ],
144
+ includeLabels: true,
145
+ labelFontSize: 2.5,
146
+ });
147
+ ```
148
+
149
+ ## Template JSON quick reference
150
+
151
+ Templates are JSON files that define page layout. Use `$schema` for IDE validation:
152
+
153
+ ```json
154
+ {
155
+ "$schema": "./path-to/template-schema.json",
156
+ "id": "my-template",
157
+ "page": { "widthMm": 420, "heightMm": 297, "marginMm": 10 },
158
+ "elements": []
159
+ }
160
+ ```
161
+
162
+ - **page**: `{ widthMm, heightMm, marginMm?, backgroundColor? }`
163
+ - **styles**: named text styles `{ fontFamily, fontSizeMm, fontWeight?, letterSpacing?, lineHeight? }`
164
+ - **assets**: `{ id, type: "image", src }` or `{ id, type: "svg", content }`
165
+ - **elements** (z-index sorted):
166
+ - `viewport`: model view with scale, filters, clip, highlight, fills
167
+ - `text`: static or `{{interpolated}}` text
168
+ - `image`: logo or decorative image
169
+ - `line`, `rect`, `circle`: basic shapes
170
+ - `polyline`, `polygon`: custom vectors
171
+ - `scaleBar`: graphical scale indicator
172
+ - `qr`: QR codes for spatial anchoring (main + corner anchors)
173
+ - `labels`: per-item data-driven labels (room names, etc.)
174
+ - `legend`: tabular data with filtering and columns
175
+ - `group`: container with transforms/clipping
176
+ - **presets**: reusable class filters and scale lists
177
+
178
+ ### Data contract
179
+
180
+ - Item metadata must use `propertySets.<Set>.<Prop>.value`. Legacy `properties.*` is rejected.
181
+ - Validate before render: use `validateLayoutTemplate` and `validateLayoutData` (or `preflight`).
182
+
183
+ ### Default templates
184
+
185
+ Default templates (A0-A4, landscape/portrait) and a JSON schema for IDE validation are in the `templates/` directory.
186
+
187
+ ### Limits
188
+
189
+ - Max 3 viewports by default (configurable in validation).
190
+ - Legend: up to 200 rows, 5 data columns + color swatch.
191
+ - Environment: PDF/QR export requires a browser/DOM with `document` and `svg2pdf.js`.
192
+ - `DEFAULT_LAYOUT_TEMPLATE` provides a bundled A3 landscape example.
193
+
194
+ ## Troubleshooting
195
+
196
+ | Message | Fix |
197
+ |---------|-----|
198
+ | `propertySets.<Set>.<Prop>.value` required | Update template/data paths to the canonical propertySets shape. |
199
+ | `viewports.<id>.items is required...` | Provide a non-empty `items` array per viewport with `propertySets` on each item. |
200
+ | `clip`/`highlight`/`legend` filter path is invalid | Use paths in the canonical shape; legacy `properties.*` is rejected. |
201
+ | `Section render state is required` / transform errors | Ensure `SectionRenderState` has `geometryTransform`, `transform`, and non-empty `paths`. |
202
+ | `Document is not available` | Run in a browser/DOM environment; headless Node is not supported out of the box. |
203
+
204
+ ## Documentation
205
+
206
+ - [Template reference (field-by-field)](../../docs/specs/printing-template-reference.md)
207
+ - [Template guide (practical examples)](../../docs/specs/printing-template-guide.md)
208
+ - [Architecture overview](../../docs/specs/printing-architecture.md)
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Represents either production or development build type
3
+ */
4
+ export type BuildType = 'Dev' | 'Prod';
5
+ /**
6
+ * Contains property metadata for the Twinfinity build
7
+ */
8
+ export interface BuildInfo {
9
+ /** Major version number */
10
+ readonly major: number;
11
+ /** Minor version number */
12
+ readonly minor: number;
13
+ /** Patch version number */
14
+ readonly patch: number;
15
+ /** Unique build id */
16
+ readonly id: number;
17
+ /** The commit checksum */
18
+ readonly commit: string;
19
+ /** String that uniquely identifies the current version */
20
+ readonly version: string;
21
+ /** The build type */
22
+ readonly buildType: BuildType;
23
+ }
24
+ export declare const BUILD_INFO: Readonly<BuildInfo>;
25
+ //# sourceMappingURL=BuildInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildInfo.d.ts","sourceRoot":"/","sources":["BuildInfo.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qBAAqB;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CACjC;AAiBD,eAAO,MAAM,UAAU,qBAAqB,CAAC"}
@@ -0,0 +1,15 @@
1
+ const gBi = {
2
+ major: 5,
3
+ minor: 0,
4
+ patch: 3,
5
+ id: 28538,
6
+ commit: '8df82701',
7
+ version: '',
8
+ buildType: 'Prod'
9
+ };
10
+ gBi.version = `${gBi.major}.${gBi.minor}.${gBi.patch}.${gBi.id}-[${gBi.commit}]`;
11
+ if (gBi.commit === 'unknownCommit') {
12
+ gBi.buildType = 'Dev';
13
+ }
14
+ export const BUILD_INFO = Object.freeze(gBi);
15
+ //# sourceMappingURL=BuildInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildInfo.js","sourceRoot":"/","sources":["BuildInfo.ts"],"names":[],"mappings":"AAyBA,MAAM,GAAG,GAAc;IACnB,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,MAAM;CACpB,CAAC;AAED,GAAG,CAAC,OAAkB,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC;AAC7F,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;IAChC,GAAG,CAAC,SAAuB,GAAG,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC","sourcesContent":["/**\r\n * Represents either production or development build type\r\n */\r\nexport type BuildType = 'Dev' | 'Prod';\r\n\r\n/**\r\n * Contains property metadata for the Twinfinity build\r\n */\r\nexport interface BuildInfo {\r\n /** Major version number */\r\n readonly major: number;\r\n /** Minor version number */\r\n readonly minor: number;\r\n /** Patch version number */\r\n readonly patch: number;\r\n /** Unique build id */\r\n readonly id: number;\r\n /** The commit checksum */\r\n readonly commit: string;\r\n /** String that uniquely identifies the current version */\r\n readonly version: string;\r\n /** The build type */\r\n readonly buildType: BuildType;\r\n}\r\n\r\nconst gBi: BuildInfo = {\r\n major: 111111,\r\n minor: 222222,\r\n patch: 333333,\r\n id: 444444,\r\n commit: 'unknownCommit',\r\n version: '',\r\n buildType: 'Prod'\r\n};\r\n\r\n(gBi.version as string) = `${gBi.major}.${gBi.minor}.${gBi.patch}.${gBi.id}-[${gBi.commit}]`;\r\nif (gBi.commit === 'unknownCommit') {\r\n (gBi.buildType as BuildType) = 'Dev';\r\n}\r\n\r\nexport const BUILD_INFO = Object.freeze(gBi);\r\n"]}
@@ -0,0 +1,7 @@
1
+ export * from './BuildInfo';
2
+ export * from './types';
3
+ export { printToSvg } from './printToSvg';
4
+ export { printToPdf, printToSvgFile, type PrintToPdfOptions } from './printToPdf';
5
+ export * from './layout/index';
6
+ export * from './sections';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGlF,cAAc,gBAAgB,CAAC;AAG/B,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export * from './BuildInfo';
2
+ export * from './types';
3
+ export { printToSvg } from './printToSvg';
4
+ export { printToPdf, printToSvgFile } from './printToPdf';
5
+ // Print-layout module (template-driven page composition)
6
+ export * from './layout/index';
7
+ // Sections SVG viewport module
8
+ export * from './sections';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,cAAc,EAA0B,MAAM,cAAc,CAAC;AAElF,yDAAyD;AACzD,cAAc,gBAAgB,CAAC;AAE/B,+BAA+B;AAC/B,cAAc,YAAY,CAAC","sourcesContent":["export * from './BuildInfo';\r\nexport * from './types';\r\nexport { printToSvg } from './printToSvg';\r\nexport { printToPdf, printToSvgFile, type PrintToPdfOptions } from './printToPdf';\r\n\r\n// Print-layout module (template-driven page composition)\r\nexport * from './layout/index';\r\n\r\n// Sections SVG viewport module\r\nexport * from './sections';\r\n"]}
@@ -0,0 +1,29 @@
1
+ import type { LayoutTemplate } from './types';
2
+ /**
3
+ * Describes the input requirements inferred from a layout template.
4
+ * Use `analyzeTemplate()` to scan a template and discover what data it needs.
5
+ */
6
+ export interface TemplateRequirements {
7
+ /** Viewport IDs the template declares. */
8
+ viewportIds: string[];
9
+ /** Property paths referenced by legends, where-filters, and labels.
10
+ * Short-path format: "SetName.propName" (e.g. "BIP.spacename"). */
11
+ propertyPaths: string[];
12
+ /** Class filters referenced (e.g. "space", "walls"). Already lowercase. */
13
+ classFilters: string[];
14
+ /** Asset IDs referenced by image/northArrow elements. */
15
+ assetIds: string[];
16
+ /** Text interpolation variables (e.g. "viewport.main.scaleText"). */
17
+ interpolationVars: string[];
18
+ /** Whether the template references remote (http/https) asset URLs. */
19
+ usesRemoteAssets: boolean;
20
+ }
21
+ /**
22
+ * Scan a layout template and return its input requirements.
23
+ *
24
+ * This is a pure, read-only analysis — it does not modify the template or
25
+ * perform any rendering. Use the result to validate inputs before calling
26
+ * `renderDrawing()` or `renderLayout()`.
27
+ */
28
+ export declare function analyzeTemplate(template: LayoutTemplate): TemplateRequirements;
29
+ //# sourceMappingURL=analyzeTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeTemplate.d.ts","sourceRoot":"/","sources":["layout/analyzeTemplate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACR,cAAc,EAWjB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACjC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;wEACoE;IACpE,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAE5B,sEAAsE;IACtE,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAiCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB,CA2I9E"}
@@ -0,0 +1,168 @@
1
+ import { normalizeClass } from './filters';
2
+ const INTERPOLATION_RE = /\{\{\s*([^}]+?)\s*\}\}/g;
3
+ /** Extract `{{path}}` tokens from a template string. */
4
+ function extractInterpolationVars(text) {
5
+ const vars = [];
6
+ let m;
7
+ INTERPOLATION_RE.lastIndex = 0;
8
+ while ((m = INTERPOLATION_RE.exec(text)) !== null) {
9
+ vars.push(m[1]);
10
+ }
11
+ return vars;
12
+ }
13
+ /** Collect keys from a WhereCondition (each key is a property short-path). */
14
+ function collectWherePaths(where, out) {
15
+ if (!where || typeof where !== 'object')
16
+ return;
17
+ for (const key of Object.keys(where)) {
18
+ out.add(key);
19
+ }
20
+ }
21
+ /** Collect class filter values, normalizing to lowercase. */
22
+ function collectClassFilter(classFilter, out) {
23
+ if (!classFilter)
24
+ return;
25
+ const classes = Array.isArray(classFilter) ? classFilter : [classFilter];
26
+ for (const c of classes) {
27
+ const normalized = normalizeClass(c);
28
+ if (normalized)
29
+ out.add(normalized);
30
+ }
31
+ }
32
+ /**
33
+ * Scan a layout template and return its input requirements.
34
+ *
35
+ * This is a pure, read-only analysis — it does not modify the template or
36
+ * perform any rendering. Use the result to validate inputs before calling
37
+ * `renderDrawing()` or `renderLayout()`.
38
+ */
39
+ export function analyzeTemplate(template) {
40
+ const viewportIds = new Set();
41
+ const propertyPaths = new Set();
42
+ const classFilters = new Set();
43
+ const assetIds = new Set();
44
+ const interpolationVars = new Set();
45
+ let usesRemoteAssets = false;
46
+ // Check assets for remote URLs
47
+ if (template.assets) {
48
+ for (const asset of template.assets) {
49
+ if (asset.src && /^https?:\/\//i.test(asset.src)) {
50
+ usesRemoteAssets = true;
51
+ }
52
+ }
53
+ }
54
+ // Walk all elements (recursing into groups)
55
+ const walk = (elements) => {
56
+ for (const el of elements) {
57
+ switch (el.kind) {
58
+ case 'viewport': {
59
+ const vp = el;
60
+ viewportIds.add(vp.id);
61
+ // Clip filter
62
+ if (vp.clip) {
63
+ collectClassFilter(vp.clip.class, classFilters);
64
+ collectWherePaths(vp.clip.where, propertyPaths);
65
+ }
66
+ // Highlight filter
67
+ if (vp.highlight) {
68
+ collectClassFilter(vp.highlight.class, classFilters);
69
+ collectWherePaths(vp.highlight.where, propertyPaths);
70
+ }
71
+ // includeClasses
72
+ if (vp.includeClasses) {
73
+ if (Array.isArray(vp.includeClasses)) {
74
+ for (const c of vp.includeClasses) {
75
+ const normalized = normalizeClass(c);
76
+ if (normalized)
77
+ classFilters.add(normalized);
78
+ }
79
+ }
80
+ // Preset references are resolved at render time, nothing to collect
81
+ }
82
+ // North arrow asset
83
+ if (vp.northArrow?.assetId) {
84
+ assetIds.add(vp.northArrow.assetId);
85
+ }
86
+ break;
87
+ }
88
+ case 'text': {
89
+ const txt = el;
90
+ if (txt.text) {
91
+ for (const v of extractInterpolationVars(txt.text)) {
92
+ interpolationVars.add(v);
93
+ }
94
+ }
95
+ break;
96
+ }
97
+ case 'image': {
98
+ const img = el;
99
+ if (img.assetId)
100
+ assetIds.add(img.assetId);
101
+ break;
102
+ }
103
+ case 'qr': {
104
+ const qr = el;
105
+ if (qr.dataTemplate) {
106
+ for (const v of extractInterpolationVars(qr.dataTemplate)) {
107
+ interpolationVars.add(v);
108
+ }
109
+ }
110
+ break;
111
+ }
112
+ case 'labels': {
113
+ const sl = el;
114
+ collectClassFilter(sl.class, classFilters);
115
+ collectWherePaths(sl.where, propertyPaths);
116
+ // Extract property paths from text interpolation (skip viewport.* which are computed)
117
+ if (sl.text) {
118
+ for (const v of extractInterpolationVars(sl.text)) {
119
+ if (!v.startsWith('viewport.')) {
120
+ propertyPaths.add(v);
121
+ }
122
+ else {
123
+ interpolationVars.add(v);
124
+ }
125
+ }
126
+ }
127
+ break;
128
+ }
129
+ case 'legend': {
130
+ const leg = el;
131
+ collectClassFilter(leg.class, classFilters);
132
+ collectWherePaths(leg.where, propertyPaths);
133
+ // Column property paths
134
+ if (leg.columns) {
135
+ for (const col of leg.columns) {
136
+ if (col.property)
137
+ propertyPaths.add(col.property);
138
+ }
139
+ }
140
+ break;
141
+ }
142
+ case 'scaleBar': {
143
+ // scaleBar references a viewport by ID (informational)
144
+ const sb = el;
145
+ if (sb.viewport)
146
+ viewportIds.add(sb.viewport);
147
+ break;
148
+ }
149
+ case 'group': {
150
+ const grp = el;
151
+ if (grp.children)
152
+ walk(grp.children);
153
+ break;
154
+ }
155
+ }
156
+ }
157
+ };
158
+ walk(template.elements);
159
+ return {
160
+ viewportIds: [...viewportIds],
161
+ propertyPaths: [...propertyPaths],
162
+ classFilters: [...classFilters],
163
+ assetIds: [...assetIds],
164
+ interpolationVars: [...interpolationVars],
165
+ usesRemoteAssets
166
+ };
167
+ }
168
+ //# sourceMappingURL=analyzeTemplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeTemplate.js","sourceRoot":"/","sources":["layout/analyzeTemplate.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeClass } from './filters';\r\nimport type {\r\n LayoutTemplate,\r\n LayoutElement,\r\n ViewportElement,\r\n TextElement,\r\n ImageElement,\r\n QrElement,\r\n LabelsElement,\r\n LegendElement,\r\n GroupElement,\r\n ScaleBarElement,\r\n WhereCondition\r\n} from './types';\r\n\r\n/**\r\n * Describes the input requirements inferred from a layout template.\r\n * Use `analyzeTemplate()` to scan a template and discover what data it needs.\r\n */\r\nexport interface TemplateRequirements {\r\n /** Viewport IDs the template declares. */\r\n viewportIds: string[];\r\n\r\n /** Property paths referenced by legends, where-filters, and labels.\r\n * Short-path format: \"SetName.propName\" (e.g. \"BIP.spacename\"). */\r\n propertyPaths: string[];\r\n\r\n /** Class filters referenced (e.g. \"space\", \"walls\"). Already lowercase. */\r\n classFilters: string[];\r\n\r\n /** Asset IDs referenced by image/northArrow elements. */\r\n assetIds: string[];\r\n\r\n /** Text interpolation variables (e.g. \"viewport.main.scaleText\"). */\r\n interpolationVars: string[];\r\n\r\n /** Whether the template references remote (http/https) asset URLs. */\r\n usesRemoteAssets: boolean;\r\n}\r\n\r\nconst INTERPOLATION_RE = /\\{\\{\\s*([^}]+?)\\s*\\}\\}/g;\r\n\r\n/** Extract `{{path}}` tokens from a template string. */\r\nfunction extractInterpolationVars(text: string): string[] {\r\n const vars: string[] = [];\r\n let m: RegExpExecArray | null;\r\n INTERPOLATION_RE.lastIndex = 0;\r\n while ((m = INTERPOLATION_RE.exec(text)) !== null) {\r\n vars.push(m[1]);\r\n }\r\n return vars;\r\n}\r\n\r\n/** Collect keys from a WhereCondition (each key is a property short-path). */\r\nfunction collectWherePaths(where: WhereCondition | undefined, out: Set<string>): void {\r\n if (!where || typeof where !== 'object') return;\r\n for (const key of Object.keys(where)) {\r\n out.add(key);\r\n }\r\n}\r\n\r\n/** Collect class filter values, normalizing to lowercase. */\r\nfunction collectClassFilter(classFilter: string | string[] | undefined, out: Set<string>): void {\r\n if (!classFilter) return;\r\n const classes = Array.isArray(classFilter) ? classFilter : [classFilter];\r\n for (const c of classes) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) out.add(normalized);\r\n }\r\n}\r\n\r\n/**\r\n * Scan a layout template and return its input requirements.\r\n *\r\n * This is a pure, read-only analysis — it does not modify the template or\r\n * perform any rendering. Use the result to validate inputs before calling\r\n * `renderDrawing()` or `renderLayout()`.\r\n */\r\nexport function analyzeTemplate(template: LayoutTemplate): TemplateRequirements {\r\n const viewportIds = new Set<string>();\r\n const propertyPaths = new Set<string>();\r\n const classFilters = new Set<string>();\r\n const assetIds = new Set<string>();\r\n const interpolationVars = new Set<string>();\r\n let usesRemoteAssets = false;\r\n\r\n // Check assets for remote URLs\r\n if (template.assets) {\r\n for (const asset of template.assets) {\r\n if (asset.src && /^https?:\\/\\//i.test(asset.src)) {\r\n usesRemoteAssets = true;\r\n }\r\n }\r\n }\r\n\r\n // Walk all elements (recursing into groups)\r\n const walk = (elements: LayoutElement[]): void => {\r\n for (const el of elements) {\r\n switch (el.kind) {\r\n case 'viewport': {\r\n const vp = el as ViewportElement;\r\n viewportIds.add(vp.id);\r\n\r\n // Clip filter\r\n if (vp.clip) {\r\n collectClassFilter(vp.clip.class, classFilters);\r\n collectWherePaths(vp.clip.where, propertyPaths);\r\n }\r\n\r\n // Highlight filter\r\n if (vp.highlight) {\r\n collectClassFilter(vp.highlight.class, classFilters);\r\n collectWherePaths(vp.highlight.where, propertyPaths);\r\n }\r\n\r\n // includeClasses\r\n if (vp.includeClasses) {\r\n if (Array.isArray(vp.includeClasses)) {\r\n for (const c of vp.includeClasses) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) classFilters.add(normalized);\r\n }\r\n }\r\n // Preset references are resolved at render time, nothing to collect\r\n }\r\n\r\n // North arrow asset\r\n if (vp.northArrow?.assetId) {\r\n assetIds.add(vp.northArrow.assetId);\r\n }\r\n break;\r\n }\r\n\r\n case 'text': {\r\n const txt = el as TextElement;\r\n if (txt.text) {\r\n for (const v of extractInterpolationVars(txt.text)) {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'image': {\r\n const img = el as ImageElement;\r\n if (img.assetId) assetIds.add(img.assetId);\r\n break;\r\n }\r\n\r\n case 'qr': {\r\n const qr = el as QrElement;\r\n if (qr.dataTemplate) {\r\n for (const v of extractInterpolationVars(qr.dataTemplate)) {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'labels': {\r\n const sl = el as LabelsElement;\r\n collectClassFilter(sl.class, classFilters);\r\n collectWherePaths(sl.where, propertyPaths);\r\n\r\n // Extract property paths from text interpolation (skip viewport.* which are computed)\r\n if (sl.text) {\r\n for (const v of extractInterpolationVars(sl.text)) {\r\n if (!v.startsWith('viewport.')) {\r\n propertyPaths.add(v);\r\n } else {\r\n interpolationVars.add(v);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'legend': {\r\n const leg = el as LegendElement;\r\n collectClassFilter(leg.class, classFilters);\r\n collectWherePaths(leg.where, propertyPaths);\r\n\r\n // Column property paths\r\n if (leg.columns) {\r\n for (const col of leg.columns) {\r\n if (col.property) propertyPaths.add(col.property);\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case 'scaleBar': {\r\n // scaleBar references a viewport by ID (informational)\r\n const sb = el as ScaleBarElement;\r\n if (sb.viewport) viewportIds.add(sb.viewport);\r\n break;\r\n }\r\n\r\n case 'group': {\r\n const grp = el as GroupElement;\r\n if (grp.children) walk(grp.children);\r\n break;\r\n }\r\n }\r\n }\r\n };\r\n\r\n walk(template.elements);\r\n\r\n return {\r\n viewportIds: [...viewportIds],\r\n propertyPaths: [...propertyPaths],\r\n classFilters: [...classFilters],\r\n assetIds: [...assetIds],\r\n interpolationVars: [...interpolationVars],\r\n usesRemoteAssets\r\n };\r\n}\r\n"]}
@@ -0,0 +1,18 @@
1
+ import type { SvgModelView } from './types';
2
+ export type Point = {
3
+ x: number;
4
+ y: number;
5
+ };
6
+ export type Polygon = Point[];
7
+ export declare const pointInPolygon: (polygon: Polygon, x: number, y: number) => boolean;
8
+ export declare const filterItemsInPolygons: (items: unknown[], polygons: Polygon[], xField: string | undefined, yField: string | undefined, getPathValue: (obj: unknown, path: string) => unknown) => unknown[];
9
+ export declare const filterEntriesByClip: (entries: unknown[], polygons: Array<Array<{
10
+ x: number;
11
+ z: number;
12
+ }>>) => unknown[];
13
+ export declare const offsetPolygons: (polys: Polygon[], delta: number) => Polygon[];
14
+ export declare const projectPolygonsToLocal: (polygonsSource: unknown, xField: string, yField: string, model: SvgModelView, rotationDeg: number, contentOffsetX: number, contentOffsetY: number, mmPerModel: number) => {
15
+ local: Polygon[];
16
+ page: Polygon[];
17
+ };
18
+ //# sourceMappingURL=clipUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipUtils.d.ts","sourceRoot":"/","sources":["layout/clipUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7C,MAAM,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;AAI9B,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,OAWvE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAC9B,OAAO,OAAO,EAAE,EAChB,UAAU,OAAO,EAAE,EACnB,0BAAY,EACZ,0BAAY,EACZ,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,KACtD,OAAO,EAUT,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,SAAS,OAAO,EAAE,EAClB,UAAU,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,KACjD,OAAO,EA2CT,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,EAAE,EAAE,OAAO,MAAM,KAAG,OAAO,EAuCvE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAC/B,gBAAgB,OAAO,EACvB,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,OAAO,YAAY,EACnB,aAAa,MAAM,EACnB,gBAAgB,MAAM,EACtB,gBAAgB,MAAM,EACtB,YAAY,MAAM,KACnB;IAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAuDrC,CAAC"}