@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"/","sources":["layout/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNonEmptyString, isPositiveNumber, isRemoteUrl, isDataUrl } from './validationUtils';\r\nimport { isRecord, getProp } from './validationHelpers';\r\nimport {\r\n ELEMENT_KIND_VIEWPORT,\r\n ELEMENT_KIND_TEXT,\r\n ELEMENT_KIND_IMAGE,\r\n ELEMENT_KIND_LINE,\r\n ELEMENT_KIND_RECT,\r\n ELEMENT_KIND_SCALE_BAR,\r\n ELEMENT_KIND_QR,\r\n ELEMENT_KIND_LABELS,\r\n ELEMENT_KIND_LEGEND,\r\n ELEMENT_KIND_GROUP\r\n} from './elementKinds';\r\n\r\nimport type { ValidationOptions, ValidationIssue, ValidationResult } from './types';\r\nexport type { ValidationOptions, ValidationIssue, ValidationResult };\r\n\r\n/**\r\n * Lightweight template validation (structure only) for v2 schema.\r\n */\r\nexport function validateLayoutTemplate(template: unknown, options?: ValidationOptions): ValidationResult {\r\n const allowRemoteAssets = options?.allowRemoteAssets ?? true;\r\n const allowDataUrls = options?.allowDataUrls ?? true;\r\n const maxViewports = options?.maxViewports ?? 3;\r\n const errors: ValidationIssue[] = [];\r\n\r\n if (!isRecord(template)) {\r\n return { ok: false, errors: [{ path: '', message: 'Template must be an object.' }] };\r\n }\r\n\r\n const t = template;\r\n\r\n const page = getProp(t, 'page');\r\n if (!isRecord(page)) {\r\n errors.push({ path: 'page', message: 'Page definition is required.' });\r\n } else {\r\n if (!isPositiveNumber(getProp(page, 'widthMm')))\r\n errors.push({ path: 'page.widthMm', message: 'widthMm must be > 0.' });\r\n if (!isPositiveNumber(getProp(page, 'heightMm')))\r\n errors.push({ path: 'page.heightMm', message: 'heightMm must be > 0.' });\r\n const marginMm = getProp(page, 'marginMm');\r\n if (marginMm !== undefined && typeof marginMm !== 'number') {\r\n errors.push({ path: 'page.marginMm', message: 'marginMm must be a number when provided.' });\r\n }\r\n }\r\n\r\n const assetIds = new Set<string>();\r\n const assets = getProp(t, 'assets');\r\n if (Array.isArray(assets)) {\r\n assets.forEach((asset: unknown, index: number) => {\r\n if (!isRecord(asset)) {\r\n errors.push({ path: `assets[${index}]`, message: 'Asset must be an object.' });\r\n return;\r\n }\r\n const id = getProp(asset, 'id');\r\n if (!isNonEmptyString(id)) {\r\n errors.push({ path: `assets[${index}].id`, message: 'Asset id is required.' });\r\n } else if (assetIds.has(id as string)) {\r\n errors.push({ path: `assets[${index}].id`, message: 'Duplicate asset id.' });\r\n } else {\r\n assetIds.add(id as string);\r\n }\r\n\r\n const src = getProp(asset, 'src');\r\n const content = getProp(asset, 'content');\r\n if (!isNonEmptyString(src) && !isNonEmptyString(content)) {\r\n errors.push({ path: `assets[${index}]`, message: 'Asset must have either src or content.' });\r\n }\r\n\r\n if (isNonEmptyString(src)) {\r\n if (isRemoteUrl(src as string) && !allowRemoteAssets) {\r\n errors.push({ path: `assets[${index}].src`, message: 'Remote URLs are not allowed for assets.' });\r\n } else if (isDataUrl(src as string) && !allowDataUrls) {\r\n errors.push({ path: `assets[${index}].src`, message: 'Data URLs are not allowed for assets.' });\r\n }\r\n }\r\n });\r\n } else if (assets !== undefined) {\r\n errors.push({ path: 'assets', message: 'Assets must be an array when provided.' });\r\n }\r\n\r\n const styleNames = new Set<string>();\r\n const styles = getProp(t, 'styles');\r\n if (styles !== undefined) {\r\n if (!isRecord(styles)) {\r\n errors.push({ path: 'styles', message: 'Styles must be an object map.' });\r\n } else {\r\n Object.entries(styles).forEach(([name, style]) => {\r\n styleNames.add(name);\r\n if (!isRecord(style)) {\r\n errors.push({ path: `styles.${name}`, message: 'Style must be an object.' });\r\n return;\r\n }\r\n if (!isNonEmptyString(getProp(style, 'fontFamily'))) {\r\n errors.push({ path: `styles.${name}.fontFamily`, message: 'fontFamily is required.' });\r\n }\r\n if (!isPositiveNumber(getProp(style, 'fontSizeMm'))) {\r\n errors.push({ path: `styles.${name}.fontSizeMm`, message: 'fontSizeMm must be > 0.' });\r\n }\r\n });\r\n }\r\n }\r\n\r\n let viewportCount = 0;\r\n\r\n const validateElement = (el: unknown, path: string): void => {\r\n if (!isRecord(el)) {\r\n errors.push({ path, message: 'Element must be an object.' });\r\n return;\r\n }\r\n const kind = getProp(el, 'kind');\r\n if (!kind || typeof kind !== 'string') {\r\n errors.push({ path: `${path}.kind`, message: 'Element kind is required.' });\r\n return;\r\n }\r\n\r\n const ensure = (condition: boolean, subPath: string, message: string): void => {\r\n if (!condition) errors.push({ path: subPath, message });\r\n };\r\n\r\n ensure(isNonEmptyString(getProp(el, 'id')), `${path}.id`, 'Element id is required.');\r\n\r\n if (kind === ELEMENT_KIND_VIEWPORT) {\r\n viewportCount++;\r\n if (viewportCount > maxViewports) {\r\n errors.push({ path, message: 'Too many viewports.' });\r\n }\r\n ensure(isPositiveNumber(getProp(el, 'widthMm')), `${path}.widthMm`, 'widthMm must be > 0.');\r\n ensure(isPositiveNumber(getProp(el, 'heightMm')), `${path}.heightMm`, 'heightMm must be > 0.');\r\n const xMm = getProp(el, 'xMm');\r\n const yMm = getProp(el, 'yMm');\r\n ensure(isPositiveNumber(xMm) || xMm === 0, `${path}.xMm`, 'xMm is required.');\r\n ensure(isPositiveNumber(yMm) || yMm === 0, `${path}.yMm`, 'yMm is required.');\r\n const border = getProp(el, 'border');\r\n if (border) {\r\n // border.stroke and border.strokeWidthMm are optional in v2\r\n }\r\n const clip = getProp(el, 'clip');\r\n if (clip && isRecord(clip)) {\r\n const where = getProp(clip, 'where');\r\n if (!isRecord(where)) {\r\n errors.push({\r\n path: `${path}.clip.where`,\r\n message: 'clip.where is required and must be an object.'\r\n });\r\n }\r\n }\r\n const highlight = getProp(el, 'highlight');\r\n if (highlight && isRecord(highlight)) {\r\n const where = getProp(highlight, 'where');\r\n if (!isRecord(where)) {\r\n errors.push({\r\n path: `${path}.highlight.where`,\r\n message: 'highlight.where is required and must be an object.'\r\n });\r\n }\r\n }\r\n } else if (kind === ELEMENT_KIND_TEXT) {\r\n const xMm = getProp(el, 'xMm');\r\n const yMm = getProp(el, 'yMm');\r\n ensure(isPositiveNumber(xMm) || xMm === 0, `${path}.xMm`, 'xMm is required.');\r\n ensure(isPositiveNumber(yMm) || yMm === 0, `${path}.yMm`, 'yMm is required.');\r\n const textStyle = getProp(el, 'textStyle');\r\n if (textStyle !== undefined) {\r\n if (typeof textStyle === 'string' && styleNames.size > 0 && !styleNames.has(textStyle)) {\r\n errors.push({\r\n path: `${path}.textStyle`,\r\n message: `Style '${textStyle}' is not defined in styles.`\r\n });\r\n }\r\n }\r\n ensure(isNonEmptyString(getProp(el, 'text')), `${path}.text`, 'text is required.');\r\n } else if (kind === ELEMENT_KIND_IMAGE) {\r\n ensure(isPositiveNumber(getProp(el, 'widthMm')), `${path}.widthMm`, 'widthMm must be > 0.');\r\n ensure(isPositiveNumber(getProp(el, 'heightMm')), `${path}.heightMm`, 'heightMm must be > 0.');\r\n ensure(isNonEmptyString(getProp(el, 'assetId')), `${path}.assetId`, 'assetId is required.');\r\n } else if (kind === ELEMENT_KIND_LINE) {\r\n // stroke and strokeWidthMm optional in v2\r\n } else if (kind === ELEMENT_KIND_RECT) {\r\n ensure(isPositiveNumber(getProp(el, 'widthMm')), `${path}.widthMm`, 'widthMm must be > 0.');\r\n ensure(isPositiveNumber(getProp(el, 'heightMm')), `${path}.heightMm`, 'heightMm must be > 0.');\r\n } else if (kind === ELEMENT_KIND_SCALE_BAR) {\r\n ensure(isPositiveNumber(getProp(el, 'maxLengthMm')), `${path}.maxLengthMm`, 'maxLengthMm must be > 0.');\r\n const textStyle = getProp(el, 'textStyle');\r\n if (textStyle !== undefined) {\r\n if (typeof textStyle === 'string' && styleNames.size > 0 && !styleNames.has(textStyle)) {\r\n errors.push({\r\n path: `${path}.textStyle`,\r\n message: `Style '${textStyle}' is not defined in styles.`\r\n });\r\n }\r\n }\r\n } else if (kind === ELEMENT_KIND_QR) {\r\n ensure(isPositiveNumber(getProp(el, 'sizeMm')), `${path}.sizeMm`, 'sizeMm must be > 0.');\r\n const xMm = getProp(el, 'xMm');\r\n const yMm = getProp(el, 'yMm');\r\n ensure(isPositiveNumber(xMm) || xMm === 0, `${path}.xMm`, 'xMm is required.');\r\n ensure(isPositiveNumber(yMm) || yMm === 0, `${path}.yMm`, 'yMm is required.');\r\n } else if (kind === ELEMENT_KIND_LABELS) {\r\n ensure(isNonEmptyString(getProp(el, 'viewport')), `${path}.viewport`, 'viewport is required.');\r\n ensure(isNonEmptyString(getProp(el, 'text')), `${path}.text`, 'text is required.');\r\n const textStyle = getProp(el, 'textStyle');\r\n if (textStyle !== undefined) {\r\n if (typeof textStyle === 'string' && styleNames.size > 0 && !styleNames.has(textStyle)) {\r\n errors.push({\r\n path: `${path}.textStyle`,\r\n message: `Style '${textStyle}' is not defined in styles.`\r\n });\r\n }\r\n }\r\n } else if (kind === ELEMENT_KIND_LEGEND) {\r\n ensure(isNonEmptyString(getProp(el, 'viewport')), `${path}.viewport`, 'viewport is required.');\r\n const columns = getProp(el, 'columns');\r\n if (!Array.isArray(columns) || !columns.length) {\r\n errors.push({ path: `${path}.columns`, message: 'columns is required and must be a non-empty array.' });\r\n } else {\r\n columns.forEach((col: unknown, idx: number) => {\r\n if (!isRecord(col)) {\r\n errors.push({ path: `${path}.columns[${idx}]`, message: 'Column must be an object.' });\r\n return;\r\n }\r\n ensure(\r\n isNonEmptyString(getProp(col, 'id')),\r\n `${path}.columns[${idx}].id`,\r\n 'Column id is required.'\r\n );\r\n ensure(\r\n isNonEmptyString(getProp(col, 'label')),\r\n `${path}.columns[${idx}].label`,\r\n 'Column label is required.'\r\n );\r\n ensure(\r\n isNonEmptyString(getProp(col, 'property')),\r\n `${path}.columns[${idx}].property`,\r\n 'Column property is required.'\r\n );\r\n });\r\n }\r\n const textStyle = getProp(el, 'textStyle');\r\n if (textStyle !== undefined) {\r\n if (typeof textStyle === 'string' && styleNames.size > 0 && !styleNames.has(textStyle)) {\r\n errors.push({\r\n path: `${path}.textStyle`,\r\n message: `Style '${textStyle}' is not defined in styles.`\r\n });\r\n }\r\n }\r\n const clipToViewport = getProp(el, 'clipToViewport');\r\n if (clipToViewport !== undefined && typeof clipToViewport !== 'boolean') {\r\n errors.push({\r\n path: `${path}.clipToViewport`,\r\n message: 'clipToViewport must be a boolean when provided.'\r\n });\r\n }\r\n } else if (kind === ELEMENT_KIND_GROUP) {\r\n const opacity = getProp(el, 'opacity');\r\n if (opacity !== undefined) {\r\n ensure(\r\n typeof opacity === 'number' && opacity >= 0 && opacity <= 1,\r\n `${path}.opacity`,\r\n 'opacity must be between 0 and 1.'\r\n );\r\n }\r\n const transform = getProp(el, 'transform');\r\n if (transform) {\r\n const scaleX = getProp(transform, 'scaleX');\r\n const scaleY = getProp(transform, 'scaleY');\r\n ensure(\r\n scaleX === undefined || typeof scaleX === 'number',\r\n `${path}.transform.scaleX`,\r\n 'scaleX must be a number'\r\n );\r\n ensure(\r\n scaleY === undefined || typeof scaleY === 'number',\r\n `${path}.transform.scaleY`,\r\n 'scaleY must be a number'\r\n );\r\n }\r\n const clip = getProp(el, 'clip');\r\n if (clip) {\r\n ensure(getProp(clip, 'type') === 'rect', `${path}.clip.type`, \"clip.type must be 'rect'.\");\r\n ensure(isPositiveNumber(getProp(clip, 'widthMm')), `${path}.clip.widthMm`, 'clip.widthMm must be > 0.');\r\n ensure(\r\n isPositiveNumber(getProp(clip, 'heightMm')),\r\n `${path}.clip.heightMm`,\r\n 'clip.heightMm must be > 0.'\r\n );\r\n const clipXMm = getProp(clip, 'xMm');\r\n const clipYMm = getProp(clip, 'yMm');\r\n ensure(isPositiveNumber(clipXMm) || clipXMm === 0, `${path}.clip.xMm`, 'clip.xMm is required.');\r\n ensure(isPositiveNumber(clipYMm) || clipYMm === 0, `${path}.clip.yMm`, 'clip.yMm is required.');\r\n }\r\n const children = getProp(el, 'children');\r\n if (Array.isArray(children)) {\r\n children.forEach((child: unknown, childIdx: number) =>\r\n validateElement(child, `${path}.children[${childIdx}]`)\r\n );\r\n }\r\n } else {\r\n errors.push({ path, message: `Unknown element kind '${kind}'.` });\r\n }\r\n };\r\n\r\n const elements = getProp(t, 'elements');\r\n if (Array.isArray(elements)) {\r\n elements.forEach((el: unknown, index: number) => validateElement(el, `elements[${index}]`));\r\n } else if (elements !== undefined) {\r\n errors.push({ path: 'elements', message: 'Elements must be an array.' });\r\n }\r\n\r\n // Validate template variables (if present)\r\n const variables = getProp(t, 'variables');\r\n if (variables !== undefined) {\r\n if (!isRecord(variables)) {\r\n errors.push({ path: 'variables', message: 'Variables must be an object.' });\r\n } else {\r\n // Validate each variable definition\r\n for (const [varName, varDef] of Object.entries(variables)) {\r\n const varPath = `variables.${varName}`;\r\n\r\n if (!isRecord(varDef)) {\r\n errors.push({ path: varPath, message: 'Variable definition must be an object.' });\r\n continue;\r\n }\r\n\r\n // Validate type\r\n const varType = getProp(varDef, 'type');\r\n if (!['string', 'number', 'boolean', 'array'].includes(varType as string)) {\r\n errors.push({\r\n path: `${varPath}.type`,\r\n message: `Type must be 'string', 'number', 'boolean', or 'array' (got '${varType}').`\r\n });\r\n }\r\n\r\n // Enforce default value (CRITICAL for fail-safe operation)\r\n const defaultValue = getProp(varDef, 'default');\r\n if (defaultValue === undefined || defaultValue === null) {\r\n errors.push({\r\n path: `${varPath}.default`,\r\n message: 'Variable must have a default value (required for fail-safe operation).'\r\n });\r\n } else {\r\n // Validate default value matches declared type\r\n const actualType = Array.isArray(defaultValue) ? 'array' : typeof defaultValue;\r\n if (varType === 'number' && actualType !== 'number') {\r\n errors.push({\r\n path: `${varPath}.default`,\r\n message: `Default value must be a number (got ${actualType}).`\r\n });\r\n } else if (varType === 'string' && actualType !== 'string') {\r\n errors.push({\r\n path: `${varPath}.default`,\r\n message: `Default value must be a string (got ${actualType}).`\r\n });\r\n } else if (varType === 'boolean' && actualType !== 'boolean') {\r\n errors.push({\r\n path: `${varPath}.default`,\r\n message: `Default value must be a boolean (got ${actualType}).`\r\n });\r\n } else if (varType === 'array' && actualType !== 'array') {\r\n errors.push({\r\n path: `${varPath}.default`,\r\n message: `Default value must be an array (got ${actualType}).`\r\n });\r\n }\r\n }\r\n\r\n // Validate numeric constraints (if present)\r\n if (varType === 'number') {\r\n const min = getProp(varDef, 'min');\r\n const max = getProp(varDef, 'max');\r\n if (min !== undefined && typeof min !== 'number') {\r\n errors.push({ path: `${varPath}.min`, message: 'min must be a number.' });\r\n }\r\n if (max !== undefined && typeof max !== 'number') {\r\n errors.push({ path: `${varPath}.max`, message: 'max must be a number.' });\r\n }\r\n if (typeof min === 'number' && typeof max === 'number' && min > max) {\r\n errors.push({ path: `${varPath}`, message: 'min cannot be greater than max.' });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (errors.length) {\r\n return { ok: false, errors };\r\n }\r\n\r\n return { ok: true, template };\r\n}\r\n"]}
@@ -0,0 +1,15 @@
1
+ import { ValidationIssue } from './types';
2
+ import { isRecord, getProp } from './typeGuards';
3
+ export { isRecord, getProp };
4
+ /**
5
+ * Check if path is a valid short path: SetName.propertyName (e.g., "Pset_SpaceCommon.Reference")
6
+ * This is the only accepted format for template paths.
7
+ */
8
+ export declare const isShortPath: (path: string) => boolean;
9
+ /**
10
+ * Push a "must use short path" error to the errors array.
11
+ */
12
+ export declare const pushShortPathError: (errors: ValidationIssue[], path: string, context: string) => void;
13
+ export declare const validateFilterPaths: (filters: unknown, basePath: string, errors: ValidationIssue[], context: string) => void;
14
+ export declare const validatePathShape: (path: string | undefined, errors: ValidationIssue[], fieldPath: string, context: string) => void;
15
+ //# sourceMappingURL=validationHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationHelpers.d.ts","sourceRoot":"/","sources":["layout/validationHelpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OACyD,CAAC;AAErG;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,eAAe,EAAE,EAAE,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,IAK7F,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,SAAS,OAAO,EAChB,UAAU,MAAM,EAChB,QAAQ,eAAe,EAAE,EACzB,SAAS,MAAM,KAChB,IAYF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC1B,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,eAAe,EAAE,EACzB,WAAW,MAAM,EACjB,SAAS,MAAM,KAChB,IAWF,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { isNonEmptyString } from './validationUtils';
2
+ import { isRecord, getProp } from './typeGuards';
3
+ export { isRecord, getProp };
4
+ /**
5
+ * Check if path is a valid short path: SetName.propertyName (e.g., "Pset_SpaceCommon.Reference")
6
+ * This is the only accepted format for template paths.
7
+ */
8
+ export const isShortPath = (path) => typeof path === 'string' && /^[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*$/.test(path.trim());
9
+ /**
10
+ * Push a "must use short path" error to the errors array.
11
+ */
12
+ export const pushShortPathError = (errors, path, context) => {
13
+ errors.push({
14
+ path,
15
+ message: `${context} must use short format: SetName.propName (e.g., "Pset_SpaceCommon.Reference")`
16
+ });
17
+ };
18
+ export const validateFilterPaths = (filters, basePath, errors, context) => {
19
+ if (Array.isArray(filters)) {
20
+ filters.forEach((f, idx) => {
21
+ const path = getProp(f, 'path');
22
+ if (isRecord(f) && isNonEmptyString(path) && !isShortPath(path)) {
23
+ errors.push({
24
+ path: `${basePath}[${idx}].path`,
25
+ message: `${context} path must use short format: SetName.propName (e.g., "Pset_SpaceCommon.Reference")`
26
+ });
27
+ }
28
+ });
29
+ }
30
+ };
31
+ export const validatePathShape = (path, errors, fieldPath, context) => {
32
+ if (!path || !path.trim().length) {
33
+ errors.push({ path: fieldPath, message: `${context} path is required.` });
34
+ return;
35
+ }
36
+ if (!isShortPath(path)) {
37
+ errors.push({
38
+ path: fieldPath,
39
+ message: `${context} path must use short format: SetName.propName (e.g., "Pset_SpaceCommon.Reference")`
40
+ });
41
+ }
42
+ };
43
+ //# sourceMappingURL=validationHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationHelpers.js","sourceRoot":"/","sources":["layout/validationHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAW,EAAE,CACjD,OAAO,IAAI,KAAK,QAAQ,IAAI,kDAAkD,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAErG;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAyB,EAAE,IAAY,EAAE,OAAe,EAAQ,EAAE;IACjG,MAAM,CAAC,IAAI,CAAC;QACR,IAAI;QACJ,OAAO,EAAE,GAAG,OAAO,+EAA+E;KACrG,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAC/B,OAAgB,EAChB,QAAgB,EAChB,MAAyB,EACzB,OAAe,EACX,EAAE;IACN,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAU,EAAE,GAAW,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAChC,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAc,CAAC,EAAE,CAAC;gBACxE,MAAM,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,GAAG,QAAQ,IAAI,GAAG,QAAQ;oBAChC,OAAO,EAAE,GAAG,OAAO,oFAAoF;iBAC1G,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC7B,IAAwB,EACxB,MAAyB,EACzB,SAAiB,EACjB,OAAe,EACX,EAAE;IACN,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,oBAAoB,EAAE,CAAC,CAAC;QAC1E,OAAO;IACX,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,GAAG,OAAO,oFAAoF;SAC1G,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { isNonEmptyString } from './validationUtils';\r\nimport { ValidationIssue } from './types';\r\n\r\nimport { isRecord, getProp } from './typeGuards';\r\nexport { isRecord, getProp };\r\n\r\n/**\r\n * Check if path is a valid short path: SetName.propertyName (e.g., \"Pset_SpaceCommon.Reference\")\r\n * This is the only accepted format for template paths.\r\n */\r\nexport const isShortPath = (path: string): boolean =>\r\n typeof path === 'string' && /^[A-Za-z_][A-Za-z0-9_]*\\.[A-Za-z_][A-Za-z0-9_]*$/.test(path.trim());\r\n\r\n/**\r\n * Push a \"must use short path\" error to the errors array.\r\n */\r\nexport const pushShortPathError = (errors: ValidationIssue[], path: string, context: string): void => {\r\n errors.push({\r\n path,\r\n message: `${context} must use short format: SetName.propName (e.g., \"Pset_SpaceCommon.Reference\")`\r\n });\r\n};\r\n\r\nexport const validateFilterPaths = (\r\n filters: unknown,\r\n basePath: string,\r\n errors: ValidationIssue[],\r\n context: string\r\n): void => {\r\n if (Array.isArray(filters)) {\r\n filters.forEach((f: unknown, idx: number) => {\r\n const path = getProp(f, 'path');\r\n if (isRecord(f) && isNonEmptyString(path) && !isShortPath(path as string)) {\r\n errors.push({\r\n path: `${basePath}[${idx}].path`,\r\n message: `${context} path must use short format: SetName.propName (e.g., \"Pset_SpaceCommon.Reference\")`\r\n });\r\n }\r\n });\r\n }\r\n};\r\n\r\nexport const validatePathShape = (\r\n path: string | undefined,\r\n errors: ValidationIssue[],\r\n fieldPath: string,\r\n context: string\r\n): void => {\r\n if (!path || !path.trim().length) {\r\n errors.push({ path: fieldPath, message: `${context} path is required.` });\r\n return;\r\n }\r\n if (!isShortPath(path)) {\r\n errors.push({\r\n path: fieldPath,\r\n message: `${context} path must use short format: SetName.propName (e.g., \"Pset_SpaceCommon.Reference\")`\r\n });\r\n }\r\n};\r\n"]}
@@ -0,0 +1,5 @@
1
+ export declare const isNonEmptyString: (value: unknown) => value is string;
2
+ export declare const isPositiveNumber: (value: unknown) => value is number;
3
+ export declare const isRemoteUrl: (value: string) => boolean;
4
+ export declare const isDataUrl: (value: string) => boolean;
5
+ //# sourceMappingURL=validationUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationUtils.d.ts","sourceRoot":"/","sources":["layout/validationUtils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACH,CAAC;AACzD,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACS,CAAC;AACrE,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,OAAsC,CAAC;AACnF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,OAAgC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export const isNonEmptyString = (value) => typeof value === 'string' && value.trim().length > 0;
2
+ export const isPositiveNumber = (value) => typeof value === 'number' && Number.isFinite(value) && value > 0;
3
+ export const isRemoteUrl = (value) => /^https?:\/\//i.test(value);
4
+ export const isDataUrl = (value) => /^data:/i.test(value);
5
+ //# sourceMappingURL=validationUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationUtils.js","sourceRoot":"/","sources":["layout/validationUtils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAmB,EAAE,CAChE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAmB,EAAE,CAChE,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC","sourcesContent":["export const isNonEmptyString = (value: unknown): value is string =>\r\n typeof value === 'string' && value.trim().length > 0;\r\nexport const isPositiveNumber = (value: unknown): value is number =>\r\n typeof value === 'number' && Number.isFinite(value) && value > 0;\r\nexport const isRemoteUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\r\nexport const isDataUrl = (value: string): boolean => /^data:/i.test(value);\r\n"]}
@@ -0,0 +1,47 @@
1
+ import { ViewportElement, SvgModelView, ComputedViewportScale } from './types';
2
+ import type { ResolvedPresets } from './presets';
3
+ export interface ViewportPrepResult {
4
+ viewportScales: Record<string, ComputedViewportScale>;
5
+ viewportClipPolygonsLocal: Record<string, Array<Array<{
6
+ x: number;
7
+ y: number;
8
+ }>>>;
9
+ viewportClipPolygonsWorld: Record<string, Array<Array<{
10
+ x: number;
11
+ z: number;
12
+ }>>>;
13
+ viewportClipBounds: Record<string, {
14
+ minX: number;
15
+ maxX: number;
16
+ minY: number;
17
+ maxY: number;
18
+ width: number;
19
+ height: number;
20
+ }>;
21
+ viewportClipLabels: Record<string, boolean>;
22
+ viewportClipStyles: Record<string, {
23
+ stroke?: string;
24
+ strokeWidthMm?: number;
25
+ strokeOpacity?: number;
26
+ fill?: string;
27
+ fillOpacity?: number;
28
+ }>;
29
+ viewportClipWhere: Record<string, WhereCondition | undefined>;
30
+ viewportHighlight: Record<string, {
31
+ gids: Set<string> | null;
32
+ styles: {
33
+ stroke?: string;
34
+ strokeWidthMm?: number;
35
+ strokeOpacity?: number;
36
+ fill?: string;
37
+ fillOpacity?: number;
38
+ };
39
+ }>;
40
+ filteredModelsByViewport: Record<string, SvgModelView>;
41
+ }
42
+ import type { WhereCondition } from './types';
43
+ export declare const prepareViewports: (viewports: ViewportElement[], models: Record<string, SvgModelView | undefined>, data: unknown, preferredScales: number[], presets: ResolvedPresets, options: {
44
+ metadataById?: unknown;
45
+ warnings: string[];
46
+ }) => ViewportPrepResult;
47
+ //# sourceMappingURL=viewportPrep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewportPrep.d.ts","sourceRoot":"/","sources":["layout/viewportPrep.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAMjD,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACtD,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC,CAAC;IAClF,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC,CAAC;IAClF,kBAAkB,EAAE,MAAM,CACtB,MAAM,EACN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAC5F,CAAC;IACF,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,kBAAkB,EAAE,MAAM,CACtB,MAAM,EACN;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAC3G,CAAC;IACF,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC,CAAC;IAC9D,iBAAiB,EAAE,MAAM,CACrB,MAAM,EACN;QACI,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QACzB,MAAM,EAAE;YACJ,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,WAAW,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;KACL,CACJ,CAAC;IACF,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC1D;AAGD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,gBAAgB,GACzB,WAAW,eAAe,EAAE,EAC5B,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,EAChD,MAAM,OAAO,EACb,iBAAiB,MAAM,EAAE,EACzB,SAAS,eAAe,EACxB,SAAS;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,KACxD,kBA2SF,CAAC"}
@@ -0,0 +1,275 @@
1
+ import { filterModelForViewport } from './model';
2
+ import { pushWarning } from './warnings';
3
+ import { pickScale } from './viewportUtils';
4
+ import { getPathValue } from './renderUtils';
5
+ import { pointInPolygon, offsetPolygons } from './clipUtils';
6
+ import { matchesV2Filter, normalizeClass } from './filters';
7
+ import { EPSILON_MIN_DIMENSION } from './geometryConstants';
8
+ import { isRecord, getProp } from './typeGuards';
9
+ export const prepareViewports = (viewports, models, data, preferredScales, presets, options) => {
10
+ const viewportScales = {};
11
+ const viewportClipPolygonsLocal = {};
12
+ const viewportClipPolygonsWorld = {};
13
+ const viewportClipBounds = {};
14
+ const viewportClipLabels = {};
15
+ const viewportClipStyles = {};
16
+ const viewportClipWhere = {};
17
+ const viewportHighlight = {};
18
+ const filteredModelsByViewport = {};
19
+ const scales = presets.scales;
20
+ viewports.forEach((vp) => {
21
+ const baseModel = models[vp.id];
22
+ let clipAllowedGids = null;
23
+ // Highlight: optional class+where filter on normalized items
24
+ let highlightGids = null;
25
+ const hlCfg = vp.highlight;
26
+ if (hlCfg && hlCfg.where) {
27
+ const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);
28
+ if (Array.isArray(sourceItems) && sourceItems.length) {
29
+ const matching = sourceItems.filter((it) => matchesV2Filter(it, hlCfg.class, hlCfg.where));
30
+ if (matching.length) {
31
+ highlightGids = new Set(matching
32
+ .map((it) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)
33
+ .filter((v) => v !== null && v !== undefined)
34
+ .map((v) => String(v)));
35
+ // Intersect with referenced viewport if specified
36
+ if (hlCfg.intersectsViewport) {
37
+ const refItems = getPathValue(data, `viewports.${hlCfg.intersectsViewport}.items`);
38
+ if (Array.isArray(refItems) && refItems.length) {
39
+ const refGids = new Set(refItems
40
+ .map((it) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)
41
+ .filter((v) => v !== null && v !== undefined)
42
+ .map((v) => String(v)));
43
+ // Keep only items that appear in both viewports
44
+ const intersection = new Set();
45
+ highlightGids.forEach((gid) => {
46
+ if (refGids.has(gid))
47
+ intersection.add(gid);
48
+ });
49
+ highlightGids = intersection;
50
+ }
51
+ else {
52
+ pushWarning(options.warnings, `Viewport '${vp.id}' highlight intersectsViewport="${hlCfg.intersectsViewport}": referenced viewport has no items.`);
53
+ highlightGids = new Set(); // No items in referenced viewport = no highlights
54
+ }
55
+ }
56
+ }
57
+ else {
58
+ highlightGids = new Set(); // explicit no matches
59
+ pushWarning(options.warnings, `Viewport '${vp.id}' highlight filter matched 0 of ${sourceItems.length} items.`);
60
+ }
61
+ }
62
+ else if (Array.isArray(sourceItems) && !sourceItems.length) {
63
+ pushWarning(options.warnings, `Viewport '${vp.id}' highlight: no items available to filter.`);
64
+ }
65
+ }
66
+ // Clip: class+where filter — find matching items, extract their polylines as clip polygons
67
+ let clipEffectiveWidthModel;
68
+ let clipEffectiveHeightModel;
69
+ const clipCfg = vp.clip;
70
+ if (clipCfg && clipCfg.where && baseModel?.transform) {
71
+ viewportClipWhere[vp.id] = clipCfg.where;
72
+ const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);
73
+ if (Array.isArray(sourceItems) && sourceItems.length) {
74
+ const matchingItems = sourceItems.filter((it) => matchesV2Filter(it, clipCfg.class, clipCfg.where));
75
+ if (!matchingItems.length) {
76
+ pushWarning(options.warnings, `Viewport '${vp.id}' clip filter matched 0 of ${sourceItems.length} items.`);
77
+ }
78
+ // Extract polylines from matched items
79
+ const allPolylines = [];
80
+ for (const item of matchingItems) {
81
+ const polylines = getProp(item, 'polylines');
82
+ if (Array.isArray(polylines)) {
83
+ for (const pl of polylines) {
84
+ if (isRecord(pl))
85
+ allPolylines.push(pl);
86
+ }
87
+ }
88
+ }
89
+ if (allPolylines.length) {
90
+ // Project polyline points from world (x/z) to model view space
91
+ const projectedLocal = [];
92
+ for (const poly of allPolylines) {
93
+ const pts = poly.points;
94
+ if (!Array.isArray(pts) || pts.length < 3)
95
+ continue;
96
+ const mapped = [];
97
+ for (const pt of pts) {
98
+ const px = pt?.x;
99
+ const pz = pt?.z;
100
+ if (!Number.isFinite(px) || !Number.isFinite(pz))
101
+ continue;
102
+ mapped.push({
103
+ x: px - baseModel.transform.viewMinX,
104
+ y: baseModel.transform.viewMaxZ - pz
105
+ });
106
+ }
107
+ if (mapped.length >= 3)
108
+ projectedLocal.push(mapped);
109
+ }
110
+ const expandByM = typeof clipCfg.expandByM === 'number' &&
111
+ Number.isFinite(clipCfg.expandByM) &&
112
+ clipCfg.expandByM > 0
113
+ ? clipCfg.expandByM
114
+ : 0;
115
+ const buffered = expandByM > 0 ? offsetPolygons(projectedLocal, expandByM) : projectedLocal;
116
+ if (buffered.length) {
117
+ // Calculate bounds from EXPANDED polygon for viewport sizing (so everything fits)
118
+ // Fill filtering (clipAllowedGids) uses ORIGINAL polygon from worldPolygons (line 239)
119
+ const boundsSource = buffered; // Use EXPANDED for viewport sizing
120
+ const flat = boundsSource.flat();
121
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
122
+ for (let i = 0; i < flat.length; i++) {
123
+ const p = flat[i];
124
+ if (p.x < minX)
125
+ minX = p.x;
126
+ if (p.x > maxX)
127
+ maxX = p.x;
128
+ if (p.y < minY)
129
+ minY = p.y;
130
+ if (p.y > maxY)
131
+ maxY = p.y;
132
+ }
133
+ clipEffectiveWidthModel = Math.max(EPSILON_MIN_DIMENSION, maxX - minX);
134
+ clipEffectiveHeightModel = Math.max(EPSILON_MIN_DIMENSION, maxY - minY);
135
+ viewportClipPolygonsLocal[vp.id] = buffered;
136
+ viewportClipLabels[vp.id] = !!clipCfg.clipLabels;
137
+ viewportClipStyles[vp.id] = {
138
+ stroke: clipCfg.stroke ?? '#000000',
139
+ strokeWidthMm: clipCfg.strokeWidthMm ?? 0.5,
140
+ strokeOpacity: clipCfg.strokeOpacity ?? 1,
141
+ fill: clipCfg.fill ?? 'none',
142
+ fillOpacity: clipCfg.fillOpacity ?? 0
143
+ };
144
+ viewportClipBounds[vp.id] = {
145
+ minX,
146
+ maxX,
147
+ minY,
148
+ maxY,
149
+ width: clipEffectiveWidthModel,
150
+ height: clipEffectiveHeightModel
151
+ };
152
+ // Build clipAllowedGids: include items whose center falls inside the clip polygons
153
+ // Polygon is in XZ coordinates (horizontal plane), Y is vertical (plane height)
154
+ const worldPolygons = allPolylines
155
+ .filter((pl) => Array.isArray(pl.points) && pl.points.length >= 3)
156
+ .map((pl) => pl.points.map((p) => ({ x: p.x, z: p.z })));
157
+ if (worldPolygons.length) {
158
+ viewportClipPolygonsWorld[vp.id] = worldPolygons;
159
+ clipAllowedGids = new Set();
160
+ for (const item of sourceItems) {
161
+ // Use item's direct x/z properties (same approach as labels)
162
+ const ix = getProp(item, 'x');
163
+ const iz = getProp(item, 'z');
164
+ if (!Number.isFinite(ix) || !Number.isFinite(iz)) {
165
+ continue;
166
+ }
167
+ // Convert polygon {x,z} to {x,y} for pointInPolygon (same as labels do)
168
+ const inside = worldPolygons.some((poly) => {
169
+ const polyWith2D = poly.map((p) => ({ x: p.x, y: p.z }));
170
+ return pointInPolygon(polyWith2D, ix, iz);
171
+ });
172
+ if (inside) {
173
+ const gid = getProp(item, 'gid') ?? getProp(item, 'id');
174
+ if (gid !== null && gid !== undefined) {
175
+ clipAllowedGids.add(String(gid));
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ // Effective allowed set: if highlight defined, use highlight set; else clipAllowed; if both exist, intersect.
185
+ // IMPORTANT: Store empty Set (not null) when clip filtering is active but finds no matches
186
+ let effectiveAllowed = null;
187
+ if (highlightGids && highlightGids.size > 0 && clipAllowedGids) {
188
+ // Both highlight and clip active - intersect them (even if clipAllowedGids is empty)
189
+ const intersection = new Set();
190
+ highlightGids.forEach((gid) => {
191
+ if (clipAllowedGids.has(gid))
192
+ intersection.add(gid);
193
+ });
194
+ effectiveAllowed = intersection;
195
+ }
196
+ else if (highlightGids && highlightGids.size > 0) {
197
+ effectiveAllowed = highlightGids;
198
+ }
199
+ else if (clipAllowedGids !== null) {
200
+ // Clip filtering is active - use clipAllowedGids even if empty (means zero items allowed)
201
+ effectiveAllowed = clipAllowedGids;
202
+ }
203
+ const hlStyles = hlCfg
204
+ ? {
205
+ stroke: typeof hlCfg.stroke === 'string' ? hlCfg.stroke : '#ff0000',
206
+ strokeWidthMm: typeof hlCfg.strokeWidthMm === 'number' ? hlCfg.strokeWidthMm : 0.5,
207
+ strokeOpacity: typeof hlCfg.strokeOpacity === 'number' ? hlCfg.strokeOpacity : 1,
208
+ fill: typeof hlCfg.fill === 'string' ? hlCfg.fill : '#ffff00',
209
+ fillOpacity: typeof hlCfg.fillOpacity === 'number' ? hlCfg.fillOpacity : 0.5
210
+ }
211
+ : {
212
+ stroke: undefined,
213
+ strokeWidthMm: undefined,
214
+ strokeOpacity: undefined,
215
+ fill: undefined,
216
+ fillOpacity: undefined
217
+ };
218
+ // Build the set of classes subject to GID-based filtering from highlight/clip configs
219
+ const filterClasses = new Set();
220
+ const addFilterClasses = (cls) => {
221
+ if (!cls)
222
+ return;
223
+ const classes = Array.isArray(cls) ? cls : [cls];
224
+ for (const c of classes) {
225
+ const normalized = normalizeClass(c);
226
+ if (normalized)
227
+ filterClasses.add(normalized);
228
+ }
229
+ };
230
+ addFilterClasses(hlCfg?.class);
231
+ addFilterClasses(clipCfg?.class);
232
+ const model = baseModel
233
+ ? filterModelForViewport(baseModel, vp, options?.metadataById, presets.includeClasses, effectiveAllowed, {
234
+ gids: highlightGids,
235
+ styles: hlStyles
236
+ }, filterClasses.size > 0 ? filterClasses : null)
237
+ : null;
238
+ viewportHighlight[vp.id] = {
239
+ gids: effectiveAllowed, // Use effectiveAllowed (includes both clip and highlight GIDs)
240
+ styles: hlStyles
241
+ };
242
+ if (!model) {
243
+ pushWarning(options.warnings, `Missing model for viewport '${vp.id}'.`);
244
+ return;
245
+ }
246
+ filteredModelsByViewport[vp.id] = model;
247
+ const effectiveWidthModel = clipEffectiveWidthModel ?? model.widthModel;
248
+ const effectiveHeightModel = clipEffectiveHeightModel ?? model.heightModel;
249
+ const scale = pickScale(vp, { ...model, widthModel: effectiveWidthModel, heightModel: effectiveHeightModel }, preferredScales, scales);
250
+ viewportScales[vp.id] = scale;
251
+ viewportClipBounds[vp.id] = viewportClipBounds[vp.id] ?? {
252
+ minX: model.transform?.viewMinX ?? 0,
253
+ maxX: model.transform ? model.transform.viewMinX + effectiveWidthModel : effectiveWidthModel,
254
+ minY: model.transform?.viewMinZ ?? 0,
255
+ maxY: model.transform ? model.transform.viewMinZ + effectiveHeightModel : effectiveHeightModel,
256
+ width: effectiveWidthModel,
257
+ height: effectiveHeightModel
258
+ };
259
+ if (!viewportClipPolygonsLocal[vp.id]) {
260
+ viewportClipPolygonsLocal[vp.id] = [];
261
+ }
262
+ });
263
+ return {
264
+ viewportScales,
265
+ viewportClipPolygonsLocal,
266
+ viewportClipPolygonsWorld,
267
+ viewportClipBounds,
268
+ viewportClipLabels,
269
+ viewportClipStyles,
270
+ viewportClipWhere,
271
+ viewportHighlight,
272
+ filteredModelsByViewport
273
+ };
274
+ };
275
+ //# sourceMappingURL=viewportPrep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewportPrep.js","sourceRoot":"/","sources":["layout/viewportPrep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAW,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAgC5D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC5B,SAA4B,EAC5B,MAAgD,EAChD,IAAa,EACb,eAAyB,EACzB,OAAwB,EACxB,OAAuD,EACrC,EAAE;IACpB,MAAM,cAAc,GAA0C,EAAE,CAAC;IACjE,MAAM,yBAAyB,GAA2D,EAAE,CAAC;IAC7F,MAAM,yBAAyB,GAA2D,EAAE,CAAC;IAC7F,MAAM,kBAAkB,GAGpB,EAAE,CAAC;IACP,MAAM,kBAAkB,GAA4B,EAAE,CAAC;IACvD,MAAM,kBAAkB,GAGpB,EAAE,CAAC;IACP,MAAM,iBAAiB,GAA+C,EAAE,CAAC;IACzE,MAAM,iBAAiB,GAA4C,EAAE,CAAC;IACtE,MAAM,wBAAwB,GAAiC,EAAE,CAAC;IAClE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QACrB,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,eAAe,GAAuB,IAAI,CAAC;QAE/C,6DAA6D;QAC7D,IAAI,aAAa,GAAuB,IAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC;QAC3B,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;gBACnD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC3F,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAClB,aAAa,GAAG,IAAI,GAAG,CACnB,QAAQ;yBACH,GAAG,CAAC,CAAC,EAAW,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC;yBACrE,MAAM,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC;yBACrD,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CACtC,CAAC;oBAEF,kDAAkD;oBAClD,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;wBAC3B,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,KAAK,CAAC,kBAAkB,QAAQ,CAAC,CAAC;wBACnF,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;4BAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,CACnB,QAAQ;iCACH,GAAG,CAAC,CAAC,EAAW,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC;iCACrE,MAAM,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC;iCACrD,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CACtC,CAAC;4BACF,gDAAgD;4BAChD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;4BACvC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gCAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;oCAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;4BAChD,CAAC,CAAC,CAAC;4BACH,aAAa,GAAG,YAAY,CAAC;wBACjC,CAAC;6BAAM,CAAC;4BACJ,WAAW,CACP,OAAO,CAAC,QAAQ,EAChB,aAAa,EAAE,CAAC,EAAE,mCAAmC,KAAK,CAAC,kBAAkB,sCAAsC,CACtH,CAAC;4BACF,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,kDAAkD;wBACjF,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,sBAAsB;oBACjD,WAAW,CACP,OAAO,CAAC,QAAQ,EAChB,aAAa,EAAE,CAAC,EAAE,mCAAmC,WAAW,CAAC,MAAM,SAAS,CACnF,CAAC;gBACN,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC3D,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,EAAE,4CAA4C,CAAC,CAAC;YAClG,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,IAAI,uBAA2C,CAAC;QAChD,IAAI,wBAA4C,CAAC;QACjD,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC;QACxB,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI,SAAS,EAAE,SAAS,EAAE,CAAC;YACnD,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;YACzC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;gBACnD,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;gBACpG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;oBACxB,WAAW,CACP,OAAO,CAAC,QAAQ,EAChB,aAAa,EAAE,CAAC,EAAE,8BAA8B,WAAW,CAAC,MAAM,SAAS,CAC9E,CAAC;gBACN,CAAC;gBAED,uCAAuC;gBACvC,MAAM,YAAY,GAAwD,EAAE,CAAC;gBAC7E,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;oBAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC3B,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;4BACzB,IAAI,QAAQ,CAAC,EAAE,CAAC;gCAAE,YAAY,CAAC,IAAI,CAAC,EAAkD,CAAC,CAAC;wBAC5F,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtB,+DAA+D;oBAC/D,MAAM,cAAc,GAAc,EAAE,CAAC;oBACrC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;wBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;wBACxB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;4BAAE,SAAS;wBACpD,MAAM,MAAM,GAAY,EAAE,CAAC;wBAC3B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;4BACnB,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;4BACjB,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;4BACjB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gCAAE,SAAS;4BAC3D,MAAM,CAAC,IAAI,CAAC;gCACR,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC,SAAU,CAAC,QAAQ;gCACrC,CAAC,EAAE,SAAS,CAAC,SAAU,CAAC,QAAQ,GAAG,EAAE;6BACxC,CAAC,CAAC;wBACP,CAAC;wBACD,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;4BAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACxD,CAAC;oBACD,MAAM,SAAS,GACX,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ;wBACrC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;wBAClC,OAAO,CAAC,SAAS,GAAG,CAAC;wBACjB,CAAC,CAAC,OAAO,CAAC,SAAS;wBACnB,CAAC,CAAC,CAAC,CAAC;oBACZ,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;oBAE5F,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAClB,kFAAkF;wBAClF,uFAAuF;wBACvF,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,mCAAmC;wBAClE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;wBACjC,IAAI,IAAI,GAAG,QAAQ,EACf,IAAI,GAAG,CAAC,QAAQ,EAChB,IAAI,GAAG,QAAQ,EACf,IAAI,GAAG,CAAC,QAAQ,CAAC;wBACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BACnC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;4BAClB,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;gCAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;4BAC3B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;gCAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;4BAC3B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;gCAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;4BAC3B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;gCAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;wBAC/B,CAAC;wBACD,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;wBACvE,wBAAwB,GAAG,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;wBACxE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;wBAC5C,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;wBACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;4BACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;4BACnC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,GAAG;4BAC3C,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,CAAC;4BACzC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;4BAC5B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;yBACxC,CAAC;wBACF,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;4BACxB,IAAI;4BACJ,IAAI;4BACJ,IAAI;4BACJ,IAAI;4BACJ,KAAK,EAAE,uBAAuB;4BAC9B,MAAM,EAAE,wBAAwB;yBACnC,CAAC;wBAEF,mFAAmF;wBACnF,gFAAgF;wBAChF,MAAM,aAAa,GAAG,YAAY;6BAC7B,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;6BACjE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC9D,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;4BACvB,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC;4BACjD,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;4BACpC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gCAC7B,6DAA6D;gCAC7D,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gCAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gCAE9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oCAC/C,SAAS;gCACb,CAAC;gCACD,wEAAwE;gCACxE,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oCACvC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oCACzD,OAAO,cAAc,CAAC,UAAU,EAAE,EAAY,EAAE,EAAY,CAAC,CAAC;gCAClE,CAAC,CAAC,CAAC;gCACH,IAAI,MAAM,EAAE,CAAC;oCACT,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oCACxD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;wCACpC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;oCACrC,CAAC;gCACL,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,8GAA8G;QAC9G,2FAA2F;QAC3F,IAAI,gBAAgB,GAAuB,IAAI,CAAC;QAChD,IAAI,aAAa,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,eAAe,EAAE,CAAC;YAC7D,qFAAqF;YACrF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;YACvC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1B,IAAI,eAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YACH,gBAAgB,GAAG,YAAY,CAAC;QACpC,CAAC;aAAM,IAAI,aAAa,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACjD,gBAAgB,GAAG,aAAa,CAAC;QACrC,CAAC;aAAM,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAClC,0FAA0F;YAC1F,gBAAgB,GAAG,eAAe,CAAC;QACvC,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK;YAClB,CAAC,CAAC;gBACI,MAAM,EAAE,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBACnE,aAAa,EAAE,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG;gBAClF,aAAa,EAAE,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAChF,IAAI,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBAC7D,WAAW,EAAE,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG;aAC/E;YACH,CAAC,CAAC;gBACI,MAAM,EAAE,SAAS;gBACjB,aAAa,EAAE,SAAS;gBACxB,aAAa,EAAE,SAAS;gBACxB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,SAAS;aACzB,CAAC;QAER,sFAAsF;QACtF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,MAAM,gBAAgB,GAAG,CAAC,GAAkC,EAAQ,EAAE;YAClE,IAAI,CAAC,GAAG;gBAAE,OAAO;YACjB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACtB,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBACrC,IAAI,UAAU;oBAAE,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClD,CAAC;QACL,CAAC,CAAC;QACF,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/B,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEjC,MAAM,KAAK,GAAG,SAAS;YACnB,CAAC,CAAC,sBAAsB,CAClB,SAAS,EACT,EAAE,EACF,OAAO,EAAE,YAAyC,EAClD,OAAO,CAAC,cAAc,EACtB,gBAAgB,EAChB;gBACI,IAAI,EAAE,aAAa;gBACnB,MAAM,EAAE,QAAQ;aACnB,EACD,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAChD;YACH,CAAC,CAAC,IAAI,CAAC;QACX,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;YACvB,IAAI,EAAE,gBAAgB,EAAE,+DAA+D;YACvF,MAAM,EAAE,QAAQ;SACnB,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,+BAA+B,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACxE,OAAO;QACX,CAAC;QACD,wBAAwB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;QACxC,MAAM,mBAAmB,GAAG,uBAAuB,IAAI,KAAK,CAAC,UAAU,CAAC;QACxE,MAAM,oBAAoB,GAAG,wBAAwB,IAAI,KAAK,CAAC,WAAW,CAAC;QAE3E,MAAM,KAAK,GAAG,SAAS,CACnB,EAAE,EACF,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,WAAW,EAAE,oBAAoB,EAAE,EAChF,eAAe,EACf,MAAM,CACT,CAAC;QACF,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;QAC9B,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;YACrD,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC;YACpC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,GAAG,mBAAmB,CAAC,CAAC,CAAC,mBAAmB;YAC5F,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC;YACpC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,GAAG,oBAAoB,CAAC,CAAC,CAAC,oBAAoB;YAC9F,KAAK,EAAE,mBAAmB;YAC1B,MAAM,EAAE,oBAAoB;SAC/B,CAAC;QACF,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACpC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QAC1C,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO;QACH,cAAc;QACd,yBAAyB;QACzB,yBAAyB;QACzB,kBAAkB;QAClB,kBAAkB;QAClB,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;QACjB,wBAAwB;KAC3B,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { filterModelForViewport } from './model';\r\nimport { ModelMetadata } from './metadata';\r\nimport { ViewportElement, SvgModelView, ComputedViewportScale } from './types';\r\nimport { pushWarning } from './warnings';\r\nimport { pickScale } from './viewportUtils';\r\nimport type { ResolvedPresets } from './presets';\r\nimport { getPathValue } from './renderUtils';\r\nimport { pointInPolygon, offsetPolygons, Polygon } from './clipUtils';\r\nimport { matchesV2Filter, normalizeClass } from './filters';\r\nimport { EPSILON_MIN_DIMENSION } from './geometryConstants';\r\n\r\nexport interface ViewportPrepResult {\r\n viewportScales: Record<string, ComputedViewportScale>;\r\n viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>>;\r\n viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>>;\r\n viewportClipBounds: Record<\r\n string,\r\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\r\n >;\r\n viewportClipLabels: Record<string, boolean>;\r\n viewportClipStyles: Record<\r\n string,\r\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\r\n >;\r\n viewportClipWhere: Record<string, WhereCondition | undefined>;\r\n viewportHighlight: Record<\r\n string,\r\n {\r\n gids: Set<string> | null;\r\n styles: {\r\n stroke?: string;\r\n strokeWidthMm?: number;\r\n strokeOpacity?: number;\r\n fill?: string;\r\n fillOpacity?: number;\r\n };\r\n }\r\n >;\r\n filteredModelsByViewport: Record<string, SvgModelView>;\r\n}\r\n\r\nimport { isRecord, getProp } from './typeGuards';\r\nimport type { WhereCondition } from './types';\r\n\r\nexport const prepareViewports = (\r\n viewports: ViewportElement[],\r\n models: Record<string, SvgModelView | undefined>,\r\n data: unknown,\r\n preferredScales: number[],\r\n presets: ResolvedPresets,\r\n options: { metadataById?: unknown; warnings: string[] }\r\n): ViewportPrepResult => {\r\n const viewportScales: Record<string, ComputedViewportScale> = {};\r\n const viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>> = {};\r\n const viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>> = {};\r\n const viewportClipBounds: Record<\r\n string,\r\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\r\n > = {};\r\n const viewportClipLabels: Record<string, boolean> = {};\r\n const viewportClipStyles: Record<\r\n string,\r\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\r\n > = {};\r\n const viewportClipWhere: Record<string, WhereCondition | undefined> = {};\r\n const viewportHighlight: ViewportPrepResult['viewportHighlight'] = {};\r\n const filteredModelsByViewport: Record<string, SvgModelView> = {};\r\n const scales = presets.scales;\r\n\r\n viewports.forEach((vp) => {\r\n const baseModel = models[vp.id];\r\n let clipAllowedGids: Set<string> | null = null;\r\n\r\n // Highlight: optional class+where filter on normalized items\r\n let highlightGids: Set<string> | null = null;\r\n const hlCfg = vp.highlight;\r\n if (hlCfg && hlCfg.where) {\r\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\r\n if (Array.isArray(sourceItems) && sourceItems.length) {\r\n const matching = sourceItems.filter((it) => matchesV2Filter(it, hlCfg.class, hlCfg.where));\r\n if (matching.length) {\r\n highlightGids = new Set(\r\n matching\r\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\r\n .filter((v: unknown) => v !== null && v !== undefined)\r\n .map((v: unknown) => String(v))\r\n );\r\n\r\n // Intersect with referenced viewport if specified\r\n if (hlCfg.intersectsViewport) {\r\n const refItems = getPathValue(data, `viewports.${hlCfg.intersectsViewport}.items`);\r\n if (Array.isArray(refItems) && refItems.length) {\r\n const refGids = new Set(\r\n refItems\r\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\r\n .filter((v: unknown) => v !== null && v !== undefined)\r\n .map((v: unknown) => String(v))\r\n );\r\n // Keep only items that appear in both viewports\r\n const intersection = new Set<string>();\r\n highlightGids.forEach((gid) => {\r\n if (refGids.has(gid)) intersection.add(gid);\r\n });\r\n highlightGids = intersection;\r\n } else {\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' highlight intersectsViewport=\"${hlCfg.intersectsViewport}\": referenced viewport has no items.`\r\n );\r\n highlightGids = new Set(); // No items in referenced viewport = no highlights\r\n }\r\n }\r\n } else {\r\n highlightGids = new Set(); // explicit no matches\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' highlight filter matched 0 of ${sourceItems.length} items.`\r\n );\r\n }\r\n } else if (Array.isArray(sourceItems) && !sourceItems.length) {\r\n pushWarning(options.warnings, `Viewport '${vp.id}' highlight: no items available to filter.`);\r\n }\r\n }\r\n\r\n // Clip: class+where filter — find matching items, extract their polylines as clip polygons\r\n let clipEffectiveWidthModel: number | undefined;\r\n let clipEffectiveHeightModel: number | undefined;\r\n const clipCfg = vp.clip;\r\n if (clipCfg && clipCfg.where && baseModel?.transform) {\r\n viewportClipWhere[vp.id] = clipCfg.where;\r\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\r\n if (Array.isArray(sourceItems) && sourceItems.length) {\r\n const matchingItems = sourceItems.filter((it) => matchesV2Filter(it, clipCfg.class, clipCfg.where));\r\n if (!matchingItems.length) {\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' clip filter matched 0 of ${sourceItems.length} items.`\r\n );\r\n }\r\n\r\n // Extract polylines from matched items\r\n const allPolylines: Array<{ points?: Array<{ x: number; z: number }> }> = [];\r\n for (const item of matchingItems) {\r\n const polylines = getProp(item, 'polylines');\r\n if (Array.isArray(polylines)) {\r\n for (const pl of polylines) {\r\n if (isRecord(pl)) allPolylines.push(pl as { points?: Array<{ x: number; z: number }> });\r\n }\r\n }\r\n }\r\n\r\n if (allPolylines.length) {\r\n // Project polyline points from world (x/z) to model view space\r\n const projectedLocal: Polygon[] = [];\r\n for (const poly of allPolylines) {\r\n const pts = poly.points;\r\n if (!Array.isArray(pts) || pts.length < 3) continue;\r\n const mapped: Polygon = [];\r\n for (const pt of pts) {\r\n const px = pt?.x;\r\n const pz = pt?.z;\r\n if (!Number.isFinite(px) || !Number.isFinite(pz)) continue;\r\n mapped.push({\r\n x: px - baseModel.transform!.viewMinX,\r\n y: baseModel.transform!.viewMaxZ - pz\r\n });\r\n }\r\n if (mapped.length >= 3) projectedLocal.push(mapped);\r\n }\r\n const expandByM =\r\n typeof clipCfg.expandByM === 'number' &&\r\n Number.isFinite(clipCfg.expandByM) &&\r\n clipCfg.expandByM > 0\r\n ? clipCfg.expandByM\r\n : 0;\r\n const buffered = expandByM > 0 ? offsetPolygons(projectedLocal, expandByM) : projectedLocal;\r\n\r\n if (buffered.length) {\r\n // Calculate bounds from EXPANDED polygon for viewport sizing (so everything fits)\r\n // Fill filtering (clipAllowedGids) uses ORIGINAL polygon from worldPolygons (line 239)\r\n const boundsSource = buffered; // Use EXPANDED for viewport sizing\r\n const flat = boundsSource.flat();\r\n let minX = Infinity,\r\n maxX = -Infinity,\r\n minY = Infinity,\r\n maxY = -Infinity;\r\n for (let i = 0; i < flat.length; i++) {\r\n const p = flat[i];\r\n if (p.x < minX) minX = p.x;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n clipEffectiveWidthModel = Math.max(EPSILON_MIN_DIMENSION, maxX - minX);\r\n clipEffectiveHeightModel = Math.max(EPSILON_MIN_DIMENSION, maxY - minY);\r\n viewportClipPolygonsLocal[vp.id] = buffered;\r\n viewportClipLabels[vp.id] = !!clipCfg.clipLabels;\r\n viewportClipStyles[vp.id] = {\r\n stroke: clipCfg.stroke ?? '#000000',\r\n strokeWidthMm: clipCfg.strokeWidthMm ?? 0.5,\r\n strokeOpacity: clipCfg.strokeOpacity ?? 1,\r\n fill: clipCfg.fill ?? 'none',\r\n fillOpacity: clipCfg.fillOpacity ?? 0\r\n };\r\n viewportClipBounds[vp.id] = {\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n width: clipEffectiveWidthModel,\r\n height: clipEffectiveHeightModel\r\n };\r\n\r\n // Build clipAllowedGids: include items whose center falls inside the clip polygons\r\n // Polygon is in XZ coordinates (horizontal plane), Y is vertical (plane height)\r\n const worldPolygons = allPolylines\r\n .filter((pl) => Array.isArray(pl.points) && pl.points.length >= 3)\r\n .map((pl) => pl.points!.map((p) => ({ x: p.x, z: p.z })));\r\n if (worldPolygons.length) {\r\n viewportClipPolygonsWorld[vp.id] = worldPolygons;\r\n clipAllowedGids = new Set<string>();\r\n for (const item of sourceItems) {\r\n // Use item's direct x/z properties (same approach as labels)\r\n const ix = getProp(item, 'x');\r\n const iz = getProp(item, 'z');\r\n\r\n if (!Number.isFinite(ix) || !Number.isFinite(iz)) {\r\n continue;\r\n }\r\n // Convert polygon {x,z} to {x,y} for pointInPolygon (same as labels do)\r\n const inside = worldPolygons.some((poly) => {\r\n const polyWith2D = poly.map((p) => ({ x: p.x, y: p.z }));\r\n return pointInPolygon(polyWith2D, ix as number, iz as number);\r\n });\r\n if (inside) {\r\n const gid = getProp(item, 'gid') ?? getProp(item, 'id');\r\n if (gid !== null && gid !== undefined) {\r\n clipAllowedGids.add(String(gid));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Effective allowed set: if highlight defined, use highlight set; else clipAllowed; if both exist, intersect.\r\n // IMPORTANT: Store empty Set (not null) when clip filtering is active but finds no matches\r\n let effectiveAllowed: Set<string> | null = null;\r\n if (highlightGids && highlightGids.size > 0 && clipAllowedGids) {\r\n // Both highlight and clip active - intersect them (even if clipAllowedGids is empty)\r\n const intersection = new Set<string>();\r\n highlightGids.forEach((gid) => {\r\n if (clipAllowedGids!.has(gid)) intersection.add(gid);\r\n });\r\n effectiveAllowed = intersection;\r\n } else if (highlightGids && highlightGids.size > 0) {\r\n effectiveAllowed = highlightGids;\r\n } else if (clipAllowedGids !== null) {\r\n // Clip filtering is active - use clipAllowedGids even if empty (means zero items allowed)\r\n effectiveAllowed = clipAllowedGids;\r\n }\r\n\r\n const hlStyles = hlCfg\r\n ? {\r\n stroke: typeof hlCfg.stroke === 'string' ? hlCfg.stroke : '#ff0000',\r\n strokeWidthMm: typeof hlCfg.strokeWidthMm === 'number' ? hlCfg.strokeWidthMm : 0.5,\r\n strokeOpacity: typeof hlCfg.strokeOpacity === 'number' ? hlCfg.strokeOpacity : 1,\r\n fill: typeof hlCfg.fill === 'string' ? hlCfg.fill : '#ffff00',\r\n fillOpacity: typeof hlCfg.fillOpacity === 'number' ? hlCfg.fillOpacity : 0.5\r\n }\r\n : {\r\n stroke: undefined,\r\n strokeWidthMm: undefined,\r\n strokeOpacity: undefined,\r\n fill: undefined,\r\n fillOpacity: undefined\r\n };\r\n\r\n // Build the set of classes subject to GID-based filtering from highlight/clip configs\r\n const filterClasses = new Set<string>();\r\n const addFilterClasses = (cls: string | string[] | undefined): void => {\r\n if (!cls) return;\r\n const classes = Array.isArray(cls) ? cls : [cls];\r\n for (const c of classes) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) filterClasses.add(normalized);\r\n }\r\n };\r\n addFilterClasses(hlCfg?.class);\r\n addFilterClasses(clipCfg?.class);\r\n\r\n const model = baseModel\r\n ? filterModelForViewport(\r\n baseModel,\r\n vp,\r\n options?.metadataById as ModelMetadata | undefined,\r\n presets.includeClasses,\r\n effectiveAllowed,\r\n {\r\n gids: highlightGids,\r\n styles: hlStyles\r\n },\r\n filterClasses.size > 0 ? filterClasses : null\r\n )\r\n : null;\r\n viewportHighlight[vp.id] = {\r\n gids: effectiveAllowed, // Use effectiveAllowed (includes both clip and highlight GIDs)\r\n styles: hlStyles\r\n };\r\n if (!model) {\r\n pushWarning(options.warnings, `Missing model for viewport '${vp.id}'.`);\r\n return;\r\n }\r\n filteredModelsByViewport[vp.id] = model;\r\n const effectiveWidthModel = clipEffectiveWidthModel ?? model.widthModel;\r\n const effectiveHeightModel = clipEffectiveHeightModel ?? model.heightModel;\r\n\r\n const scale = pickScale(\r\n vp,\r\n { ...model, widthModel: effectiveWidthModel, heightModel: effectiveHeightModel },\r\n preferredScales,\r\n scales\r\n );\r\n viewportScales[vp.id] = scale;\r\n viewportClipBounds[vp.id] = viewportClipBounds[vp.id] ?? {\r\n minX: model.transform?.viewMinX ?? 0,\r\n maxX: model.transform ? model.transform.viewMinX + effectiveWidthModel : effectiveWidthModel,\r\n minY: model.transform?.viewMinZ ?? 0,\r\n maxY: model.transform ? model.transform.viewMinZ + effectiveHeightModel : effectiveHeightModel,\r\n width: effectiveWidthModel,\r\n height: effectiveHeightModel\r\n };\r\n if (!viewportClipPolygonsLocal[vp.id]) {\r\n viewportClipPolygonsLocal[vp.id] = [];\r\n }\r\n });\r\n\r\n return {\r\n viewportScales,\r\n viewportClipPolygonsLocal,\r\n viewportClipPolygonsWorld,\r\n viewportClipBounds,\r\n viewportClipLabels,\r\n viewportClipStyles,\r\n viewportClipWhere,\r\n viewportHighlight,\r\n filteredModelsByViewport\r\n };\r\n};\r\n"]}
@@ -0,0 +1,42 @@
1
+ import { ViewportRenderInfo } from './labelsRender';
2
+ import { ComputedViewportScale, SvgModelView, ViewportElement, AssetSpec } from './types';
3
+ type PolyPoint = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ export declare const renderViewportElement: (vp: ViewportElement, baseModel: SvgModelView | null, dataWithViewport: any, preferredScales: number[], scales: Record<string, {
8
+ preferredScales?: number[];
9
+ }>, assetMap: Map<string, AssetSpec>, viewportScales: Record<string, ComputedViewportScale>, viewportClipPolygonsLocal: Record<string, Array<Array<PolyPoint>>>, viewportClipBounds: Record<string, {
10
+ minX: number;
11
+ maxX: number;
12
+ minY: number;
13
+ maxY: number;
14
+ width: number;
15
+ height: number;
16
+ }>, viewportClipLabels: Record<string, boolean>, viewportClipStyles: Record<string, {
17
+ stroke?: string;
18
+ strokeWidthMm?: number;
19
+ strokeOpacity?: number;
20
+ fill?: string;
21
+ fillOpacity?: number;
22
+ }>, viewportHighlight: Record<string, {
23
+ gids: Set<string> | null;
24
+ styles: any;
25
+ }>, viewportRenderInfo: Record<string, ViewportRenderInfo>, warnings: string[], legendColorMaps?: Map<string, Map<string, string>>, precomputed?: {
26
+ effectiveWidthModel?: number;
27
+ effectiveHeightModel?: number;
28
+ clipPolygonsMm?: Array<Array<PolyPoint>>;
29
+ clipPolygonsLocal?: Array<Array<PolyPoint>>;
30
+ clipBounds?: {
31
+ minX: number;
32
+ maxX: number;
33
+ minY: number;
34
+ maxY: number;
35
+ width: number;
36
+ height: number;
37
+ };
38
+ renderCenterModelX?: number;
39
+ renderCenterModelY?: number;
40
+ }) => string[];
41
+ export {};
42
+ //# sourceMappingURL=viewportRender.d.ts.map