@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":"index.js","sourceRoot":"/","sources":["layout/index.ts"],"names":[],"mappings":"AACA,OAAO,mBAAmB,MAAM,oCAAoC,CAAC;AACrE,OAAO,EACH,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,sBAAsB,IAAI,8BAA8B,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAsB,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EACrB,MAAM,gBAAgB,CAAC;AAwCxB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACrB,QAAwB,EACxB,IAAa,EACb,mBAA6B,EAC7B,YAAiC,EAClB,EAAE;IACjB,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;IACrE,MAAM,iBAAiB,GAAG,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAa,EAAE,CAAC;IAEpG,MAAM,EAAE,GAAG,kBAAkB,CAAC,EAAE,IAAI,cAAc,CAAC,EAAE,IAAI,iBAAiB,CAAC,EAAE,CAAC;IAC9E,IAAI,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAE5B,OAAO;QACH,EAAE,EAAE,KAAK;QACT,cAAc,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM;QAC7E,UAAU,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM;QACjE,aAAa,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM;KAC7E,CAAC;AACN,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAa,EAAE,mBAA6B,EAA8B,EAAE;IAC3G,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,+BAA+B,CAAC,EAAE,CAAC;IACpE,CAAC;IACD,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,0CAA0C,CAAC,CAAC;YACzE,OAAO;QACX,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,CAAC,EAAW,EAAE,GAAW,EAAE,EAAE;YACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,UAAU,GAAG,sBAAsB,CAAC,CAAC;gBAClE,OAAO;YACX,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,UAAU,GAAG,+CAA+C,CAAC,CAAC;gBAC3F,OAAO;YACX,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,UAAU,GAAG,kBAAkB,OAAO,qBAAqB,CAAC,CAAC;oBAC1F,OAAO;gBACX,CAAC;gBACD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,EAAE;oBAClD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;wBAC9C,MAAM,CAAC,IAAI,CACP,aAAa,IAAI,UAAU,GAAG,kBAAkB,OAAO,IAAI,QAAQ,0DAA0D,CAChI,CAAC;oBACN,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AAChE,CAAC,CAAC;AAyDF,MAAM,sBAAsB,GAAG,8BAA8B,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC;AAC9G,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,qGAAqG;AACrG,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,qGAAqG;AACrG,OAAO,EACH,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACd,MAAM,YAAY,CAAC;AACpB,iGAAiG;AACjG,OAAO,EAAE,sBAAsB,IAAI,8BAA8B,EAAE,MAAM,cAAc,CAAC;AACxF,6GAA6G;AAC7G,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAC7G,iGAAiG;AACjG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAElG,MAAM,MAAM,GAAG,4BAA4B,CAAC;AAE5C,2EAA2E;AAC3E,OAAO,EAAE,eAAe,EAAyC,MAAM,cAAc,CAAC;AAGtF,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACpG;;;GAGG;AACH,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,sBAAsB,EACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,wEAAwE;AACxE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG3D,uFAAuF;AACvF,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACzB,MAAM,qBAAqB,CAAC;AAY7B,8EAA8E;AAC9E,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAqC,CAAC;AAE7E,MAAM,SAAS,GAAG,CAAC,MAAgB,EAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE1F,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE;IAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,QAAwB,EACxB,IAAgB,EAChB,MAAoB,EACpB,OAA6B;IAE7B,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElD,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,EAAE;QAChD,iBAAiB,EAAE,OAAO,EAAE,iBAAiB;QAC7C,aAAa,EAAE,OAAO,EAAE,aAAa;QACrC,YAAY,EAAE,OAAO,EAAE,YAAY;KACtC,CAAC,CAAC;IACH,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACX,+BAA+B,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvH,CAAC;IACN,CAAC;IAED,MAAM,eAAe,GAAG,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,yFAAyF;IACzF,MAAM,WAAW,GAAoB,EAAE,CAAC;IACxC,MAAM,eAAe,GAAG,CAAC,QAAyB,EAAQ,EAAE;QACxD,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YACpB,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrB,IAAI,EAAE,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBACjC,eAAe,CAAE,EAAmB,CAAC,QAAQ,CAAC,CAAC;YACnD,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IACF,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,qBAAqB,CAAsB,CAAC;IAErG,MAAM,cAAc,GAAG,kBAAkB,CACrC,IAAI,EACJ,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC7B,CAAC;IACF,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,kCAAkC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,EACF,cAAc,EACd,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB;IAClB,qEAAqE;IACrE,iBAAiB,EACjB,wBAAwB,EAC3B,GAAG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE;QACpE,YAAY,EAAE,OAAO,EAAE,YAAY;QACnC,QAAQ;KACX,CAAC,CAAC;IAEH,MAAM,YAAY,GAQd,EAAE,CAAC;IAEP,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;QACnD,YAAY,CAAC,EAAE,CAAC,GAAG;YACf,UAAU,EAAE,KAAK,CAAC,KAAK;YACvB,SAAS,EAAE,KAAK,KAAK,CAAC,KAAK,EAAE;YAC7B,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,IAAI,EAAE,KAAK,CAAC,IAAI;SACnB,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAE7D,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IAExF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CACN,eAAe,MAAM,YAAY,IAAI,CAAC,OAAO,eAAe,IAAI,CAAC,QAAQ,oBAAoB,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,IAAI,CACjI,CAAC;IAEF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACN,4BAA4B,IAAI,CAAC,OAAO,aAAa,IAAI,CAAC,QAAQ,WAAW,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CACrH,CAAC;IACN,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC9C,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAE1E,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,eAAe,CAAgB,CAAC;IAC1F,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,mBAAmB,CAAoB,CAAC;IACrG,MAAM,kBAAkB,GAAuC,EAAE,CAAC;IAElE,+EAA+E;IAC/E,MAAM,eAAe,GAAG,IAAI,GAAG,EAA+B,CAAC,CAAC,2BAA2B;IAC3F,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,mBAAmB,CAAoB,CAAC;IACtG,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAC9B,IAAI,MAAM,CAAC,YAAY,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,MAAM,CAAC,QAAQ,QAAQ,CAAC,CAAC;YAC7E,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,MAAM,kBAAkB,GAAG,iBAAiB,CACxC,cAAc,EACd,MAAM,EACN,SAAS,EACT,yBAAyB,EACzB,kBAAkB,CACrB,CAAC;YACF,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,MAAM,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC7D,MAAM,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC1F,MAAM,MAAM,GAAG,gBAAgB,CAC3B,MAAM,EACN,QAAQ,CAAC,MAAM,EACf,IAAI,EACJ,IAAI,CAAC,QAAQ,EACb,kBAAkB,EAClB,WAAW,CACd,CAAC;gBACF,IAAI,MAAM,EAAE,QAAQ,EAAE,CAAC;oBACnB,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACtD,OAAO,CAAC,GAAG,CACP,uDAAuD,MAAM,CAAC,QAAQ,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,SAAS,CAC5G,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QAClB,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,EAAiB,CAAC;YAC5B,KAAK,CAAC,IAAI,CACN,YAAY,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,QAAQ,GAAG;gBACzE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;gBAC3D,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;gBACnB,KAAK,CACZ,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,EAAiB,CAAC;YAC5B,KAAK,CAAC,IAAI,CACN,aAAa,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,GAAG;gBAC/D,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;gBACnB,KAAK,CACZ,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,EAAmB,CAAC;YAC9B,KAAK,CAAC,IAAI,CACN,eAAe,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,GAAG,GAAG;gBAChD,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;gBAC3D,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;gBACnB,KAAK,CACZ,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAC3C,MAAM,EAAE,GAAG,EAAqB,CAAC;YACjC,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClG,KAAK,CAAC,IAAI,CACN,qBAAqB,SAAS,aAAa,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,aAAa,gBAAgB,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAC/I,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YAC1C,MAAM,EAAE,GAAG,EAAoB,CAAC;YAChC,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClG,KAAK,CAAC,IAAI,CACN,oBAAoB,SAAS,GAAG;gBAC5B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/D,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;gBAC7D,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC;gBACpB,KAAK,CACZ,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,EAAiB,CAAC;YAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;YAChC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,WAAW,CAAC,QAAQ,EAAE,uBAAuB,SAAS,IAAI,QAAQ,kBAAkB,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;gBAChG,OAAO;YACX,CAAC;YACD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YAC3F,KAAK,CAAC,IAAI,CACN,YAAY,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,kBAAkB,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB,KAAK,CAAC,UAAU,GAAG;gBAC/G,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1E,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzF,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,iBAAiB,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC,SAAS,CAC5D,CAAC;QACN,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,EAAkB,CAAC;YAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,CAAC,OAAO,gBAAgB,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;gBAC/E,OAAO;YACX,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACZ,KAAK,CAAC,IAAI,CACN,gBAAgB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,OAAO,aAAa,GAAG,CAAC,QAAQ,GAAG;oBAClH,CAAC,GAAG,CAAC,GAAG,KAAK,OAAO;wBAChB,CAAC,CAAC,uCAAuC;wBACzC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS;4BACrB,CAAC,CAAC,6BAA6B;4BAC/B,CAAC,CAAC,sCAAsC,CAAC;oBAC/C,KAAK,CACZ,CAAC;YACN,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CACN,2BAA2B,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,MAAM,KAAK,CAAC,OAAO,MAAM,CAC/G,CAAC;YACN,CAAC;QACL,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC5C,MAAM,EAAE,GAAG,EAAqB,CAAC;YACjC,+DAA+D;YAC/D,MAAM,aAAa,GAAG,EAAE,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;YAC9D,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,WAAW,CAAC,QAAQ,EAAE,cAAc,EAAE,CAAC,EAAE,+BAA+B,CAAC,CAAC;gBAC1E,OAAO;YACX,CAAC;YACD,MAAM,SAAS,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,WAAW,CAAC,QAAQ,EAAE,aAAa,aAAa,uCAAuC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;gBAClG,OAAO;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC;YAChC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;YACtC,MAAM,WAAW,GAAG,CAAC,GAAG,SAAS,CAAC,cAAc,CAAC;YACjD,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;YACpD,MAAM,UAAU,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAClD,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC;YACrC,MAAM,aAAa,GAAG,EAAE,CAAC,aAAa,IAAI,GAAG,CAAC;YAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;gBACjC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,SAAS,GAAG,CAAC,CAAC;gBACjC,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,KAAK,CAAC,CAAC;gBACtC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CACT,aAAa,CAAC,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,GAAG,MAAM,aAAa,UAAU,CAClF,QAAQ,CACX,mBAAmB,aAAa,MAAM,CAC1C,CAAC;gBACF,IAAI,OAAO,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;oBAC9C,IAAI,KAAK,EAAE,CAAC;wBACR,MAAM,UAAU,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;wBACxE,QAAQ,CAAC,IAAI,CACT,YAAY,CAAC,QAAQ,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,kBAAkB,UAAU,CAC1E,KAAK,CAAC,UAAU,CACnB,gBAAgB,KAAK,CAAC,UAAU,0BAA0B,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,SAAS,CAC1G,CAAC;oBACN,CAAC;gBACL,CAAC;YACL,CAAC;YAED,QAAQ,CAAC,IAAI,CACT,aAAa,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,GAAG,QAAQ,SAAS,EAAE,CAAC,GAAG,aAAa,UAAU,CAC9F,QAAQ,CACX,mBAAmB,aAAa,MAAM,CAC1C,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAC3C,MAAM,EAAE,GAAG,EAAqB,CAAC;YACjC,MAAM,KAAK,GAAG,wBAAwB,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;YACvE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,EAAE,kBAAkB,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,OAAO,GAAG,qBAAqB,CACjC,EAAE,EACF,KAAK,EACL,gBAAgB,EAChB,eAAe,EACf,OAAO,CAAC,MAAM,EACd,QAAQ,EACR,cAAc,EACd,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,CAClB,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,EAAmB,CAAC;YACnC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,MAAM,CAAC,QAAQ,QAAQ,CAAC,CAAC;YAC7E,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,MAAM,kBAAkB,GAAG,iBAAiB,CACxC,cAAc,EACd,MAAM,EACN,SAAS,EACT,yBAAyB,EACzB,kBAAkB,CACrB,CAAC;YACF,IAAI,CAAC,kBAAkB,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC;gBACpD,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;oBACzB,WAAW,CAAC,QAAQ,EAAE,WAAW,MAAM,CAAC,EAAE,iCAAiC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACpG,CAAC;qBAAM,CAAC;oBACJ,WAAW,CACP,QAAQ,EACR,WAAW,MAAM,CAAC,EAAE,yBAAyB,cAAc,CAAC,MAAM,iBAAiB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC7J,CAAC;gBACN,CAAC;YACL,CAAC;YACD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7D,iFAAiF;YACjF,MAAM,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1F,MAAM,YAAY,GAAG,gBAAgB,CACjC,MAAM,EACN,QAAQ,CAAC,MAAM,EACf,IAAI,EACJ,IAAI,CAAC,QAAQ,EACb,kBAAkB,IAAI,EAAE,EACxB,WAAW,CACd,CAAC;YACF,IAAI,YAAY,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;QACL,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,YAAY,CAC3B,aAAa,EACb,IAAI,EACJ,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,EACzB,QAAQ,CAAC,MAAM,IAAI,EAAE,EACrB,gBAAgB,EAChB,QAAQ,CACX,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAClC,UAAU,EACV,SAAS,EACT,cAAc,EACd,MAAM,EACN,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,EACjC,gBAAgB,EAChB,QAAQ,CACX,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAErB,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;AAC7D,CAAC;AAED,6EAA6E;AAC7E,oFAAoF;AACpF,OAAO,EAAE,sBAAsB,IAAI,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACxE,WAAW,CAAC,YAAmB,CAAC,CAAC","sourcesContent":["import type { SectionRenderState } from '@twinfinity/geometry';\r\nimport defaultTemplateJson from '../templates/default-template.json';\r\nimport {\r\n pointInPolygon,\r\n filterItemsInPolygons,\r\n filterEntriesByClip,\r\n offsetPolygons,\r\n projectPolygonsToLocal\r\n} from './clipUtils';\r\nimport { uniquePositiveDenoms } from './utils';\r\nimport { validateLayoutTemplate as validateLayoutTemplateExternal } from './validation';\r\nimport { renderViewportElement } from './viewportRender';\r\nimport { prepareViewports } from './viewportPrep';\r\nimport { renderLabels, ViewportRenderInfo } from './labelsRender';\r\nimport { renderQrElements } from './qrRender';\r\nimport { applyLegendFilter, buildLegendGroup } from './legendRender';\r\nimport { RenderLayoutOptions } from './options';\r\nimport { resolvePresets } from './presets';\r\nimport { pushWarning } from './warnings';\r\nimport { escapeAttr, escapeText, interpolate, getPathValue } from './renderUtils';\r\nimport { validateSectionState } from './sectionValidation';\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_CIRCLE,\r\n ELEMENT_KIND_POLYLINE,\r\n ELEMENT_KIND_POLYGON,\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\nimport {\r\n AssetSpec,\r\n LayoutElement,\r\n ViewportElement,\r\n TextElement,\r\n ImageElement,\r\n LineElement,\r\n RectElement,\r\n CircleElement,\r\n PolylineElement,\r\n PolygonElement,\r\n ScaleBarElement,\r\n QrElement,\r\n LabelsElement,\r\n LegendElement,\r\n GroupElement,\r\n LayoutTemplate,\r\n ModelContext,\r\n LayoutData,\r\n ValidationIssue,\r\n ComputedViewportScale\r\n} from './types';\r\n\r\nexport type LayoutDataValidationResult =\r\n | { ok: true }\r\n | {\r\n ok: false;\r\n errors: string[];\r\n };\r\n\r\nexport type PreflightResult =\r\n | { ok: true }\r\n | {\r\n ok: false;\r\n templateErrors?: ValidationIssue[];\r\n dataErrors?: string[];\r\n sectionErrors?: string[];\r\n };\r\n\r\nimport { isRecord, getProp } from './typeGuards';\r\n\r\n/**\r\n * Validate template, layout data, and section state in a single call.\r\n * Combines `validateLayoutTemplate`, `validateLayoutData`, and `validateSectionState`.\r\n */\r\nexport const preflight = (\r\n template: LayoutTemplate,\r\n data: unknown,\r\n expectedViewportIds: string[],\r\n sectionState?: SectionRenderState\r\n): PreflightResult => {\r\n const templateValidation = validateLayoutTemplate(template);\r\n const dataValidation = validateLayoutData(data, expectedViewportIds);\r\n const sectionValidation = sectionState ? validateSectionState(sectionState) : { ok: true as const };\r\n\r\n const ok = templateValidation.ok && dataValidation.ok && sectionValidation.ok;\r\n if (ok) return { ok: true };\r\n\r\n return {\r\n ok: false,\r\n templateErrors: templateValidation.ok ? undefined : templateValidation.errors,\r\n dataErrors: dataValidation.ok ? undefined : dataValidation.errors,\r\n sectionErrors: sectionValidation.ok ? undefined : sectionValidation.errors\r\n };\r\n};\r\n\r\n/**\r\n * Validate layout data before rendering to catch missing propertySets or items arrays.\r\n */\r\nexport const validateLayoutData = (data: unknown, expectedViewportIds: string[]): LayoutDataValidationResult => {\r\n const errors: string[] = [];\r\n if (!isRecord(data)) {\r\n return { ok: false, errors: ['layout data must be an object'] };\r\n }\r\n expectedViewportIds.forEach((vpId) => {\r\n const viewports = getProp(data, 'viewports');\r\n const viewport = isRecord(viewports) ? getProp(viewports, vpId) : undefined;\r\n const items = getProp(viewport, 'items');\r\n if (!Array.isArray(items)) {\r\n errors.push(`viewports.${vpId}.items is required and must be an array.`);\r\n return;\r\n }\r\n items.forEach((it: unknown, idx: number) => {\r\n if (!isRecord(it)) {\r\n errors.push(`viewports.${vpId}.items[${idx}] must be an object.`);\r\n return;\r\n }\r\n const sets = getProp(it, 'propertySets');\r\n if (!isRecord(sets)) {\r\n errors.push(`viewports.${vpId}.items[${idx}] is missing propertySets.<Set>.<Prop>.value.`);\r\n return;\r\n }\r\n Object.entries(sets).forEach(([setName, props]) => {\r\n if (!isRecord(props)) {\r\n errors.push(`viewports.${vpId}.items[${idx}].propertySets.${setName} must be an object.`);\r\n return;\r\n }\r\n Object.entries(props).forEach(([propName, payload]) => {\r\n if (!isRecord(payload) || !('value' in payload)) {\r\n errors.push(\r\n `viewports.${vpId}.items[${idx}].propertySets.${setName}.${propName} must include a value (propertySets.<Set>.<Prop>.value).`\r\n );\r\n }\r\n });\r\n });\r\n });\r\n });\r\n return errors.length ? { ok: false, errors } : { ok: true };\r\n};\r\n\r\nexport type {\r\n PageSpec,\r\n TextStyle,\r\n StyleMap,\r\n AssetSpec,\r\n LayoutElement,\r\n BaseElement,\r\n ViewportElement,\r\n TextElement,\r\n ImageElement,\r\n LineElement,\r\n RectElement,\r\n CircleElement,\r\n PolylineElement,\r\n PolygonElement,\r\n PointMm,\r\n ScaleBarElement,\r\n QrElement,\r\n LabelsElement,\r\n LegendElement,\r\n GroupElement,\r\n LayoutTemplate,\r\n LegendAnchor,\r\n LegendColumn,\r\n SvgModelView,\r\n ModelContext,\r\n LayoutData,\r\n LayoutDataViewports,\r\n ViewportItemsMap,\r\n PagePresetKey,\r\n PageOrientation,\r\n ValidationOptions,\r\n ValidationIssue,\r\n ValidationResult,\r\n ComputedViewportScale,\r\n NormalizedProductItem,\r\n SectionStateValidationResult,\r\n LabelStyle,\r\n WhereCondition,\r\n ClipConfig,\r\n HighlightConfig,\r\n ViewportLineStyle,\r\n ViewportLineStyles,\r\n SectionResult,\r\n FillRule,\r\n RenderDrawingInput,\r\n RenderDrawingResult,\r\n IncludeClassesFilter,\r\n ResolvedIncludeFilter,\r\n TemplateVariableDef,\r\n TemplateVariableInfo\r\n} from './types';\r\n\r\nexport type { RenderLayoutOptions } from './options';\r\n\r\nconst validateLayoutTemplate = validateLayoutTemplateExternal;\r\n\r\nexport { pointInPolygon, filterItemsInPolygons, filterEntriesByClip, offsetPolygons, projectPolygonsToLocal };\r\n/** Normalize IFC class names to lowercase for consistent matching. */\r\nexport { normalizeClass } from './filters';\r\n/** Test whether an item matches a class + where filter (used by clip, highlight, labels, legend). */\r\nexport { matchesV2Filter } from './filters';\r\n/** Metadata utilities: build lookup maps, resolve IFC class includes, and merge metadata sources. */\r\nexport {\r\n buildMetadataMap,\r\n normalizePropertySets,\r\n resolveIfcClassName,\r\n resolveIfcClassId,\r\n resolveIncludeClasses,\r\n resolveAllowedClasses,\r\n resolveMeta\r\n} from './metadata';\r\n/** Validate a layout template JSON structure. Returns `{ ok, errors }` or `{ ok, template }`. */\r\nexport { validateLayoutTemplate as validateLayoutTemplateExternal } from './validation';\r\n/** Layout utility functions: scale denominators, label sizing, color parsing, and line style application. */\r\nexport { uniquePositiveDenoms, computeLabelFontSize, colorFromString, applyLineStyleToPaths } from './utils';\r\n/** Property resolution: traverse nested objects with dot-path strings like `\"BIP.spacename\"`. */\r\nexport { getPathValue, resolveProperty, resolvePath, matchesPropertyFilter } from './renderUtils';\r\n\r\nconst SVG_NS = 'http://www.w3.org/2000/svg';\r\n\r\n/** Build legend table rows from product items with property formatting. */\r\nexport { buildLegendRows, type LegendRow, type LegendRowOptions } from './legendRows';\r\n/** Product normalization, viewport item builders, and section-state-to-SVG-model conversion. */\r\nexport type { ProductLike, BuildViewportItemsOptions } from './itemBuilders';\r\nexport { normalizeProductEntry, buildViewportItems, sectionStateToModelView } from './itemBuilders';\r\n/**\r\n * High-level facade: renders a complete drawing from a template + section geometry.\r\n * Internalizes all data wiring (items, colors, labels, metadata) that `renderLayout` requires manually.\r\n */\r\nexport {\r\n renderDrawing,\r\n resolveFillColor,\r\n BUILTIN_LINE_DEFAULTS,\r\n BUILTIN_HIDDEN_DEFAULTS,\r\n BUILTIN_LABEL_DEFAULTS,\r\n CATEGORY_BUILTIN_OVERRIDES,\r\n setRenderLayoutBinding\r\n} from './renderDrawing';\r\nexport type { ResolvedLineStyles } from './renderDrawing';\r\n\r\nexport { EXAMPLE_BUILDING_CLASSES } from './presets';\r\n\r\nexport { analyzeTemplate } from './analyzeTemplate';\r\nexport type { TemplateRequirements } from './analyzeTemplate';\r\n\r\n/** Drawing export utilities: convert SVG markup to PDF or SVG files. */\r\nexport { exportToPdf, exportToSvg } from './exportDrawing';\r\nexport type { ExportPdfOptions, ExportSvgOptions } from './exportDrawing';\r\n\r\n/** Template variable utilities: extract, validate, and resolve template parameters. */\r\nexport {\r\n getTemplateVariables,\r\n getTemplateDefaults,\r\n resolveTemplateValues,\r\n applyTemplateVariables\r\n} from './templateVariables';\r\n\r\n/** Result of {@link renderLayout}: the final SVG markup, per-viewport scale info, and any warnings. */\r\nexport interface RenderLayoutResult {\r\n /** Complete SVG markup string ready for embedding or PDF conversion. */\r\n svg: string;\r\n /** Per-viewport computed scale information (denominator, mm-per-model-unit, fit status). */\r\n viewportScales: Record<string, ComputedViewportScale>;\r\n /** Non-fatal issues encountered during rendering (missing assets, unresolved styles, etc.). */\r\n warnings: string[];\r\n}\r\n\r\n/** Built-in default layout template (A3 landscape with a single viewport). */\r\nexport const DEFAULT_LAYOUT_TEMPLATE = defaultTemplateJson as LayoutTemplate;\r\n\r\nconst dashArray = (dashed?: boolean): string => (dashed ? ' stroke-dasharray=\"4 2\"' : '');\r\n\r\nconst formatNumber = (value: number): number => {\r\n if (!Number.isFinite(value)) return 0;\r\n return Number.parseFloat(value.toFixed(3));\r\n};\r\n\r\n/**\r\n * Render a layout template to SVG.\r\n *\r\n * This is the low-level rendering function. For most use cases, prefer {@link renderDrawing}\r\n * which handles all data wiring automatically.\r\n *\r\n * @param template - Validated layout template (page, elements, styles, presets).\r\n * @param data - Layout data with viewport items, template variables, and legend rows.\r\n * @param models - Per-viewport SVG model views (geometry + transforms).\r\n * @param options - Optional rendering settings (remote assets, scale overrides, metadata).\r\n * @returns SVG markup string, computed viewport scales, and any warnings.\r\n */\r\nexport async function renderLayout(\r\n template: LayoutTemplate,\r\n data: LayoutData,\r\n models: ModelContext,\r\n options?: RenderLayoutOptions\r\n): Promise<RenderLayoutResult> {\r\n const presets = resolvePresets(template?.presets);\r\n\r\n const validation = validateLayoutTemplate(template, {\r\n allowRemoteAssets: options?.allowRemoteAssets,\r\n allowDataUrls: options?.allowDataUrls,\r\n maxViewports: options?.maxViewports\r\n });\r\n if (!validation.ok) {\r\n throw new Error(\r\n `Template validation failed: ${validation.errors.map((e: ValidationIssue) => `${e.path}: ${e.message}`).join('; ')}`\r\n );\r\n }\r\n\r\n const preferredScales = uniquePositiveDenoms(options?.scaleDenominators);\r\n const page = template.page;\r\n const warnings: string[] = [];\r\n\r\n // Flatten all elements to collect viewports, qrs, labels, legends regardless of grouping\r\n const allElements: LayoutElement[] = [];\r\n const collectElements = (elements: LayoutElement[]): void => {\r\n elements.forEach((el) => {\r\n allElements.push(el);\r\n if (el.kind === ELEMENT_KIND_GROUP) {\r\n collectElements((el as GroupElement).children);\r\n }\r\n });\r\n };\r\n collectElements(template.elements);\r\n\r\n const viewports = allElements.filter((el) => el.kind === ELEMENT_KIND_VIEWPORT) as ViewportElement[];\r\n\r\n const dataValidation = validateLayoutData(\r\n data,\r\n viewports.map((v) => v.id)\r\n );\r\n if (!dataValidation.ok) {\r\n throw new Error(`Layout data validation failed: ${dataValidation.errors.join('; ')}`);\r\n }\r\n\r\n const {\r\n viewportScales,\r\n viewportClipPolygonsLocal,\r\n viewportClipPolygonsWorld,\r\n viewportClipBounds,\r\n viewportClipLabels,\r\n viewportClipStyles,\r\n // viewportClipWhere intentionally omitted — not needed for rendering\r\n viewportHighlight,\r\n filteredModelsByViewport\r\n } = prepareViewports(viewports, models, data, preferredScales, presets, {\r\n metadataById: options?.metadataById,\r\n warnings\r\n });\r\n\r\n const viewportData: Record<\r\n string,\r\n {\r\n scaleDenom: number;\r\n scaleText: string;\r\n mmPerModelUnit: number;\r\n fits: boolean;\r\n }\r\n > = {};\r\n\r\n Object.entries(viewportScales).forEach(([id, scale]) => {\r\n viewportData[id] = {\r\n scaleDenom: scale.denom,\r\n scaleText: `1:${scale.denom}`,\r\n mmPerModelUnit: scale.mmPerModelUnit,\r\n fits: scale.fits\r\n };\r\n });\r\n\r\n const dataWithViewport = { ...data, viewport: viewportData };\r\n\r\n const sorted = [...template.elements].sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));\r\n\r\n const parts: string[] = [];\r\n parts.push(\r\n `<svg xmlns=\"${SVG_NS}\" width=\"${page.widthMm}mm\" height=\"${page.heightMm}mm\" viewBox=\"0 0 ${page.widthMm} ${page.heightMm}\">`\r\n );\r\n\r\n if (page.backgroundColor) {\r\n parts.push(\r\n `<rect x=\"0\" y=\"0\" width=\"${page.widthMm}\" height=\"${page.heightMm}\" fill=\"${escapeAttr(page.backgroundColor)}\"/>`\r\n );\r\n }\r\n\r\n const assetMap = new Map<string, AssetSpec>();\r\n (template.assets ?? []).forEach((asset) => assetMap.set(asset.id, asset));\r\n\r\n const qrElements = allElements.filter((el) => el.kind === ELEMENT_KIND_QR) as QrElement[];\r\n const labelElements = allElements.filter((el) => el.kind === ELEMENT_KIND_LABELS) as LabelsElement[];\r\n const viewportRenderInfo: Record<string, ViewportRenderInfo> = {};\r\n\r\n // Pre-process legends to collect color maps (needed before viewport rendering)\r\n const legendColorMaps = new Map<string, Map<string, string>>(); // viewport ID -> color map\r\n const legendElements = allElements.filter((el) => el.kind === ELEMENT_KIND_LEGEND) as LegendElement[];\r\n legendElements.forEach((legend) => {\r\n if (legend.assignColors?.enabled && legend.groupBy) {\r\n const legendItems = getPathValue(data, `viewports.${legend.viewport}.items`);\r\n const rawLegendItems = Array.isArray(legendItems) ? legendItems : [];\r\n const legendDataFiltered = applyLegendFilter(\r\n rawLegendItems,\r\n legend,\r\n viewports,\r\n viewportClipPolygonsLocal,\r\n viewportRenderInfo\r\n );\r\n if (legendDataFiltered && legendDataFiltered.length) {\r\n const vpEl = viewports.find((v) => v.id === legend.viewport);\r\n const fillOpacity = vpEl?.fills?.length ? (vpEl.fills[0].fillOpacity ?? 0.35) : undefined;\r\n const result = buildLegendGroup(\r\n legend,\r\n template.styles,\r\n page,\r\n page.marginMm,\r\n legendDataFiltered,\r\n fillOpacity\r\n );\r\n if (result?.colorMap) {\r\n legendColorMaps.set(legend.viewport, result.colorMap);\r\n console.log(\r\n `[LEGEND PRE-PROCESS] Stored color map for viewport \"${legend.viewport}\": ${result.colorMap.size} colors`\r\n );\r\n }\r\n }\r\n }\r\n });\r\n\r\n sorted.forEach((el) => {\r\n if (el.kind === ELEMENT_KIND_RECT) {\r\n const r = el as RectElement;\r\n parts.push(\r\n `<rect x=\"${r.xMm}\" y=\"${r.yMm}\" width=\"${r.widthMm}\" height=\"${r.heightMm}\"` +\r\n (r.stroke ? ` stroke=\"${escapeAttr(r.stroke)}\"` : '') +\r\n (r.strokeWidthMm ? ` stroke-width=\"${r.strokeWidthMm}\"` : '') +\r\n (r.fill ? ` fill=\"${escapeAttr(r.fill)}\"` : ' fill=\"none\"') +\r\n dashArray(r.dashed) +\r\n ` />`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_LINE) {\r\n const l = el as LineElement;\r\n parts.push(\r\n `<line x1=\"${l.x1Mm}\" y1=\"${l.y1Mm}\" x2=\"${l.x2Mm}\" y2=\"${l.y2Mm}\"` +\r\n (l.stroke ? ` stroke=\"${escapeAttr(l.stroke)}\"` : '') +\r\n (l.strokeWidthMm ? ` stroke-width=\"${l.strokeWidthMm}\"` : '') +\r\n dashArray(l.dashed) +\r\n ` />`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_CIRCLE) {\r\n const c = el as CircleElement;\r\n parts.push(\r\n `<circle cx=\"${c.cxMm}\" cy=\"${c.cyMm}\" r=\"${c.rMm}\"` +\r\n (c.stroke ? ` stroke=\"${escapeAttr(c.stroke)}\"` : '') +\r\n (c.strokeWidthMm ? ` stroke-width=\"${c.strokeWidthMm}\"` : '') +\r\n (c.fill ? ` fill=\"${escapeAttr(c.fill)}\"` : ' fill=\"none\"') +\r\n dashArray(c.dashed) +\r\n ` />`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_POLYLINE) {\r\n const pl = el as PolylineElement;\r\n const pointsStr = pl.points.map((p) => `${formatNumber(p.xMm)},${formatNumber(p.yMm)}`).join(' ');\r\n parts.push(\r\n `<polyline points=\"${pointsStr}\" stroke=\"${escapeAttr(pl.stroke)}\" stroke-width=\"${pl.strokeWidthMm}\" fill=\"none\"${dashArray(pl.dashed)} />`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_POLYGON) {\r\n const pg = el as PolygonElement;\r\n const pointsStr = pg.points.map((p) => `${formatNumber(p.xMm)},${formatNumber(p.yMm)}`).join(' ');\r\n parts.push(\r\n `<polygon points=\"${pointsStr}\"` +\r\n (pg.stroke ? ` stroke=\"${escapeAttr(pg.stroke)}\"` : '') +\r\n (pg.strokeWidthMm ? ` stroke-width=\"${pg.strokeWidthMm}\"` : '') +\r\n (pg.fill ? ` fill=\"${escapeAttr(pg.fill)}\"` : ' fill=\"none\"') +\r\n dashArray(pg.dashed) +\r\n ` />`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_TEXT) {\r\n const tEl = el as TextElement;\r\n const styleName = tEl.textStyle;\r\n const style = styleName ? template.styles?.[styleName] : undefined;\r\n if (!style) {\r\n pushWarning(warnings, `Missing text style '${styleName ?? '(none)'}' for element '${tEl.id}'.`);\r\n return;\r\n }\r\n const text = interpolate(tEl.text, dataWithViewport, warnings);\r\n const anchor = tEl.align === 'center' ? 'middle' : tEl.align === 'right' ? 'end' : 'start';\r\n parts.push(\r\n `<text x=\"${tEl.xMm}\" y=\"${tEl.yMm}\" font-family=\"${escapeAttr(style.fontFamily)}\" font-size=\"${style.fontSizeMm}\"` +\r\n (style.fontWeight ? ` font-weight=\"${escapeAttr(style.fontWeight)}\"` : '') +\r\n (style.color ? ` fill=\"${escapeAttr(style.color)}\"` : '') +\r\n (style.letterSpacingMm !== undefined ? ` letter-spacing=\"${style.letterSpacingMm}\"` : '') +\r\n (style.lineHeightMm !== undefined ? ` line-height=\"${style.lineHeightMm}\"` : '') +\r\n ` text-anchor=\"${anchor}\">${escapeText(text)}</text>`\r\n );\r\n } else if (el.kind === ELEMENT_KIND_IMAGE) {\r\n const img = el as ImageElement;\r\n const asset = assetMap.get(img.assetId);\r\n if (!asset) {\r\n pushWarning(warnings, `Missing asset '${img.assetId}' for image '${img.id}'.`);\r\n return;\r\n }\r\n if (asset.src) {\r\n parts.push(\r\n `<image href=\"${escapeAttr(asset.src)}\" x=\"${img.xMm}\" y=\"${img.yMm}\" width=\"${img.widthMm}\" height=\"${img.heightMm}\"` +\r\n (img.fit === 'cover'\r\n ? ' preserveAspectRatio=\"xMidYMid slice\"'\r\n : img.fit === 'stretch'\r\n ? ' preserveAspectRatio=\"none\"'\r\n : ' preserveAspectRatio=\"xMidYMid meet\"') +\r\n ` />`\r\n );\r\n } else if (asset.content) {\r\n parts.push(\r\n `<g transform=\"translate(${img.xMm} ${img.yMm}) scale(${img.widthMm} ${img.heightMm})\">${asset.content}</g>`\r\n );\r\n }\r\n } else if (el.kind === ELEMENT_KIND_SCALE_BAR) {\r\n const sb = el as ScaleBarElement;\r\n // Scale bar declares which viewport it binds to via `viewport`\r\n const boundViewport = sb.viewport ?? viewports[0]?.id ?? null;\r\n if (!boundViewport) {\r\n pushWarning(warnings, `Scale bar '${sb.id}' is not bound to a viewport.`);\r\n return;\r\n }\r\n const scaleInfo = viewportScales[boundViewport];\r\n if (!scaleInfo) {\r\n pushWarning(warnings, `Viewport '${boundViewport}' missing scale info for scale bar '${sb.id}'.`);\r\n return;\r\n }\r\n const lengthMm = sb.maxLengthMm;\r\n const segments = sb.segments ?? 10;\r\n const segmentMm = lengthMm / segments;\r\n const metersPerMm = 1 / scaleInfo.mmPerModelUnit;\r\n const segmentMeters = segmentMm * metersPerMm;\r\n const labelsEvery = Math.max(1, sb.labelEvery ?? 1);\r\n const unitSuffix = sb.unit ? ` ${sb.unit}` : ' m';\r\n const barParts: string[] = [];\r\n const sbStroke = sb.stroke ?? '#000';\r\n const sbStrokeWidth = sb.strokeWidthMm ?? 0.5;\r\n\r\n for (let i = 0; i <= segments; i++) {\r\n const x = sb.xMm + segmentMm * i;\r\n const isLabel = i % labelsEvery === 0;\r\n const height = isLabel ? 4 : 3;\r\n barParts.push(\r\n `<line x1=\"${x}\" y1=\"${sb.yMm}\" x2=\"${x}\" y2=\"${sb.yMm - height}\" stroke=\"${escapeAttr(\r\n sbStroke\r\n )}\" stroke-width=\"${sbStrokeWidth}\" />`\r\n );\r\n if (isLabel && sb.textStyle) {\r\n const style = template.styles?.[sb.textStyle];\r\n if (style) {\r\n const labelValue = (segmentMeters * i).toFixed(2).replace(/\\.?0+$/, '');\r\n barParts.push(\r\n `<text x=\"${x}\" y=\"${sb.yMm + style.fontSizeMm + 1}\" font-family=\"${escapeAttr(\r\n style.fontFamily\r\n )}\" font-size=\"${style.fontSizeMm}\" text-anchor=\"middle\">${escapeText(labelValue + unitSuffix)}</text>`\r\n );\r\n }\r\n }\r\n }\r\n\r\n barParts.push(\r\n `<line x1=\"${sb.xMm}\" y1=\"${sb.yMm}\" x2=\"${sb.xMm + lengthMm}\" y2=\"${sb.yMm}\" stroke=\"${escapeAttr(\r\n sbStroke\r\n )}\" stroke-width=\"${sbStrokeWidth}\" />`\r\n );\r\n\r\n parts.push(barParts.join(''));\r\n } else if (el.kind === ELEMENT_KIND_VIEWPORT) {\r\n const vp = el as ViewportElement;\r\n const model = filteredModelsByViewport[vp.id] ?? models[vp.id] ?? null;\r\n if (!model) {\r\n pushWarning(warnings, `Viewport '${vp.id}' missing model.`);\r\n }\r\n const vpParts = renderViewportElement(\r\n vp,\r\n model,\r\n dataWithViewport,\r\n preferredScales,\r\n presets.scales,\r\n assetMap,\r\n viewportScales,\r\n viewportClipPolygonsLocal,\r\n viewportClipBounds,\r\n viewportClipLabels,\r\n viewportClipStyles,\r\n viewportHighlight,\r\n viewportRenderInfo,\r\n warnings,\r\n legendColorMaps\r\n );\r\n parts.push(...vpParts);\r\n } else if (el.kind === ELEMENT_KIND_LEGEND) {\r\n const legend = el as LegendElement;\r\n const legendItems = getPathValue(data, `viewports.${legend.viewport}.items`);\r\n const rawLegendItems = Array.isArray(legendItems) ? legendItems : [];\r\n const legendDataFiltered = applyLegendFilter(\r\n rawLegendItems,\r\n legend,\r\n viewports,\r\n viewportClipPolygonsLocal,\r\n viewportRenderInfo\r\n );\r\n if (!legendDataFiltered || !legendDataFiltered.length) {\r\n if (!rawLegendItems.length) {\r\n pushWarning(warnings, `Legend '${legend.id}' has no items from viewport '${legend.viewport}'.`);\r\n } else {\r\n pushWarning(\r\n warnings,\r\n `Legend '${legend.id}' filter matched 0 of ${rawLegendItems.length} items (class=${JSON.stringify(legend.class)}, where=${JSON.stringify(legend.where)}).`\r\n );\r\n }\r\n }\r\n const vpEl = viewports.find((v) => v.id === legend.viewport);\r\n // Derive swatch opacity from viewport fill rules (first matching rule's opacity)\r\n const fillOpacity = vpEl?.fills?.length ? (vpEl.fills[0].fillOpacity ?? 0.35) : undefined;\r\n const legendResult = buildLegendGroup(\r\n legend,\r\n template.styles,\r\n page,\r\n page.marginMm,\r\n legendDataFiltered || [],\r\n fillOpacity\r\n );\r\n if (legendResult) {\r\n parts.push(legendResult.svg);\r\n }\r\n }\r\n });\r\n\r\n if (labelElements.length) {\r\n const labelParts = renderLabels(\r\n labelElements,\r\n data,\r\n viewportRenderInfo,\r\n viewportClipLabels,\r\n viewportClipPolygonsLocal,\r\n viewportClipPolygonsWorld,\r\n template.styles ?? {},\r\n dataWithViewport,\r\n warnings\r\n );\r\n parts.push(...labelParts);\r\n }\r\n\r\n if (qrElements.length) {\r\n const qrParts = await renderQrElements(\r\n qrElements,\r\n viewports,\r\n viewportScales,\r\n models,\r\n { qrContext: options?.qrContext },\r\n dataWithViewport,\r\n warnings\r\n );\r\n parts.push(...qrParts);\r\n }\r\n\r\n parts.push('</svg>');\r\n\r\n return { svg: parts.join(''), viewportScales, warnings };\r\n}\r\n\r\n// Register renderLayout with renderDrawing to break the circular dependency.\r\n// This runs at module evaluation time — safe because renderLayout is defined above.\r\nimport { setRenderLayoutBinding as _setBinding } from './renderDrawing';\r\n_setBinding(renderLayout as any);\r\n"]}
@@ -0,0 +1,29 @@
1
+ import type { SectionRenderState } from '@twinfinity/geometry';
2
+ import { ProductFieldPaths, NormalizedProductItem, SvgModelView, LabelStyle } from './types';
3
+ export interface ProductLike {
4
+ product?: any;
5
+ polylines?: Array<{
6
+ points?: Array<{
7
+ x: number;
8
+ z: number;
9
+ }>;
10
+ }>;
11
+ }
12
+ export interface BuildViewportItemsOptions {
13
+ productFields?: ProductFieldPaths;
14
+ }
15
+ /**
16
+ * Normalize a single product entry using explicit field paths.
17
+ */
18
+ export declare const normalizeProductEntry: (entry: ProductLike, productFields: ProductFieldPaths) => NormalizedProductItem;
19
+ export declare const computePolylinesCenter: (entry: unknown) => {
20
+ x: number | null;
21
+ z: number | null;
22
+ };
23
+ /**
24
+ * Normalize raw product entries into viewport items using explicit field paths.
25
+ * Requires productFields (id/name/area/class) pointing to propertySets.<Set>.<Prop>.value.
26
+ */
27
+ export declare const buildViewportItems: (entries: ProductLike[], options?: BuildViewportItemsOptions) => NormalizedProductItem[];
28
+ export declare function sectionStateToModelView(state: SectionRenderState, labelStyle?: LabelStyle): SvgModelView;
29
+ //# sourceMappingURL=itemBuilders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemBuilders.d.ts","sourceRoot":"/","sources":["layout/itemBuilders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI/D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI7F,MAAM,WAAW,WAAW;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,yBAAyB;IACtC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACrC;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,WAAW,EAAE,eAAe,iBAAiB,KAAG,qBAoD5F,CAAC;AAuBF,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG;IAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CA6B3F,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC3B,SAAS,WAAW,EAAE,EACtB,UAAU,yBAAyB,KACpC,qBAAqB,EAWvB,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,CAYxG"}
@@ -0,0 +1,135 @@
1
+ import { normalizePropertySets } from './metadata';
2
+ import { getPathValue } from './renderUtils';
3
+ import { buildModelViewFromRaw } from './model';
4
+ import { getProp } from './typeGuards';
5
+ /**
6
+ * Normalize a single product entry using explicit field paths.
7
+ */
8
+ export const normalizeProductEntry = (entry, productFields) => {
9
+ if (!productFields?.idPath || !productFields?.namePath || !productFields?.areaPath) {
10
+ throw new Error('productFields must include idPath, namePath, and areaPath using propertySets.<Set>.<Prop>.value.');
11
+ }
12
+ const product = getProp(entry, 'product') ?? entry;
13
+ const propertySets = normalizePropertySets(product);
14
+ const getVal = (path) => getPathValue({ propertySets }, path);
15
+ const idVal = getVal(productFields.idPath) ?? getProp(product, 'gid');
16
+ const nameVal = getVal(productFields.namePath);
17
+ const areaVal = getVal(productFields.areaPath);
18
+ // class.type = IfcClassType ("space", "walls", etc.) — used by template filters
19
+ // class.id = PredefinedIfcClassId ("IfcSpace", "IfcWall", etc.) — used as fallback
20
+ // classPath from propertySets may contain a PredefinedIfcClassId
21
+ const classPathVal = productFields.classPath ? getVal(productFields.classPath) : null;
22
+ const productClass = getProp(product, 'class');
23
+ const classType = getProp(productClass, 'type'); // IfcClassType
24
+ const classId = getProp(productClass, 'id'); // PredefinedIfcClassId
25
+ // ifcClass = IfcClassType category; ifcClassId = PredefinedIfcClassId
26
+ const ifcClass = (classType ?? null);
27
+ const ifcClassId = (classPathVal ?? classId ?? null);
28
+ // Try multiple sources for coordinates:
29
+ // 1. BBox center from product
30
+ // 2. Polylines center from entry
31
+ // 3. Direct x/z on entry or product
32
+ let { x, z } = getBBoxCenter(product);
33
+ if (x === null || z === null) {
34
+ const polyCenter = computePolylinesCenter(entry);
35
+ x = polyCenter.x ?? x;
36
+ z = polyCenter.z ?? z;
37
+ }
38
+ if (x === null || z === null) {
39
+ const directX = getProp(entry, 'x') ?? getProp(product, 'x');
40
+ const directZ = getProp(entry, 'z') ?? getProp(product, 'z');
41
+ if (Number.isFinite(directX))
42
+ x = directX;
43
+ if (Number.isFinite(directZ))
44
+ z = directZ;
45
+ }
46
+ const rawPolylines = getProp(entry, 'polylines');
47
+ return {
48
+ gid: getProp(product, 'gid'),
49
+ ifcClass,
50
+ ifcClassId,
51
+ propertySets,
52
+ productId: idVal ? String(idVal) : '-',
53
+ productName: typeof nameVal === 'string' && nameVal.trim().length ? nameVal.trim() : '-',
54
+ area: typeof areaVal === 'number' && Number.isFinite(areaVal) ? areaVal : null,
55
+ x,
56
+ z,
57
+ text: typeof nameVal === 'string' && nameVal.trim().length ? nameVal.trim() : '-',
58
+ polylines: Array.isArray(rawPolylines) ? rawPolylines : undefined
59
+ };
60
+ };
61
+ const getBBoxCenter = (product) => {
62
+ try {
63
+ const boundingInfo = getProp(product, 'boundingInfo');
64
+ const boundingInfoResult = typeof boundingInfo === 'function' ? boundingInfo() : null;
65
+ const bbox = getProp(boundingInfoResult, 'boundingBox');
66
+ const min = getProp(bbox, 'minimumWorld') ?? getProp(bbox, 'minimum');
67
+ const max = getProp(bbox, 'maximumWorld') ?? getProp(bbox, 'maximum');
68
+ const minX = getProp(min, 'x');
69
+ const maxX = getProp(max, 'x');
70
+ const minZ = getProp(min, 'z');
71
+ const maxZ = getProp(max, 'z');
72
+ if (Number.isFinite(minX) && Number.isFinite(maxX) && Number.isFinite(minZ) && Number.isFinite(maxZ)) {
73
+ return { x: (minX + maxX) * 0.5, z: (minZ + maxZ) * 0.5 };
74
+ }
75
+ }
76
+ catch {
77
+ // Bounding info access may fail for products without geometry or with malformed data structures.
78
+ // This is expected behavior - we return null coordinates as fallback.
79
+ }
80
+ return { x: null, z: null };
81
+ };
82
+ export const computePolylinesCenter = (entry) => {
83
+ try {
84
+ const polylines = getProp(entry, 'polylines');
85
+ if (!Array.isArray(polylines) || !polylines.length) {
86
+ return { x: null, z: null };
87
+ }
88
+ let sumX = 0;
89
+ let sumZ = 0;
90
+ let count = 0;
91
+ for (const polyline of polylines) {
92
+ const points = getProp(polyline, 'points');
93
+ if (!Array.isArray(points))
94
+ continue;
95
+ for (const pt of points) {
96
+ const px = getProp(pt, 'x');
97
+ const pz = getProp(pt, 'z');
98
+ if (Number.isFinite(px) && Number.isFinite(pz)) {
99
+ sumX += px;
100
+ sumZ += pz;
101
+ count++;
102
+ }
103
+ }
104
+ }
105
+ if (count > 0) {
106
+ return { x: sumX / count, z: sumZ / count };
107
+ }
108
+ }
109
+ catch {
110
+ // Polyline access may fail - return null
111
+ }
112
+ return { x: null, z: null };
113
+ };
114
+ /**
115
+ * Normalize raw product entries into viewport items using explicit field paths.
116
+ * Requires productFields (id/name/area/class) pointing to propertySets.<Set>.<Prop>.value.
117
+ */
118
+ export const buildViewportItems = (entries, options) => {
119
+ if (!options?.productFields) {
120
+ throw new Error('buildViewportItems requires productFields (idPath/namePath/areaPath/classPath).');
121
+ }
122
+ const { idPath, namePath, areaPath } = options.productFields;
123
+ if (!idPath || !namePath || !areaPath) {
124
+ throw new Error('productFields must include idPath, namePath, and areaPath using propertySets.<Set>.<Prop>.value.');
125
+ }
126
+ return (entries ?? []).map((entry) => normalizeProductEntry(entry, options.productFields));
127
+ };
128
+ export function sectionStateToModelView(state, labelStyle) {
129
+ const model = buildModelViewFromRaw(state.paths, state.labels, state.transform, state.geometryTransform, labelStyle);
130
+ if (!model) {
131
+ throw new Error('sectionStateToModelView requires paths, transform, and geometryTransform.');
132
+ }
133
+ return model;
134
+ }
135
+ //# sourceMappingURL=itemBuilders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemBuilders.js","sourceRoot":"/","sources":["layout/itemBuilders.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SectionRenderState } from '@twinfinity/geometry';\r\nimport { normalizePropertySets } from './metadata';\r\nimport { getPathValue } from './renderUtils';\r\nimport { buildModelViewFromRaw } from './model';\r\nimport { ProductFieldPaths, NormalizedProductItem, SvgModelView, LabelStyle } from './types';\r\n\r\nimport { getProp } from './typeGuards';\r\n\r\nexport interface ProductLike {\r\n product?: any;\r\n polylines?: Array<{ points?: Array<{ x: number; z: number }> }>;\r\n}\r\n\r\nexport interface BuildViewportItemsOptions {\r\n productFields?: ProductFieldPaths;\r\n}\r\n\r\n/**\r\n * Normalize a single product entry using explicit field paths.\r\n */\r\nexport const normalizeProductEntry = (entry: ProductLike, productFields: ProductFieldPaths): NormalizedProductItem => {\r\n if (!productFields?.idPath || !productFields?.namePath || !productFields?.areaPath) {\r\n throw new Error(\r\n 'productFields must include idPath, namePath, and areaPath using propertySets.<Set>.<Prop>.value.'\r\n );\r\n }\r\n const product = getProp(entry, 'product') ?? entry;\r\n const propertySets = normalizePropertySets(product);\r\n const getVal = (path: string): unknown => getPathValue({ propertySets }, path);\r\n const idVal = getVal(productFields.idPath) ?? getProp(product, 'gid');\r\n const nameVal = getVal(productFields.namePath);\r\n const areaVal = getVal(productFields.areaPath);\r\n // class.type = IfcClassType (\"space\", \"walls\", etc.) — used by template filters\r\n // class.id = PredefinedIfcClassId (\"IfcSpace\", \"IfcWall\", etc.) — used as fallback\r\n // classPath from propertySets may contain a PredefinedIfcClassId\r\n const classPathVal = productFields.classPath ? getVal(productFields.classPath) : null;\r\n const productClass = getProp(product, 'class');\r\n const classType = getProp(productClass, 'type') as string | null; // IfcClassType\r\n const classId = getProp(productClass, 'id') as string | null; // PredefinedIfcClassId\r\n // ifcClass = IfcClassType category; ifcClassId = PredefinedIfcClassId\r\n const ifcClass = (classType ?? null) as string | null;\r\n const ifcClassId = (classPathVal ?? classId ?? null) as string | null;\r\n // Try multiple sources for coordinates:\r\n // 1. BBox center from product\r\n // 2. Polylines center from entry\r\n // 3. Direct x/z on entry or product\r\n let { x, z } = getBBoxCenter(product);\r\n if (x === null || z === null) {\r\n const polyCenter = computePolylinesCenter(entry);\r\n x = polyCenter.x ?? x;\r\n z = polyCenter.z ?? z;\r\n }\r\n if (x === null || z === null) {\r\n const directX = getProp(entry, 'x') ?? getProp(product, 'x');\r\n const directZ = getProp(entry, 'z') ?? getProp(product, 'z');\r\n if (Number.isFinite(directX)) x = directX as number;\r\n if (Number.isFinite(directZ)) z = directZ as number;\r\n }\r\n const rawPolylines = getProp(entry, 'polylines');\r\n return {\r\n gid: getProp(product, 'gid') as string | undefined,\r\n ifcClass,\r\n ifcClassId,\r\n propertySets,\r\n productId: idVal ? String(idVal) : '-',\r\n productName: typeof nameVal === 'string' && nameVal.trim().length ? nameVal.trim() : '-',\r\n area: typeof areaVal === 'number' && Number.isFinite(areaVal) ? areaVal : null,\r\n x,\r\n z,\r\n text: typeof nameVal === 'string' && nameVal.trim().length ? nameVal.trim() : '-',\r\n polylines: Array.isArray(rawPolylines) ? rawPolylines : undefined\r\n };\r\n};\r\n\r\nconst getBBoxCenter = (product: unknown): { x: number | null; z: number | null } => {\r\n try {\r\n const boundingInfo = getProp(product, 'boundingInfo');\r\n const boundingInfoResult = typeof boundingInfo === 'function' ? boundingInfo() : null;\r\n const bbox = getProp(boundingInfoResult, 'boundingBox');\r\n const min = getProp(bbox, 'minimumWorld') ?? getProp(bbox, 'minimum');\r\n const max = getProp(bbox, 'maximumWorld') ?? getProp(bbox, 'maximum');\r\n const minX = getProp(min, 'x');\r\n const maxX = getProp(max, 'x');\r\n const minZ = getProp(min, 'z');\r\n const maxZ = getProp(max, 'z');\r\n if (Number.isFinite(minX) && Number.isFinite(maxX) && Number.isFinite(minZ) && Number.isFinite(maxZ)) {\r\n return { x: ((minX as number) + (maxX as number)) * 0.5, z: ((minZ as number) + (maxZ as number)) * 0.5 };\r\n }\r\n } catch {\r\n // Bounding info access may fail for products without geometry or with malformed data structures.\r\n // This is expected behavior - we return null coordinates as fallback.\r\n }\r\n return { x: null, z: null };\r\n};\r\n\r\nexport const computePolylinesCenter = (entry: unknown): { x: number | null; z: number | null } => {\r\n try {\r\n const polylines = getProp(entry, 'polylines');\r\n if (!Array.isArray(polylines) || !polylines.length) {\r\n return { x: null, z: null };\r\n }\r\n let sumX = 0;\r\n let sumZ = 0;\r\n let count = 0;\r\n for (const polyline of polylines) {\r\n const points = getProp(polyline, 'points');\r\n if (!Array.isArray(points)) continue;\r\n for (const pt of points) {\r\n const px = getProp(pt, 'x');\r\n const pz = getProp(pt, 'z');\r\n if (Number.isFinite(px) && Number.isFinite(pz)) {\r\n sumX += px as number;\r\n sumZ += pz as number;\r\n count++;\r\n }\r\n }\r\n }\r\n if (count > 0) {\r\n return { x: sumX / count, z: sumZ / count };\r\n }\r\n } catch {\r\n // Polyline access may fail - return null\r\n }\r\n return { x: null, z: null };\r\n};\r\n\r\n/**\r\n * Normalize raw product entries into viewport items using explicit field paths.\r\n * Requires productFields (id/name/area/class) pointing to propertySets.<Set>.<Prop>.value.\r\n */\r\nexport const buildViewportItems = (\r\n entries: ProductLike[],\r\n options?: BuildViewportItemsOptions\r\n): NormalizedProductItem[] => {\r\n if (!options?.productFields) {\r\n throw new Error('buildViewportItems requires productFields (idPath/namePath/areaPath/classPath).');\r\n }\r\n const { idPath, namePath, areaPath } = options.productFields;\r\n if (!idPath || !namePath || !areaPath) {\r\n throw new Error(\r\n 'productFields must include idPath, namePath, and areaPath using propertySets.<Set>.<Prop>.value.'\r\n );\r\n }\r\n return (entries ?? []).map((entry: any) => normalizeProductEntry(entry, options.productFields!));\r\n};\r\n\r\nexport function sectionStateToModelView(state: SectionRenderState, labelStyle?: LabelStyle): SvgModelView {\r\n const model = buildModelViewFromRaw(\r\n state.paths,\r\n state.labels,\r\n state.transform,\r\n state.geometryTransform,\r\n labelStyle\r\n );\r\n if (!model) {\r\n throw new Error('sectionStateToModelView requires paths, transform, and geometryTransform.');\r\n }\r\n return model;\r\n}\r\n"]}
@@ -0,0 +1,29 @@
1
+ import { LabelsElement, LayoutData } from './types';
2
+ export interface ViewportRenderInfo {
3
+ mmPerModel: number;
4
+ contentWidthMm: number;
5
+ contentHeightMm: number;
6
+ offsetX: number;
7
+ offsetY: number;
8
+ rotationDeg: number;
9
+ transform: {
10
+ viewMinX: number;
11
+ viewMaxX: number;
12
+ viewMinZ: number;
13
+ viewMaxZ: number;
14
+ viewWidth: number;
15
+ viewHeight: number;
16
+ };
17
+ centerX: number;
18
+ centerY: number;
19
+ centerModelX: number;
20
+ centerModelY: number;
21
+ }
22
+ export declare const renderLabels: (labelElements: LabelsElement[], data: LayoutData, viewportRenderInfo: Record<string, ViewportRenderInfo>, viewportClipLabels: Record<string, boolean>, viewportClipPolygonsLocal: Record<string, Array<Array<{
23
+ x: number;
24
+ y: number;
25
+ }>>>, viewportClipPolygonsWorld: Record<string, Array<Array<{
26
+ x: number;
27
+ z: number;
28
+ }>>>, styles: Record<string, unknown>, dataWithViewport: unknown, warnings: string[]) => string[];
29
+ //# sourceMappingURL=labelsRender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labelsRender.d.ts","sourceRoot":"/","sources":["layout/labelsRender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAOpD,MAAM,WAAW,kBAAkB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,GACrB,eAAe,aAAa,EAAE,EAC9B,MAAM,UAAU,EAChB,oBAAoB,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACtD,oBAAoB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,2BAA2B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC,EACjF,2BAA2B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC,EACjF,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,kBAAkB,OAAO,EACzB,UAAU,MAAM,EAAE,KACnB,MAAM,EAmIR,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { matchesV2Filter } from './filters';
2
+ import { pointInPolygon } from './clipUtils';
3
+ import { getPathValue, resolvePath, escapeAttr, escapeText } from './renderUtils';
4
+ import { isRecord, getProp } from './typeGuards';
5
+ export const renderLabels = (labelElements, data, viewportRenderInfo, viewportClipLabels, viewportClipPolygonsLocal, viewportClipPolygonsWorld, styles, dataWithViewport, warnings) => {
6
+ const parts = [];
7
+ for (const dl of labelElements) {
8
+ const vpInfo = viewportRenderInfo[dl.viewport];
9
+ if (!vpInfo) {
10
+ warnings.push(`Labels '${dl.id}' missing viewport '${dl.viewport}'.`);
11
+ continue;
12
+ }
13
+ if (vpInfo.rotationDeg !== 0) {
14
+ warnings.push(`Labels '${dl.id}' skipped because rotation is not supported.`);
15
+ continue;
16
+ }
17
+ if (!vpInfo.transform) {
18
+ warnings.push(`Labels '${dl.id}' skipped because model transform is missing.`);
19
+ continue;
20
+ }
21
+ // Items come from the bound viewport's data
22
+ const items = getPathValue(data, `viewports.${dl.viewport}.items`);
23
+ if (!Array.isArray(items) || !items.length) {
24
+ continue;
25
+ }
26
+ // Filter by class + where
27
+ let filteredItems = dl.class || dl.where ? items.filter((item) => matchesV2Filter(item, dl.class, dl.where)) : items;
28
+ console.log(`[Labels ${dl.id}] Total items:`, items.length, 'After class+where filter:', filteredItems.length);
29
+ // If matchClipFilter is true, filter by spatial position inside clip polygon
30
+ if (dl.matchClipFilter && viewportClipPolygonsWorld[dl.viewport]?.length) {
31
+ const clipPolygons = viewportClipPolygonsWorld[dl.viewport];
32
+ console.log(`[Labels ${dl.id}] Applying matchClipFilter (spatial) with ${clipPolygons.length} polygons`);
33
+ const beforeClipFilter = filteredItems.length;
34
+ filteredItems = filteredItems.filter((item) => {
35
+ const ix = getProp(item, 'x');
36
+ const iz = getProp(item, 'z');
37
+ if (!Number.isFinite(ix) || !Number.isFinite(iz))
38
+ return false;
39
+ return clipPolygons.some((poly) => {
40
+ // pointInPolygon expects y coordinate, but we use z for world space
41
+ const polyWith2D = poly.map((p) => ({ x: p.x, y: p.z }));
42
+ return pointInPolygon(polyWith2D, ix, iz);
43
+ });
44
+ });
45
+ console.log(`[Labels ${dl.id}] After matchClipFilter (spatial):`, filteredItems.length, '(was:', beforeClipFilter, ')');
46
+ // Debug: log first few items to see their properties
47
+ if (filteredItems.length === 0 && beforeClipFilter > 0) {
48
+ console.log('[Labels] Sample item that was filtered out:', items[0]);
49
+ }
50
+ }
51
+ if (!filteredItems.length) {
52
+ console.log(`[Labels ${dl.id}] No items left after filtering, skipping.`);
53
+ continue;
54
+ }
55
+ const styleName = dl.textStyle;
56
+ const style = styleName && isRecord(styles) ? getProp(styles, styleName) : undefined;
57
+ if (!isRecord(style)) {
58
+ warnings.push(`Labels '${dl.id}' missing textStyle '${styleName ?? '(none)'}'.`);
59
+ continue;
60
+ }
61
+ const anchor = dl.align === 'center' ? 'middle' : dl.align === 'right' ? 'end' : 'start';
62
+ const t = vpInfo.transform;
63
+ let renderedCount = 0;
64
+ let spatiallyFilteredCount = 0;
65
+ filteredItems.forEach((item) => {
66
+ // Hardcoded x/z for BIM floor plane convention
67
+ const xVal = getProp(item, 'x');
68
+ const yVal = getProp(item, 'z');
69
+ if (!Number.isFinite(xVal) || !Number.isFinite(yVal)) {
70
+ return;
71
+ }
72
+ const viewX = xVal - t.viewMinX;
73
+ const viewY = t.viewMaxZ - yVal;
74
+ const centerModelX = vpInfo.centerModelX;
75
+ const centerModelY = vpInfo.centerModelY;
76
+ const xMm = vpInfo.centerX + (viewX - centerModelX) * vpInfo.mmPerModel;
77
+ const yMm = vpInfo.centerY + (viewY - centerModelY) * vpInfo.mmPerModel;
78
+ if (viewportClipLabels[dl.viewport] && viewportClipPolygonsLocal[dl.viewport]?.length) {
79
+ const inside = viewportClipPolygonsLocal[dl.viewport].some((poly) => pointInPolygon(poly, viewX, viewY));
80
+ if (!inside) {
81
+ spatiallyFilteredCount++;
82
+ return;
83
+ }
84
+ }
85
+ renderedCount++;
86
+ const text = escapeText(dl.text && typeof dl.text === 'string'
87
+ ? dl.text.replace(/\{\{\s*([^}]+?)\s*\}\}/g, (_m, path) => {
88
+ const val = resolvePath(item, path) ?? getPathValue(dataWithViewport, path);
89
+ return val === undefined || val === null || typeof val === 'object' ? '' : String(val);
90
+ })
91
+ : '');
92
+ const fontFamily = getProp(style, 'fontFamily');
93
+ const fontSizeMm = getProp(style, 'fontSizeMm');
94
+ const fontWeight = getProp(style, 'fontWeight');
95
+ const color = getProp(style, 'color');
96
+ const letterSpacingMm = getProp(style, 'letterSpacingMm');
97
+ const lineHeightMm = getProp(style, 'lineHeightMm');
98
+ parts.push(`<text x="${xMm}" y="${yMm}" font-family="${escapeAttr(String(fontFamily))}" font-size="${fontSizeMm}"` +
99
+ (fontWeight ? ` font-weight="${escapeAttr(String(fontWeight))}"` : '') +
100
+ (color ? ` fill="${escapeAttr(String(color))}"` : '') +
101
+ (letterSpacingMm !== undefined ? ` letter-spacing="${letterSpacingMm}"` : '') +
102
+ (lineHeightMm !== undefined ? ` line-height="${lineHeightMm}"` : '') +
103
+ ` text-anchor="${anchor}">${text}</text>`);
104
+ });
105
+ console.log(`[Labels ${dl.id}] Rendered ${renderedCount} labels. Spatially filtered out: ${spatiallyFilteredCount}`);
106
+ }
107
+ return parts;
108
+ };
109
+ //# sourceMappingURL=labelsRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labelsRender.js","sourceRoot":"/","sources":["layout/labelsRender.ts"],"names":[],"mappings":"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","sourcesContent":["import { LabelsElement, LayoutData } from './types';\r\nimport { matchesV2Filter } from './filters';\r\nimport { pointInPolygon } from './clipUtils';\r\nimport { getPathValue, resolvePath, escapeAttr, escapeText } from './renderUtils';\r\n\r\nimport { isRecord, getProp } from './typeGuards';\r\n\r\nexport interface ViewportRenderInfo {\r\n mmPerModel: number;\r\n contentWidthMm: number;\r\n contentHeightMm: number;\r\n offsetX: number;\r\n offsetY: number;\r\n rotationDeg: number;\r\n transform: {\r\n viewMinX: number;\r\n viewMaxX: number;\r\n viewMinZ: number;\r\n viewMaxZ: number;\r\n viewWidth: number;\r\n viewHeight: number;\r\n };\r\n centerX: number;\r\n centerY: number;\r\n centerModelX: number;\r\n centerModelY: number;\r\n}\r\n\r\nexport const renderLabels = (\r\n labelElements: LabelsElement[],\r\n data: LayoutData,\r\n viewportRenderInfo: Record<string, ViewportRenderInfo>,\r\n viewportClipLabels: Record<string, boolean>,\r\n viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>>,\r\n viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>>,\r\n styles: Record<string, unknown>,\r\n dataWithViewport: unknown,\r\n warnings: string[]\r\n): string[] => {\r\n const parts: string[] = [];\r\n\r\n for (const dl of labelElements) {\r\n const vpInfo = viewportRenderInfo[dl.viewport];\r\n if (!vpInfo) {\r\n warnings.push(`Labels '${dl.id}' missing viewport '${dl.viewport}'.`);\r\n continue;\r\n }\r\n if (vpInfo.rotationDeg !== 0) {\r\n warnings.push(`Labels '${dl.id}' skipped because rotation is not supported.`);\r\n continue;\r\n }\r\n if (!vpInfo.transform) {\r\n warnings.push(`Labels '${dl.id}' skipped because model transform is missing.`);\r\n continue;\r\n }\r\n // Items come from the bound viewport's data\r\n const items = getPathValue(data, `viewports.${dl.viewport}.items`);\r\n if (!Array.isArray(items) || !items.length) {\r\n continue;\r\n }\r\n // Filter by class + where\r\n let filteredItems =\r\n dl.class || dl.where ? items.filter((item) => matchesV2Filter(item, dl.class, dl.where)) : items;\r\n\r\n console.log(`[Labels ${dl.id}] Total items:`, items.length, 'After class+where filter:', filteredItems.length);\r\n\r\n // If matchClipFilter is true, filter by spatial position inside clip polygon\r\n if (dl.matchClipFilter && viewportClipPolygonsWorld[dl.viewport]?.length) {\r\n const clipPolygons = viewportClipPolygonsWorld[dl.viewport];\r\n console.log(`[Labels ${dl.id}] Applying matchClipFilter (spatial) with ${clipPolygons.length} polygons`);\r\n const beforeClipFilter = filteredItems.length;\r\n filteredItems = filteredItems.filter((item) => {\r\n const ix = getProp(item, 'x');\r\n const iz = getProp(item, 'z');\r\n if (!Number.isFinite(ix) || !Number.isFinite(iz)) return false;\r\n return clipPolygons.some((poly) => {\r\n // pointInPolygon expects y coordinate, but we use z for world space\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 });\r\n console.log(\r\n `[Labels ${dl.id}] After matchClipFilter (spatial):`,\r\n filteredItems.length,\r\n '(was:',\r\n beforeClipFilter,\r\n ')'\r\n );\r\n\r\n // Debug: log first few items to see their properties\r\n if (filteredItems.length === 0 && beforeClipFilter > 0) {\r\n console.log('[Labels] Sample item that was filtered out:', items[0]);\r\n }\r\n }\r\n\r\n if (!filteredItems.length) {\r\n console.log(`[Labels ${dl.id}] No items left after filtering, skipping.`);\r\n continue;\r\n }\r\n const styleName = dl.textStyle;\r\n const style = styleName && isRecord(styles) ? getProp(styles, styleName) : undefined;\r\n if (!isRecord(style)) {\r\n warnings.push(`Labels '${dl.id}' missing textStyle '${styleName ?? '(none)'}'.`);\r\n continue;\r\n }\r\n const anchor = dl.align === 'center' ? 'middle' : dl.align === 'right' ? 'end' : 'start';\r\n const t = vpInfo.transform;\r\n\r\n let renderedCount = 0;\r\n let spatiallyFilteredCount = 0;\r\n\r\n filteredItems.forEach((item) => {\r\n // Hardcoded x/z for BIM floor plane convention\r\n const xVal = getProp(item, 'x');\r\n const yVal = getProp(item, 'z');\r\n if (!Number.isFinite(xVal as number) || !Number.isFinite(yVal as number)) {\r\n return;\r\n }\r\n const viewX = (xVal as number) - t.viewMinX;\r\n const viewY = t.viewMaxZ - (yVal as number);\r\n const centerModelX = vpInfo.centerModelX;\r\n const centerModelY = vpInfo.centerModelY;\r\n const xMm = vpInfo.centerX + (viewX - centerModelX) * vpInfo.mmPerModel;\r\n const yMm = vpInfo.centerY + (viewY - centerModelY) * vpInfo.mmPerModel;\r\n\r\n if (viewportClipLabels[dl.viewport] && viewportClipPolygonsLocal[dl.viewport]?.length) {\r\n const inside = viewportClipPolygonsLocal[dl.viewport].some((poly) =>\r\n pointInPolygon(poly, viewX, viewY)\r\n );\r\n if (!inside) {\r\n spatiallyFilteredCount++;\r\n return;\r\n }\r\n }\r\n\r\n renderedCount++;\r\n\r\n const text = escapeText(\r\n dl.text && typeof dl.text === 'string'\r\n ? dl.text.replace(/\\{\\{\\s*([^}]+?)\\s*\\}\\}/g, (_m, path) => {\r\n const val = resolvePath(item, path) ?? getPathValue(dataWithViewport, path);\r\n return val === undefined || val === null || typeof val === 'object' ? '' : String(val);\r\n })\r\n : ''\r\n );\r\n\r\n const fontFamily = getProp(style, 'fontFamily');\r\n const fontSizeMm = getProp(style, 'fontSizeMm');\r\n const fontWeight = getProp(style, 'fontWeight');\r\n const color = getProp(style, 'color');\r\n const letterSpacingMm = getProp(style, 'letterSpacingMm');\r\n const lineHeightMm = getProp(style, 'lineHeightMm');\r\n\r\n parts.push(\r\n `<text x=\"${xMm}\" y=\"${yMm}\" font-family=\"${escapeAttr(String(fontFamily))}\" font-size=\"${fontSizeMm}\"` +\r\n (fontWeight ? ` font-weight=\"${escapeAttr(String(fontWeight))}\"` : '') +\r\n (color ? ` fill=\"${escapeAttr(String(color))}\"` : '') +\r\n (letterSpacingMm !== undefined ? ` letter-spacing=\"${letterSpacingMm}\"` : '') +\r\n (lineHeightMm !== undefined ? ` line-height=\"${lineHeightMm}\"` : '') +\r\n ` text-anchor=\"${anchor}\">${text}</text>`\r\n );\r\n });\r\n\r\n console.log(\r\n `[Labels ${dl.id}] Rendered ${renderedCount} labels. Spatially filtered out: ${spatiallyFilteredCount}`\r\n );\r\n }\r\n\r\n return parts;\r\n};\r\n"]}
@@ -0,0 +1,12 @@
1
+ export declare const PX_PER_MM: number;
2
+ export declare const DEFAULT_LEGEND_SWATCH_WIDTH_MM = 8;
3
+ export declare const DEFAULT_LEGEND_CELL_PADDING_MM = 2;
4
+ export declare const DEFAULT_LEGEND_BORDER_WIDTH_MM = 0.25;
5
+ export declare const DEFAULT_LEGEND_GRID_WIDTH_MM = 0.25;
6
+ export declare const DEFAULT_LEGEND_HEADER_WIDTH_MM = 0.65;
7
+ export declare const DEFAULT_LEGEND_OFFSET_MM = 5;
8
+ export declare const LEGEND_TEXT_WIDTH_FACTOR = 0.7;
9
+ export declare const LEGEND_MIN_CONTENT_WIDTH_EM = 4;
10
+ export declare const LEGEND_TEXT_Y_OFFSET_FACTOR = 0.3;
11
+ export declare const MAX_LEGEND_ROWS = 200;
12
+ //# sourceMappingURL=legendConstants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legendConstants.d.ts","sourceRoot":"/","sources":["layout/legendConstants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,QAAY,CAAC;AACnC,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAC7C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,eAAe,MAAM,CAAC"}
@@ -0,0 +1,12 @@
1
+ export const PX_PER_MM = 96 / 25.4;
2
+ export const DEFAULT_LEGEND_SWATCH_WIDTH_MM = 8;
3
+ export const DEFAULT_LEGEND_CELL_PADDING_MM = 2;
4
+ export const DEFAULT_LEGEND_BORDER_WIDTH_MM = 0.25;
5
+ export const DEFAULT_LEGEND_GRID_WIDTH_MM = 0.25;
6
+ export const DEFAULT_LEGEND_HEADER_WIDTH_MM = 0.65;
7
+ export const DEFAULT_LEGEND_OFFSET_MM = 5;
8
+ export const LEGEND_TEXT_WIDTH_FACTOR = 0.7;
9
+ export const LEGEND_MIN_CONTENT_WIDTH_EM = 4;
10
+ export const LEGEND_TEXT_Y_OFFSET_FACTOR = 0.3;
11
+ export const MAX_LEGEND_ROWS = 200;
12
+ //# sourceMappingURL=legendConstants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legendConstants.js","sourceRoot":"/","sources":["layout/legendConstants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AACjD,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAC7C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAC/C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC","sourcesContent":["export const PX_PER_MM = 96 / 25.4;\r\nexport const DEFAULT_LEGEND_SWATCH_WIDTH_MM = 8;\r\nexport const DEFAULT_LEGEND_CELL_PADDING_MM = 2;\r\nexport const DEFAULT_LEGEND_BORDER_WIDTH_MM = 0.25;\r\nexport const DEFAULT_LEGEND_GRID_WIDTH_MM = 0.25;\r\nexport const DEFAULT_LEGEND_HEADER_WIDTH_MM = 0.65;\r\nexport const DEFAULT_LEGEND_OFFSET_MM = 5;\r\nexport const LEGEND_TEXT_WIDTH_FACTOR = 0.7;\r\nexport const LEGEND_MIN_CONTENT_WIDTH_EM = 4;\r\nexport const LEGEND_TEXT_Y_OFFSET_FACTOR = 0.3;\r\nexport const MAX_LEGEND_ROWS = 200;\r\n"]}
@@ -0,0 +1,13 @@
1
+ import { LegendElement, PageSpec, StyleMap } from './types';
2
+ export declare const applyLegendFilter: (legendData: unknown[], legend: LegendElement, viewports: unknown[], viewportClipPolygonsLocal: Record<string, Array<Array<{
3
+ x: number;
4
+ y: number;
5
+ }>>>, viewportRenderInfo: Record<string, {
6
+ transform?: unknown;
7
+ }>) => unknown[];
8
+ export interface LegendResult {
9
+ svg: string;
10
+ colorMap?: Map<string, string>;
11
+ }
12
+ export declare const buildLegendGroup: (legend: LegendElement, styles: StyleMap | undefined, page: PageSpec, marginMm: number | undefined, legendData: unknown[], fillOpacity?: number) => LegendResult | null;
13
+ //# sourceMappingURL=legendRender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legendRender.d.ts","sourceRoot":"/","sources":["layout/legendRender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA+E5D,eAAO,MAAM,iBAAiB,GAC1B,YAAY,OAAO,EAAE,EACrB,QAAQ,aAAa,EACrB,WAAW,OAAO,EAAE,EACpB,2BAA2B,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC,EACjF,oBAAoB,MAAM,CAAC,MAAM,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,KAC5D,OAAO,EA6BT,CAAC;AAEF,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GACzB,QAAQ,aAAa,EACrB,QAAQ,QAAQ,GAAG,SAAS,EAC5B,MAAM,QAAQ,EACd,UAAU,MAAM,GAAG,SAAS,EAC5B,YAAY,OAAO,EAAE,EACrB,cAAc,MAAM,KACrB,YAAY,GAAG,IA8ZjB,CAAC"}