@yuuvis/client-framework 0.6.5

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 (392) hide show
  1. package/README.md +62 -0
  2. package/actions/README.md +3 -0
  3. package/actions/index.d.ts +6 -0
  4. package/actions/lib/actions/copy-action/copy-action.d.ts +17 -0
  5. package/actions/lib/actions/cut-action/cut-action.d.ts +17 -0
  6. package/actions/lib/actions/delete-action/delete/delete.component.d.ts +22 -0
  7. package/actions/lib/actions/delete-action/delete-action.d.ts +17 -0
  8. package/actions/lib/actions/download-action/download-action.d.ts +17 -0
  9. package/actions/lib/actions.icon.d.ts +7 -0
  10. package/actions/lib/actions.interface.d.ts +86 -0
  11. package/actions/lib/actions.module.d.ts +8 -0
  12. package/actions/lib/actions.service.d.ts +38 -0
  13. package/actions/lib/components/contextmenu/contextmenu.component.d.ts +11 -0
  14. package/app-bar/README.md +3 -0
  15. package/app-bar/index.d.ts +1 -0
  16. package/app-bar/lib/app-bar.component.d.ts +47 -0
  17. package/clipboard/README.md +3 -0
  18. package/clipboard/index.d.ts +1 -0
  19. package/clipboard/lib/clipboard.component.d.ts +16 -0
  20. package/common/README.md +3 -0
  21. package/common/index.d.ts +5 -0
  22. package/common/lib/components/focus-indicator/focus-indicator.component.d.ts +7 -0
  23. package/common/lib/components/token-input/token-input.component.d.ts +55 -0
  24. package/common/lib/components/token-input/token-input.interface.d.ts +8 -0
  25. package/common/lib/directives/busy-overlay.directive.d.ts +25 -0
  26. package/common/lib/directives/click-double.directive.d.ts +17 -0
  27. package/common/lib/directives/container-size.directive.d.ts +30 -0
  28. package/common/lib/directives/drag-select.directive.d.ts +21 -0
  29. package/common/lib/directives/file-drop-zone/file-drop-zone.directive.d.ts +18 -0
  30. package/common/lib/directives/file-drop-zone/file-drop-zone.interface.d.ts +5 -0
  31. package/common/lib/directives/focus-within.directive.d.ts +36 -0
  32. package/common/lib/directives/index.d.ts +8 -0
  33. package/common/lib/directives/light-dismiss.directive.d.ts +19 -0
  34. package/common/lib/directives/longpress.directive.d.ts +13 -0
  35. package/common/lib/directives/noop-value-accessor.directive.d.ts +10 -0
  36. package/esm2022/actions/index.mjs +7 -0
  37. package/esm2022/actions/lib/actions/copy-action/copy-action.mjs +31 -0
  38. package/esm2022/actions/lib/actions/cut-action/cut-action.mjs +30 -0
  39. package/esm2022/actions/lib/actions/delete-action/delete/delete.component.mjs +67 -0
  40. package/esm2022/actions/lib/actions/delete-action/delete-action.mjs +44 -0
  41. package/esm2022/actions/lib/actions/download-action/download-action.mjs +33 -0
  42. package/esm2022/actions/lib/actions.icon.mjs +8 -0
  43. package/esm2022/actions/lib/actions.interface.mjs +19 -0
  44. package/esm2022/actions/lib/actions.module.mjs +16 -0
  45. package/esm2022/actions/lib/actions.service.mjs +89 -0
  46. package/esm2022/actions/lib/components/contextmenu/contextmenu.component.mjs +27 -0
  47. package/esm2022/actions/yuuvis-client-framework-actions.mjs +5 -0
  48. package/esm2022/app-bar/index.mjs +2 -0
  49. package/esm2022/app-bar/lib/app-bar.component.mjs +89 -0
  50. package/esm2022/app-bar/yuuvis-client-framework-app-bar.mjs +5 -0
  51. package/esm2022/clipboard/index.mjs +2 -0
  52. package/esm2022/clipboard/lib/clipboard.component.mjs +48 -0
  53. package/esm2022/clipboard/yuuvis-client-framework-clipboard.mjs +5 -0
  54. package/esm2022/common/index.mjs +6 -0
  55. package/esm2022/common/lib/components/focus-indicator/focus-indicator.component.mjs +41 -0
  56. package/esm2022/common/lib/components/token-input/token-input.component.mjs +324 -0
  57. package/esm2022/common/lib/components/token-input/token-input.interface.mjs +2 -0
  58. package/esm2022/common/lib/directives/busy-overlay.directive.mjs +88 -0
  59. package/esm2022/common/lib/directives/click-double.directive.mjs +61 -0
  60. package/esm2022/common/lib/directives/container-size.directive.mjs +56 -0
  61. package/esm2022/common/lib/directives/drag-select.directive.mjs +114 -0
  62. package/esm2022/common/lib/directives/file-drop-zone/file-drop-zone.directive.mjs +153 -0
  63. package/esm2022/common/lib/directives/file-drop-zone/file-drop-zone.interface.mjs +2 -0
  64. package/esm2022/common/lib/directives/focus-within.directive.mjs +81 -0
  65. package/esm2022/common/lib/directives/index.mjs +9 -0
  66. package/esm2022/common/lib/directives/light-dismiss.directive.mjs +44 -0
  67. package/esm2022/common/lib/directives/longpress.directive.mjs +36 -0
  68. package/esm2022/common/lib/directives/noop-value-accessor.directive.mjs +42 -0
  69. package/esm2022/common/yuuvis-client-framework-common.mjs +5 -0
  70. package/esm2022/forms/index.mjs +19 -0
  71. package/esm2022/forms/lib/elements/catalog/catalog.component.mjs +118 -0
  72. package/esm2022/forms/lib/elements/datetime/datetime.component.mjs +82 -0
  73. package/esm2022/forms/lib/elements/datetime-range/datetime-range.component.mjs +166 -0
  74. package/esm2022/forms/lib/elements/number/number.component.mjs +195 -0
  75. package/esm2022/forms/lib/elements/number-range/number-range.component.mjs +176 -0
  76. package/esm2022/forms/lib/elements/organization/organization.component.mjs +268 -0
  77. package/esm2022/forms/lib/elements/string/string.component.mjs +254 -0
  78. package/esm2022/forms/lib/form-input/form-input.component.mjs +88 -0
  79. package/esm2022/forms/lib/forms.module.mjs +58 -0
  80. package/esm2022/forms/yuuvis-client-framework-forms.mjs +5 -0
  81. package/esm2022/icons/index.mjs +4 -0
  82. package/esm2022/icons/lib/icon.service.mjs +59 -0
  83. package/esm2022/icons/lib/icons.mjs +31 -0
  84. package/esm2022/icons/lib/object-type-icon/object-type-icon.component.mjs +29 -0
  85. package/esm2022/icons/yuuvis-client-framework-icons.mjs +5 -0
  86. package/esm2022/index.mjs +2 -0
  87. package/esm2022/lib/yuuvis-client-framework.module.mjs +15 -0
  88. package/esm2022/list/index.mjs +3 -0
  89. package/esm2022/list/lib/list-item.directive.mjs +72 -0
  90. package/esm2022/list/lib/list.component.mjs +133 -0
  91. package/esm2022/list/yuuvis-client-framework-list.mjs +5 -0
  92. package/esm2022/metadata-form/index.mjs +4 -0
  93. package/esm2022/metadata-form/lib/metadata-default-templates/metadata-default-templates.component.mjs +31 -0
  94. package/esm2022/metadata-form/lib/metadata-form-element-registry.service.mjs +99 -0
  95. package/esm2022/metadata-form/lib/metadata-form-field/metadata-form-field.component.mjs +126 -0
  96. package/esm2022/metadata-form/lib/object-metadata-element-template.directive.mjs +52 -0
  97. package/esm2022/metadata-form/yuuvis-client-framework-metadata-form.mjs +5 -0
  98. package/esm2022/object-details/index.mjs +7 -0
  99. package/esm2022/object-details/lib/object-audit/object-audit.component.mjs +195 -0
  100. package/esm2022/object-details/lib/object-details-shell/object-details-shell.component.mjs +127 -0
  101. package/esm2022/object-details/lib/object-details.component.mjs +61 -0
  102. package/esm2022/object-details/lib/object-metadata/form-section-group.pipe.mjs +17 -0
  103. package/esm2022/object-details/lib/object-metadata/object-metadata.component.mjs +201 -0
  104. package/esm2022/object-details/lib/object-metadata/object-metadata.interface.mjs +2 -0
  105. package/esm2022/object-details/yuuvis-client-framework-object-details.mjs +5 -0
  106. package/esm2022/object-flavor/index.mjs +6 -0
  107. package/esm2022/object-flavor/lib/abstract-apply-create-flavor/abstract-apply-create-flavor.component.mjs +25 -0
  108. package/esm2022/object-flavor/lib/abstract-apply-object-flavor/abstract-apply-object-flavor.component.mjs +21 -0
  109. package/esm2022/object-flavor/lib/flavor-chip/flavor-chip.component.mjs +35 -0
  110. package/esm2022/object-flavor/lib/object-flavor/object-flavor.component.mjs +93 -0
  111. package/esm2022/object-flavor/lib/object-flavor-picker/object-flavor-picker.component.mjs +43 -0
  112. package/esm2022/object-flavor/yuuvis-client-framework-object-flavor.mjs +5 -0
  113. package/esm2022/object-form/index.mjs +5 -0
  114. package/esm2022/object-form/lib/form-scripting.api.interface.mjs +2 -0
  115. package/esm2022/object-form/lib/form-scripting.service.mjs +160 -0
  116. package/esm2022/object-form/lib/object-form-element/object-form-element.component.mjs +87 -0
  117. package/esm2022/object-form/lib/object-form-extension.interface.mjs +36 -0
  118. package/esm2022/object-form/lib/object-form-group/object-form-group.component.mjs +85 -0
  119. package/esm2022/object-form/lib/object-form-script/form-scripting-element-extension/form-scripting-element-extension.component.mjs +23 -0
  120. package/esm2022/object-form/lib/object-form-script/object-form-script.service.mjs +115 -0
  121. package/esm2022/object-form/lib/object-form-script/object-form-scripting-scope.mjs +251 -0
  122. package/esm2022/object-form/lib/object-form-translate.service.mjs +73 -0
  123. package/esm2022/object-form/lib/object-form.component.mjs +627 -0
  124. package/esm2022/object-form/lib/object-form.interface.mjs +9 -0
  125. package/esm2022/object-form/lib/object-form.model.mjs +20 -0
  126. package/esm2022/object-form/lib/object-form.service.mjs +127 -0
  127. package/esm2022/object-form/lib/object-form.utils.mjs +55 -0
  128. package/esm2022/object-form/lib/object-form.validation.mjs +48 -0
  129. package/esm2022/object-form/yuuvis-client-framework-object-form.mjs +5 -0
  130. package/esm2022/object-preview/index.mjs +3 -0
  131. package/esm2022/object-preview/lib/components/index.mjs +3 -0
  132. package/esm2022/object-preview/lib/components/object-email-preview/object-email-preview.component.mjs +45 -0
  133. package/esm2022/object-preview/lib/components/object-preview/object-preview.component.mjs +78 -0
  134. package/esm2022/object-preview/lib/services/object-preview.service.mjs +92 -0
  135. package/esm2022/object-preview/yuuvis-client-framework-object-preview.mjs +5 -0
  136. package/esm2022/object-summary/index.mjs +5 -0
  137. package/esm2022/object-summary/lib/multi-object-summary/multi-object-summary.component.mjs +33 -0
  138. package/esm2022/object-summary/lib/object-summary/object-summary.component.mjs +273 -0
  139. package/esm2022/object-summary/lib/object-summary-data/object-summary-data.component.mjs +80 -0
  140. package/esm2022/object-summary/lib/object-summary.module.mjs +15 -0
  141. package/esm2022/object-summary/yuuvis-client-framework-object-summary.mjs +5 -0
  142. package/esm2022/pagination/index.mjs +3 -0
  143. package/esm2022/pagination/lib/pagination.component.mjs +48 -0
  144. package/esm2022/pagination/lib/pagination.interface.mjs +2 -0
  145. package/esm2022/pagination/yuuvis-client-framework-pagination.mjs +5 -0
  146. package/esm2022/panel/index.mjs +2 -0
  147. package/esm2022/panel/lib/panel.component.mjs +20 -0
  148. package/esm2022/panel/yuuvis-client-framework-panel.mjs +5 -0
  149. package/esm2022/renderer/index.mjs +11 -0
  150. package/esm2022/renderer/lib/property-renderer/abstract.renderer.mjs +29 -0
  151. package/esm2022/renderer/lib/property-renderer/datetime.renderer.mjs +13 -0
  152. package/esm2022/renderer/lib/property-renderer/decimal.renderer.component.mjs +12 -0
  153. package/esm2022/renderer/lib/property-renderer/filesize.renderer.component.mjs +28 -0
  154. package/esm2022/renderer/lib/property-renderer/icon.renderer.component.mjs +23 -0
  155. package/esm2022/renderer/lib/property-renderer/integer.renderer.component.mjs +12 -0
  156. package/esm2022/renderer/lib/property-renderer/organization.renderer.mjs +19 -0
  157. package/esm2022/renderer/lib/property-renderer/string.renderer.component.mjs +12 -0
  158. package/esm2022/renderer/lib/property-renderer/unknown.renderer.mjs +12 -0
  159. package/esm2022/renderer/lib/renderer.directive.mjs +51 -0
  160. package/esm2022/renderer/lib/services/renderer/renderer.interface.mjs +2 -0
  161. package/esm2022/renderer/lib/services/renderer/renderer.service.mjs +84 -0
  162. package/esm2022/renderer/yuuvis-client-framework-renderer.mjs +5 -0
  163. package/esm2022/sequence-list/index.mjs +6 -0
  164. package/esm2022/sequence-list/lib/due-date-picker/due-date-picker.component.mjs +99 -0
  165. package/esm2022/sequence-list/lib/sequence-list-template-manage/sequence-list-template-manage.component.mjs +183 -0
  166. package/esm2022/sequence-list/lib/sequence-list-templates/sequence-list-templates.component.mjs +114 -0
  167. package/esm2022/sequence-list/lib/sequence-list.component.mjs +146 -0
  168. package/esm2022/sequence-list/lib/sequence-list.interface.mjs +2 -0
  169. package/esm2022/sequence-list/yuuvis-client-framework-sequence-list.mjs +5 -0
  170. package/esm2022/simple-search/index.mjs +3 -0
  171. package/esm2022/simple-search/lib/simple-search/simple-search.component.mjs +111 -0
  172. package/esm2022/simple-search/lib/simple-search/simple-search.interface.mjs +2 -0
  173. package/esm2022/simple-search/yuuvis-client-framework-simple-search.mjs +5 -0
  174. package/esm2022/tile-list/index.mjs +11 -0
  175. package/esm2022/tile-list/lib/tile/tile.component.mjs +53 -0
  176. package/esm2022/tile-list/lib/tile-config/action-select/action-select.component.mjs +22 -0
  177. package/esm2022/tile-list/lib/tile-config/icon-select/icon-select.component.mjs +33 -0
  178. package/esm2022/tile-list/lib/tile-config/property-select/property-select.component.mjs +91 -0
  179. package/esm2022/tile-list/lib/tile-config/tile-config-tile/tile-config-tile.component.mjs +66 -0
  180. package/esm2022/tile-list/lib/tile-config/tile-config-trigger/tile-config-trigger.component.mjs +46 -0
  181. package/esm2022/tile-list/lib/tile-config/tile-config.component.mjs +156 -0
  182. package/esm2022/tile-list/lib/tile-extension/directive/tile-extension.directive.mjs +37 -0
  183. package/esm2022/tile-list/lib/tile-extension/extensions/email.extension.mjs +42 -0
  184. package/esm2022/tile-list/lib/tile-extension/tile-extension.service.mjs +35 -0
  185. package/esm2022/tile-list/lib/tile-list/tile-list.component.mjs +510 -0
  186. package/esm2022/tile-list/lib/tile-list/tile-list.interface.mjs +2 -0
  187. package/esm2022/tile-list/yuuvis-client-framework-tile-list.mjs +5 -0
  188. package/esm2022/token-search/index.mjs +3 -0
  189. package/esm2022/token-search/token-search.component.mjs +78 -0
  190. package/esm2022/token-search/token-search.interface.mjs +2 -0
  191. package/esm2022/token-search/yuuvis-client-framework-token-search.mjs +5 -0
  192. package/esm2022/tree/index.mjs +3 -0
  193. package/esm2022/tree/lib/tree-node/tree-node.component.mjs +65 -0
  194. package/esm2022/tree/lib/tree.component.mjs +148 -0
  195. package/esm2022/tree/lib/tree.interface.mjs +2 -0
  196. package/esm2022/tree/lib/tree.service.mjs +95 -0
  197. package/esm2022/tree/yuuvis-client-framework-tree.mjs +5 -0
  198. package/esm2022/upload-progress/index.mjs +2 -0
  199. package/esm2022/upload-progress/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.mjs +49 -0
  200. package/esm2022/upload-progress/lib/upload-progress/upload-progress.component.mjs +37 -0
  201. package/esm2022/upload-progress/yuuvis-client-framework-upload-progress.mjs +5 -0
  202. package/esm2022/user-avatar/index.mjs +3 -0
  203. package/esm2022/user-avatar/lib/user-avatar.component.mjs +69 -0
  204. package/esm2022/user-avatar/lib/user-avatar.module.mjs +24 -0
  205. package/esm2022/user-avatar/yuuvis-client-framework-user-avatar.mjs +5 -0
  206. package/esm2022/yuuvis-client-framework.mjs +5 -0
  207. package/fesm2022/yuuvis-client-framework-actions.mjs +333 -0
  208. package/fesm2022/yuuvis-client-framework-actions.mjs.map +1 -0
  209. package/fesm2022/yuuvis-client-framework-app-bar.mjs +96 -0
  210. package/fesm2022/yuuvis-client-framework-app-bar.mjs.map +1 -0
  211. package/fesm2022/yuuvis-client-framework-clipboard.mjs +55 -0
  212. package/fesm2022/yuuvis-client-framework-clipboard.mjs.map +1 -0
  213. package/fesm2022/yuuvis-client-framework-common.mjs +1020 -0
  214. package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -0
  215. package/fesm2022/yuuvis-client-framework-forms.mjs +1355 -0
  216. package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -0
  217. package/fesm2022/yuuvis-client-framework-icons.mjs +123 -0
  218. package/fesm2022/yuuvis-client-framework-icons.mjs.map +1 -0
  219. package/fesm2022/yuuvis-client-framework-list.mjs +209 -0
  220. package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -0
  221. package/fesm2022/yuuvis-client-framework-metadata-form.mjs +302 -0
  222. package/fesm2022/yuuvis-client-framework-metadata-form.mjs.map +1 -0
  223. package/fesm2022/yuuvis-client-framework-object-details.mjs +583 -0
  224. package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -0
  225. package/fesm2022/yuuvis-client-framework-object-flavor.mjs +200 -0
  226. package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -0
  227. package/fesm2022/yuuvis-client-framework-object-form.mjs +1664 -0
  228. package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -0
  229. package/fesm2022/yuuvis-client-framework-object-preview.mjs +213 -0
  230. package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -0
  231. package/fesm2022/yuuvis-client-framework-object-summary.mjs +397 -0
  232. package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -0
  233. package/fesm2022/yuuvis-client-framework-pagination.mjs +55 -0
  234. package/fesm2022/yuuvis-client-framework-pagination.mjs.map +1 -0
  235. package/fesm2022/yuuvis-client-framework-panel.mjs +27 -0
  236. package/fesm2022/yuuvis-client-framework-panel.mjs.map +1 -0
  237. package/fesm2022/yuuvis-client-framework-renderer.mjs +262 -0
  238. package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -0
  239. package/fesm2022/yuuvis-client-framework-sequence-list.mjs +519 -0
  240. package/fesm2022/yuuvis-client-framework-sequence-list.mjs.map +1 -0
  241. package/fesm2022/yuuvis-client-framework-simple-search.mjs +118 -0
  242. package/fesm2022/yuuvis-client-framework-simple-search.mjs.map +1 -0
  243. package/fesm2022/yuuvis-client-framework-tile-list.mjs +1036 -0
  244. package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -0
  245. package/fesm2022/yuuvis-client-framework-token-search.mjs +85 -0
  246. package/fesm2022/yuuvis-client-framework-token-search.mjs.map +1 -0
  247. package/fesm2022/yuuvis-client-framework-tree.mjs +307 -0
  248. package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -0
  249. package/fesm2022/yuuvis-client-framework-upload-progress.mjs +84 -0
  250. package/fesm2022/yuuvis-client-framework-upload-progress.mjs.map +1 -0
  251. package/fesm2022/yuuvis-client-framework-user-avatar.mjs +96 -0
  252. package/fesm2022/yuuvis-client-framework-user-avatar.mjs.map +1 -0
  253. package/fesm2022/yuuvis-client-framework.mjs +22 -0
  254. package/fesm2022/yuuvis-client-framework.mjs.map +1 -0
  255. package/forms/README.md +3 -0
  256. package/forms/index.d.ts +9 -0
  257. package/forms/lib/elements/catalog/catalog.component.d.ts +68 -0
  258. package/forms/lib/elements/datetime/datetime.component.d.ts +32 -0
  259. package/forms/lib/elements/datetime-range/datetime-range.component.d.ts +51 -0
  260. package/forms/lib/elements/number/number.component.d.ts +77 -0
  261. package/forms/lib/elements/number-range/number-range.component.d.ts +66 -0
  262. package/forms/lib/elements/organization/organization.component.d.ts +93 -0
  263. package/forms/lib/elements/string/string.component.d.ts +104 -0
  264. package/forms/lib/form-input/form-input.component.d.ts +48 -0
  265. package/forms/lib/forms.module.d.ts +16 -0
  266. package/icons/README.md +5 -0
  267. package/icons/index.d.ts +3 -0
  268. package/icons/lib/icon.service.d.ts +38 -0
  269. package/icons/lib/icons.d.ts +1 -0
  270. package/icons/lib/object-type-icon/object-type-icon.component.d.ts +11 -0
  271. package/index.d.ts +1 -0
  272. package/lib/yuuvis-client-framework.module.d.ts +7 -0
  273. package/list/README.md +3 -0
  274. package/list/index.d.ts +2 -0
  275. package/list/lib/list-item.directive.d.ts +15 -0
  276. package/list/lib/list.component.d.ts +36 -0
  277. package/metadata-form/README.md +21 -0
  278. package/metadata-form/index.d.ts +3 -0
  279. package/metadata-form/lib/metadata-default-templates/metadata-default-templates.component.d.ts +5 -0
  280. package/metadata-form/lib/metadata-form-element-registry.service.d.ts +47 -0
  281. package/metadata-form/lib/metadata-form-field/metadata-form-field.component.d.ts +31 -0
  282. package/metadata-form/lib/object-metadata-element-template.directive.d.ts +27 -0
  283. package/object-details/README.md +28 -0
  284. package/object-details/index.d.ts +6 -0
  285. package/object-details/lib/object-audit/object-audit.component.d.ts +59 -0
  286. package/object-details/lib/object-details-shell/object-details-shell.component.d.ts +51 -0
  287. package/object-details/lib/object-details.component.d.ts +36 -0
  288. package/object-details/lib/object-metadata/form-section-group.pipe.d.ts +8 -0
  289. package/object-details/lib/object-metadata/object-metadata.component.d.ts +48 -0
  290. package/object-details/lib/object-metadata/object-metadata.interface.d.ts +26 -0
  291. package/object-flavor/README.md +3 -0
  292. package/object-flavor/index.d.ts +5 -0
  293. package/object-flavor/lib/abstract-apply-create-flavor/abstract-apply-create-flavor.component.d.ts +12 -0
  294. package/object-flavor/lib/abstract-apply-object-flavor/abstract-apply-object-flavor.component.d.ts +12 -0
  295. package/object-flavor/lib/flavor-chip/flavor-chip.component.d.ts +17 -0
  296. package/object-flavor/lib/object-flavor/object-flavor.component.d.ts +26 -0
  297. package/object-flavor/lib/object-flavor-picker/object-flavor-picker.component.d.ts +10 -0
  298. package/object-form/README.md +3 -0
  299. package/object-form/index.d.ts +4 -0
  300. package/object-form/lib/form-scripting.api.interface.d.ts +131 -0
  301. package/object-form/lib/form-scripting.service.d.ts +30 -0
  302. package/object-form/lib/object-form-element/object-form-element.component.d.ts +22 -0
  303. package/object-form/lib/object-form-extension.interface.d.ts +22 -0
  304. package/object-form/lib/object-form-group/object-form-group.component.d.ts +22 -0
  305. package/object-form/lib/object-form-script/form-scripting-element-extension/form-scripting-element-extension.component.d.ts +10 -0
  306. package/object-form/lib/object-form-script/object-form-script.service.d.ts +45 -0
  307. package/object-form/lib/object-form-script/object-form-scripting-scope.d.ts +50 -0
  308. package/object-form/lib/object-form-translate.service.d.ts +15 -0
  309. package/object-form/lib/object-form.component.d.ts +60 -0
  310. package/object-form/lib/object-form.interface.d.ts +113 -0
  311. package/object-form/lib/object-form.model.d.ts +18 -0
  312. package/object-form/lib/object-form.service.d.ts +39 -0
  313. package/object-form/lib/object-form.utils.d.ts +20 -0
  314. package/object-form/lib/object-form.validation.d.ts +21 -0
  315. package/object-preview/README.md +3 -0
  316. package/object-preview/index.d.ts +2 -0
  317. package/object-preview/lib/components/index.d.ts +2 -0
  318. package/object-preview/lib/components/object-email-preview/object-email-preview.component.d.ts +16 -0
  319. package/object-preview/lib/components/object-preview/object-preview.component.d.ts +13 -0
  320. package/object-preview/lib/services/object-preview.service.d.ts +37 -0
  321. package/object-summary/README.md +3 -0
  322. package/object-summary/index.d.ts +4 -0
  323. package/object-summary/lib/multi-object-summary/multi-object-summary.component.d.ts +7 -0
  324. package/object-summary/lib/object-summary/object-summary.component.d.ts +73 -0
  325. package/object-summary/lib/object-summary-data/object-summary-data.component.d.ts +11 -0
  326. package/object-summary/lib/object-summary.module.d.ts +7 -0
  327. package/package.json +173 -0
  328. package/pagination/README.md +3 -0
  329. package/pagination/index.d.ts +2 -0
  330. package/pagination/lib/pagination.component.d.ts +18 -0
  331. package/pagination/lib/pagination.interface.d.ts +5 -0
  332. package/panel/README.md +3 -0
  333. package/panel/index.d.ts +1 -0
  334. package/panel/lib/panel.component.d.ts +12 -0
  335. package/renderer/README.md +5 -0
  336. package/renderer/index.d.ts +10 -0
  337. package/renderer/lib/property-renderer/abstract.renderer.d.ts +14 -0
  338. package/renderer/lib/property-renderer/datetime.renderer.d.ts +6 -0
  339. package/renderer/lib/property-renderer/decimal.renderer.component.d.ts +6 -0
  340. package/renderer/lib/property-renderer/filesize.renderer.component.d.ts +7 -0
  341. package/renderer/lib/property-renderer/icon.renderer.component.d.ts +6 -0
  342. package/renderer/lib/property-renderer/integer.renderer.component.d.ts +6 -0
  343. package/renderer/lib/property-renderer/organization.renderer.d.ts +7 -0
  344. package/renderer/lib/property-renderer/string.renderer.component.d.ts +6 -0
  345. package/renderer/lib/property-renderer/unknown.renderer.d.ts +6 -0
  346. package/renderer/lib/renderer.directive.d.ts +17 -0
  347. package/renderer/lib/services/renderer/renderer.interface.d.ts +8 -0
  348. package/renderer/lib/services/renderer/renderer.service.d.ts +35 -0
  349. package/sequence-list/README.md +3 -0
  350. package/sequence-list/index.d.ts +5 -0
  351. package/sequence-list/lib/due-date-picker/due-date-picker.component.d.ts +28 -0
  352. package/sequence-list/lib/sequence-list-template-manage/sequence-list-template-manage.component.d.ts +52 -0
  353. package/sequence-list/lib/sequence-list-templates/sequence-list-templates.component.d.ts +36 -0
  354. package/sequence-list/lib/sequence-list.component.d.ts +43 -0
  355. package/sequence-list/lib/sequence-list.interface.d.ts +16 -0
  356. package/simple-search/README.md +3 -0
  357. package/simple-search/index.d.ts +2 -0
  358. package/simple-search/lib/simple-search/simple-search.component.d.ts +55 -0
  359. package/simple-search/lib/simple-search/simple-search.interface.d.ts +4 -0
  360. package/styles/client-framework.scss +27 -0
  361. package/tile-list/README.md +3 -0
  362. package/tile-list/index.d.ts +10 -0
  363. package/tile-list/lib/tile/tile.component.d.ts +22 -0
  364. package/tile-list/lib/tile-config/action-select/action-select.component.d.ts +13 -0
  365. package/tile-list/lib/tile-config/icon-select/icon-select.component.d.ts +11 -0
  366. package/tile-list/lib/tile-config/property-select/property-select.component.d.ts +25 -0
  367. package/tile-list/lib/tile-config/tile-config-tile/tile-config-tile.component.d.ts +20 -0
  368. package/tile-list/lib/tile-config/tile-config-trigger/tile-config-trigger.component.d.ts +17 -0
  369. package/tile-list/lib/tile-config/tile-config.component.d.ts +47 -0
  370. package/tile-list/lib/tile-extension/directive/tile-extension.directive.d.ts +11 -0
  371. package/tile-list/lib/tile-extension/extensions/email.extension.d.ts +10 -0
  372. package/tile-list/lib/tile-extension/tile-extension.service.d.ts +16 -0
  373. package/tile-list/lib/tile-list/tile-list.component.d.ts +116 -0
  374. package/tile-list/lib/tile-list/tile-list.interface.d.ts +18 -0
  375. package/token-search/README.md +3 -0
  376. package/token-search/index.d.ts +2 -0
  377. package/token-search/token-search.component.d.ts +22 -0
  378. package/token-search/token-search.interface.d.ts +4 -0
  379. package/tree/README.md +3 -0
  380. package/tree/index.d.ts +2 -0
  381. package/tree/lib/tree-node/tree-node.component.d.ts +21 -0
  382. package/tree/lib/tree.component.d.ts +53 -0
  383. package/tree/lib/tree.interface.d.ts +11 -0
  384. package/tree/lib/tree.service.d.ts +35 -0
  385. package/upload-progress/README.md +3 -0
  386. package/upload-progress/index.d.ts +1 -0
  387. package/upload-progress/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.d.ts +17 -0
  388. package/upload-progress/lib/upload-progress/upload-progress.component.d.ts +16 -0
  389. package/user-avatar/README.md +3 -0
  390. package/user-avatar/index.d.ts +2 -0
  391. package/user-avatar/lib/user-avatar.component.d.ts +44 -0
  392. package/user-avatar/lib/user-avatar.module.d.ts +8 -0
@@ -0,0 +1,627 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectorRef, Component, effect, ElementRef, inject, input, output, ViewEncapsulation } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { ReactiveFormsModule, Validators } from '@angular/forms';
5
+ import { Situation, SystemService, UserService, Utils } from '@yuuvis/client-core';
6
+ import { debounceTime, of } from 'rxjs';
7
+ import { FormScriptingApiService } from './form-scripting.service';
8
+ import { ObjectFormGroupComponent } from './object-form-group/object-form-group.component';
9
+ import { ObjectFormScriptService } from './object-form-script/object-form-script.service';
10
+ import { ObjectFormScriptingScope } from './object-form-script/object-form-scripting-scope';
11
+ import { ObjectFormControlWrapper } from './object-form.interface';
12
+ import { ObjectFormControl, ObjectFormGroup } from './object-form.model';
13
+ import { ObjectFormService } from './object-form.service';
14
+ import { ObjectFormUtils } from './object-form.utils';
15
+ import { FormValidation } from './object-form.validation';
16
+ import * as i0 from "@angular/core";
17
+ import * as i1 from "@angular/forms";
18
+ export class ObjectFormComponent {
19
+ #elementRef;
20
+ #systemService;
21
+ #formScriptService;
22
+ #formHelperService;
23
+ #userService;
24
+ #cdRef;
25
+ #formScriptingApiService;
26
+ #skipTranslationsFor;
27
+ #namePrefix;
28
+ #formOptionsEffect;
29
+ #elementExtensionsEffect;
30
+ #scriptModel;
31
+ #scriptingScope;
32
+ #subscriptions;
33
+ // local store for all the form control references
34
+ #formControls;
35
+ #initialValidators;
36
+ constructor() {
37
+ this.#elementRef = inject(ElementRef);
38
+ this.#systemService = inject(SystemService);
39
+ this.#formScriptService = inject(ObjectFormScriptService);
40
+ this.#formHelperService = inject(ObjectFormService);
41
+ this.#userService = inject(UserService);
42
+ this.#cdRef = inject(ChangeDetectorRef);
43
+ this.#formScriptingApiService = inject(FormScriptingApiService);
44
+ this.#skipTranslationsFor = ['core', 'data'];
45
+ this.#namePrefix = 'fg_';
46
+ this.gCount = 0;
47
+ this.id = Utils.uuid();
48
+ this.formOptions = input();
49
+ this.#formOptionsEffect = effect(() => {
50
+ this.#init(this.formOptions());
51
+ });
52
+ this.inert = input();
53
+ this.elementExtensions = input([]);
54
+ this.#elementExtensionsEffect = effect(() => {
55
+ this.#formHelperService.setElementExtensions(this.elementExtensions());
56
+ });
57
+ /**
58
+ * There are special scenarios where forms are within a form themselves.
59
+ * Setting this property to true, will handle the current form in a
60
+ * slightly different way when it comes to form scripting.
61
+ */
62
+ this.isInnerTableForm = input();
63
+ /**
64
+ * triggered when the forms state has been changed
65
+ */
66
+ this.statusChanged = output();
67
+ /**
68
+ * handler to be executed after the form has been set up
69
+ */
70
+ this.onFormReady = output();
71
+ this.#scriptModel = {};
72
+ this.#subscriptions = [];
73
+ // local store for all the form control references
74
+ this.#formControls = {};
75
+ this.#initialValidators = {};
76
+ /**
77
+ * This method will be called each time the script changes its internal model.
78
+ * It is used to transfer the script changes to the actual form model.
79
+ *
80
+ * To ensure the right context, we define an instance method as callback for the scripting scope
81
+ * @see: https://blog.johnnyreilly.com/2014/04/typescript-instance-methods.html
82
+ *
83
+ * @param formControlName
84
+ * @param change
85
+ */
86
+ this.#onScriptingModelChanged = (formControlName, change, formId) => {
87
+ if (!this.form || (formId && this.id !== formId))
88
+ return;
89
+ // find the target control
90
+ const fc = this.#formControls[formControlName];
91
+ if (fc) {
92
+ // change only allowed properties
93
+ switch (change.name) {
94
+ case 'value': {
95
+ if (Array.isArray(change.newValue)) {
96
+ this.#processArrayValueChange(fc, change);
97
+ }
98
+ else {
99
+ fc._eoFormElement.value = change.newValue;
100
+ if (fc.value !== change.newValue) {
101
+ fc.patchValue(change.newValue);
102
+ fc.updateValueAndValidity();
103
+ fc.markAsDirty();
104
+ }
105
+ }
106
+ this.form.markAsDirty();
107
+ break;
108
+ }
109
+ case 'required': {
110
+ fc._eoFormElement.required = change.newValue;
111
+ // apply new validators
112
+ // @see: https://scotch.io/tutorials/how-to-implement-conditional-validation-in-angular-2-model-driven-forms
113
+ fc.setValidators(Validators.compose(this.#getValidators(fc._eoFormElement).concat([this.#initialValidators[fc._eoFormElement.name]])));
114
+ // need to mark form control as touched because otherwise form validation will not show
115
+ // error messages
116
+ fc.markAsTouched();
117
+ fc.updateValueAndValidity();
118
+ break;
119
+ }
120
+ case 'readonly': {
121
+ fc._eoFormElement.readonly = change.newValue;
122
+ if (change.newValue === true) {
123
+ fc.disable();
124
+ }
125
+ else {
126
+ fc.enable();
127
+ }
128
+ break;
129
+ }
130
+ case 'error': {
131
+ fc._eoFormElement.error = change.newValue;
132
+ fc.markAsTouched();
133
+ fc.updateValueAndValidity();
134
+ break;
135
+ }
136
+ // new onrowedit function was applied by the script
137
+ case 'onrowedit': {
138
+ fc._eoFormElement.onrowedit = change.newValue;
139
+ break;
140
+ }
141
+ // new onchange function was applied by the script
142
+ case 'onchange': {
143
+ fc._eoFormElement.onchange = change.newValue;
144
+ break;
145
+ }
146
+ }
147
+ this.#cdRef.detectChanges();
148
+ }
149
+ };
150
+ this.#formScriptingApiService.formId = this.id;
151
+ this.#formScriptingApiService.api.events
152
+ .on(FormScriptingApiService.EVENT_MODEL_CHANGED)
153
+ .pipe(takeUntilDestroyed())
154
+ .subscribe((event) => event.data && this.#onScriptingModelChanged(event.data.formControlName, event.data.change, event.data.formId));
155
+ this.#formScriptingApiService.formId = this.id;
156
+ }
157
+ // initialize the form based on the provided form options
158
+ #init(fo) {
159
+ this.form = undefined;
160
+ if (!fo)
161
+ return;
162
+ setTimeout(() => {
163
+ this.#initialValidators = {};
164
+ this.unsubscribeAll();
165
+ this.#buildReactiveForm(fo);
166
+ }, 0);
167
+ }
168
+ #initScriptingScope(formOptions, dataFormModel) {
169
+ const { data, actions, objects, context } = (formOptions || {});
170
+ if (this.#scriptingScope) {
171
+ this.#scriptingScope.setModel(this.#scriptModel);
172
+ /** provide access to actions (used inside of BPM-Forms) */
173
+ this.#scriptingScope.actions = actions;
174
+ /** provide access to additional objects (used for example in BPM-Start-Forms to
175
+ * add data of DMS-Objects to start the process for)
176
+ */
177
+ this.#scriptingScope.objects = objects || [];
178
+ this.#scriptingScope.context = context || { id: '', title: '', objectTypeId: '' };
179
+ /** provide readonly access to initial form data (which may also contain values that
180
+ * are not rendered as form elements (invisible values))
181
+ */
182
+ this.#scriptingScope.data = data;
183
+ /** by default, scripting scopes are applied to forms. But table elements create their own scope
184
+ * for editing rows. Being one of those inner forms should not run the form script again, but
185
+ * instead just provide the observing abilities of the scripting scope.
186
+ */
187
+ if (!this.isInnerTableForm() && dataFormModel) {
188
+ const scriptName = dataFormModel.name + '_' + dataFormModel.situation;
189
+ console.debug('executing form script ' + scriptName);
190
+ this.#formScriptService.runFormScript(this.#scriptingScope, dataFormModel.script, scriptName);
191
+ }
192
+ }
193
+ }
194
+ focusForm() {
195
+ this.#elementRef.nativeElement.querySelector('input').focus();
196
+ }
197
+ getGroup(id) {
198
+ return this.form?.get(id);
199
+ }
200
+ setFormData(data) {
201
+ const fo = this.formOptions();
202
+ if (!fo)
203
+ return;
204
+ fo.data = data;
205
+ setTimeout(() => this.#init(fo), 0);
206
+ }
207
+ patchValue(data) {
208
+ Object.keys(data).forEach((key) => {
209
+ this.#onScriptingModelChanged(key, {
210
+ name: 'value',
211
+ newValue: data[key]
212
+ });
213
+ });
214
+ }
215
+ /**
216
+ * Extracts the values from the form model. Each form value is represented by one
217
+ * property on the result object holding the fields value. The keys (properties) are the `name`
218
+ * properties of the form element.
219
+ *
220
+ * How values are extracted is influenced by the forms situation.
221
+ *
222
+ * @return object of key value pairs
223
+ */
224
+ getFormData() {
225
+ return this.#formToData();
226
+ }
227
+ getFormElements() {
228
+ const formElements = {};
229
+ Object.keys(this.#formControls).forEach((k) => {
230
+ formElements[k] = this.#formControls[k].__eoFormElement;
231
+ });
232
+ return formElements;
233
+ }
234
+ setFormPristine() {
235
+ if (!this.form)
236
+ return;
237
+ this.form.markAsPristine();
238
+ }
239
+ // reset the form to its initial state
240
+ resetForm() {
241
+ const fo = this.formOptions();
242
+ if (!fo)
243
+ return;
244
+ this.setFormData(fo.data);
245
+ this.#emitFormChangedEvent();
246
+ }
247
+ /**
248
+ * Returns the observed model that was passed to the current form script running. If there is
249
+ * no form script, this method will return NULL.
250
+ * @returns
251
+ */
252
+ getObservedScriptModel() {
253
+ return this.#scriptingScope ? this.#scriptingScope.getModel() : null;
254
+ }
255
+ // Create a reactive form from the enaio form model
256
+ #buildReactiveForm(formOptions) {
257
+ this.#scriptingScope = undefined;
258
+ this.#scriptModel = {};
259
+ this.#formControls = {};
260
+ const formModel = this.#dataToForm(formOptions.formModel, formOptions.data);
261
+ if (!formModel) {
262
+ return;
263
+ }
264
+ // if a script is available, we'll init the form scripting for the
265
+ // current form
266
+ if (this.isInnerTableForm() || (formModel.script && formModel.script.length > 0)) {
267
+ console.debug('adding form scripting scope');
268
+ this.#scriptingScope = new ObjectFormScriptingScope(formModel.situation, this.#onScriptingModelChanged, this.#formScriptingApiService.getApi(), this.isInnerTableForm());
269
+ this.#scriptingScope.objectId = this.formOptions().objectId;
270
+ }
271
+ const form = new ObjectFormGroup({});
272
+ if (formModel?.elements[0]?.elements) {
273
+ this.#addFormControl(form, formModel.elements[0], 'core');
274
+ }
275
+ if (formModel?.elements[1]?.elements) {
276
+ this.#addFormControl(form, formModel.elements[1], 'data');
277
+ }
278
+ this.form = form;
279
+ this.#formScriptingApiService.registerActiveForm(this);
280
+ setTimeout(() => {
281
+ if (!this.form)
282
+ return;
283
+ this.initValidators(this.form);
284
+ this.#subscriptions.push(this.form.valueChanges.pipe(debounceTime(500)).subscribe(() => this.#emitFormChangedEvent()));
285
+ this.#initScriptingScope(formOptions, formModel);
286
+ this.onFormReady.emit();
287
+ this.#emitFormChangedEvent(false);
288
+ }, 300);
289
+ }
290
+ initValidators(form) {
291
+ if (this.form) {
292
+ for (const key of Object.keys(form.controls)) {
293
+ const control = form.controls[key];
294
+ if (control.controls) {
295
+ this.initValidators(control);
296
+ }
297
+ else {
298
+ this.#initialValidators[control._eoFormElement.name] = control.validator;
299
+ control.setValidators(Validators.compose(this.#getValidators(control._eoFormElement).concat([this.#initialValidators[control._eoFormElement.name]])));
300
+ control.updateValueAndValidity();
301
+ }
302
+ }
303
+ }
304
+ }
305
+ #emitFormChangedEvent(compare = true) {
306
+ // check if indexdata has been changed
307
+ const currentFormData = this.getFormData();
308
+ const idxChange = compare ? JSON.stringify(this.formData) !== JSON.stringify(currentFormData) : false;
309
+ this.formData = currentFormData;
310
+ if (this.form) {
311
+ this.statusChanged.emit({
312
+ invalid: this.form.invalid,
313
+ dirty: this.form.dirty,
314
+ data: this.formData,
315
+ indexdataChanged: idxChange
316
+ });
317
+ }
318
+ }
319
+ /**
320
+ * This method will be called each time the script changes its internal model.
321
+ * It is used to transfer the script changes to the actual form model.
322
+ *
323
+ * To ensure the right context, we define an instance method as callback for the scripting scope
324
+ * @see: https://blog.johnnyreilly.com/2014/04/typescript-instance-methods.html
325
+ *
326
+ * @param formControlName
327
+ * @param change
328
+ */
329
+ #onScriptingModelChanged;
330
+ #processArrayValueChange(fc, change) {
331
+ const newVal = change.newValue;
332
+ const targetType = fc._eoFormElement.type;
333
+ // for some types we have to ensure that meta data are provided as well
334
+ switch (targetType) {
335
+ case 'ORGANIZATION': {
336
+ this.#getDataMeta(fc._eoFormElement, newVal).subscribe((m) => {
337
+ fc._eoFormElement.dataMeta = m;
338
+ });
339
+ break;
340
+ }
341
+ case 'TABLE': {
342
+ const dataToBeProcessed = {};
343
+ fc._eoFormElement.elements.forEach((e) => {
344
+ if (e.type === 'ORGANIZATION' || e.type === 'CODESYSTEM') {
345
+ dataToBeProcessed[e.name] = e;
346
+ }
347
+ });
348
+ if (Object.keys(dataToBeProcessed).length) {
349
+ newVal.forEach((rowData) => {
350
+ Object.keys(rowData).forEach((key) => {
351
+ if (dataToBeProcessed[key]) {
352
+ this.#getDataMeta(dataToBeProcessed[key], rowData[key]).subscribe((m) => {
353
+ if (m) {
354
+ rowData[key + '_meta'] = m;
355
+ }
356
+ else {
357
+ delete rowData[key + '_meta'];
358
+ }
359
+ this.#updateArrayValue(fc, newVal);
360
+ });
361
+ }
362
+ });
363
+ });
364
+ }
365
+ break;
366
+ }
367
+ }
368
+ this.#updateArrayValue(fc, newVal);
369
+ }
370
+ #updateArrayValue(fc, newValue) {
371
+ fc._eoFormElement.value = [].concat(newValue);
372
+ fc.patchValue([].concat(newValue));
373
+ fc.updateValueAndValidity();
374
+ fc.markAsDirty();
375
+ }
376
+ #getDataMeta(formElement, newValue) {
377
+ if (newValue) {
378
+ switch (formElement.type) {
379
+ case 'ORGANIZATION': {
380
+ return this.#userService.getUserById(newValue);
381
+ }
382
+ }
383
+ }
384
+ return of(null);
385
+ }
386
+ #patchFormValue(formValue) {
387
+ let value;
388
+ if (Array.isArray(formValue)) {
389
+ value = [];
390
+ // copy by value for arrays of objects (e.g. table data)
391
+ formValue.forEach((o) => value.push(JSON.parse(JSON.stringify(o))));
392
+ }
393
+ else {
394
+ value = formValue;
395
+ }
396
+ return value;
397
+ }
398
+ /**
399
+ * Recursive method adding a new FormControl (group or control) to a parent form group
400
+ *
401
+ * @param parentGroup - the parent group to add the control to
402
+ * @param formElement - the enaio form model element to create the child control from
403
+ * @param [useName] - use this name instead of the one from the model
404
+ */
405
+ #addFormControl(parentGroup, formElement, useName) {
406
+ const fo = this.formOptions();
407
+ if (!fo)
408
+ return;
409
+ let ctrl;
410
+ let name;
411
+ // add a form group
412
+ if (formElement.type === 'o2mGroup' || formElement.type === 'o2mGroupStack') {
413
+ // do not add groups that are empty
414
+ const isRootGroup = formElement.name && (formElement.name !== 'data' || formElement.name !== 'core');
415
+ if (!isRootGroup && (!formElement.elements || formElement.elements.length === 0)) {
416
+ console.error('Found empty form group', formElement);
417
+ return;
418
+ }
419
+ ctrl = new ObjectFormGroup({});
420
+ ctrl._eoFormGroup = {
421
+ layout: formElement.layout,
422
+ type: formElement.type
423
+ };
424
+ if (formElement.name) {
425
+ if (this.#skipTranslationsFor.includes(formElement.name)) {
426
+ ctrl._eoFormGroup.label = formElement.name;
427
+ }
428
+ else if (!formElement.label) {
429
+ // no label, so try to translate the technical name
430
+ ctrl._eoFormGroup.label = this.#systemService.getLocalizedResource(`${formElement.name}_label`) || formElement.name;
431
+ }
432
+ else {
433
+ // there is a label so we take this one
434
+ ctrl._eoFormGroup.label = formElement.label;
435
+ }
436
+ }
437
+ if (useName === 'core' || useName === 'data') {
438
+ ctrl._eoFormGroup.label = useName;
439
+ }
440
+ for (const e of formElement.elements) {
441
+ this.#addFormControl(ctrl, e);
442
+ }
443
+ name = useName || 'fg' + this.gCount++;
444
+ }
445
+ else {
446
+ // add form control
447
+ // To be able to integrate recursive form controls into the main form,
448
+ // we have to wrap them in a form group
449
+ ctrl = new ObjectFormControlWrapper({});
450
+ ctrl._eoFormControlWrapper = {
451
+ // the name of the wrapped FormControl
452
+ controlName: formElement.name,
453
+ situation: fo.formModel.situation
454
+ };
455
+ // do not set a reference as the form controls value
456
+ // otherwise we could not reset the form
457
+ const value = formElement?.value
458
+ ? this.#patchFormValue(formElement?.value)
459
+ : !Utils.isEmpty(formElement?.defaultvalue) && fo.formModel.situation === Situation.CREATE
460
+ ? this.#patchFormValue(formElement?.defaultvalue)
461
+ : formElement?.value;
462
+ // create the actual form control
463
+ const controlDisabled = fo.disabled || !!formElement.readonly;
464
+ const formControl = new ObjectFormControl({
465
+ value,
466
+ disabled: controlDisabled
467
+ });
468
+ // if form element has a 'label' property it will be shown as is ...
469
+ if (!formElement.label) {
470
+ // ... if there is no label but a 'labelKey' property we are going to localize that key ...
471
+ if (formElement.labelkey) {
472
+ formElement.label = this.#systemService.getLocalizedResource(`${formElement.labelkey}_label`) || formElement.labelkey;
473
+ formElement.description = this.#systemService.getLocalizedResource(`${formElement.labelkey}_description`);
474
+ }
475
+ else {
476
+ // ... no 'label' and also no 'labelKey' means that we are showing technical name instead
477
+ formElement.label = formElement.name;
478
+ }
479
+ }
480
+ formElement.readonly = controlDisabled;
481
+ // we are using an internal type to distinguish between the components
482
+ // to be used to render certain form elements
483
+ formElement._internalType = this.#systemService.getInternalFormElementType(formElement.type, formElement.classifications);
484
+ formControl._eoFormElement = formElement;
485
+ this.#formControls[formElement.name] = formControl;
486
+ if (formElement.type === 'TABLE') {
487
+ // Add 'onrowedit' property even if it's not set.
488
+ // This is required because otherwise mobX-Observer would not recognize
489
+ // changes to this property applied by the form script
490
+ if (!Object.keys(formControl._eoFormElement).includes('onrowedit')) {
491
+ formControl._eoFormElement.onrowedit = null;
492
+ }
493
+ if (this.#scriptingScope && formControl._eoFormElement.value) {
494
+ // having a scripting scope and table rows means that we need to set empty
495
+ // columns to NULL, because otherwise mobX won't be able to track those values
496
+ const valueFields = formControl._eoFormElement.elements.map((e) => e.name);
497
+ formControl._eoFormElement.value.forEach((rowValue) => {
498
+ valueFields.forEach((valueField) => {
499
+ if (!Object.keys(rowValue).includes(valueField)) {
500
+ rowValue[valueField] = null;
501
+ }
502
+ });
503
+ });
504
+ // update form controls value as well to reflect the observed value
505
+ formControl.patchValue(formControl._eoFormElement.value, {
506
+ onlySelf: true,
507
+ emitEvent: false,
508
+ emitModelToViewChange: false,
509
+ emitViewToModelChange: false
510
+ });
511
+ }
512
+ }
513
+ if (formElement._internalType === 'string:organization') {
514
+ formControl._eoFormElement.setFilter = (filterObject) => {
515
+ formControl._eoFormElement.filter = filterObject;
516
+ };
517
+ }
518
+ ObjectFormUtils.updateFormElement(formElement);
519
+ // remove empty descriptions
520
+ const desc = formControl._eoFormElement.description;
521
+ if (desc && desc.trim().length === 0) {
522
+ formControl._eoFormElement.description = null;
523
+ }
524
+ // add the form element to the script model that will be injected into
525
+ // the forms scripting scope later on
526
+ this.#scriptModel[formElement.name] = formControl._eoFormElement;
527
+ // apply change listener to the form control, that will trigger
528
+ // the form elements onChange listener
529
+ const controlWatch = ctrl.valueChanges.pipe(debounceTime(500));
530
+ this.#subscriptions.push(controlWatch.subscribe((v) => {
531
+ if (this.#scriptingScope) {
532
+ this.#scriptingScope.modelChanged(v);
533
+ }
534
+ }));
535
+ ctrl.addControl(formElement.name, formControl);
536
+ name = this.#namePrefix + formElement.name;
537
+ }
538
+ parentGroup.addControl(name, ctrl);
539
+ }
540
+ /**
541
+ * Build validators for the given form element to be attached to
542
+ * a reactive formControl.
543
+ *
544
+ * @param formElement - form element object
545
+ */
546
+ #getValidators(formElement) {
547
+ const fo = this.formOptions();
548
+ const elmValidators = FormValidation.getValidators(formElement, fo?.formModel.situation);
549
+ // add custom validator for script enabled forms
550
+ if (this.#scriptingScope) {
551
+ elmValidators.push(FormValidation.customScriptingValidation);
552
+ }
553
+ return elmValidators;
554
+ }
555
+ /**
556
+ * Extract the values from the form
557
+ */
558
+ #formToData() {
559
+ const fo = this.formOptions();
560
+ return fo && this.form ? this.#formHelperService.extractFormData(this.form, fo.formModel.situation, fo.data, this.isInnerTableForm()) : {};
561
+ }
562
+ /**
563
+ * Merge data into a form model.
564
+ *
565
+ * @param model - form model
566
+ * @param data - data object or array of SearchFilter objects in case of a search form
567
+ */
568
+ #dataToForm(model, data) {
569
+ if (model && data) {
570
+ this.#setElementValues(model.elements, data);
571
+ }
572
+ return model;
573
+ }
574
+ // recursive method for adding values to model elements
575
+ #setElementValues(elements, data) {
576
+ elements?.forEach((element) => {
577
+ if (this.#hasValue(data, element)) {
578
+ element.value = this.#getValue(data, element);
579
+ }
580
+ else {
581
+ delete element.value;
582
+ }
583
+ if (element.type !== 'TABLE' && element.elements && element.elements.length > 0) {
584
+ this.#setElementValues(element.elements, data);
585
+ }
586
+ });
587
+ }
588
+ #hasValue(data, element) {
589
+ // differ between array of SearchFilters and a form data object
590
+ if (Array.isArray(data)) {
591
+ return !!data.find((filter) => filter.property === element.id);
592
+ }
593
+ else {
594
+ return Object.keys(data).includes(element.name);
595
+ }
596
+ }
597
+ #getValue(data, element) {
598
+ return data[element.name];
599
+ }
600
+ ngOnDestroy() {
601
+ this.unsubscribeAll();
602
+ this.#formScriptingApiService.unregisterActiveForm(this);
603
+ }
604
+ ngAfterViewInit() {
605
+ this.#cdRef.detectChanges();
606
+ }
607
+ // unsubscribe from all value change listeners for the current form
608
+ // to avoid memory leaks. This method will also be called every time
609
+ // a new form is rendered to get rid of the old form element subscriptions
610
+ unsubscribeAll() {
611
+ if (this.#subscriptions.length) {
612
+ console.debug('unsubscribed from ' + this.#subscriptions.length + ' value change listeners.');
613
+ this.#subscriptions.forEach((s) => s.unsubscribe());
614
+ this.#subscriptions = [];
615
+ }
616
+ }
617
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
618
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ObjectFormComponent, isStandalone: true, selector: "yuv-object-form", inputs: { formOptions: { classPropertyName: "formOptions", publicName: "formOptions", isSignal: true, isRequired: false, transformFunction: null }, inert: { classPropertyName: "inert", publicName: "inert", isSignal: true, isRequired: false, transformFunction: null }, elementExtensions: { classPropertyName: "elementExtensions", publicName: "elementExtensions", isSignal: true, isRequired: false, transformFunction: null }, isInnerTableForm: { classPropertyName: "isInnerTableForm", publicName: "isInnerTableForm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { statusChanged: "statusChanged", onFormReady: "onFormReady" }, host: { properties: { "attr.inert": "inert() ? true : null" }, classAttribute: "yuv-object-form" }, providers: [ObjectFormService, ObjectFormScriptService, FormScriptingApiService], ngImport: i0, template: "@let fo = formOptions();\n@if (fo && form) {\n <div class=\"yuv-object-form\" [formGroup]=\"form\">\n <div class=\"form-element-wrap core\">\n <yuv-object-form-group [group]=\"getGroup('core')\" [situation]=\"fo.formModel.situation\"></yuv-object-form-group>\n </div>\n <div class=\"form-element-wrap data\">\n <yuv-object-form-group [group]=\"getGroup('data')\" [situation]=\"fo.formModel.situation\"></yuv-object-form-group>\n </div>\n </div>\n}\n", styles: [".yuv-object-form>.core{padding:calc(var(--app-pane-padding) / 2)}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack{background:transparent;border:0}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack>yuv-object-form-group>.o2mGroup{background-color:var(--panel-background-lightgrey);border-top:1px solid rgba(0,0,0,.1);padding:var(--app-pane-padding)}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack>p-tabview>.p-tabview>.p-tabview-panels{background-color:var(--panel-background-lightgrey)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ObjectFormGroupComponent, selector: "yuv-object-form-group", inputs: ["situation", "group", "noGroupLabels"] }], encapsulation: i0.ViewEncapsulation.None }); }
619
+ }
620
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectFormComponent, decorators: [{
621
+ type: Component,
622
+ args: [{ selector: 'yuv-object-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, ObjectFormGroupComponent], providers: [ObjectFormService, ObjectFormScriptService, FormScriptingApiService], encapsulation: ViewEncapsulation.None, host: {
623
+ class: 'yuv-object-form',
624
+ '[attr.inert]': 'inert() ? true : null'
625
+ }, template: "@let fo = formOptions();\n@if (fo && form) {\n <div class=\"yuv-object-form\" [formGroup]=\"form\">\n <div class=\"form-element-wrap core\">\n <yuv-object-form-group [group]=\"getGroup('core')\" [situation]=\"fo.formModel.situation\"></yuv-object-form-group>\n </div>\n <div class=\"form-element-wrap data\">\n <yuv-object-form-group [group]=\"getGroup('data')\" [situation]=\"fo.formModel.situation\"></yuv-object-form-group>\n </div>\n </div>\n}\n", styles: [".yuv-object-form>.core{padding:calc(var(--app-pane-padding) / 2)}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack{background:transparent;border:0}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack>yuv-object-form-group>.o2mGroup{background-color:var(--panel-background-lightgrey);border-top:1px solid rgba(0,0,0,.1);padding:var(--app-pane-padding)}.yuv-object-form>.data>yuv-object-form-group>.form-element.o2mGroupStack>p-tabview>.p-tabview>.p-tabview-panels{background-color:var(--panel-background-lightgrey)}\n"] }]
626
+ }], ctorParameters: () => [] });
627
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LWZvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy95dXV2aXMvY2xpZW50LWZyYW1ld29yay9vYmplY3QtZm9ybS9zcmMvbGliL29iamVjdC1mb3JtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMveXV1dmlzL2NsaWVudC1mcmFtZXdvcmsvb2JqZWN0LWZvcm0vc3JjL2xpYi9vYmplY3QtZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFpQixpQkFBaUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNySixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQWUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25GLE9BQU8sRUFBRSxZQUFZLEVBQWMsRUFBRSxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUNsRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVuRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUMzRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUMxRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUM1RixPQUFPLEVBQTBCLHdCQUF3QixFQUE0QyxNQUFNLHlCQUF5QixD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QUFjLEVBQUUsdUJBQXVCO3FCQUN4QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBlZmZlY3QsIEVsZW1lbnRSZWYsIGluamVjdCwgaW5wdXQsIE9uRGVzdHJveSwgb3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTaXR1YXRpb24sIFN5c3RlbVNlcnZpY2UsIFVzZXJTZXJ2aWNlLCBVdGlscyB9IGZyb20gJ0B5dXV2aXMvY2xpZW50LWNvcmUnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBPYnNlcnZhYmxlLCBvZiwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBGb3JtU2NyaXB0aW5nQXBpU2VydmljZSB9IGZyb20gJy4vZm9ybS1zY3JpcHRpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBJT2JqZWN0Rm9ybUVsZW1lbnRFeHRlbnNpb24gfSBmcm9tICcuL29iamVjdC1mb3JtLWV4dGVuc2lvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgT2JqZWN0Rm9ybUdyb3VwQ29tcG9uZW50IH0gZnJvbSAnLi9vYmplY3QtZm9ybS1ncm91cC9vYmplY3QtZm9ybS1ncm91cC5jb21wb25lbnQnO1xuaW1wb3J0IHsgT2JqZWN0Rm9ybVNjcmlwdFNlcnZpY2UgfSBmcm9tICcuL29iamVjdC1mb3JtLXNjcmlwdC9vYmplY3QtZm9ybS1zY3JpcHQuc2VydmljZSc7XG5pbXBvcnQgeyBPYmplY3RGb3JtU2NyaXB0aW5nU2NvcGUgfSBmcm9tICcuL29iamVjdC1mb3JtLXNjcmlwdC9vYmplY3QtZm9ybS1zY3JpcHRpbmctc2NvcGUnO1xuaW1wb3J0IHsgRm9ybVN0YXR1c0NoYW5nZWRFdmVudCwgT2JqZWN0Rm9ybUNvbnRyb2xXcmFwcGVyLCBPYmplY3RGb3JtTW9kZWxDaGFuZ2UsIE9iamVjdEZvcm1PcHRpb25zIH0gZnJvbSAnLi9vYmplY3QtZm9ybS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgT2JqZWN0Rm9ybUNvbnRyb2wsIE9iamVjdEZvcm1Hcm91cCB9IGZyb20gJy4vb2JqZWN0LWZvcm0ubW9kZWwnO1xuaW1wb3J0IHsgT2JqZWN0Rm9ybVNlcnZpY2UgfSBmcm9tICcuL29iamVjdC1mb3JtLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JqZWN0Rm9ybVV0aWxzIH0gZnJvbSAnLi9vYmplY3QtZm9ybS51dGlscyc7XG5pbXBvcnQgeyBGb3JtVmFsaWRhdGlvbiB9IGZyb20gJy4vb2JqZWN0LWZvcm0udmFsaWRhdGlvbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3l1di1vYmplY3QtZm9ybScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIE9iamVjdEZvcm1Hcm91cENvbXBvbmVudF0sXG4gIHByb3ZpZGVyczogW09iamVjdEZvcm1TZXJ2aWNlLCBPYmplY3RGb3JtU2NyaXB0U2VydmljZSwgRm9ybVNjcmlwdGluZ0FwaVNlcnZpY2VdLFxuICB0ZW1wbGF0ZVVybDogJy4vb2JqZWN0LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vb2JqZWN0LWZvcm0uY29tcG9uZW50LnNjc3MnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICd5dXYtb2JqZWN0LWZvcm0nLFxuICAgICdbYXR0ci5pbmVydF0nOiAnaW5lcnQoKSA/IHRydWUgOiBudWxsJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE9iamVjdEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICAjZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgI3N5c3RlbVNlcnZpY2UgPSBpbmplY3QoU3lzdGVtU2VydmljZSk7XG4gICNmb3JtU2NyaXB0U2VydmljZSA9IGluamVjdChPYmplY3RGb3JtU2NyaXB0U2VydmljZSk7XG4gICNmb3JtSGVscGVyU2VydmljZSA9IGluamVjdChPYmplY3RGb3JtU2VydmljZSk7XG4gICN1c2VyU2VydmljZSA9IGluamVjdChVc2VyU2VydmljZSk7XG4gICNjZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gICNmb3JtU2NyaXB0aW5nQXBpU2VydmljZSA9IGluamVjdChGb3JtU2NyaXB0aW5nQXBpU2VydmljZSk7XG5cbiAgI3NraXBUcmFuc2xhdGlvbnNGb3IgPSBbJ2NvcmUnLCAnZGF0YSddO1xuICAjbmFtZVByZWZpeCA9ICdmZ18nO1xuICBnQ291bnQgPSAwO1xuXG4gIGlkID0gVXRpbHMudXVpZCgpO1xuXG4gIGZvPzogT2JqZWN0Rm9ybU9wdGlvbnM7XG4gIGZvcm1PcHRpb25zID0gaW5wdXQ8T2JqZWN0Rm9ybU9wdGlvbnM+KCk7XG4gICNmb3JtT3B0aW9uc0VmZmVjdCA9IGVmZmVjdCgoKSA9PiB7XG4gICAgdGhpcy4jaW5pdCh0aGlzLmZvcm1PcHRpb25zKCkpO1xuICB9KTtcblxuICBpbmVydCA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIGVsZW1lbnRFeHRlbnNpb25zID0gaW5wdXQ8SU9iamVjdEZvcm1FbGVtZW50RXh0ZW5zaW9uW10+KFtdKTtcbiAgI2VsZW1lbnRFeHRlbnNpb25zRWZmZWN0ID0gZWZmZWN0KCgpID0+IHtcbiAgICB0aGlzLiNmb3JtSGVscGVyU2VydmljZS5zZXRFbGVtZW50RXh0ZW5zaW9ucyh0aGlzLmVsZW1lbnRFeHRlbnNpb25zKCkpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlcmUgYXJlIHNwZWNpYWwgc2NlbmFyaW9zIHdoZXJlIGZvcm1zIGFyZSB3aXRoaW4gYSBmb3JtIHRoZW1zZWx2ZXMuXG4gICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSB0byB0cnVlLCB3aWxsIGhhbmRsZSB0aGUgY3VycmVudCBmb3JtIGluIGFcbiAgICogc2xpZ2h0bHkgZGlmZmVyZW50IHdheSB3aGVuIGl0IGNvbWVzIHRvIGZvcm0gc2NyaXB0aW5nLlxuICAgKi9cbiAgaXNJbm5lclRhYmxlRm9ybSA9IGlucHV0PGJvb2xlYW4+KCk7XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJlZCB3aGVuIHRoZSBmb3JtcyBzdGF0ZSBoYXMgYmVlbiBjaGFuZ2VkXG4gICAqL1xuICBzdGF0dXNDaGFuZ2VkID0gb3V0cHV0PEZvcm1TdGF0dXNDaGFuZ2VkRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIGhhbmRsZXIgdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIGZvcm0gaGFzIGJlZW4gc2V0IHVwXG4gICAqL1xuICBvbkZvcm1SZWFkeSA9IG91dHB1dCgpO1xuXG4gIC8vIHRoZSBhY3R1YWwgZm9ybSBpbnN0YW5jZVxuICBmb3JtPzogT2JqZWN0Rm9ybUdyb3VwO1xuICAvLyBwcm9wZXJ0eSBmb3IgaG9sZGluZyB0aGUgZm9ybXMgZGF0YSB1c2VkIGZvciBjb21wYXJpc29uIHdoZW4gYSBmb3JtLWNoYW5nZWQtZXZlbnRcbiAgLy8gaXMgZmV0Y2hlZCB0byBpbmRpY2F0ZSB3aGVyIG9yIG5vdCB0aGUgaW5kZXhkYXRhIHdlcmUgY2hhbmdlZCBvciBqdXN0IHRoZSBwcm9wZXJ0aWVzXG4gIC8vIG9mIHRoZSBmb3JtIGVsZW1lbnRzIChlZy4gZm9ybSBzY3JpcHQgc2V0dGluZyBmaWVsZHMgdG8gcmVhZG9ubHkpXG4gIGZvcm1EYXRhOiBhbnk7XG4gICNzY3JpcHRNb2RlbDogYW55ID0ge307XG4gICNzY3JpcHRpbmdTY29wZT86IE9iamVjdEZvcm1TY3JpcHRpbmdTY29wZTtcbiAgI3N1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgLy8gbG9jYWwgc3RvcmUgZm9yIGFsbCB0aGUgZm9ybSBjb250cm9sIHJlZmVyZW5jZXNcbiAgI2Zvcm1Db250cm9sczogYW55ID0ge307XG4gICNpbml0aWFsVmFsaWRhdG9yczogYW55ID0ge307XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy4jZm9ybVNjcmlwdGluZ0FwaVNlcnZpY2UuZm9ybUlkID0gdGhpcy5pZDtcbiAgICB0aGlzLiNmb3JtU2NyaXB0aW5nQXBpU2VydmljZS5hcGkuZXZlbnRzXG4gICAgICAub24oRm9ybVNjcmlwdGluZ0FwaVNlcnZpY2UuRVZFTlRfTU9ERUxfQ0hBTkdFRClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoZXZlbnQpID0+IGV2ZW50LmRhdGEgJiYgdGhpcy4jb25TY3JpcHRpbmdNb2RlbENoYW5nZWQoZXZlbnQuZGF0YS5mb3JtQ29udHJvbE5hbWUsIGV2ZW50LmRhdGEuY2hhbmdlLCBldmVudC5kYXRhLmZvcm1JZCkpO1xuXG4gICAgdGhpcy4jZm9ybVNjcmlwdGluZ0FwaVNlcnZpY2UuZm9ybUlkID0gdGhpcy5pZDsgICAgXG4gIH1cblxuICAvLyBpbml0aWFsaXplIHRoZSBmb3JtIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBmb3JtIG9wdGlvbnNcbiAgI2luaXQoZm86IE9iamVjdEZvcm1PcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5mb3JtID0gdW5kZWZpbmVkO1xuICAgIGlmICghZm8pIHJldHVybjtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuI2luaXRpYWxWYWxpZGF0b3JzID0ge307XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlQWxsKCk7XG4gICAgICB0aGlzLiNidWlsZFJlYWN0aXZlRm9ybShmbyk7XG4gICAgfSwgMCk7XG4gIH1cblxuICAjaW5pdFNjcmlwdGluZ1Njb3BlKGZvcm1PcHRpb25zOiBPYmplY3RGb3JtT3B0aW9ucywgZGF0YUZvcm1Nb2RlbDogYW55KSB7XG4gICAgY29uc3QgeyBkYXRhLCBhY3Rpb25zLCBvYmplY3RzLCBjb250ZXh0IH0gPSAoZm9ybU9wdGlvbnMgfHwge30pIGFzIE9iamVjdEZvcm1PcHRpb25zO1xuXG4gICAgaWYgKHRoaXMuI3NjcmlwdGluZ1Njb3BlKSB7XG4gICAgICB0aGlzLiNzY3JpcHRpbmdTY29wZS5zZXRNb2RlbCh0aGlzLiNzY3JpcHRNb2RlbCk7XG4gICAgICAvKiogcHJvdmlkZSBhY2Nlc3MgdG8gYWN0aW9ucyAodXNlZCBpbnNpZGUgb2YgQlBNLUZvcm1zKSAqL1xuICAgICAgdGhpcy4jc2NyaXB0aW5nU2NvcGUuYWN0aW9ucyA9IGFjdGlvbnM7XG4gICAgICAvKiogcHJvdmlkZSBhY2Nlc3MgdG8gYWRkaXRpb25hbCBvYmplY3RzICh1c2VkIGZvciBleGFtcGxlIGluIEJQTS1TdGFydC1Gb3JtcyB0b1xuICAgICAgICogYWRkIGRhdGEgb2YgRE1TLU9iamVjdHMgdG8gc3RhcnQgdGhlIHByb2Nlc3MgZm9yKVxuICAgICAgICovXG4gICAgICB0aGlzLiNzY3JpcHRpbmdTY29wZS5vYmplY3RzID0gb2JqZWN0cyB8fCBbXTtcbiAgICAgIHRoaXMuI3NjcmlwdGluZ1Njb3BlLmNvbnRleHQgPSBjb250ZXh0IHx8IHsgaWQ6ICcnLCB0aXRsZTogJycsIG9iamVjdFR5cGVJZDogJycgfTtcbiAgICAgIC8qKiBwcm92aWRlIHJlYWRvbmx5IGFjY2VzcyB0byBpbml0aWFsIGZvcm0gZGF0YSAod2hpY2ggbWF5IGFsc28gY29udGFpbiB2YWx1ZXMgdGhhdFxuICAgICAgICogYXJlIG5vdCByZW5kZXJlZCBhcyBmb3JtIGVsZW1lbnRzIChpbnZpc2libGUgdmFsdWVzKSlcbiAgICAgICAqL1xuICAgICAgdGhpcy4jc2NyaXB0aW5nU2NvcGUuZGF0YSA9IGRhdGE7XG5cbiAgICAgIC8qKiBieSBkZWZhdWx0LCBzY3JpcHRpbmcgc2NvcGVzIGFyZSBhcHBsaWVkIHRvIGZvcm1zLiBCdXQgdGFibGUgZWxlbWVudHMgY3JlYXRlIHRoZWlyIG93biBzY29wZVxuICAgICAgICogZm9yIGVkaXRpbmcgcm93cy4gQmVpbmcgb25lIG9mIHRob3NlIGlubmVyIGZvcm1zIHNob3VsZCBub3QgcnVuIHRoZSBmb3JtIHNjcmlwdCBhZ2FpbiwgYnV0XG4gICAgICAgKiBpbnN0ZWFkIGp1c3QgcHJvdmlkZSB0aGUgb2JzZXJ2aW5nIGFiaWxpdGllcyBvZiB0aGUgc2NyaXB0aW5nIHNjb3BlLlxuICAgICAgICovXG4gICAgICBpZiAoIXRoaXMuaXNJbm5lclRhYmxlRm9ybSgpICYmIGRhdGFGb3JtTW9kZWwpIHtcbiAgICAgICAgY29uc3Qgc2NyaXB0TmFtZSA9IGRhdGFGb3JtTW9kZWwubmFtZSArICdfJyArIGRhdGFGb3JtTW9kZWwuc2l0dWF0aW9uO1xuICAgICAgICBjb25zb2xlLmRlYnVnKCdleGVjdXRpbmcgZm9ybSBzY3JpcHQgJyArIHNjcmlwdE5hbWUpO1xuICAgICAgICB0aGlzLiNmb3JtU2NyaXB0U2VydmljZS5ydW5Gb3JtU2NyaXB0KHRoaXMuI3NjcmlwdGluZ1Njb3BlLCBkYXRhRm9ybU1vZGVsLnNjcmlwdCwgc2NyaXB0TmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9jdXNGb3JtKCkge1xuICAgIHRoaXMuI2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpLmZvY3VzKCk7XG4gIH1cblxuICBnZXRHcm91cChpZDogc3RyaW5nKTogT2JqZWN0Rm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtPy5nZXQoaWQpIGFzIE9iamVjdEZvcm1Hcm91cDtcbiAgfVxuXG4gIHNldEZvcm1EYXRhKGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgY29uc3QgZm8gPSB0aGlzLmZvcm1PcHRpb25zKCk7XG4gICAgaWYgKCFmbykgcmV0dXJuO1xuICAgIGZvLmRhdGEgPSBkYXRhO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy4jaW5pdChmbyksIDApO1xuICB9XG5cbiAgcGF0Y2hWYWx1ZShkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5rZXlzKGRhdGEpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgdGhpcy4jb25TY3JpcHRpbmdNb2RlbENoYW5nZWQoa2V5LCB7XG4gICAgICAgIG5hbWU6ICd2YWx1ZScsXG4gICAgICAgIG5ld1ZhbHVlOiBkYXRhW2tleV1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIHRoZSB2YWx1ZXMgZnJvbSB0aGUgZm9ybSBtb2RlbC4gRWFjaCBmb3JtIHZhbHVlIGlzIHJlcHJlc2VudGVkIGJ5IG9uZVxuICAgKiBwcm9wZXJ0eSBvbiB0aGUgcmVzdWx0IG9iamVjdCBob2xkaW5nIHRoZSBmaWVsZHMgdmFsdWUuIFRoZSBrZXlzIChwcm9wZXJ0aWVzKSBhcmUgdGhlIGBuYW1lYFxuICAgKiBwcm9wZXJ0aWVzIG9mIHRoZSBmb3JtIGVsZW1lbnQuXG4gICAqXG4gICAqIEhvdyB2YWx1ZXMgYXJlIGV4dHJhY3RlZCBpcyBpbmZsdWVuY2VkIGJ5IHRoZSBmb3JtcyBzaXR1YXRpb24uXG4gICAqXG4gICAqIEByZXR1cm4gb2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlyc1xuICAgKi9cbiAgZ2V0Rm9ybURhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2Zvcm1Ub0RhdGEoKTtcbiAgfVxuXG4gIGdldEZvcm1FbGVtZW50cygpIHtcbiAgICBjb25zdCBmb3JtRWxlbWVudHM6IGFueSA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHRoaXMuI2Zvcm1Db250cm9scykuZm9yRWFjaCgoaykgPT4ge1xuICAgICAgZm9ybUVsZW1lbnRzW2tdID0gdGhpcy4jZm9ybUNvbnRyb2xzW2tdLl9fZW9Gb3JtRWxlbWVudDtcbiAgICB9KTtcbiAgICByZXR1cm4gZm9ybUVsZW1lbnRzO1xuICB9XG5cbiAgc2V0Rm9ybVByaXN0aW5lKCkge1xuICAgIGlmICghdGhpcy5mb3JtKSByZXR1cm47XG4gICAgdGhpcy5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gIH1cblxuICAvLyByZXNldCB0aGUgZm9ybSB0byBpdHMgaW5pdGlhbCBzdGF0ZVxuICByZXNldEZvcm0oKSB7XG4gICAgY29uc3QgZm8gPSB0aGlzLmZvcm1PcHRpb25zKCk7XG4gICAgaWYgKCFmbykgcmV0dXJuO1xuICAgIHRoaXMuc2V0Rm9ybURhdGEoZm8uZGF0YSk7XG4gICAgdGhpcy4jZW1pdEZvcm1DaGFuZ2VkRXZlbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBvYnNlcnZlZCBtb2RlbCB0aGF0IHdhcyBwYXNzZWQgdG8gdGhlIGN1cnJlbnQgZm9ybSBzY3JpcHQgcnVubmluZy4gSWYgdGhlcmUgaXNcbiAgICogbm8gZm9ybSBzY3JpcHQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIE5VTEwuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBnZXRPYnNlcnZlZFNjcmlwdE1vZGVsKCkge1xuICAgIHJldHVybiB0aGlzLiNzY3JpcHRpbmdTY29wZSA/IHRoaXMuI3NjcmlwdGluZ1Njb3BlLmdldE1vZGVsKCkgOiBudWxsO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgcmVhY3RpdmUgZm9ybSBmcm9tIHRoZSBlbmFpbyBmb3JtIG1vZGVsXG4gICNidWlsZFJlYWN0aXZlRm9ybShmb3JtT3B0aW9uczogT2JqZWN0Rm9ybU9wdGlvbnMpIHtcbiAgICB0aGlzLiNzY3JpcHRpbmdTY29wZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLiNzY3JpcHRNb2RlbCA9IHt9O1xuICAgIHRoaXMuI2Zvcm1Db250cm9scyA9IHt9O1xuICAgIGNvbnN0IGZvcm1Nb2RlbCA9IHRoaXMuI2RhdGFUb0Zvcm0oZm9ybU9wdGlvbnMuZm9ybU1vZGVsLCBmb3JtT3B0aW9ucy5kYXRhKTtcblxuICAgIGlmICghZm9ybU1vZGVsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGlmIGEgc2NyaXB0IGlzIGF2YWlsYWJsZSwgd2UnbGwgaW5pdCB0aGUgZm9ybSBzY3JpcHRpbmcgZm9yIHRoZVxuICAgIC8vIGN1cnJlbnQgZm9ybVxuICAgIGlmICh0aGlzLmlzSW5uZXJUYWJsZUZvcm0oKSB8fCAoZm9ybU1vZGVsLnNjcmlwdCAmJiBmb3JtTW9kZWwuc2NyaXB0Lmxlbmd0aCA+IDApKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKCdhZGRpbmcgZm9ybSBzY3JpcHRpbmcgc2NvcGUnKTtcbiAgICAgIHRoaXMuI3NjcmlwdGluZ1Njb3BlID0gbmV3IE9iamVjdEZvcm1TY3JpcHRpbmdTY29wZShcbiAgICAgICAgZm9ybU1vZGVsLnNpdHVhdGlvbixcbiAgICAgICAgdGhpcy4jb25TY3JpcHRpbmdNb2RlbENoYW5nZWQsXG4gICAgICAgIHRoaXMuI2Zvcm1TY3JpcHRpbmdBcGlTZXJ2aWNlLmdldEFwaSgpLFxuICAgICAgICB0aGlzLmlzSW5uZXJUYWJsZUZvcm0oKVxuICAgICAgKTtcbiAgICAgIHRoaXMuI3NjcmlwdGluZ1Njb3BlLm9iamVjdElkID0gdGhpcy5mb3JtT3B0aW9ucygpIS5vYmplY3RJZDtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtID0gbmV3IE9iamVjdEZvcm1Hcm91cCh7fSk7XG4gICAgaWYgKGZvcm1Nb2RlbD8uZWxlbWVudHNbMF0/LmVsZW1lbnRzKSB7XG4gICAgICB0aGlzLiNhZGRGb3JtQ29udHJvbChmb3JtLCBmb3JtTW9kZWwuZWxlbWVudHNbMF0sICdjb3JlJyk7XG4gICAgfVxuICAgIGlmIChmb3JtTW9kZWw/LmVsZW1lbnRzWzFdPy5lbGVtZW50cykge1xuICAgICAgdGhpcy4jYWRkRm9ybUNvbnRyb2woZm9ybSwgZm9ybU1vZGVsLmVsZW1lbnRzWzFdLCAnZGF0YScpO1xuICAgIH1cbiAgICB0aGlzLmZvcm0gPSBmb3JtO1xuICAgIHRoaXMuI2Zvcm1TY3JpcHRpbmdBcGlTZXJ2aWNlLnJlZ2lzdGVyQWN0aXZlRm9ybSh0aGlzKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmZvcm0pIHJldHVybjtcbiAgICAgIHRoaXMuaW5pdFZhbGlkYXRvcnModGhpcy5mb3JtKTtcbiAgICAgIHRoaXMuI3N1YnNjcmlwdGlvbnMucHVzaCh0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKDUwMCkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLiNlbWl0Rm9ybUNoYW5nZWRFdmVudCgpKSk7XG5cbiAgICAgIHRoaXMuI2luaXRTY3JpcHRpbmdTY29wZShmb3JtT3B0aW9ucywgZm9ybU1vZGVsKTtcblxuICAgICAgdGhpcy5vbkZvcm1SZWFkeS5lbWl0KCk7XG4gICAgICB0aGlzLiNlbWl0Rm9ybUNoYW5nZWRFdmVudChmYWxzZSk7XG4gICAgfSwgMzAwKTtcbiAgfVxuXG4gIGluaXRWYWxpZGF0b3JzKGZvcm06IGFueSkge1xuICAgIGlmICh0aGlzLmZvcm0pIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGZvcm0uY29udHJvbHMpKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtLmNvbnRyb2xzW2tleV07XG4gICAgICAgIGlmIChjb250cm9sLmNvbnRyb2xzKSB7XG4gICAgICAgICAgdGhpcy5pbml0VmFsaWRhdG9ycyhjb250cm9sKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLiNpbml0aWFsVmFsaWRhdG9yc1tjb250cm9sLl9lb0Zvcm1FbGVtZW50Lm5hbWVdID0gY29udHJvbC52YWxpZGF0b3I7XG4gICAgICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKFZhbGlkYXRvcnMuY29tcG9zZSh0aGlzLiNnZXRWYWxpZGF0b3JzKGNvbnRyb2wuX2VvRm9ybUVsZW1lbnQpLmNvbmNhdChbdGhpcy4jaW5pdGlhbFZhbGlkYXRvcnNbY29udHJvbC5fZW9Gb3JtRWxlbWVudC5uYW1lXV0pKSk7XG4gICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAjZW1pdEZvcm1DaGFuZ2VkRXZlbnQoY29tcGFyZSA9IHRydWUpIHtcbiAgICAvLyBjaGVjayBpZiBpbmRleGRhdGEgaGFzIGJlZW4gY2hhbmdlZFxuICAgIGNvbnN0IGN1cnJlbnRGb3JtRGF0YSA9IHRoaXMuZ2V0Rm9ybURhdGEoKTtcbiAgICBjb25zdCBpZHhDaGFuZ2UgPSBjb21wYXJlID8gSlNPTi5zdHJpbmdpZnkodGhpcy5mb3JtRGF0YSkgIT09IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRGb3JtRGF0YSkgOiBmYWxzZTtcbiAgICB0aGlzLmZvcm1EYXRhID0gY3VycmVudEZvcm1EYXRhO1xuICAgIGlmICh0aGlzLmZvcm0pIHtcbiAgICAgIHRoaXMuc3RhdHVzQ2hhbmdlZC5lbWl0KHtcbiAgICAgICAgaW52YWxpZDogdGhpcy5mb3JtLmludmFsaWQsXG4gICAgICAgIGRpcnR5OiB0aGlzLmZvcm0uZGlydHksXG4gICAgICAgIGRhdGE6IHRoaXMuZm9ybURhdGEsXG4gICAgICAgIGluZGV4ZGF0YUNoYW5nZWQ6IGlkeENoYW5nZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGVhY2ggdGltZSB0aGUgc2NyaXB0IGNoYW5nZXMgaXRzIGludGVybmFsIG1vZGVsLlxuICAgKiBJdCBpcyB1c2VkIHRvIHRyYW5zZmVyIHRoZSBzY3JpcHQgY2hhbmdlcyB0byB0aGUgYWN0dWFsIGZvcm0gbW9kZWwuXG4gICAqXG4gICAqIFRvIGVuc3VyZSB0aGUgcmlnaHQgY29udGV4dCwgd2UgZGVmaW5lIGFuIGluc3RhbmNlIG1ldGhvZCBhcyBjYWxsYmFjayBmb3IgdGhlIHNjcmlwdGluZyBzY29wZVxuICAgKiBAc2VlOiBodHRwczovL2Jsb2cuam9obm55cmVpbGx5LmNvbS8yMDE0LzA0L3R5cGVzY3JpcHQtaW5zdGFuY2UtbWV0aG9kcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBmb3JtQ29udHJvbE5hbWVcbiAgICogQHBhcmFtIGNoYW5nZVxuICAgKi9cbiAgI29uU2NyaXB0aW5nTW9kZWxDaGFuZ2VkID0gKGZvcm1Db250cm9sTmFtZTogc3RyaW5nLCBjaGFuZ2U6IE9iamVjdEZvcm1Nb2RlbENoYW5nZSwgZm9ybUlkPzogc3RyaW5nKSA9PiB7XG4gICAgaWYgKCF0aGlzLmZvcm0gfHwgKGZvcm1JZCAmJiB0aGlzLmlkICE9PSBmb3JtSWQpKSByZXR1cm47XG4gICAgLy8gZmluZCB0aGUgdGFyZ2V0IGNvbnRyb2xcbiAgICBjb25zdCBmYzogT2JqZWN0Rm9ybUNvbnRyb2wgPSB0aGlzLiNmb3JtQ29udHJvbHNbZm9ybUNvbnRyb2xOYW1lXSBhcyBPYmplY3RGb3JtQ29udHJvbDtcbiAgICBpZiAoZmMpIHtcbiAgICAgIC8vIGNoYW5nZSBvbmx5IGFsbG93ZWQgcHJvcGVydGllc1xuICAgICAgc3dpdGNoIChjaGFuZ2UubmFtZSkge1xuICAgICAgICBjYXNlICd2YWx1ZSc6IHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjaGFuZ2UubmV3VmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLiNwcm9jZXNzQXJyYXlWYWx1ZUNoYW5nZShmYywgY2hhbmdlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmMuX2VvRm9ybUVsZW1lbnQudmFsdWUgPSBjaGFuZ2UubmV3VmFsdWU7XG4gICAgICAgICAgICBpZiAoZmMudmFsdWUgIT09IGNoYW5nZS5uZXdWYWx1ZSkge1xuICAgICAgICAgICAgICBmYy5wYXRjaFZhbHVlKGNoYW5nZS5uZXdWYWx1ZSk7XG4gICAgICAgICAgICAgIGZjLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgICAgICAgZmMubWFya0FzRGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAncmVxdWlyZWQnOiB7XG4gICAgICAgICAgZmMuX2VvRm9ybUVsZW1lbnQucmVxdWlyZWQgPSBjaGFuZ2UubmV3VmFsdWU7XG4gICAgICAgICAgLy8gYXBwbHkgbmV3IHZhbGlkYXRvcnNcbiAgICAgICAgICAvLyBAc2VlOiBodHRwczovL3Njb3RjaC5pby90dXRvcmlhbHMvaG93LXRvLWltcGxlbWVudC1jb25kaXRpb25hbC12YWxpZGF0aW9uLWluLWFuZ3VsYXItMi1tb2RlbC1kcml2ZW4tZm9ybXNcbiAgICAgICAgICBmYy5zZXRWYWxpZGF0b3JzKFZhbGlkYXRvcnMuY29tcG9zZSh0aGlzLiNnZXRWYWxpZGF0b3JzKGZjLl9lb0Zvcm1FbGVtZW50KS5jb25jYXQoW3RoaXMuI2luaXRpYWxWYWxpZGF0b3JzW2ZjLl9lb0Zvcm1FbGVtZW50Lm5hbWVdXSkpKTtcbiAgICAgICAgICAvLyBuZWVkIHRvIG1hcmsgZm9ybSBjb250cm9sIGFzIHRvdWNoZWQgYmVjYXVzZSBvdGhlcndpc2UgZm9ybSB2YWxpZGF0aW9uIHdpbGwgbm90IHNob3dcbiAgICAgICAgICAvLyBlcnJvciBtZXNzYWdlc1xuICAgICAgICAgIGZjLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICBmYy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAncmVhZG9ubHknOiB7XG4gICAgICAgICAgZmMuX2VvRm9ybUVsZW1lbnQucmVhZG9ubHkgPSBjaGFuZ2UubmV3VmFsdWU7XG4gICAgICAgICAgaWYgKGNoYW5nZS5uZXdWYWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgZmMuZGlzYWJsZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmYy5lbmFibGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnZXJyb3InOiB7XG4gICAgICAgICAgZmMuX2VvRm9ybUVsZW1lbnQuZXJyb3IgPSBjaGFuZ2UubmV3VmFsdWU7XG4gICAgICAgICAgZmMubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICAgIGZjLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBuZXcgb25yb3dlZGl0IGZ1bmN0aW9uIHdhcyBhcHBsaWVkIGJ5IHRoZSBzY3JpcHRcbiAgICAgICAgY2FzZSAnb25yb3dlZGl0Jzoge1xuICAgICAgICAgIGZjLl9lb0Zvcm1FbGVtZW50Lm9ucm93ZWRpdCA9IGNoYW5nZS5uZXdWYWx1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBuZXcgb25jaGFuZ2UgZnVuY3Rpb24gd2FzIGFwcGxpZWQgYnkgdGhlIHNjcmlwdFxuICAgICAgICBjYXNlICdvbmNoYW5nZSc6IHtcbiAgICAgICAgICBmYy5fZW9Gb3JtRWxlbWVudC5vbmNoYW5nZSA9IGNoYW5nZS5uZXdWYWx1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy4jY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfTtcblxuICAjcHJvY2Vzc0FycmF5VmFsdWVDaGFuZ2UoZmM6IGFueSwgY2hhbmdlOiBhbnkpIHtcbiAgICBjb25zdCBuZXdWYWwgPSBjaGFuZ2UubmV3VmFsdWU7XG4gICAgY29uc3QgdGFyZ2V0VHlwZSA9IGZjLl9lb0Zvcm1FbGVtZW50LnR5cGU7XG4gICAgLy8gZm9yIHNvbWUgdHlwZXMgd2UgaGF2ZSB0byBlbnN1cmUgdGhhdCBtZXRhIGRhdGEgYXJlIHByb3ZpZGVkIGFzIHdlbGxcbiAgICBzd2l0Y2ggKHRhcmdldFR5cGUpIHtcbiAgICAgIGNhc2UgJ09SR0FOSVpBVElPTic6IHtcbiAgICAgICAgdGhpcy4jZ2V0RGF0YU1ldGEoZmMuX2VvRm9ybUVsZW1lbnQsIG5ld1ZhbCkuc3Vic2NyaWJlKChtKSA9PiB7XG4gICAgICAgICAgZmMuX2VvRm9ybUVsZW1lbnQuZGF0YU1ldGEgPSBtO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdUQUJMRSc6IHtcbiAgICAgICAgY29uc3QgZGF0YVRvQmVQcm9jZXNzZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgICAgIGZjLl9lb0Zvcm1FbGVtZW50LmVsZW1lbnRzLmZvckVhY2goKGU6IGFueSkgPT4ge1xuICAgICAgICAgIGlmIChlLnR5cGUgPT09ICdPUkdBTklaQVRJT04nIHx8IGUudHlwZSA9PT0gJ0NPREVTWVNURU0nKSB7XG4gICAgICAgICAgICBkYXRhVG9CZVByb2Nlc3NlZFtlLm5hbWVdID0gZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMoZGF0YVRvQmVQcm9jZXNzZWQpLmxlbmd0aCkge1xuICAgICAgICAgIG5ld1ZhbC5mb3JFYWNoKChyb3dEYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHJvd0RhdGEpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoZGF0YVRvQmVQcm9jZXNzZWRba2V5XSkge1xuICAgICAgICAgICAgICAgIHRoaXMuI2dldERhdGFNZXRhKGRhdGFUb0JlUHJvY2Vzc2VkW2tleV0sIHJvd0RhdGFba2V5XSkuc3Vic2NyaWJlKChtKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgICAgICAgICByb3dEYXRhW2tleSArICdfbWV0YSddID0gbTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByb3dEYXRhW2tleSArICdfbWV0YSddO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgdGhpcy4jdXBkYXRlQXJyYXlWYWx1ZShmYywgbmV3VmFsKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuI3VwZGF0ZUFycmF5VmFsdWUoZmMsIG5ld1ZhbCk7XG4gIH1cblxuICAjdXBkYXRlQXJyYXlWYWx1ZShmYzogYW55LCBuZXdWYWx1ZTogYW55KSB7XG4gICAgZmMuX2VvRm9ybUVsZW1lbnQudmFsdWUgPSBbXS5jb25jYXQobmV3VmFsdWUpO1xuICAgIGZjLnBhdGNoVmFsdWUoW10uY29uY2F0KG5ld1ZhbHVlKSk7XG4gICAgZmMudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIGZjLm1hcmtBc0RpcnR5KCk7XG4gIH1cblxuICAjZ2V0RGF0YU1ldGEoZm9ybUVsZW1lbnQ6IGFueSwgbmV3VmFsdWU6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgaWYgKG5ld1ZhbHVlKSB7XG4gICAgICBzd2l0Y2ggKGZvcm1FbGVtZW50LnR5cGUpIHtcbiAgICAgICAgY2FzZSAnT1JHQU5JWkFUSU9OJzoge1xuICAgICAgICAgIHJldHVybiB0aGlzLiN1c2VyU2VydmljZS5nZXRVc2VyQnlJZChuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9mKG51bGwpO1xuICB9XG5cbiAgI3BhdGNoRm9ybVZhbHVlKGZvcm1WYWx1ZTogc3RyaW5nW10gfCBzdHJpbmcpIHtcbiAgICBsZXQgdmFsdWU6IGFueTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShmb3JtVmFsdWUpKSB7XG4gICAgICB2YWx1ZSA9IFtdO1xuICAgICAgLy8gY29weSBieSB2YWx1ZSBmb3IgYXJyYXlzIG9mIG9iamVjdHMgKGUuZy4gdGFibGUgZGF0YSlcbiAgICAgIGZvcm1WYWx1ZS5mb3JFYWNoKChvKSA9PiB2YWx1ZS5wdXNoKEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gZm9ybVZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogUmVjdXJzaXZlIG1ldGhvZCBhZGRpbmcgYSBuZXcgRm9ybUNvbnRyb2wgKGdyb3VwIG9yIGNvbnRyb2wpIHRvIGEgcGFyZW50IGZvcm0gZ3JvdXBcbiAgICpcbiAgICogQHBhcmFtIHBhcmVudEdyb3VwIC0gdGhlIHBhcmVudCBncm91cCB0byBhZGQgdGhlIGNvbnRyb2wgdG9cbiAgICogQHBhcmFtIGZvcm1FbGVtZW50IC0gdGhlIGVuYWlvIGZvcm0gbW9kZWwgZWxlbWVudCB0byBjcmVhdGUgdGhlIGNoaWxkIGNvbnRyb2wgZnJvbVxuICAgKiBAcGFyYW0gW3VzZU5hbWVdIC0gdXNlIHRoaXMgbmFtZSBpbnN0ZWFkIG9mIHRoZSBvbmUgZnJvbSB0aGUgbW9kZWxcbiAgICovXG4gICNhZGRGb3JtQ29udHJvbChwYXJlbnRHcm91cDogT2JqZWN0Rm9ybUdyb3VwLCBmb3JtRWxlbWVudDogYW55LCB1c2VOYW1lPzogc3RyaW5nKSB7XG4gICAgY29uc3QgZm8gPSB0aGlzLmZvcm1PcHRpb25zKCk7XG4gICAgaWYgKCFmbykgcmV0dXJuO1xuXG4gICAgbGV0IGN0cmw7XG4gICAgbGV0IG5hbWU7XG5cbiAgICAvLyBhZGQgYSBmb3JtIGdyb3VwXG4gICAgaWYgKGZvcm1FbGVtZW50LnR5cGUgPT09ICdvMm1Hcm91cCcgfHwgZm9ybUVsZW1lbnQudHlwZSA9PT0gJ28ybUdyb3VwU3RhY2snKSB7XG4gICAgICAvLyBkbyBub3QgYWRkIGdyb3VwcyB0aGF0IGFyZSBlbXB0eVxuICAgICAgY29uc3QgaXNSb290R3JvdXAgPSBmb3JtRWxlbWVudC5uYW1lICYmIChmb3JtRWxlbWVudC5uYW1lICE9PSAnZGF0YScgfHwgZm9ybUVsZW1lbnQubmFtZSAhPT0gJ2NvcmUnKTtcbiAgICAgIGlmICghaXNSb290R3JvdXAgJiYgKCFmb3JtRWxlbWVudC5lbGVtZW50cyB8fCBmb3JtRWxlbWVudC5lbGVtZW50cy5sZW5ndGggPT09IDApKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZvdW5kIGVtcHR5IGZvcm0gZ3JvdXAnLCBmb3JtRWxlbWVudCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY3RybCA9IG5ldyBPYmplY3RGb3JtR3JvdXAoe30pO1xuICAgICAgY3RybC5fZW9Gb3JtR3JvdXAgPSB7XG4gICAgICAgIGxheW91dDogZm9ybUVsZW1lbnQubGF5b3V0LFxuICAgICAgICB0eXBlOiBmb3JtRWxlbWVudC50eXBlXG4gICAgICB9O1xuXG4gICAgICBpZiAoZm9ybUVsZW1lbnQubmFtZSkge1xuICAgICAgICBpZiAodGhpcy4jc2tpcFRyYW5zbGF0aW9uc0Zvci5pbmNsdWRlcyhmb3JtRWxlbWVudC5uYW1lKSkge1xuICAgICAgICAgIGN0cmwuX2VvRm9ybUdyb3VwLmxhYmVsID0gZm9ybUVsZW1lbnQubmFtZTtcbiAgICAgICAgfSBlbHNlIGlmICghZm9ybUVsZW1lbnQubGFiZWwpIHtcbiAgICAgICAgICAvLyBubyBsYWJlbCwgc28gdHJ5IHRvIHRyYW5zbGF0ZSB0aGUgdGVjaG5pY2FsIG5hbWVcbiAgICAgICAgICBjdHJsLl9lb0Zvcm1Hcm91cC5sYWJlbCA9IHRoaXMuI3N5c3RlbVNlcnZpY2UuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7Zm9ybUVsZW1lbnQubmFtZX1fbGFiZWxgKSB8fCBmb3JtRWxlbWVudC5uYW1lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHRoZXJlIGlzIGEgbGFiZWwgc28gd2UgdGFrZSB0aGlzIG9uZVxuICAgICAgICAgIGN0cmwuX2VvRm9ybUdyb3VwLmxhYmVsID0gZm9ybUVsZW1lbnQubGFiZWw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHVzZU5hbWUgPT09ICdjb3JlJyB8fCB1c2VOYW1lID09PSAnZGF0YScpIHtcbiAgICAgICAgY3RybC5fZW9Gb3JtR3JvdXAubGFiZWwgPSB1c2VOYW1lO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGUgb2YgZm9ybUVsZW1lbnQuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy4jYWRkRm9ybUNvbnRyb2woY3RybCwgZSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gdXNlTmFtZSB8fCAnZmcnICsgdGhpcy5nQ291bnQrKztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYWRkIGZvcm0gY29udHJvbFxuICAgICAgLy8gVG8gYmUgYWJsZSB0byBpbnRlZ3JhdGUgcmVjdXJzaXZlIGZvcm0gY29udHJvbHMgaW50byB0aGUgbWFpbiBmb3JtLFxuICAgICAgLy8gd2UgaGF2ZSB0byB3cmFwIHRoZW0gaW4gYSBmb3JtIGdyb3VwXG4gICAgICBjdHJsID0gbmV3IE9iamVjdEZvcm1Db250cm9sV3JhcHBlcih7fSk7XG4gICAgICBjdHJsLl9lb0Zvcm1Db250cm9sV3JhcHBlciA9IHtcbiAgICAgICAgLy8gdGhlIG5hbWUgb2YgdGhlIHdyYXBwZWQgRm9ybUNvbnRyb2xcbiAgICAgICAgY29udHJvbE5hbWU6IGZvcm1FbGVtZW50Lm5hbWUsXG4gICAgICAgIHNpdHVhdGlvbjogZm8uZm9ybU1vZGVsLnNpdHVhdGlvblxuICAgICAgfTtcblxuICAgICAgLy8gZG8gbm90IHNldCBhIHJlZmVyZW5jZSBhcyB0aGUgZm9ybSBjb250cm9scyB2YWx1ZVxuICAgICAgLy8gb3RoZXJ3aXNlIHdlIGNvdWxkIG5vdCByZXNldCB0aGUgZm9ybVxuICAgICAgY29uc3QgdmFsdWUgPSBmb3JtRWxlbWVudD8udmFsdWVcbiAgICAgICAgPyB0aGlzLiNwYXRjaEZvcm1WYWx1ZShmb3JtRWxlbWVudD8udmFsdWUpXG4gICAgICAgIDogIVV0aWxzLmlzRW1wdHkoZm9ybUVsZW1lbnQ/LmRlZmF1bHR2YWx1ZSkgJiYgZm8uZm9ybU1vZGVsLnNpdHVhdGlvbiA9PT0gU2l0dWF0aW9uLkNSRUFURVxuICAgICAgICAgID8gdGhpcy4jcGF0Y2hGb3JtVmFsdWUoZm9ybUVsZW1lbnQ/LmRlZmF1bHR2YWx1ZSlcbiAgICAgICAgICA6IGZvcm1FbGVtZW50Py52YWx1ZTtcblxuICAgICAgLy8gY3JlYXRlIHRoZSBhY3R1YWwgZm9ybSBjb250cm9sXG4gICAgICBjb25zdCBjb250cm9sRGlzYWJsZWQgPSBmby5kaXNhYmxlZCB8fCAhIWZvcm1FbGVtZW50LnJlYWRvbmx5O1xuICAgICAgY29uc3QgZm9ybUNvbnRyb2wgPSBuZXcgT2JqZWN0Rm9ybUNvbnRyb2woe1xuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZGlzYWJsZWQ6IGNvbnRyb2xEaXNhYmxlZFxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlmIGZvcm0gZWxlbWVudCBoYXMgYSAnbGFiZWwnIHByb3BlcnR5IGl0IHdpbGwgYmUgc2hvd24gYXMgaXMgLi4uXG4gICAgICBpZiAoIWZvcm1FbGVtZW50LmxhYmVsKSB7XG4gICAgICAgIC8vIC4uLiBpZiB0aGVyZSBpcyBubyBsYWJlbCBidXQgYSAnbGFiZWxLZXknIHByb3BlcnR5IHdlIGFyZSBnb2luZyB0byBsb2NhbGl6ZSB0aGF0IGtleSAuLi5cbiAgICAgICAgaWYgKGZvcm1FbGVtZW50LmxhYmVsa2V5KSB7XG4gICAgICAgICAgZm9ybUVsZW1lbnQubGFiZWwgPSB0aGlzLiNzeXN0ZW1TZXJ2aWNlLmdldExvY2FsaXplZFJlc291cmNlKGAke2Zvcm1FbGVtZW50LmxhYmVsa2V5fV9sYWJlbGApIHx8IGZvcm1FbGVtZW50LmxhYmVsa2V5O1xuICAgICAgICAgIGZvcm1FbGVtZW50LmRlc2NyaXB0aW9uID0gdGhpcy4jc3lzdGVtU2VydmljZS5nZXRMb2NhbGl6ZWRSZXNvdXJjZShgJHtmb3JtRWxlbWVudC5sYWJlbGtleX1fZGVzY3JpcHRpb25gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyAuLi4gbm8gJ2xhYmVsJyBhbmQgYWxzbyBubyAnbGFiZWxLZXknIG1lYW5zIHRoYXQgd2UgYXJlIHNob3dpbmcgdGVjaG5pY2FsIG5hbWUgaW5zdGVhZFxuICAgICAgICAgIGZvcm1FbGVtZW50LmxhYmVsID0gZm9ybUVsZW1lbnQubmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZm9ybUVsZW1lbnQucmVhZG9ubHkgPSBjb250cm9sRGlzYWJsZWQ7XG4gICAgICAvLyB3ZSBhcmUgdXNpbmcgYW4gaW50ZXJuYWwgdHlwZSB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIHRoZSBjb21wb25lbnRzXG4gICAgICAvLyB0byBiZSB1c2VkIHRvIHJlbmRlciBjZXJ0YWluIGZvcm0gZWxlbWVudHNcbiAgICAgIGZvcm1FbGVtZW50Ll9pbnRlcm5hbFR5cGUgPSB0aGlzLiNzeXN0ZW1TZXJ2aWNlLmdldEludGVybmFsRm9ybUVsZW1lbnRUeXBlKGZvcm1FbGVtZW50LnR5cGUsIGZvcm1FbGVtZW50LmNsYXNzaWZpY2F0aW9ucyk7XG5cbiAgICAgIGZvcm1Db250cm9sLl9lb0Zvcm1FbGVtZW50ID0gZm9ybUVsZW1lbnQ7XG4gICAgICB0aGlzLiNmb3JtQ29udHJvbHNbZm9ybUVsZW1lbnQubmFtZV0gPSBmb3JtQ29udHJvbDtcblxuICAgICAgaWYgKGZvcm1FbGVtZW50LnR5cGUgPT09ICdUQUJMRScpIHtcbiAgICAgICAgLy8gQWRkICdvbnJvd2VkaXQnIHByb3BlcnR5IGV2ZW4gaWYgaXQncyBub3Qgc2V0LlxuICAgICAgICAvLyBUaGlzIGlzIHJlcXVpcmVkIGJlY2F1c2Ugb3RoZXJ3aXNlIG1vYlgtT2JzZXJ2ZXIgd291bGQgbm90IHJlY29nbml6ZVxuICAgICAgICAvLyBjaGFuZ2VzIHRvIHRoaXMgcHJvcGVydHkgYXBwbGllZCBieSB0aGUgZm9ybSBzY3JpcHRcbiAgICAgICAgaWYgKCFPYmplY3Qua2V5cyhmb3JtQ29udHJvbC5fZW9Gb3JtRWxlbWVudCkuaW5jbHVkZXMoJ29ucm93ZWRpdCcpKSB7XG4gICAgICAgICAgZm9ybUNvbnRyb2wuX2VvRm9ybUVsZW1lbnQub25yb3dlZGl0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLiNzY3JpcHRpbmdTY29wZSAmJiBmb3JtQ29udHJvbC5fZW9Gb3JtRWxlbWVudC52YWx1ZSkge1xuICAgICAgICAgIC8vIGhhdmluZyBhIHNjcmlwdGluZyBzY29wZSBhbmQgdGFibGUgcm93cyBtZWFucyB0aGF0IHdlIG5lZWQgdG8gc2V0IGVtcHR5XG4gICAgICAgICAgLy8gY29sdW1ucyB0byBOVUxMLCBiZWNhdXNlIG90aGVyd2lzZSBtb2JYIHdvbid0IGJlIGFibGUgdG8gdHJhY2sgdGhvc2UgdmFsdWVzXG4gICAgICAgICAgY29uc3QgdmFsdWVGaWVsZHMgPSBmb3JtQ29udHJvbC5fZW9Gb3JtRWxlbWVudC5lbGVtZW50cy5tYXAoKGU6IGFueSkgPT4gZS5uYW1lKTtcbiAgICAgICAgICBmb3JtQ29udHJvbC5fZW9Gb3JtRWxlbWVudC52YWx1ZS5mb3JFYWNoKChyb3dWYWx1ZTogYW55KSA9PiB7XG4gICAgICAgICAgICB2YWx1ZUZpZWxkcy5mb3JFYWNoKCh2YWx1ZUZpZWxkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFPYmplY3Qua2V5cyhyb3dWYWx1ZSkuaW5jbHVkZXModmFsdWVGaWVsZCkpIHtcbiAgICAgICAgICAgICAgICByb3dWYWx1ZVt2YWx1ZUZpZWxkXSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIHVwZGF0ZSBmb3JtIGNvbnRyb2xzIHZhbHVlIGFzIHdlbGwgdG8gcmVmbGVjdCB0aGUgb2JzZXJ2ZWQgdmFsdWVcbiAgICAgICAgICBmb3JtQ29udHJvbC5wYXRjaFZhbHVlKGZvcm1Db250cm9sLl9lb0Zvcm1FbGVtZW50LnZhbHVlLCB7XG4gICAgICAgICAgICBvbmx5U2VsZjogdHJ1ZSxcbiAgICAgICAgICAgIGVtaXRFdmVudDogZmFsc2UsXG4gICAgICAgICAgICBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgZW1pdFZpZXdUb01vZGVsQ2hhbmdlOiBmYWxzZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3JtRWxlbWVudC5faW50ZXJuYWxUeXBlID09PSAnc3RyaW5nOm9yZ2FuaXphdGlvbicpIHtcbiAgICAgICAgZm9ybUNvbnRyb2wuX2VvRm9ybUVsZW1lbnQuc2V0RmlsdGVyID0gKGZpbHRlck9iamVjdDogYW55KSA9PiB7XG4gICAgICAgICAgZm9ybUNvbnRyb2wuX2VvRm9ybUVsZW1lbnQuZmlsdGVyID0gZmlsdGVyT2JqZWN0O1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBPYmplY3RGb3JtVXRpbHMudXBkYXRlRm9ybUVsZW1lbnQoZm9ybUVsZW1lbnQpO1xuXG4gICAgICAvLyByZW1vdmUgZW1wdHkgZGVzY3JpcHRpb25zXG4gICAgICBjb25zdCBkZXNjID0gZm9ybUNvbnRyb2wuX2VvRm9ybUVsZW1lbnQuZGVzY3JpcHRpb247XG4gICAgICBpZiAoZGVzYyAmJiBkZXNjLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZm9ybUNvbnRyb2wuX2VvRm9ybUVsZW1lbnQuZGVzY3JpcHRpb24gPSBudWxsO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgdGhlIGZvcm0gZWxlbWVudCB0byB0aGUgc2NyaXB0IG1vZGVsIHRoYXQgd2lsbCBiZSBpbmplY3RlZCBpbnRvXG4gICAgICAvLyB0aGUgZm9ybXMgc2NyaXB0aW5nIHNjb3BlIGxhdGVyIG9uXG4gICAgICB0aGlzLiNzY3JpcHRNb2RlbFtmb3JtRWxlbWVudC5uYW1lXSA9IGZvcm1Db250cm9sLl9lb0Zvcm1FbGVtZW50O1xuXG4gICAgICAvLyBhcHBseSBjaGFuZ2UgbGlzdGVuZXIgdG8gdGhlIGZvcm0gY29udHJvbCwgdGhhdCB3aWxsIHRyaWdnZXJcbiAgICAgIC8vIHRoZSBmb3JtIGVsZW1lbnRzIG9uQ2hhbmdlIGxpc3RlbmVyXG4gICAgICBjb25zdCBjb250cm9sV2F0Y2ggPSBjdHJsLnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZSg1MDApKTtcbiAgICAgIHRoaXMuI3N1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICAgY29udHJvbFdhdGNoLnN1YnNjcmliZSgodikgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLiNzY3JpcHRpbmdTY29wZSkge1xuICAgICAgICAgICAgdGhpcy4jc2NyaXB0aW5nU2NvcGUubW9kZWxDaGFuZ2VkKHYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIGN0cmwuYWRkQ29udHJvbChmb3JtRWxlbWVudC5uYW1lLCBmb3JtQ29udHJvbCk7XG4gICAgICBuYW1lID0gdGhpcy4jbmFtZVByZWZpeCArIGZvcm1FbGVtZW50Lm5hbWU7XG4gICAgfVxuICAgIHBhcmVudEdyb3VwLmFkZENvbnRyb2wobmFtZSwgY3RybCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgdmFsaWRhdG9ycyBmb3IgdGhlIGdpdmVuIGZvcm0gZWxlbWVudCB0byBiZSBhdHRhY2hlZCB0b1xuICAgKiBhIHJlYWN0aXZlIGZvcm1Db250cm9sLlxuICAgKlxuICAgKiBAcGFyYW0gZm9ybUVsZW1lbnQgLSBmb3JtIGVsZW1lbnQgb2JqZWN0XG4gICAqL1xuICAjZ2V0VmFsaWRhdG9ycyhmb3JtRWxlbWVudDogYW55KTogVmFsaWRhdG9yRm5bXSB7XG4gICAgY29uc3QgZm8gPSB0aGlzLmZvcm1PcHRpb25zKCk7XG4gICAgY29uc3QgZWxtVmFsaWRhdG9ycyA9IEZvcm1WYWxpZGF0aW9uLmdldFZhbGlkYXRvcnMoZm9ybUVsZW1lbnQsIGZvPy5mb3JtTW9kZWwuc2l0dWF0aW9uKTtcblxuICAgIC8vIGFkZCBjdXN0b20gdmFsaWRhdG9yIGZvciBzY3JpcHQgZW5hYmxlZCBmb3Jtc1xuICAgIGlmICh0aGlzLiNzY3JpcHRpbmdTY29wZSkge1xuICAgICAgZWxtVmFsaWRhdG9ycy5wdXNoKEZvcm1WYWxpZGF0aW9uLmN1c3RvbVNjcmlwdGluZ1ZhbGlkYXRpb24pO1xuICAgIH1cblxuICAgIHJldHVybiBlbG1WYWxpZGF0b3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgdGhlIHZhbHVlcyBmcm9tIHRoZSBmb3JtXG4gICAqL1xuICAjZm9ybVRvRGF0YSgpIHtcbiAgICBjb25zdCBmbyA9IHRoaXMuZm9ybU9wdGlvbnMoKTtcbiAgICByZXR1cm4gZm8gJiYgdGhpcy5mb3JtID8gdGhpcy4jZm9ybUhlbHBlclNlcnZpY2UuZXh0cmFjdEZvcm1EYXRhKHRoaXMuZm9ybSwgZm8uZm9ybU1vZGVsLnNpdHVhdGlvbiwgZm8uZGF0YSwgdGhpcy5pc0lubmVyVGFibGVGb3JtKCkpIDoge307XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgZGF0YSBpbnRvIGEgZm9ybSBtb2RlbC5cbiAgICpcbiAgICogQHBhcmFtIG1vZGVsIC0gZm9ybSBtb2RlbFxuICAgKiBAcGFyYW0gZGF0YSAtIGRhdGEgb2JqZWN0IG9yIGFycmF5IG9mIFNlYXJjaEZpbHRlciBvYmplY3RzIGluIGNhc2Ugb2YgYSBzZWFyY2ggZm9ybVxuICAgKi9cbiAgI2RhdGFUb0Zvcm0obW9kZWw6IGFueSwgZGF0YTogYW55KSB7XG4gICAgaWYgKG1vZGVsICYmIGRhdGEpIHtcbiAgICAgIHRoaXMuI3NldEVsZW1lbnRWYWx1ZXMobW9kZWwuZWxlbWVudHMsIGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvLyByZWN1cnNpdmUgbWV0aG9kIGZvciBhZGRpbmcgdmFsdWVzIHRvIG1vZGVsIGVsZW1lbnRzXG4gICNzZXRFbGVtZW50VmFsdWVzKGVsZW1lbnRzOiBhbnlbXSwgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIHtcbiAgICBlbGVtZW50cz8uZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKHRoaXMuI2hhc1ZhbHVlKGRhdGEsIGVsZW1lbnQpKSB7XG4gICAgICAgIGVsZW1lbnQudmFsdWUgPSB0aGlzLiNnZXRWYWx1ZShkYXRhLCBlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBlbGVtZW50LnZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGVsZW1lbnQudHlwZSAhPT0gJ1RBQkxFJyAmJiBlbGVtZW50LmVsZW1lbnRzICYmIGVsZW1lbnQuZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLiNzZXRFbGVtZW50VmFsdWVzKGVsZW1lbnQuZWxlbWVudHMsIGRhdGEpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgI2hhc1ZhbHVlKGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBlbGVtZW50OiBhbnkpIHtcbiAgICAvLyBkaWZmZXIgYmV0d2VlbiBhcnJheSBvZiBTZWFyY2hGaWx0ZXJzIGFuZCBhIGZvcm0gZGF0YSBvYmplY3RcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgcmV0dXJuICEhZGF0YS5maW5kKChmaWx0ZXIpID0+IGZpbHRlci5wcm9wZXJ0eSA9PT0gZWxlbWVudC5pZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhkYXRhKS5pbmNsdWRlcyhlbGVtZW50Lm5hbWUpO1xuICAgIH1cbiAgfVxuXG4gICNnZXRWYWx1ZShkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgZWxlbWVudDogYW55KSB7XG4gICAgcmV0dXJuIGRhdGFbZWxlbWVudC5uYW1lXTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMudW5zdWJzY3JpYmVBbGwoKTtcbiAgICB0aGlzLiNmb3JtU2NyaXB0aW5nQXBpU2VydmljZS51bnJlZ2lzdGVyQWN0aXZlRm9ybSh0aGlzKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLiNjZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvLyB1bnN1YnNjcmliZSBmcm9tIGFsbCB2YWx1ZSBjaGFuZ2UgbGlzdGVuZXJzIGZvciB0aGUgY3VycmVudCBmb3JtXG4gIC8vIHRvIGF2b2lkIG1lbW9yeSBsZWFrcy4gVGhpcyBtZXRob2Qgd2lsbCBhbHNvIGJlIGNhbGxlZCBldmVyeSB0aW1lXG4gIC8vIGEgbmV3IGZvcm0gaXMgcmVuZGVyZWQgdG8gZ2V0IHJpZCBvZiB0aGUgb2xkIGZvcm0gZWxlbWVudCBzdWJzY3JpcHRpb25zXG4gIHByaXZhdGUgdW5zdWJzY3JpYmVBbGwoKSB7XG4gICAgaWYgKHRoaXMuI3N1YnNjcmlwdGlvbnMubGVuZ3RoKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKCd1bnN1YnNjcmliZWQgZnJvbSAnICsgdGhpcy4jc3Vic2NyaXB0aW9ucy5sZW5ndGggKyAnIHZhbHVlIGNoYW5nZSBsaXN0ZW5lcnMuJyk7XG4gICAgICB0aGlzLiNzdWJzY3JpcHRpb25zLmZvckVhY2goKHMpID0+IHMudW5zdWJzY3JpYmUoKSk7XG4gICAgICB0aGlzLiNzdWJzY3JpcHRpb25zID0gW107XG4gICAgfVxuICB9XG59XG4iLCJAbGV0IGZvID0gZm9ybU9wdGlvbnMoKTtcbkBpZiAoZm8gJiYgZm9ybSkge1xuICA8ZGl2IGNsYXNzPVwieXV2LW9iamVjdC1mb3JtXCIgW2Zvcm1Hcm91cF09XCJmb3JtXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZWxlbWVudC13cmFwIGNvcmVcIj5cbiAgICAgIDx5dXYtb2JqZWN0LWZvcm0tZ3JvdXAgW2dyb3VwXT1cImdldEdyb3VwKCdjb3JlJylcIiBbc2l0dWF0aW9uXT1cImZvLmZvcm1Nb2RlbC5zaXR1YXRpb25cIj48L3l1di1vYmplY3QtZm9ybS1ncm91cD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS1lbGVtZW50LXdyYXAgZGF0YVwiPlxuICAgICAgPHl1di1vYmplY3QtZm9ybS1ncm91cCBbZ3JvdXBdPVwiZ2V0R3JvdXAoJ2RhdGEnKVwiIFtzaXR1YXRpb25dPVwiZm8uZm9ybU1vZGVsLnNpdHVhdGlvblwiPjwveXV2LW9iamVjdC1mb3JtLWdyb3VwPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbn1cbiJdfQ==