@igo2/geo 18.0.0 → 18.0.1-next.2

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 (510) hide show
  1. package/fesm2022/igo2-geo.mjs +684 -709
  2. package/fesm2022/igo2-geo.mjs.map +1 -1
  3. package/lib/offline/geoDB/geoDB.service.d.ts +1 -1
  4. package/lib/offline/layerDB/layerDB.service.d.ts +1 -1
  5. package/lib/style/style-list/style-list.provider.d.ts +1 -8
  6. package/lib/style/style-list/style-list.service.d.ts +1 -1
  7. package/package.json +15 -17
  8. package/src/lib/layer/layer-list/layer-list.theme.scss +2 -1
  9. package/src/lib/map/menu-button/menu-button.theming.scss +3 -3
  10. package/src/style/style.scss +1 -1
  11. package/esm2022/igo2-geo.mjs +0 -5
  12. package/esm2022/lib/catalog/catalog-browser/catalog-browser-group.component.mjs +0 -234
  13. package/esm2022/lib/catalog/catalog-browser/catalog-browser-layer.component.mjs +0 -272
  14. package/esm2022/lib/catalog/catalog-browser/catalog-browser.component.mjs +0 -246
  15. package/esm2022/lib/catalog/catalog-browser/catalog-browser.module.mjs +0 -19
  16. package/esm2022/lib/catalog/catalog-library/add-catalog-dialog.component.mjs +0 -136
  17. package/esm2022/lib/catalog/catalog-library/catalog-library-item.component.mjs +0 -60
  18. package/esm2022/lib/catalog/catalog-library/catalog-library.component.mjs +0 -232
  19. package/esm2022/lib/catalog/catalog-library/catalog-library.module.mjs +0 -24
  20. package/esm2022/lib/catalog/catalog-library/index.mjs +0 -4
  21. package/esm2022/lib/catalog/catalog.module.mjs +0 -26
  22. package/esm2022/lib/catalog/index.mjs +0 -6
  23. package/esm2022/lib/catalog/shared/catalog.abstract.mjs +0 -32
  24. package/esm2022/lib/catalog/shared/catalog.enum.mjs +0 -16
  25. package/esm2022/lib/catalog/shared/catalog.interface.mjs +0 -2
  26. package/esm2022/lib/catalog/shared/catalog.service.mjs +0 -706
  27. package/esm2022/lib/catalog/shared/catalogs.mjs +0 -75
  28. package/esm2022/lib/catalog/shared/index.mjs +0 -5
  29. package/esm2022/lib/datasource/index.mjs +0 -3
  30. package/esm2022/lib/datasource/shared/capabilities.interface.mjs +0 -17
  31. package/esm2022/lib/datasource/shared/capabilities.service.mjs +0 -441
  32. package/esm2022/lib/datasource/shared/datasource.service.mjs +0 -258
  33. package/esm2022/lib/datasource/shared/datasources/any-datasource.interface.mjs +0 -2
  34. package/esm2022/lib/datasource/shared/datasources/any-datasource.mjs +0 -2
  35. package/esm2022/lib/datasource/shared/datasources/arcgisrest-datasource.interface.mjs +0 -2
  36. package/esm2022/lib/datasource/shared/datasources/arcgisrest-datasource.mjs +0 -222
  37. package/esm2022/lib/datasource/shared/datasources/carto-datasource.interface.mjs +0 -2
  38. package/esm2022/lib/datasource/shared/datasources/carto-datasource.mjs +0 -118
  39. package/esm2022/lib/datasource/shared/datasources/cluster-datasource.interface.mjs +0 -2
  40. package/esm2022/lib/datasource/shared/datasources/cluster-datasource.mjs +0 -24
  41. package/esm2022/lib/datasource/shared/datasources/data.service.mjs +0 -3
  42. package/esm2022/lib/datasource/shared/datasources/datasource.interface.mjs +0 -2
  43. package/esm2022/lib/datasource/shared/datasources/datasource.mjs +0 -41
  44. package/esm2022/lib/datasource/shared/datasources/feature-datasource.interface.mjs +0 -2
  45. package/esm2022/lib/datasource/shared/datasources/feature-datasource.mjs +0 -52
  46. package/esm2022/lib/datasource/shared/datasources/imagearcgisrest-datasource.interface.mjs +0 -2
  47. package/esm2022/lib/datasource/shared/datasources/imagearcgisrest-datasource.mjs +0 -70
  48. package/esm2022/lib/datasource/shared/datasources/index.mjs +0 -36
  49. package/esm2022/lib/datasource/shared/datasources/mvt-datasource.interface.mjs +0 -2
  50. package/esm2022/lib/datasource/shared/datasources/mvt-datasource.mjs +0 -33
  51. package/esm2022/lib/datasource/shared/datasources/osm-datasource.interface.mjs +0 -2
  52. package/esm2022/lib/datasource/shared/datasources/osm-datasource.mjs +0 -14
  53. package/esm2022/lib/datasource/shared/datasources/tilearcgisrest-datasource.interface.mjs +0 -2
  54. package/esm2022/lib/datasource/shared/datasources/tilearcgisrest-datasource.mjs +0 -60
  55. package/esm2022/lib/datasource/shared/datasources/tiledebug-datasource.interface.mjs +0 -2
  56. package/esm2022/lib/datasource/shared/datasources/tiledebug-datasource.mjs +0 -17
  57. package/esm2022/lib/datasource/shared/datasources/websocket-datasource.interface.mjs +0 -2
  58. package/esm2022/lib/datasource/shared/datasources/websocket-datasource.mjs +0 -56
  59. package/esm2022/lib/datasource/shared/datasources/wfs-datasource.interface.mjs +0 -2
  60. package/esm2022/lib/datasource/shared/datasources/wfs-datasource.mjs +0 -137
  61. package/esm2022/lib/datasource/shared/datasources/wfs.service.mjs +0 -170
  62. package/esm2022/lib/datasource/shared/datasources/wms-datasource.interface.mjs +0 -2
  63. package/esm2022/lib/datasource/shared/datasources/wms-datasource.mjs +0 -227
  64. package/esm2022/lib/datasource/shared/datasources/wms-wfs.utils.mjs +0 -224
  65. package/esm2022/lib/datasource/shared/datasources/wmts-datasource.interface.mjs +0 -2
  66. package/esm2022/lib/datasource/shared/datasources/wmts-datasource.mjs +0 -18
  67. package/esm2022/lib/datasource/shared/datasources/xyz-datasource.interface.mjs +0 -2
  68. package/esm2022/lib/datasource/shared/datasources/xyz-datasource.mjs +0 -11
  69. package/esm2022/lib/datasource/shared/index.mjs +0 -6
  70. package/esm2022/lib/datasource/shared/options/index.mjs +0 -5
  71. package/esm2022/lib/datasource/shared/options/options-api.interface.mjs +0 -2
  72. package/esm2022/lib/datasource/shared/options/options-api.providers.mjs +0 -15
  73. package/esm2022/lib/datasource/shared/options/options-api.service.mjs +0 -85
  74. package/esm2022/lib/datasource/shared/options/options.service.mjs +0 -3
  75. package/esm2022/lib/datasource/utils/index.mjs +0 -2
  76. package/esm2022/lib/datasource/utils/tilegrid.mjs +0 -20
  77. package/esm2022/lib/directions/directions-buttons/directions-buttons.component.mjs +0 -246
  78. package/esm2022/lib/directions/directions-buttons/index.mjs +0 -2
  79. package/esm2022/lib/directions/directions-inputs/directions-inputs.component.mjs +0 -312
  80. package/esm2022/lib/directions/directions-inputs/index.mjs +0 -2
  81. package/esm2022/lib/directions/directions-results/directions-results.component.mjs +0 -192
  82. package/esm2022/lib/directions/directions-results/index.mjs +0 -2
  83. package/esm2022/lib/directions/directions-sources/directions-source.interface.mjs +0 -5
  84. package/esm2022/lib/directions/directions-sources/directions-source.mjs +0 -3
  85. package/esm2022/lib/directions/directions-sources/directions-source.provider.mjs +0 -23
  86. package/esm2022/lib/directions/directions-sources/index.mjs +0 -5
  87. package/esm2022/lib/directions/directions-sources/osrm-directions-source.mjs +0 -159
  88. package/esm2022/lib/directions/directions.component.mjs +0 -437
  89. package/esm2022/lib/directions/directions.module.mjs +0 -46
  90. package/esm2022/lib/directions/directions.provider.mjs +0 -16
  91. package/esm2022/lib/directions/index.mjs +0 -8
  92. package/esm2022/lib/directions/shared/directions-source.service.mjs +0 -18
  93. package/esm2022/lib/directions/shared/directions.enum.mjs +0 -72
  94. package/esm2022/lib/directions/shared/directions.interface.mjs +0 -2
  95. package/esm2022/lib/directions/shared/directions.service.mjs +0 -239
  96. package/esm2022/lib/directions/shared/directions.utils.mjs +0 -522
  97. package/esm2022/lib/directions/shared/index.mjs +0 -6
  98. package/esm2022/lib/directions/shared/store.mjs +0 -21
  99. package/esm2022/lib/download/download-button/download-button.component.mjs +0 -48
  100. package/esm2022/lib/download/download-button/index.mjs +0 -2
  101. package/esm2022/lib/download/download.module.mjs +0 -24
  102. package/esm2022/lib/download/index.mjs +0 -3
  103. package/esm2022/lib/download/shared/download.interface.mjs +0 -2
  104. package/esm2022/lib/download/shared/download.service.mjs +0 -67
  105. package/esm2022/lib/download/shared/index.mjs +0 -3
  106. package/esm2022/lib/draw/draw/draw-layer-popup.component.mjs +0 -42
  107. package/esm2022/lib/draw/draw/draw-popup.component.mjs +0 -421
  108. package/esm2022/lib/draw/draw/draw-shorcuts.component.mjs +0 -28
  109. package/esm2022/lib/draw/draw/draw.component.mjs +0 -1136
  110. package/esm2022/lib/draw/draw/draw.module.mjs +0 -19
  111. package/esm2022/lib/draw/drawingTool.module.mjs +0 -18
  112. package/esm2022/lib/draw/index.mjs +0 -3
  113. package/esm2022/lib/draw/shared/draw-icon.service.mjs +0 -30
  114. package/esm2022/lib/draw/shared/draw.enum.mjs +0 -21
  115. package/esm2022/lib/draw/shared/draw.interface.mjs +0 -2
  116. package/esm2022/lib/draw/shared/draw.utils.mjs +0 -125
  117. package/esm2022/lib/draw/shared/index.mjs +0 -5
  118. package/esm2022/lib/environment/environment.interface.mjs +0 -2
  119. package/esm2022/lib/environment/index.mjs +0 -2
  120. package/esm2022/lib/feature/feature-details/feature-details.component.mjs +0 -306
  121. package/esm2022/lib/feature/feature-details/feature-details.directive.mjs +0 -56
  122. package/esm2022/lib/feature/feature-details/feature-details.module.mjs +0 -26
  123. package/esm2022/lib/feature/feature-details/index.mjs +0 -4
  124. package/esm2022/lib/feature/feature-form/feature-form.component.mjs +0 -101
  125. package/esm2022/lib/feature/feature-form/feature-form.module.mjs +0 -19
  126. package/esm2022/lib/feature/feature.module.mjs +0 -26
  127. package/esm2022/lib/feature/index.mjs +0 -5
  128. package/esm2022/lib/feature/shared/feature-store.utils.mjs +0 -28
  129. package/esm2022/lib/feature/shared/feature.enums.mjs +0 -9
  130. package/esm2022/lib/feature/shared/feature.interfaces.mjs +0 -2
  131. package/esm2022/lib/feature/shared/feature.utils.mjs +0 -332
  132. package/esm2022/lib/feature/shared/index.mjs +0 -8
  133. package/esm2022/lib/feature/shared/store.mjs +0 -143
  134. package/esm2022/lib/feature/shared/strategies/geo-properties.mjs +0 -216
  135. package/esm2022/lib/feature/shared/strategies/in-map-extent.mjs +0 -119
  136. package/esm2022/lib/feature/shared/strategies/in-map-resolution.mjs +0 -99
  137. package/esm2022/lib/feature/shared/strategies/index.mjs +0 -8
  138. package/esm2022/lib/feature/shared/strategies/loading-layer.mjs +0 -103
  139. package/esm2022/lib/feature/shared/strategies/loading.mjs +0 -136
  140. package/esm2022/lib/feature/shared/strategies/search.mjs +0 -158
  141. package/esm2022/lib/feature/shared/strategies/selection.mjs +0 -385
  142. package/esm2022/lib/feature/shared/strategies.utils.mjs +0 -37
  143. package/esm2022/lib/filter/filter.module.mjs +0 -131
  144. package/esm2022/lib/filter/index.mjs +0 -17
  145. package/esm2022/lib/filter/ogc-filter-button/index.mjs +0 -2
  146. package/esm2022/lib/filter/ogc-filter-button/ogc-filter-button.component.mjs +0 -141
  147. package/esm2022/lib/filter/ogc-filter-form/index.mjs +0 -2
  148. package/esm2022/lib/filter/ogc-filter-form/ogc-filter-form.component.mjs +0 -325
  149. package/esm2022/lib/filter/ogc-filter-selection/index.mjs +0 -2
  150. package/esm2022/lib/filter/ogc-filter-selection/ogc-filter-selection.component.mjs +0 -787
  151. package/esm2022/lib/filter/ogc-filter-time/index.mjs +0 -3
  152. package/esm2022/lib/filter/ogc-filter-time/ogc-filter-time-slider.component.mjs +0 -201
  153. package/esm2022/lib/filter/ogc-filter-time/ogc-filter-time.component.mjs +0 -665
  154. package/esm2022/lib/filter/ogc-filterable-form/index.mjs +0 -2
  155. package/esm2022/lib/filter/ogc-filterable-form/ogc-filterable-form.component.mjs +0 -66
  156. package/esm2022/lib/filter/ogc-filterable-item/index.mjs +0 -2
  157. package/esm2022/lib/filter/ogc-filterable-item/ogc-filterable-item.component.mjs +0 -244
  158. package/esm2022/lib/filter/ogc-filterable-list/index.mjs +0 -3
  159. package/esm2022/lib/filter/ogc-filterable-list/ogc-filterable-list-binding.directive.mjs +0 -39
  160. package/esm2022/lib/filter/ogc-filterable-list/ogc-filterable-list.component.mjs +0 -32
  161. package/esm2022/lib/filter/shared/filterable-datasource.pipe.mjs +0 -63
  162. package/esm2022/lib/filter/shared/index.mjs +0 -12
  163. package/esm2022/lib/filter/shared/ogc-filter-time.service.mjs +0 -72
  164. package/esm2022/lib/filter/shared/ogc-filter.enum.mjs +0 -30
  165. package/esm2022/lib/filter/shared/ogc-filter.interface.mjs +0 -2
  166. package/esm2022/lib/filter/shared/ogc-filter.mjs +0 -756
  167. package/esm2022/lib/filter/shared/ogc-filter.service.mjs +0 -47
  168. package/esm2022/lib/filter/shared/spatial-filter.enum.mjs +0 -23
  169. package/esm2022/lib/filter/shared/spatial-filter.interface.mjs +0 -2
  170. package/esm2022/lib/filter/shared/spatial-filter.service.mjs +0 -282
  171. package/esm2022/lib/filter/shared/time-filter.enum.mjs +0 -13
  172. package/esm2022/lib/filter/shared/time-filter.interface.mjs +0 -2
  173. package/esm2022/lib/filter/shared/time-filter.service.mjs +0 -107
  174. package/esm2022/lib/filter/spatial-filter/spatial-filter-item/index.mjs +0 -2
  175. package/esm2022/lib/filter/spatial-filter/spatial-filter-item/spatial-filter-item.component.mjs +0 -875
  176. package/esm2022/lib/filter/spatial-filter/spatial-filter-list/index.mjs +0 -2
  177. package/esm2022/lib/filter/spatial-filter/spatial-filter-list/spatial-filter-list.component.mjs +0 -191
  178. package/esm2022/lib/filter/spatial-filter/spatial-filter-type/index.mjs +0 -2
  179. package/esm2022/lib/filter/spatial-filter/spatial-filter-type/spatial-filter-type.component.mjs +0 -120
  180. package/esm2022/lib/filter/time-filter-button/index.mjs +0 -2
  181. package/esm2022/lib/filter/time-filter-button/time-filter-button.component.mjs +0 -70
  182. package/esm2022/lib/filter/time-filter-form/index.mjs +0 -2
  183. package/esm2022/lib/filter/time-filter-form/time-filter-form.component.mjs +0 -537
  184. package/esm2022/lib/filter/time-filter-item/index.mjs +0 -2
  185. package/esm2022/lib/filter/time-filter-item/time-filter-item.component.mjs +0 -90
  186. package/esm2022/lib/filter/time-filter-list/index.mjs +0 -3
  187. package/esm2022/lib/filter/time-filter-list/time-filter-list-binding.directive.mjs +0 -39
  188. package/esm2022/lib/filter/time-filter-list/time-filter-list.component.mjs +0 -24
  189. package/esm2022/lib/geo.module.mjs +0 -63
  190. package/esm2022/lib/geometry/geometry-form-field/geometry-form-field-input.component.mjs +0 -559
  191. package/esm2022/lib/geometry/geometry-form-field/geometry-form-field.component.mjs +0 -170
  192. package/esm2022/lib/geometry/geometry-form-field/geometry-form-field.module.mjs +0 -24
  193. package/esm2022/lib/geometry/geometry-form-field/index.mjs +0 -4
  194. package/esm2022/lib/geometry/geometry.module.mjs +0 -18
  195. package/esm2022/lib/geometry/index.mjs +0 -3
  196. package/esm2022/lib/geometry/shared/controls/draw.mjs +0 -340
  197. package/esm2022/lib/geometry/shared/controls/index.mjs +0 -4
  198. package/esm2022/lib/geometry/shared/controls/modify.mjs +0 -538
  199. package/esm2022/lib/geometry/shared/controls/slice.mjs +0 -190
  200. package/esm2022/lib/geometry/shared/geometry.errors.mjs +0 -24
  201. package/esm2022/lib/geometry/shared/geometry.interfaces.mjs +0 -2
  202. package/esm2022/lib/geometry/shared/geometry.utils.mjs +0 -113
  203. package/esm2022/lib/geometry/shared/index.mjs +0 -5
  204. package/esm2022/lib/import-export/export-button/export-button.component.mjs +0 -49
  205. package/esm2022/lib/import-export/export-button/index.mjs +0 -2
  206. package/esm2022/lib/import-export/import-export/import-export.component.mjs +0 -876
  207. package/esm2022/lib/import-export/import-export/index.mjs +0 -2
  208. package/esm2022/lib/import-export/import-export.module.mjs +0 -31
  209. package/esm2022/lib/import-export/index.mjs +0 -5
  210. package/esm2022/lib/import-export/shared/drop-geo-file.directive.mjs +0 -114
  211. package/esm2022/lib/import-export/shared/export.errors.mjs +0 -15
  212. package/esm2022/lib/import-export/shared/export.interface.mjs +0 -2
  213. package/esm2022/lib/import-export/shared/export.service.mjs +0 -378
  214. package/esm2022/lib/import-export/shared/export.type.mjs +0 -13
  215. package/esm2022/lib/import-export/shared/export.utils.mjs +0 -51
  216. package/esm2022/lib/import-export/shared/import.errors.mjs +0 -39
  217. package/esm2022/lib/import-export/shared/import.interface.mjs +0 -2
  218. package/esm2022/lib/import-export/shared/import.service.mjs +0 -221
  219. package/esm2022/lib/import-export/shared/import.utils.mjs +0 -203
  220. package/esm2022/lib/import-export/shared/index.mjs +0 -11
  221. package/esm2022/lib/layer/index.mjs +0 -16
  222. package/esm2022/lib/layer/layer-group/index.mjs +0 -2
  223. package/esm2022/lib/layer/layer-group/layer-group.component.mjs +0 -103
  224. package/esm2022/lib/layer/layer-item/index.mjs +0 -2
  225. package/esm2022/lib/layer/layer-item/layer-item.component.mjs +0 -196
  226. package/esm2022/lib/layer/layer-legend/index.mjs +0 -2
  227. package/esm2022/lib/layer/layer-legend/layer-legend.component.mjs +0 -287
  228. package/esm2022/lib/layer/layer-legend-item/index.mjs +0 -2
  229. package/esm2022/lib/layer/layer-legend-item/layer-legend-item.component.mjs +0 -85
  230. package/esm2022/lib/layer/layer-legend-list/index.mjs +0 -3
  231. package/esm2022/lib/layer/layer-legend-list/layer-legend-list-binding.directive.mjs +0 -54
  232. package/esm2022/lib/layer/layer-legend-list/layer-legend-list.component.mjs +0 -104
  233. package/esm2022/lib/layer/layer-list/index.mjs +0 -2
  234. package/esm2022/lib/layer/layer-list/layer-list.component.mjs +0 -232
  235. package/esm2022/lib/layer/layer-list-tool/index.mjs +0 -4
  236. package/esm2022/lib/layer/layer-list-tool/layer-list-tool.component.mjs +0 -92
  237. package/esm2022/lib/layer/layer-list-tool/layer-list-tool.interface.mjs +0 -7
  238. package/esm2022/lib/layer/layer-list-tool/layer-list-tool.service.mjs +0 -61
  239. package/esm2022/lib/layer/layer-search/index.mjs +0 -2
  240. package/esm2022/lib/layer/layer-search/layer-search.component.mjs +0 -65
  241. package/esm2022/lib/layer/layer-unavailable/index.mjs +0 -3
  242. package/esm2022/lib/layer/layer-unavailable/layer-unavailable-list/layer-unavailable-list.component.mjs +0 -25
  243. package/esm2022/lib/layer/layer-unavailable/layer-unavailable.component.mjs +0 -35
  244. package/esm2022/lib/layer/layer-viewer/index.mjs +0 -3
  245. package/esm2022/lib/layer/layer-viewer/layer-viewer.component.mjs +0 -226
  246. package/esm2022/lib/layer/layer-viewer/layer-viewer.interface.mjs +0 -2
  247. package/esm2022/lib/layer/layer-viewer-bottom-actions/index.mjs +0 -2
  248. package/esm2022/lib/layer/layer-viewer-bottom-actions/layer-viewer-bottom-actions.component.mjs +0 -207
  249. package/esm2022/lib/layer/layer-visibility-button/index.mjs +0 -2
  250. package/esm2022/lib/layer/layer-visibility-button/layer-visibility-button.component.mjs +0 -83
  251. package/esm2022/lib/layer/layer.module.mjs +0 -107
  252. package/esm2022/lib/layer/shared/clusterParam.mjs +0 -2
  253. package/esm2022/lib/layer/shared/index.mjs +0 -6
  254. package/esm2022/lib/layer/shared/layer-controller.mjs +0 -316
  255. package/esm2022/lib/layer/shared/layer-selection.mjs +0 -38
  256. package/esm2022/lib/layer/shared/layer.enums.mjs +0 -2
  257. package/esm2022/lib/layer/shared/layer.service.mjs +0 -315
  258. package/esm2022/lib/layer/shared/layers/any-layer.interface.mjs +0 -2
  259. package/esm2022/lib/layer/shared/layers/any-layer.mjs +0 -2
  260. package/esm2022/lib/layer/shared/layers/image-layer.interface.mjs +0 -2
  261. package/esm2022/lib/layer/shared/layers/image-layer.mjs +0 -75
  262. package/esm2022/lib/layer/shared/layers/index.mjs +0 -18
  263. package/esm2022/lib/layer/shared/layers/layer-base.mjs +0 -199
  264. package/esm2022/lib/layer/shared/layers/layer-group.interface.mjs +0 -2
  265. package/esm2022/lib/layer/shared/layers/layer-group.mjs +0 -120
  266. package/esm2022/lib/layer/shared/layers/layer.interface.mjs +0 -7
  267. package/esm2022/lib/layer/shared/layers/layer.mjs +0 -178
  268. package/esm2022/lib/layer/shared/layers/legend.interface.mjs +0 -2
  269. package/esm2022/lib/layer/shared/layers/linked/index.mjs +0 -4
  270. package/esm2022/lib/layer/shared/layers/linked/linked-layer.interface.mjs +0 -12
  271. package/esm2022/lib/layer/shared/layers/linked/linked-layer.mjs +0 -242
  272. package/esm2022/lib/layer/shared/layers/linked/linked-layer.utils.mjs +0 -70
  273. package/esm2022/lib/layer/shared/layers/tile-layer.interface.mjs +0 -2
  274. package/esm2022/lib/layer/shared/layers/tile-layer.mjs +0 -55
  275. package/esm2022/lib/layer/shared/layers/vector-layer.interface.mjs +0 -2
  276. package/esm2022/lib/layer/shared/layers/vector-layer.mjs +0 -576
  277. package/esm2022/lib/layer/shared/layers/vectortile-layer.interface.mjs +0 -2
  278. package/esm2022/lib/layer/shared/layers/vectortile-layer.mjs +0 -112
  279. package/esm2022/lib/layer/track-feature-button/index.mjs +0 -2
  280. package/esm2022/lib/layer/track-feature-button/track-feature-button.component.mjs +0 -54
  281. package/esm2022/lib/layer/utils/image-watcher.mjs +0 -62
  282. package/esm2022/lib/layer/utils/index.mjs +0 -6
  283. package/esm2022/lib/layer/utils/layer.utils.mjs +0 -57
  284. package/esm2022/lib/layer/utils/outputLegend.mjs +0 -32
  285. package/esm2022/lib/layer/utils/tile-watcher.mjs +0 -52
  286. package/esm2022/lib/layer/utils/vector-watcher.mjs +0 -50
  287. package/esm2022/lib/map/baselayers-switcher/baselayers-switcher.animation.mjs +0 -20
  288. package/esm2022/lib/map/baselayers-switcher/baselayers-switcher.component.mjs +0 -87
  289. package/esm2022/lib/map/baselayers-switcher/index.mjs +0 -3
  290. package/esm2022/lib/map/baselayers-switcher/mini-basemap.component.mjs +0 -122
  291. package/esm2022/lib/map/geolocate-button/geolocate-button.component.mjs +0 -78
  292. package/esm2022/lib/map/geolocate-button/index.mjs +0 -2
  293. package/esm2022/lib/map/home-extent-button/home-extent-button.component.mjs +0 -73
  294. package/esm2022/lib/map/home-extent-button/home-extent-button.interface.mjs +0 -2
  295. package/esm2022/lib/map/home-extent-button/index.mjs +0 -3
  296. package/esm2022/lib/map/index.mjs +0 -14
  297. package/esm2022/lib/map/info-section/index.mjs +0 -2
  298. package/esm2022/lib/map/info-section/info-section.component.mjs +0 -15
  299. package/esm2022/lib/map/map-browser/index.mjs +0 -2
  300. package/esm2022/lib/map/map-browser/map-browser.component.mjs +0 -67
  301. package/esm2022/lib/map/map-center/index.mjs +0 -2
  302. package/esm2022/lib/map/map-center/map-center.component.mjs +0 -56
  303. package/esm2022/lib/map/map.module.mjs +0 -89
  304. package/esm2022/lib/map/menu-button/index.mjs +0 -2
  305. package/esm2022/lib/map/menu-button/menu-button.component.mjs +0 -57
  306. package/esm2022/lib/map/offline-button/index.mjs +0 -2
  307. package/esm2022/lib/map/offline-button/offline-button.component.mjs +0 -53
  308. package/esm2022/lib/map/rotation-button/index.mjs +0 -2
  309. package/esm2022/lib/map/rotation-button/rotation-button.component.mjs +0 -58
  310. package/esm2022/lib/map/shared/controllers/controller.mjs +0 -44
  311. package/esm2022/lib/map/shared/controllers/geolocation.interface.mjs +0 -8
  312. package/esm2022/lib/map/shared/controllers/geolocation.mjs +0 -431
  313. package/esm2022/lib/map/shared/controllers/index.mjs +0 -5
  314. package/esm2022/lib/map/shared/controllers/view.mjs +0 -361
  315. package/esm2022/lib/map/shared/hover-feature.directive.mjs +0 -481
  316. package/esm2022/lib/map/shared/index.mjs +0 -15
  317. package/esm2022/lib/map/shared/linkedLayers.utils.mjs +0 -238
  318. package/esm2022/lib/map/shared/map-pointer-position.directive.mjs +0 -122
  319. package/esm2022/lib/map/shared/map.abstract.mjs +0 -24
  320. package/esm2022/lib/map/shared/map.enums.mjs +0 -6
  321. package/esm2022/lib/map/shared/map.interface.mjs +0 -2
  322. package/esm2022/lib/map/shared/map.mjs +0 -201
  323. package/esm2022/lib/map/shared/map.service.mjs +0 -29
  324. package/esm2022/lib/map/shared/map.utils.mjs +0 -455
  325. package/esm2022/lib/map/shared/mapOffline.directive.mjs +0 -114
  326. package/esm2022/lib/map/shared/projection.interfaces.mjs +0 -2
  327. package/esm2022/lib/map/shared/projection.service.mjs +0 -67
  328. package/esm2022/lib/map/shared/projection.utils.mjs +0 -122
  329. package/esm2022/lib/map/swipe-control/index.mjs +0 -2
  330. package/esm2022/lib/map/swipe-control/swipe-control.component.mjs +0 -211
  331. package/esm2022/lib/map/utils/index.mjs +0 -2
  332. package/esm2022/lib/map/utils/layer-watcher.mjs +0 -112
  333. package/esm2022/lib/map/wake-lock-button/index.mjs +0 -2
  334. package/esm2022/lib/map/wake-lock-button/wake-lock-button.component.mjs +0 -103
  335. package/esm2022/lib/map/zoom-button/index.mjs +0 -2
  336. package/esm2022/lib/map/zoom-button/zoom-button.component.mjs +0 -35
  337. package/esm2022/lib/measure/index.mjs +0 -3
  338. package/esm2022/lib/measure/measure.module.mjs +0 -20
  339. package/esm2022/lib/measure/measurer/index.mjs +0 -6
  340. package/esm2022/lib/measure/measurer/measure-format.pipe.mjs +0 -40
  341. package/esm2022/lib/measure/measurer/measurer-dialog.component.mjs +0 -38
  342. package/esm2022/lib/measure/measurer/measurer-item.component.mjs +0 -143
  343. package/esm2022/lib/measure/measurer/measurer.component.mjs +0 -948
  344. package/esm2022/lib/measure/measurer/measurer.module.mjs +0 -20
  345. package/esm2022/lib/measure/shared/index.mjs +0 -4
  346. package/esm2022/lib/measure/shared/measure.enum.mjs +0 -37
  347. package/esm2022/lib/measure/shared/measure.interfaces.mjs +0 -2
  348. package/esm2022/lib/measure/shared/measure.utils.mjs +0 -497
  349. package/esm2022/lib/metadata/index.mjs +0 -4
  350. package/esm2022/lib/metadata/metadata-button/index.mjs +0 -2
  351. package/esm2022/lib/metadata/metadata-button/metadata-button.component.mjs +0 -96
  352. package/esm2022/lib/metadata/metadata.module.mjs +0 -29
  353. package/esm2022/lib/metadata/shared/index.mjs +0 -3
  354. package/esm2022/lib/metadata/shared/metadata.interface.mjs +0 -2
  355. package/esm2022/lib/metadata/shared/metadata.service.mjs +0 -18
  356. package/esm2022/lib/offline/geoDB/configFileToGeoDB.service.mjs +0 -130
  357. package/esm2022/lib/offline/geoDB/geoDB.enums.mjs +0 -6
  358. package/esm2022/lib/offline/geoDB/geoDB.interface.mjs +0 -2
  359. package/esm2022/lib/offline/geoDB/geoDB.service.mjs +0 -172
  360. package/esm2022/lib/offline/geoDB/index.mjs +0 -5
  361. package/esm2022/lib/offline/index.mjs +0 -6
  362. package/esm2022/lib/offline/layerDB/index.mjs +0 -3
  363. package/esm2022/lib/offline/layerDB/layerDB.interface.mjs +0 -2
  364. package/esm2022/lib/offline/layerDB/layerDB.service.mjs +0 -83
  365. package/esm2022/lib/offline/offline.interface.mjs +0 -2
  366. package/esm2022/lib/offline/offline.provider.mjs +0 -50
  367. package/esm2022/lib/offline/shared/geo-network.service.mjs +0 -79
  368. package/esm2022/lib/offline/shared/index.mjs +0 -2
  369. package/esm2022/lib/overlay/index.mjs +0 -2
  370. package/esm2022/lib/overlay/shared/index.mjs +0 -4
  371. package/esm2022/lib/overlay/shared/overlay.enum.mjs +0 -8
  372. package/esm2022/lib/overlay/shared/overlay.mjs +0 -139
  373. package/esm2022/lib/overlay/shared/overlay.utils.mjs +0 -17
  374. package/esm2022/lib/print/index.mjs +0 -4
  375. package/esm2022/lib/print/print/print.component.mjs +0 -116
  376. package/esm2022/lib/print/print-form/index.mjs +0 -2
  377. package/esm2022/lib/print/print-form/print-form.component.mjs +0 -320
  378. package/esm2022/lib/print/print.module.mjs +0 -20
  379. package/esm2022/lib/print/shared/geopdf.mjs +0 -68
  380. package/esm2022/lib/print/shared/index.mjs +0 -5
  381. package/esm2022/lib/print/shared/print.interface.mjs +0 -2
  382. package/esm2022/lib/print/shared/print.service.mjs +0 -1136
  383. package/esm2022/lib/print/shared/print.type.mjs +0 -30
  384. package/esm2022/lib/query/index.mjs +0 -2
  385. package/esm2022/lib/query/query.module.mjs +0 -27
  386. package/esm2022/lib/query/shared/index.mjs +0 -8
  387. package/esm2022/lib/query/shared/query-search-source.mjs +0 -35
  388. package/esm2022/lib/query/shared/query-search-source.providers.mjs +0 -22
  389. package/esm2022/lib/query/shared/query.directive.mjs +0 -290
  390. package/esm2022/lib/query/shared/query.enums.mjs +0 -32
  391. package/esm2022/lib/query/shared/query.interfaces.mjs +0 -2
  392. package/esm2022/lib/query/shared/query.service.mjs +0 -753
  393. package/esm2022/lib/query/shared/query.utils.mjs +0 -45
  394. package/esm2022/lib/search/index.mjs +0 -10
  395. package/esm2022/lib/search/search-bar/search-bar.component.mjs +0 -483
  396. package/esm2022/lib/search/search-bar/search-bar.module.mjs +0 -19
  397. package/esm2022/lib/search/search-results/index.mjs +0 -5
  398. package/esm2022/lib/search/search-results/save-feature-dialog.component.mjs +0 -101
  399. package/esm2022/lib/search/search-results/search-results-add-button.component.mjs +0 -433
  400. package/esm2022/lib/search/search-results/search-results-item.component.mjs +0 -119
  401. package/esm2022/lib/search/search-results/search-results.component.mjs +0 -297
  402. package/esm2022/lib/search/search-results/search-results.directive.mjs +0 -7
  403. package/esm2022/lib/search/search-results/search-results.module.mjs +0 -20
  404. package/esm2022/lib/search/search-selector/search-selector.component.mjs +0 -118
  405. package/esm2022/lib/search/search-selector/search-selector.module.mjs +0 -19
  406. package/esm2022/lib/search/search-settings/search-settings.component.mjs +0 -264
  407. package/esm2022/lib/search/search-settings/search-settings.module.mjs +0 -19
  408. package/esm2022/lib/search/search.module.mjs +0 -77
  409. package/esm2022/lib/search/shared/index.mjs +0 -10
  410. package/esm2022/lib/search/shared/search-pointer-summary.directive.mjs +0 -328
  411. package/esm2022/lib/search/shared/search-source-service.providers.mjs +0 -20
  412. package/esm2022/lib/search/shared/search-source.service.mjs +0 -56
  413. package/esm2022/lib/search/shared/search.enums.mjs +0 -4
  414. package/esm2022/lib/search/shared/search.interfaces.mjs +0 -2
  415. package/esm2022/lib/search/shared/search.provider.mjs +0 -20
  416. package/esm2022/lib/search/shared/search.service.mjs +0 -149
  417. package/esm2022/lib/search/shared/search.utils.mjs +0 -92
  418. package/esm2022/lib/search/shared/sources/cadastre.mjs +0 -142
  419. package/esm2022/lib/search/shared/sources/cadastre.providers.mjs +0 -32
  420. package/esm2022/lib/search/shared/sources/coordinates.interfaces.mjs +0 -2
  421. package/esm2022/lib/search/shared/sources/coordinates.mjs +0 -168
  422. package/esm2022/lib/search/shared/sources/coordinates.providers.mjs +0 -52
  423. package/esm2022/lib/search/shared/sources/icherche-icons.mjs +0 -32
  424. package/esm2022/lib/search/shared/sources/icherche.interfaces.mjs +0 -2
  425. package/esm2022/lib/search/shared/sources/icherche.mjs +0 -816
  426. package/esm2022/lib/search/shared/sources/icherche.providers.mjs +0 -87
  427. package/esm2022/lib/search/shared/sources/ilayer.interfaces.mjs +0 -2
  428. package/esm2022/lib/search/shared/sources/ilayer.mjs +0 -339
  429. package/esm2022/lib/search/shared/sources/ilayer.providers.mjs +0 -58
  430. package/esm2022/lib/search/shared/sources/index.mjs +0 -23
  431. package/esm2022/lib/search/shared/sources/nominatim.interfaces.mjs +0 -2
  432. package/esm2022/lib/search/shared/sources/nominatim.mjs +0 -263
  433. package/esm2022/lib/search/shared/sources/nominatim.providers.mjs +0 -31
  434. package/esm2022/lib/search/shared/sources/source.interfaces.mjs +0 -13
  435. package/esm2022/lib/search/shared/sources/source.mjs +0 -221
  436. package/esm2022/lib/search/shared/sources/storedqueries.interfaces.mjs +0 -2
  437. package/esm2022/lib/search/shared/sources/storedqueries.mjs +0 -454
  438. package/esm2022/lib/search/shared/sources/storedqueries.providers.mjs +0 -56
  439. package/esm2022/lib/search/shared/sources/workspace.interfaces.mjs +0 -2
  440. package/esm2022/lib/search/shared/sources/workspace.mjs +0 -192
  441. package/esm2022/lib/search/shared/sources/workspace.providers.mjs +0 -31
  442. package/esm2022/lib/style/index.mjs +0 -5
  443. package/esm2022/lib/style/shared/datasource/esri-style-generator.mjs +0 -360
  444. package/esm2022/lib/style/shared/datasource/index.mjs +0 -2
  445. package/esm2022/lib/style/shared/feature/feature-style.mjs +0 -162
  446. package/esm2022/lib/style/shared/feature/index.mjs +0 -2
  447. package/esm2022/lib/style/shared/font.enum.mjs +0 -17
  448. package/esm2022/lib/style/shared/index.mjs +0 -5
  449. package/esm2022/lib/style/shared/overlay/index.mjs +0 -3
  450. package/esm2022/lib/style/shared/overlay/overlay-marker-style.utils.mjs +0 -39
  451. package/esm2022/lib/style/shared/overlay/overlay-style.utils.mjs +0 -88
  452. package/esm2022/lib/style/shared/vector/commonVectorStyle.mjs +0 -78
  453. package/esm2022/lib/style/shared/vector/conversion.utils.mjs +0 -27
  454. package/esm2022/lib/style/shared/vector/index.mjs +0 -4
  455. package/esm2022/lib/style/shared/vector/vector-style.interface.mjs +0 -2
  456. package/esm2022/lib/style/style-list/index.mjs +0 -5
  457. package/esm2022/lib/style/style-list/style-list.interface.mjs +0 -2
  458. package/esm2022/lib/style/style-list/style-list.module.mjs +0 -23
  459. package/esm2022/lib/style/style-list/style-list.provider.mjs +0 -21
  460. package/esm2022/lib/style/style-list/style-list.service.mjs +0 -52
  461. package/esm2022/lib/style/style-modal/drawing/index.mjs +0 -2
  462. package/esm2022/lib/style/style-modal/drawing/style-modal-drawing.component.mjs +0 -193
  463. package/esm2022/lib/style/style-modal/index.mjs +0 -5
  464. package/esm2022/lib/style/style-modal/layer/index.mjs +0 -2
  465. package/esm2022/lib/style/style-modal/layer/style-modal-layer.component.mjs +0 -142
  466. package/esm2022/lib/style/style-modal/layer-button/index.mjs +0 -2
  467. package/esm2022/lib/style/style-modal/layer-button/style-modal-layer-button.component.mjs +0 -44
  468. package/esm2022/lib/style/style-modal/shared/index.mjs +0 -2
  469. package/esm2022/lib/style/style-modal/shared/style-modal.interface.mjs +0 -2
  470. package/esm2022/lib/style/style-service/draw-style.service.mjs +0 -255
  471. package/esm2022/lib/style/style-service/index.mjs +0 -3
  472. package/esm2022/lib/style/style-service/style.service.mjs +0 -393
  473. package/esm2022/lib/style/style.module.mjs +0 -46
  474. package/esm2022/lib/toast/index.mjs +0 -2
  475. package/esm2022/lib/toast/toast.component.mjs +0 -99
  476. package/esm2022/lib/toast/toast.module.mjs +0 -24
  477. package/esm2022/lib/utils/googleLinks.mjs +0 -13
  478. package/esm2022/lib/utils/id-generator.mjs +0 -112
  479. package/esm2022/lib/utils/index.mjs +0 -5
  480. package/esm2022/lib/utils/osmLinks.mjs +0 -9
  481. package/esm2022/lib/utils/propertyTypeDetector/index.mjs +0 -3
  482. package/esm2022/lib/utils/propertyTypeDetector/propertyTypeDetector.interface.mjs +0 -2
  483. package/esm2022/lib/utils/propertyTypeDetector/propertyTypeDetector.service.mjs +0 -64
  484. package/esm2022/lib/wkt/index.mjs +0 -2
  485. package/esm2022/lib/wkt/shared/index.mjs +0 -2
  486. package/esm2022/lib/wkt/shared/wkt.service.mjs +0 -235
  487. package/esm2022/lib/wkt/wkt.module.mjs +0 -25
  488. package/esm2022/lib/workspace/confirmation-popup/confirmation-popup.component.mjs +0 -36
  489. package/esm2022/lib/workspace/confirmation-popup/confirmation-popup.module.mjs +0 -19
  490. package/esm2022/lib/workspace/confirmation-popup/index.mjs +0 -3
  491. package/esm2022/lib/workspace/index.mjs +0 -8
  492. package/esm2022/lib/workspace/shared/edition-workspace.mjs +0 -301
  493. package/esm2022/lib/workspace/shared/edition-workspace.service.mjs +0 -720
  494. package/esm2022/lib/workspace/shared/feature-workspace.mjs +0 -41
  495. package/esm2022/lib/workspace/shared/feature-workspace.service.mjs +0 -113
  496. package/esm2022/lib/workspace/shared/index.mjs +0 -8
  497. package/esm2022/lib/workspace/shared/wfs-workspace.mjs +0 -41
  498. package/esm2022/lib/workspace/shared/wfs-workspace.service.mjs +0 -121
  499. package/esm2022/lib/workspace/shared/wms-workspace.service.mjs +0 -248
  500. package/esm2022/lib/workspace/shared/workspace.utils.mjs +0 -188
  501. package/esm2022/lib/workspace/widgets/index.mjs +0 -4
  502. package/esm2022/lib/workspace/widgets/ogc-filter/ogc-filter.component.mjs +0 -48
  503. package/esm2022/lib/workspace/widgets/ogc-filter/ogc-filter.module.mjs +0 -19
  504. package/esm2022/lib/workspace/widgets/widgets.mjs +0 -15
  505. package/esm2022/lib/workspace/workspace-selector/workspace-selector.directive.mjs +0 -172
  506. package/esm2022/lib/workspace/workspace-selector/workspace-selector.module.mjs +0 -19
  507. package/esm2022/lib/workspace/workspace-updator/workspace-updator.directive.mjs +0 -137
  508. package/esm2022/lib/workspace/workspace-updator/workspace-updator.module.mjs +0 -19
  509. package/esm2022/lib/workspace/workspace.module.mjs +0 -32
  510. package/esm2022/public_api.mjs +0 -56
@@ -1,1136 +0,0 @@
1
- import { DOCUMENT } from '@angular/common';
2
- import { HttpClient } from '@angular/common/http';
3
- import { Inject, Injectable } from '@angular/core';
4
- import { SecureImagePipe } from '@igo2/common/image';
5
- import { ActivityService } from '@igo2/core/activity';
6
- import { ConfigService } from '@igo2/core/config';
7
- import { LanguageService } from '@igo2/core/language';
8
- import { MessageService } from '@igo2/core/message';
9
- import { SubjectStatus } from '@igo2/utils';
10
- import { saveAs } from 'file-saver';
11
- import html2canvas from 'html2canvas';
12
- import jsPDF from 'jspdf';
13
- import { default as JSZip } from 'jszip';
14
- import { Observable, Subject, forkJoin } from 'rxjs';
15
- import { map as rxMap } from 'rxjs/operators';
16
- import { getLayersLegends } from '../../layer/utils/outputLegend';
17
- import { formatScale } from '../../map/shared/map.utils';
18
- import GeoPdfPlugin from './geopdf';
19
- import { PrintPaperFormat } from './print.type';
20
- import * as i0 from "@angular/core";
21
- import * as i1 from "@angular/common/http";
22
- import * as i2 from "@igo2/core/message";
23
- import * as i3 from "@igo2/core/activity";
24
- import * as i4 from "@igo2/core/language";
25
- import * as i5 from "@igo2/core/config";
26
- export class PrintService {
27
- http;
28
- messageService;
29
- activityService;
30
- languageService;
31
- configService;
32
- document;
33
- zipFile;
34
- nbFileToProcess;
35
- activityId;
36
- mapPrintExtent;
37
- imgSizeAdded;
38
- TEXTPDFFONT = {
39
- titleFont: 'times',
40
- titleFontStyle: 'bold',
41
- subtitleFont: 'times',
42
- subtitleFontStyle: 'bold',
43
- commentFont: 'times',
44
- commentFontStyle: 'normal',
45
- commentFontSize: 12
46
- };
47
- constructor(http, messageService, activityService, languageService, configService, document) {
48
- this.http = http;
49
- this.messageService = messageService;
50
- this.activityService = activityService;
51
- this.languageService = languageService;
52
- this.configService = configService;
53
- this.document = document;
54
- }
55
- print(map, options) {
56
- const status$ = new Subject();
57
- const paperFormat = options.paperFormat;
58
- const resolution = +options.resolution; // Default is 96
59
- const orientation = options.orientation;
60
- const legendPostion = options.legendPosition;
61
- this.activityId = this.activityService.register();
62
- GeoPdfPlugin(jsPDF.API);
63
- const doc = new jsPDF({
64
- orientation,
65
- format: paperFormat.toLowerCase(),
66
- unit: 'mm' // default
67
- });
68
- const { width: pageWidth, height: pageHeight } = doc.internal.pageSize;
69
- /** top | right | bottom | left */
70
- const baseMargins = [10, 10, 10, 10];
71
- let titleSizes;
72
- let subtitleSizes;
73
- // if paper format A1 or A0 add margin top
74
- if ((options.title !== '' || options.subtitle !== '') &&
75
- (paperFormat === PrintPaperFormat.A1 ||
76
- paperFormat === PrintPaperFormat.A0)) {
77
- baseMargins[0] += 10;
78
- }
79
- // PDF title
80
- const fontSizeInPt = Math.round(2 * (pageHeight + 145) * 0.05) / 2; //calculate the fontSize title from the page height.
81
- if (options.title !== undefined && options.title !== '') {
82
- titleSizes = this.getTextPdfObjectSizeAndMarg(options.title, baseMargins, this.TEXTPDFFONT.titleFont, fontSizeInPt, this.TEXTPDFFONT.titleFontStyle, doc);
83
- this.addTextInPdfDoc(doc, options.title, this.TEXTPDFFONT.titleFont, this.TEXTPDFFONT.titleFontStyle, titleSizes.fontSize, titleSizes.marginLeft + baseMargins[3], baseMargins[0]);
84
- baseMargins[0] = titleSizes.height + baseMargins[0]; // cumulative margin top for next elem to place in pdf doc
85
- }
86
- // PDF subtitle
87
- if (options.subtitle !== undefined && options.subtitle !== '') {
88
- subtitleSizes = this.getTextPdfObjectSizeAndMarg(options.subtitle, baseMargins, this.TEXTPDFFONT.subtitleFont, options.title !== '' ? titleSizes.fontSize * 0.7 : fontSizeInPt * 0.7, // 70% size of title
89
- this.TEXTPDFFONT.subtitleFontStyle, doc);
90
- this.addTextInPdfDoc(doc, options.subtitle, this.TEXTPDFFONT.subtitleFont, this.TEXTPDFFONT.subtitleFontStyle, subtitleSizes.fontSize, subtitleSizes.marginLeft + baseMargins[3], baseMargins[0]);
91
- baseMargins[0] += 5; // cumulative marg top for next elem to place in pdf doc. 5 is a fix it could be adjust
92
- }
93
- const verticalSpacing = 5;
94
- if (options.comment !== undefined && options.comment !== '') {
95
- this.addComment(doc, options.comment, baseMargins, verticalSpacing);
96
- }
97
- this.handleFooter(map, doc, options, resolution, verticalSpacing, baseMargins);
98
- const width = pageWidth - baseMargins[3] - baseMargins[1];
99
- const height = pageHeight - baseMargins[0] - baseMargins[2];
100
- const size = [width, height];
101
- this.addMap(doc, map, resolution, size, baseMargins).subscribe(async (status) => {
102
- if (status === SubjectStatus.Done) {
103
- const width = this.imgSizeAdded[0];
104
- const height = this.imgSizeAdded[1];
105
- this.addGeoRef(doc, map, width, height, baseMargins);
106
- await this.handleMeasureLayer(doc, map, baseMargins);
107
- if (options.showNorthArrow) {
108
- const northArrowCanvas = await this.createNorthDirectionArrow(map.viewController.getRotation());
109
- await this.addNorthArrowInDoc(doc, northArrowCanvas, baseMargins, legendPostion, width);
110
- }
111
- if (options.legendPosition !== 'none') {
112
- if (['topleft', 'topright', 'bottomleft', 'bottomright'].indexOf(options.legendPosition) > -1) {
113
- await this.addLegendSamePage(doc, map, baseMargins, resolution, options.legendPosition);
114
- }
115
- else if (options.legendPosition === 'newpage') {
116
- await this.addLegend(doc, map, baseMargins, resolution);
117
- }
118
- }
119
- else {
120
- await this.saveDoc(doc);
121
- }
122
- }
123
- if (status === SubjectStatus.Done || status === SubjectStatus.Error) {
124
- this.activityService.unregister(this.activityId);
125
- status$.next(SubjectStatus.Done);
126
- }
127
- });
128
- return status$;
129
- }
130
- // ref GeoMoose https://github.com/geomoose/gm3/tree/main/src/gm3/components/print
131
- addGeoRef(doc, map, width, height, baseMargins) {
132
- const unit = 'mm';
133
- const docHeight = doc.internal.pageSize.getHeight();
134
- // x,y = margin left-bottom corner for img in pdf doc
135
- const x = baseMargins[3];
136
- const y = docHeight - baseMargins[0] - height;
137
- const pdf_extents = [x, y, x + width, y + height];
138
- for (let i = 0; i < pdf_extents.length; i++) {
139
- pdf_extents[i] = this.pdf_units2points(pdf_extents[i], unit);
140
- }
141
- doc.setGeoArea(pdf_extents, this.mapPrintExtent);
142
- }
143
- /**
144
- * Add measure overlay on the map on the document when the measure layer is present
145
- * @param doc - Pdf document where measure tooltip will be added
146
- * @param map - Map of the app
147
- * @param baseMargins - Page margins
148
- */
149
- async handleMeasureLayer(doc, map, baseMargins) {
150
- if (map.layerController.all.find((layer) => layer.visible && layer.id.startsWith('igo-measures-'))) {
151
- let canvasOverlayHTMLMeasures;
152
- const mapOverlayMeasuresHTML = map.ol.getOverlayContainer();
153
- await html2canvas(mapOverlayMeasuresHTML, {
154
- scale: 1,
155
- backgroundColor: null
156
- }).then((e) => {
157
- canvasOverlayHTMLMeasures = e;
158
- });
159
- this.addCanvas(doc, canvasOverlayHTMLMeasures, baseMargins); // this adds measure overlays
160
- }
161
- }
162
- /**
163
- * Get html code for all layers legend
164
- * @param map IgoMap
165
- * @param width The width that the legend need to be
166
- * @return Html code for the legend
167
- */
168
- getLayersLegendHtml(map, width) {
169
- return new Observable((observer) => {
170
- let html = '';
171
- const legends = getLayersLegends(map.layerController.all);
172
- if (legends.filter((l) => l.display === true).length === 0) {
173
- observer.next(html);
174
- observer.complete();
175
- return;
176
- }
177
- // Define important style to be sure that all container is convert
178
- // to image not just visible part
179
- html += '<style media="screen" type="text/css">';
180
- html +=
181
- '.html2canvas-container { width: ' +
182
- width +
183
- 'mm !important; height: 2000px !important; }';
184
- html += 'table.tableLegend {table-layout: auto;}';
185
- html +=
186
- 'div.styleLegend {padding-top: 5px; padding-right:5px;padding-left:5px;padding-bottom:5px;}';
187
- html += '</style>';
188
- // The font size will also be lowered afterwards (globally along the legend size)
189
- // this allows having a good relative font size here and to keep ajusting the legend size
190
- // while keeping good relative font size
191
- html += '<font size="3" face="Times" >';
192
- html += '<div class="styleLegend">';
193
- html += '<table class="tableLegend" >';
194
- // For each legend, define an html table cell
195
- const images$ = legends
196
- .filter((l) => l.display && l.isInResolutionsRange === true)
197
- .map((legend) => this.getDataImage(legend.url).pipe(rxMap((dataImage) => {
198
- let htmlImg = '<tr><td>' + legend.title.toUpperCase() + '</td></tr>';
199
- htmlImg += '<tr><td><img src="' + dataImage + '"></td></tr>';
200
- return htmlImg;
201
- })));
202
- forkJoin(images$).subscribe((dataImages) => {
203
- html = dataImages.reduce((acc, current) => (acc += current), html);
204
- html += '</table>';
205
- html += '</div>';
206
- observer.next(html);
207
- observer.complete();
208
- });
209
- });
210
- }
211
- getDataImage(url) {
212
- const secureIMG = new SecureImagePipe(this.http, this.configService);
213
- return secureIMG.transform(url);
214
- }
215
- /**
216
- * Get all the legend in a single image
217
- * * @param format - Image format. default value to "png"
218
- * @return The image of the legend
219
- */
220
- async getLayersLegendImage(map, format = 'png', doZipFile) {
221
- const status$ = new Subject();
222
- // Get html code for the legend
223
- const width = 200; // milimeters unit, originally define for document pdf
224
- let html = await this.getLayersLegendHtml(map, width).toPromise();
225
- format = format.toLowerCase();
226
- // If no legend show No LEGEND in an image
227
- if (html.length === 0) {
228
- html = '<font size="12" face="Courier New" >';
229
- html += '<div align="center"><b>NO LEGEND</b></div>';
230
- }
231
- // Create div to contain html code for legend
232
- const div = window.document.createElement('div');
233
- div.style.position = 'absolute';
234
- div.style.top = '0';
235
- div.style.zIndex = '-1';
236
- // Add html code to convert in the new window
237
- window.document.body.appendChild(div);
238
- div.innerHTML = html;
239
- await this.timeout(1);
240
- const canvas = await html2canvas(div, { useCORS: true }).catch((e) => {
241
- console.log(e);
242
- });
243
- this.removeHtmlElement(div);
244
- if (canvas) {
245
- let status = SubjectStatus.Done;
246
- try {
247
- if (!doZipFile) {
248
- // Save the canvas as file
249
- this.saveCanvasImageAsFile(canvas, 'legendImage', format);
250
- }
251
- else {
252
- // Add the canvas to zip
253
- this.generateCanvaFileToZip(canvas, 'legendImage' + '.' + format);
254
- }
255
- }
256
- catch {
257
- status = SubjectStatus.Error;
258
- }
259
- status$.next(status);
260
- }
261
- return status$;
262
- }
263
- removeHtmlElement(element) {
264
- element.parentNode.removeChild(element);
265
- }
266
- getTextPdfObjectSizeAndMarg(text, margins, font, fontSizeInPt, fontStyle, doc) {
267
- const docWidth = doc.internal.pageSize.getWidth();
268
- const pageWidth = docWidth - margins[1] - margins[3];
269
- // important to set it first, the textDimension change when font change!
270
- doc.setFont(font, fontStyle);
271
- doc.setFontSize(fontSizeInPt);
272
- let textDimensions = doc.getTextDimensions(text);
273
- let textMarginLeft;
274
- if (textDimensions.w > pageWidth) {
275
- // if the text is to long, reduce fontSize 70% and the overflow with be cut in print...
276
- textMarginLeft = 0;
277
- fontSizeInPt = fontSizeInPt * 0.7;
278
- doc.setFontSize(fontSizeInPt);
279
- textDimensions = doc.getTextDimensions(text);
280
- }
281
- else {
282
- textMarginLeft = (pageWidth - textDimensions.w) / 2;
283
- }
284
- return {
285
- fontSize: fontSizeInPt,
286
- marginLeft: textMarginLeft,
287
- height: textDimensions.h
288
- };
289
- }
290
- /**
291
- * Add comment to the document
292
- * @param doc - pdf document
293
- * @param comment - Comment to add in the document
294
- * @param baseMargins - top | right | bottom | left
295
- * @param verticalSpacing - calculate text position and map height
296
- */
297
- addComment(doc, comment, baseMargins, verticalSpacing) {
298
- // calculate map image height
299
- baseMargins[2] += verticalSpacing;
300
- const xPosition = baseMargins[3]; //margin left and bottom is fix
301
- const marginBottom = baseMargins[2];
302
- // calculate text position Y
303
- const yPosition = doc.internal.pageSize.height - marginBottom + verticalSpacing;
304
- this.addTextInPdfDoc(doc, comment, this.TEXTPDFFONT.commentFont, this.TEXTPDFFONT.commentFontStyle, this.TEXTPDFFONT.commentFontSize, xPosition, yPosition, true);
305
- }
306
- addTextInPdfDoc(doc, textToAdd, textFont, textFontStyle, textFontSize, textMarginLeft, textMarginTop, isComment = false) {
307
- doc.setFont(textFont, textFontStyle);
308
- doc.setFontSize(textFontSize);
309
- if (isComment) {
310
- textToAdd = doc.splitTextToSize(textToAdd, doc.internal.pageSize.getWidth() - textMarginLeft * 3);
311
- }
312
- doc.text(textToAdd, textMarginLeft, textMarginTop);
313
- }
314
- /**
315
- * Add attribution and/or (projection and/or scale) to the document
316
- * @param map - Map of the app
317
- * @param doc - pdf document
318
- * @param options - Print options
319
- * @param resolution - cart resolution
320
- * @param baseMargins - top | right | bottom | left
321
- * @param verticalSpacing - calculate text position and map height
322
- */
323
- async handleFooter(map, doc, options, resolution, verticalSpacing, baseMargins) {
324
- let text = '';
325
- const attributionText = this.getAttributionText(map);
326
- if (attributionText) {
327
- text += attributionText + '. ';
328
- }
329
- if (options.showProjection === true || options.showScale === true) {
330
- text += this.getProjScale(map, options, resolution);
331
- }
332
- if (text) {
333
- baseMargins[2] += verticalSpacing;
334
- }
335
- const xPosition = baseMargins[3];
336
- const marginBottom = baseMargins[2];
337
- // calculate text position Y
338
- const yPosition = doc.internal.pageSize.height - marginBottom + verticalSpacing;
339
- this.addTextInPdfDoc(doc, text, this.TEXTPDFFONT.commentFont, this.TEXTPDFFONT.commentFontStyle, this.TEXTPDFFONT.commentFontSize, xPosition, yPosition);
340
- }
341
- getAttributionText(map) {
342
- const mapOverlayHtml = map.ol.getOverlayContainerStopEvent();
343
- const htmlAttribution = mapOverlayHtml
344
- .getElementsByClassName('ol-attribution')[0]
345
- .cloneNode(true);
346
- htmlAttribution.getElementsByTagName('button')[0].remove();
347
- return htmlAttribution.innerText;
348
- }
349
- getProjScale(map, options, dpi) {
350
- const translate = this.languageService.translate;
351
- let textProjScale = '';
352
- if (options.showProjection === true) {
353
- const projText = translate.instant('igo.geo.printForm.projection');
354
- textProjScale += projText + ': ' + map.projection;
355
- }
356
- if (options.showScale === true) {
357
- if (options.showProjection === true) {
358
- textProjScale += ' ';
359
- }
360
- const scaleText = translate.instant('igo.geo.printForm.scale');
361
- const mapScale = map.viewController.getScale(dpi);
362
- textProjScale += scaleText + ': ~ 1 / ' + formatScale(mapScale);
363
- }
364
- return textProjScale;
365
- }
366
- /**
367
- * Add the legend to the document
368
- * @param doc - Pdf document where legend will be added
369
- * @param map - Map of the app
370
- * @param margins - Page margins
371
- */
372
- async addLegend(doc, map, margins, resolution) {
373
- // Get html code for the legend
374
- const width = doc.internal.pageSize.width;
375
- const html = await this.getLayersLegendHtml(map, width).toPromise();
376
- // If no legend, save the map directly
377
- if (html === '') {
378
- await this.saveDoc(doc);
379
- return true;
380
- }
381
- // Create div to contain html code for legend
382
- const div = window.document.createElement('div');
383
- div.style.position = 'absolute';
384
- div.style.top = '0';
385
- div.style.zIndex = '-1';
386
- // Add html code to convert in the new window
387
- window.document.body.appendChild(div);
388
- div.innerHTML = html;
389
- await this.timeout(1);
390
- const canvas = await html2canvas(div, { useCORS: true }).catch((e) => {
391
- console.log(e);
392
- });
393
- this.removeHtmlElement(div);
394
- if (canvas) {
395
- const pourcentageReduction = 0.85;
396
- const imageSize = [
397
- (pourcentageReduction * (25.4 * canvas.width)) / resolution,
398
- (pourcentageReduction * (25.4 * canvas.height)) / resolution
399
- ];
400
- doc.addPage();
401
- const imgData = canvas.toDataURL('image/png');
402
- doc.addImage(imgData, 'PNG', 10, 10, imageSize[0], imageSize[1]);
403
- }
404
- await this.saveDoc(doc);
405
- }
406
- /**
407
- * Add the legend to the document
408
- * @param doc - Pdf document where legend will be added
409
- * @param map - Map of the app
410
- * @param baseMargins - Page margins
411
- */
412
- async addLegendSamePage(doc, map, baseMargins, resolution, legendPosition) {
413
- // Get html code for the legend
414
- const width = doc.internal.pageSize.width;
415
- const html = await this.getLayersLegendHtml(map, width).toPromise();
416
- // If no legend, save the map directly
417
- if (html === '') {
418
- await this.saveDoc(doc);
419
- return true;
420
- }
421
- // Create div to contain html code for legend
422
- const div = window.document.createElement('div');
423
- div.style.position = 'absolute';
424
- div.style.top = '0';
425
- div.style.zIndex = '-1';
426
- // Add html code to convert in the new window
427
- window.document.body.appendChild(div);
428
- div.innerHTML = html;
429
- await this.timeout(1);
430
- const canvas = await html2canvas(div, { useCORS: true }).catch((e) => {
431
- console.log(e);
432
- });
433
- this.removeHtmlElement(div);
434
- let marginsLegend;
435
- if (canvas) {
436
- const pourcentageReduction = 0.85;
437
- const imageSize = [
438
- (pourcentageReduction * (25.4 * canvas.width)) / resolution,
439
- (pourcentageReduction * (25.4 * canvas.height)) / resolution
440
- ];
441
- // Move the legend to the correct position on the page
442
- if (legendPosition === 'bottomright') {
443
- marginsLegend = [
444
- doc.internal.pageSize.height - baseMargins[2] - imageSize[1],
445
- baseMargins[1],
446
- baseMargins[2],
447
- doc.internal.pageSize.width - baseMargins[1] - imageSize[0]
448
- ];
449
- }
450
- else if (legendPosition === 'topright') {
451
- marginsLegend = [
452
- baseMargins[0],
453
- baseMargins[1],
454
- doc.internal.pageSize.height - baseMargins[0] - imageSize[1],
455
- doc.internal.pageSize.width - baseMargins[1] - imageSize[0]
456
- ];
457
- }
458
- else if (legendPosition === 'bottomleft') {
459
- // When the legend is in the bottom left, raise the legend slightly upward so that attributions are visible
460
- marginsLegend = [
461
- doc.internal.pageSize.height - baseMargins[2] - imageSize[1],
462
- doc.internal.pageSize.width - baseMargins[3] - imageSize[0],
463
- baseMargins[2],
464
- baseMargins[3]
465
- ];
466
- }
467
- else if (legendPosition === 'topleft') {
468
- marginsLegend = [
469
- baseMargins[0],
470
- doc.internal.pageSize.width - baseMargins[3] - imageSize[0],
471
- doc.internal.pageSize.height - baseMargins[0] - imageSize[1],
472
- baseMargins[3]
473
- ];
474
- }
475
- this.addCanvas(doc, canvas, marginsLegend); // this adds the legend
476
- await this.saveDoc(doc);
477
- }
478
- }
479
- defineNbFileToProcess(nbFileToProcess) {
480
- this.nbFileToProcess = nbFileToProcess;
481
- }
482
- timeout(ms) {
483
- return new Promise((resolve) => setTimeout(resolve, ms));
484
- }
485
- addCanvas(doc, canvas, baseMargins) {
486
- let image;
487
- if (canvas) {
488
- image = canvas.toDataURL('image/png');
489
- }
490
- if (image !== undefined) {
491
- if (image.length < 20) {
492
- console.log('Warning: An image cannot be print in pdf file');
493
- return;
494
- }
495
- const imageSize = this.getImageSizeToFitPdf(doc, canvas, baseMargins);
496
- doc.addImage(image, 'PNG', baseMargins[3], baseMargins[0], imageSize[0], imageSize[1]);
497
- doc.rect(baseMargins[3], baseMargins[0], imageSize[0], imageSize[1]);
498
- this.imgSizeAdded = imageSize; // keep img size for georef later
499
- }
500
- }
501
- // TODO fix printing with image resolution
502
- addMap(doc, map, resolution, imageDimensions, baseMargins) {
503
- const mapSize = map.ol.getSize();
504
- const viewResolution = map.ol.getView().getResolution();
505
- const dimensionPixels = this.setMapResolution(map, imageDimensions, resolution, viewResolution);
506
- const status$ = new Subject();
507
- let timeout;
508
- map.ol.once('rendercomplete', async (event) => {
509
- const mapCanvas = event.target
510
- .getViewport()
511
- .getElementsByTagName('canvas');
512
- const mapResultCanvas = await this.drawMap(dimensionPixels, mapCanvas);
513
- this.mapPrintExtent = map.viewController.getExtent('EPSG:3857');
514
- this.resetOriginalMapSize(map, mapSize, viewResolution);
515
- await this.drawMapControls(map, mapResultCanvas);
516
- const mapStatus$$ = map.status$.subscribe((mapStatus) => {
517
- clearTimeout(timeout);
518
- if (mapStatus !== SubjectStatus.Done) {
519
- return;
520
- }
521
- mapStatus$$.unsubscribe();
522
- let status = SubjectStatus.Done;
523
- try {
524
- if (mapResultCanvas.width !== 0) {
525
- this.addCanvas(doc, mapResultCanvas, baseMargins);
526
- }
527
- }
528
- catch {
529
- status = SubjectStatus.Error;
530
- this.messageService.error('igo.geo.printForm.corsErrorMessageBody', 'igo.geo.printForm.corsErrorMessageHeader');
531
- }
532
- status$.next(status);
533
- });
534
- // If no loading as started after 200ms, then probably no loading
535
- // is required.
536
- timeout = window.setTimeout(() => {
537
- mapStatus$$.unsubscribe();
538
- let status = SubjectStatus.Done;
539
- try {
540
- if (mapResultCanvas.width !== 0) {
541
- this.addCanvas(doc, mapResultCanvas, baseMargins);
542
- }
543
- }
544
- catch {
545
- status = SubjectStatus.Error;
546
- this.messageService.error('igo.geo.printForm.corsErrorMessageBody', 'igo.geo.printForm.corsErrorMessageHeader');
547
- }
548
- this.resetOriginalMapSize(map, mapSize, viewResolution);
549
- status$.next(status);
550
- }, 200);
551
- });
552
- return status$;
553
- }
554
- setMapResolution(map, initialSize, resolution, viewResolution) {
555
- const mapSize = map.ol.getSize();
556
- const widthPixels = Math.round((initialSize[0] * resolution) / 25.4);
557
- const heightPixels = Math.round((initialSize[1] * resolution) / 25.4);
558
- // Set print size
559
- const printSize = [widthPixels, heightPixels];
560
- map.ol.setSize(printSize);
561
- const scaling = Math.min(widthPixels / mapSize[0], heightPixels / mapSize[1]);
562
- map.ol.getView().setResolution(viewResolution / scaling);
563
- return [widthPixels, heightPixels];
564
- }
565
- resetOriginalMapSize(map, initialSize, viewResolution) {
566
- map.ol.setSize(initialSize);
567
- map.ol.getView().setResolution(viewResolution);
568
- map.ol.updateSize();
569
- map.ol.renderSync();
570
- }
571
- async drawMap(size, mapCanvas) {
572
- const mapResultCanvas = document.createElement('canvas');
573
- mapResultCanvas.width = size[0];
574
- mapResultCanvas.height = size[1];
575
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
576
- for (let index = 0; index < mapCanvas.length; index++) {
577
- const canvas = mapCanvas[index];
578
- if (canvas.width > 0) {
579
- this.handleCanvas(canvas, mapResultCanvas);
580
- }
581
- }
582
- return mapResultCanvas;
583
- }
584
- handleCanvas(canvas, mapResultCanvas) {
585
- const mapContextResult = mapResultCanvas.getContext('2d');
586
- const opacity = canvas.parentElement.style.opacity || canvas.style.opacity;
587
- mapContextResult.globalAlpha = opacity === '' ? 1 : Number(opacity);
588
- const transform = canvas.style.transform;
589
- let matrix;
590
- if (transform) {
591
- // Get the transform parameters from the style's transform matrix
592
- matrix = transform
593
- .match(/^matrix\(([^\(]*)\)$/)[1]
594
- .split(',')
595
- .map(Number);
596
- }
597
- else {
598
- matrix = [
599
- parseFloat(canvas.style.width) / canvas.width,
600
- 0,
601
- 0,
602
- parseFloat(canvas.style.height) / canvas.height,
603
- 0,
604
- 0
605
- ];
606
- }
607
- CanvasRenderingContext2D.prototype.setTransform.apply(mapContextResult, matrix);
608
- const backgroundColor = canvas.parentElement.style.backgroundColor;
609
- if (backgroundColor) {
610
- mapContextResult.fillStyle = backgroundColor;
611
- mapContextResult.fillRect(0, 0, canvas.width, canvas.height);
612
- }
613
- mapContextResult.drawImage(canvas, 0, 0);
614
- mapContextResult.globalAlpha = 1;
615
- // reset canvas transform to initial
616
- mapContextResult.setTransform(1, 0, 0, 1, 0, 0);
617
- }
618
- async drawMapControls(map, canvas) {
619
- const context = canvas.getContext('2d');
620
- // Get the scale and attribution
621
- // we use cloneNode to modify the nodes to print without modifying it on the page, using deep:true to get children
622
- const mapOverlayHTML = map.ol
623
- .getOverlayContainerStopEvent()
624
- .cloneNode(true);
625
- // set 'OverlayContainer' size to print size
626
- mapOverlayHTML.style.width = canvas.width + 'px';
627
- mapOverlayHTML.style.height = canvas.height + 'px';
628
- // we add zindex -1 to not show modification to the user
629
- mapOverlayHTML.style.zIndex = '-1';
630
- // and make sure html2canvas to render the image correctly
631
- document
632
- .getElementsByClassName('ol-viewport')[0]
633
- .appendChild(mapOverlayHTML);
634
- // Change the styles of hyperlink in the printed version
635
- // Transform the Overlay into a canvas
636
- // scale is necessary to make it in google chrome
637
- // background as null because otherwise it is white and cover the map
638
- // allowtaint is to allow rendering images in the attributions
639
- // useCORS: true pour permettre de renderer les images (ne marche pas en local)
640
- const canvasOverlayHTML = await html2canvas(mapOverlayHTML, {
641
- scale: 1,
642
- backgroundColor: null,
643
- allowTaint: true,
644
- useCORS: true,
645
- ignoreElements: (element) => {
646
- return element instanceof HTMLElement
647
- ? element.className.includes('ol-attribution')
648
- : false;
649
- }
650
- });
651
- if (canvasOverlayHTML.width !== 0 && canvasOverlayHTML.height !== 0) {
652
- context.drawImage(canvasOverlayHTML, 0, 0);
653
- }
654
- // remove 'mapOverlayHTML' after generating canvas
655
- mapOverlayHTML.remove();
656
- }
657
- async addNorthArrowInDoc(doc, arrawCanvas, baseMargins, legendPosition, width, yPosition = 0) {
658
- let xPosition = 0;
659
- let northArrowDimension = 0;
660
- if (doc instanceof CanvasRenderingContext2D) {
661
- northArrowDimension = 50;
662
- xPosition =
663
- legendPosition === 'topright' ? 0 : width - northArrowDimension;
664
- doc.drawImage(arrawCanvas, xPosition, yPosition, northArrowDimension, northArrowDimension);
665
- }
666
- else {
667
- northArrowDimension = 16;
668
- xPosition = legendPosition === 'topright' ? 10 : width - baseMargins[1];
669
- yPosition = baseMargins[0];
670
- doc.addImage(arrawCanvas.toDataURL(), xPosition, yPosition, northArrowDimension, northArrowDimension);
671
- }
672
- }
673
- /**
674
- * @param rotation - map rotation 'rad' unit
675
- *
676
- */
677
- async createNorthDirectionArrow(rotation) {
678
- const div = this.document.createElement('div');
679
- div.style.maxWidth = '50mm';
680
- div.style.maxHeight = '50mm';
681
- div.style.textAlign = 'center';
682
- const img = this.document.createElement('img');
683
- img.src = './assets/igo2/geo/images/north-direction.png';
684
- img.style.maxWidth = '50mm';
685
- img.style.maxHeight = '50mm';
686
- img.style.transform = 'rotate(' + rotation + 'rad)';
687
- img.style.padding = '5mm';
688
- div.appendChild(img);
689
- this.document.body.appendChild(div);
690
- const canvas = await html2canvas(div, { backgroundColor: null });
691
- this.removeHtmlElement(div);
692
- if (canvas) {
693
- return canvas;
694
- }
695
- }
696
- /**
697
- * Download an image of the map with addition of informations
698
- * @param map - Map of the app
699
- * @param format - Image format. default value to "png"
700
- * @param projection - Indicate if projection need to be add. Default to false
701
- * @param scale - Indicate if scale need to be add. Default to false
702
- * @param legend - Indicate if the legend of layers need to be download. Default to false
703
- * @param title - Title to add for the map - Default to blank
704
- * @param subtitle - Subtitle to add for the map - Default to blank
705
- * @param comment - Comment to add for the map - Default to blank
706
- * @param doZipFile - Indicate if we do a zip with the file
707
- * @return Image file of the map with extension format given as parameter
708
- */
709
- downloadMapImage(map, printResolution, format = 'png', projection = false, scale = false, title = '', subtitle = '', comment = '', doZipFile = true, legendPosition, showNorthArrow) {
710
- const status$ = new Subject();
711
- this.activityId = this.activityService.register();
712
- const translate = this.languageService.translate;
713
- format = format.toLowerCase();
714
- const resolution = +printResolution;
715
- const initialMapSize = map.ol.getSize();
716
- const viewResolution = map.ol.getView().getResolution();
717
- map.ol.once('rendercomplete', async (event) => {
718
- const size = map.ol.getSize();
719
- const mapCanvas = event.target
720
- .getViewport()
721
- .getElementsByTagName('canvas');
722
- const mapResultCanvas = await this.drawMap(size, mapCanvas);
723
- this.resetOriginalMapSize(map, initialMapSize, viewResolution);
724
- await this.drawMapControls(map, mapResultCanvas);
725
- // Check the legendPosition
726
- if (legendPosition !== 'none') {
727
- if (['topleft', 'topright', 'bottomleft', 'bottomright'].indexOf(legendPosition) > -1) {
728
- await this.addLegendToImage(mapResultCanvas, map, resolution, legendPosition, format);
729
- }
730
- else if (legendPosition === 'newpage') {
731
- await this.getLayersLegendImage(map, format, doZipFile);
732
- }
733
- }
734
- // add other information to final canvas before exporting
735
- const newCanvas = document.createElement('canvas');
736
- const newContext = newCanvas.getContext('2d');
737
- // Postion in height to set the canvas in new canvas
738
- let positionHCanvas = 0;
739
- // Get height/width of map canvas
740
- const width = mapResultCanvas.width;
741
- let height = mapResultCanvas.height;
742
- // Set Font to calculate comment width
743
- newContext.font = '20px Calibri';
744
- const commentWidth = newContext.measureText(comment).width;
745
- // Add height for title if defined
746
- height = title !== '' ? height + 30 : height;
747
- // Add height for title if defined
748
- height = subtitle !== '' ? height + 30 : height;
749
- // Add height for projection or scale (same line) if defined
750
- height = projection !== false || scale !== false ? height + 30 : height;
751
- const positionHProjScale = height - 10;
752
- // Define number of line depending of the comment length
753
- const commentNbLine = Math.ceil(commentWidth / width);
754
- // Add height for multiline comment if defined
755
- height = comment !== '' ? height + commentNbLine * 30 : height;
756
- let positionHComment = height - commentNbLine * 20 + 5;
757
- // Set the new canvas with the new calculated size
758
- newCanvas.width = width;
759
- newCanvas.height = height;
760
- if (['bmp', 'gif', 'jpeg', 'png', 'tiff'].indexOf(format) > -1) {
761
- // Patch Jpeg default black background to white
762
- if (format === 'jpeg' ||
763
- title !== '' ||
764
- subtitle !== '' ||
765
- comment !== '' ||
766
- projection !== false ||
767
- scale !== false) {
768
- newContext.fillStyle = '#ffffff';
769
- newContext.fillRect(0, 0, width, height);
770
- newContext.fillStyle = '#000000';
771
- }
772
- }
773
- // If a title need to be added to canvas
774
- if (title !== '') {
775
- // Set font for title
776
- // Adjust according to title length
777
- newContext.font = '26px Calibri';
778
- positionHCanvas = 30;
779
- newContext.textAlign = 'center';
780
- newContext.fillText(title, width / 2, 20, width * 0.9);
781
- }
782
- if (subtitle !== '') {
783
- // Set font for subtitle
784
- // Adjust according to title length
785
- newContext.font = '26px Calibri';
786
- positionHCanvas = 60;
787
- newContext.textAlign = 'center';
788
- newContext.fillText(subtitle, width / 2, 50, width * 0.9);
789
- }
790
- // Set font for next section
791
- newContext.font = '20px Calibri';
792
- // If projection or/end scale need to be added to canvas
793
- if (projection !== false || scale !== false) {
794
- let projectionScaleText = '';
795
- if (projection !== false) {
796
- const projText = translate.instant('igo.geo.printForm.projection');
797
- projectionScaleText = projText + ': ' + map.projection + ' ';
798
- }
799
- if (scale !== false) {
800
- const scaleText = translate.instant('igo.geo.printForm.scale');
801
- const mapScale = map.viewController.getScale(resolution);
802
- projectionScaleText += scaleText + ': ~ 1 / ' + formatScale(mapScale);
803
- }
804
- newContext.textAlign = 'center';
805
- newContext.fillText(projectionScaleText, width / 2, positionHProjScale, width * 0.9);
806
- }
807
- // If a comment need to be added to canvas
808
- if (comment !== '') {
809
- newContext.textAlign = 'center';
810
- // If only one line, no need to multiline the comment
811
- if (commentNbLine === 1) {
812
- newContext.fillText(comment, width / 2, positionHComment);
813
- }
814
- else {
815
- // Separate the setenses to be approx. the same length
816
- const nbCommentChar = comment.length;
817
- const CommentLengthToCut = Math.floor(nbCommentChar / commentNbLine);
818
- let commentCurrentLine = '';
819
- let positionFirstCutChar = 0;
820
- let positionLastBlank;
821
- // Loop for the number of line calculated
822
- for (let i = 0; i < commentNbLine; i++) {
823
- // For all line except last
824
- if (commentNbLine - 1 > i) {
825
- // Get comment current line to find the right place tu cut comment
826
- commentCurrentLine = comment.substr(positionFirstCutChar, CommentLengthToCut);
827
- // Cut the setence at blank
828
- positionLastBlank = commentCurrentLine.lastIndexOf(' ');
829
- newContext.fillText(commentCurrentLine.substr(0, positionLastBlank), width / 2, positionHComment);
830
- positionFirstCutChar += positionLastBlank;
831
- // Go to next line for insertion
832
- positionHComment += 20;
833
- }
834
- else {
835
- // Don't cut last part
836
- newContext.fillText(comment.substr(positionFirstCutChar), width / 2, positionHComment);
837
- }
838
- }
839
- }
840
- }
841
- newContext.drawImage(mapResultCanvas, 0, positionHCanvas);
842
- if (showNorthArrow) {
843
- const northArrowCanvas = await this.createNorthDirectionArrow(map.viewController.getRotation());
844
- await this.addNorthArrowInDoc(newContext, northArrowCanvas, null, legendPosition, width, positionHCanvas);
845
- }
846
- let status = SubjectStatus.Done;
847
- let fileNameWithExt = 'map.' + format;
848
- if (format.toLowerCase() === 'tiff') {
849
- fileNameWithExt =
850
- 'map' + map.projection.replace(':', '_') + '.' + format;
851
- }
852
- try {
853
- // Save the canvas as file
854
- if (!doZipFile) {
855
- this.saveCanvasImageAsFile(newCanvas, fileNameWithExt, format);
856
- }
857
- else if (format.toLowerCase() === 'tiff') {
858
- // Add the canvas to zip
859
- this.generateCanvaFileToZip(newCanvas, fileNameWithExt);
860
- }
861
- else {
862
- // Add the canvas to zip
863
- this.generateCanvaFileToZip(newCanvas, fileNameWithExt);
864
- }
865
- }
866
- catch {
867
- status = SubjectStatus.Error;
868
- }
869
- status$.next(status);
870
- if (format.toLowerCase() === 'tiff') {
871
- const tfwFileNameWithExt = fileNameWithExt.substring(0, fileNameWithExt.toLowerCase().indexOf('.tiff')) + '.tfw';
872
- const tiwContent = this.getWorldFileInformation(map);
873
- const blob = new Blob([tiwContent], {
874
- type: 'text/plain;charset=utf-8'
875
- });
876
- if (!doZipFile) {
877
- // saveAs automaticly replace ':' for '_'
878
- saveAs(blob, tfwFileNameWithExt);
879
- this.saveFileProcessing();
880
- }
881
- else {
882
- // Add the canvas to zip
883
- this.addFileToZip(tfwFileNameWithExt, blob);
884
- }
885
- }
886
- });
887
- this.setMapImageResolution(map, initialMapSize, resolution, viewResolution);
888
- return status$;
889
- }
890
- setMapImageResolution(map, initialMapSize, resolution, viewResolution) {
891
- const scaleFactor = resolution / 96;
892
- const newMapSize = [
893
- Math.round(initialMapSize[0] * scaleFactor), // width
894
- Math.round(initialMapSize[1] * scaleFactor) // height
895
- ];
896
- map.ol.setSize(newMapSize);
897
- const scaling = Math.min(newMapSize[0] / initialMapSize[0], newMapSize[1] / initialMapSize[1]);
898
- const view = map.ol.getView();
899
- view.setResolution(viewResolution / scaling);
900
- map.ol.renderSync();
901
- }
902
- /**
903
- * Create and Add Legend to the map canvas
904
- * @param canvas Canvas of the map
905
- * @param map Map of the app
906
- * @param resolution Resolution of map
907
- * @param legendPosition Legend position
908
- * @param format Image format
909
- */
910
- async addLegendToImage(canvas, map, resolution, legendPosition, format) {
911
- const fileNameWithExt = 'map.' + format;
912
- const context = canvas.getContext('2d');
913
- // Get html code for the legend
914
- const html = await this.getLayersLegendHtml(map, canvas.width).toPromise();
915
- // If no legend, save the map directly
916
- if (html === '') {
917
- await this.saveCanvasImageAsFile(canvas, fileNameWithExt, format);
918
- return true;
919
- }
920
- // Create div to contain html code for legend
921
- const div = window.document.createElement('div');
922
- div.style.position = 'absolute';
923
- div.style.top = '0';
924
- div.style.zIndex = '-1';
925
- // Add html code to convert in the new window
926
- window.document.body.appendChild(div);
927
- div.innerHTML = html;
928
- await this.timeout(1);
929
- const canvasLegend = await html2canvas(div, { useCORS: true }).catch((e) => {
930
- console.log(e);
931
- });
932
- if (canvasLegend) {
933
- const canvasHeight = canvas.height;
934
- const canvasWidth = canvas.width;
935
- const legendHeight = canvasLegend.height;
936
- const legendWidth = canvasLegend.width;
937
- // Move the legend to the correct position on the page
938
- const offset = canvasHeight * 0.01;
939
- let legendX;
940
- let legendY;
941
- if (legendPosition === 'bottomright') {
942
- legendX = canvasWidth - legendWidth - offset;
943
- legendY = canvasHeight - legendHeight - offset;
944
- }
945
- else if (legendPosition === 'topright') {
946
- legendX = canvasWidth - legendWidth - offset;
947
- legendY = offset;
948
- }
949
- else if (legendPosition === 'bottomleft') {
950
- legendX = offset;
951
- legendY = canvasHeight - legendHeight - offset - 15;
952
- }
953
- else if (legendPosition === 'topleft') {
954
- legendX = offset;
955
- legendY = offset;
956
- }
957
- context.drawImage(canvasLegend, legendX, legendY, legendWidth, legendHeight);
958
- context.strokeRect(legendX, legendY, legendWidth, legendHeight);
959
- this.removeHtmlElement(div);
960
- return true;
961
- }
962
- }
963
- /**
964
- * Save document
965
- * @param doc - Document to save
966
- */
967
- async saveDoc(doc) {
968
- await doc.save('map_georef.pdf', { returnPromise: true });
969
- }
970
- /**
971
- * Calculate the best Image size to fit in pdf
972
- * @param doc - Pdf Document
973
- * @param canvas - Canvas of image
974
- * @param margins - Page margins
975
- */
976
- getImageSizeToFitPdf(doc, canvas, margins) {
977
- // Define variable to calculate best size to fit in one page
978
- const pageHeight = doc.internal.pageSize.getHeight() - (margins[0] + margins[2]);
979
- const pageWidth = doc.internal.pageSize.getWidth() - (margins[1] + margins[3]);
980
- const canHeight = this.pdf_units2points(canvas.height, 'mm');
981
- const canWidth = this.pdf_units2points(canvas.width, 'mm');
982
- const heightRatio = canHeight / pageHeight;
983
- const widthRatio = canWidth / pageWidth;
984
- const maxRatio = heightRatio > widthRatio ? heightRatio : widthRatio;
985
- const imgHeigh = maxRatio > 1 ? canHeight / maxRatio : canHeight;
986
- const imgWidth = maxRatio > 1 ? canWidth / maxRatio : canWidth;
987
- return [imgWidth, imgHeigh];
988
- }
989
- /**
990
- * Get a world file information for tiff
991
- * @param map - Map of the app
992
- */
993
- getWorldFileInformation(map) {
994
- const currentResolution = map.viewController.getResolution();
995
- const currentExtent = map.viewController.getExtent(); // Return [minx, miny, maxx, maxy]
996
- return [
997
- currentResolution,
998
- 0,
999
- 0,
1000
- -currentResolution,
1001
- currentExtent[0] + currentResolution / 0.5,
1002
- currentExtent[3] - currentResolution / 0.5
1003
- ].join('\n');
1004
- }
1005
- /**
1006
- * Save canvas image as file
1007
- * @param canvas - Canvas to save
1008
- * @param name - Name of the file
1009
- * @param format - file format
1010
- */
1011
- saveCanvasImageAsFile(canvas, nameWithExt, format) {
1012
- const blobFormat = 'image/' + format;
1013
- try {
1014
- canvas.toDataURL(); // Just to make the catch trigger wihtout toBlob Error throw not catched
1015
- canvas.toBlob((blob) => {
1016
- // download image
1017
- saveAs(blob, nameWithExt);
1018
- this.saveFileProcessing();
1019
- }, blobFormat);
1020
- }
1021
- catch {
1022
- this.messageService.error('igo.geo.printForm.corsErrorMessageBody', 'igo.geo.printForm.corsErrorMessageHeader');
1023
- }
1024
- }
1025
- /**
1026
- * Add file to a zip
1027
- * @param canvas - File to add to the zip
1028
- * @param name -Name of the fileoverview
1029
- */
1030
- generateCanvaFileToZip(canvas, name) {
1031
- const blobFormat = 'image/' + 'jpeg';
1032
- if (
1033
- // eslint-disable-next-line no-prototype-builtins
1034
- !this.hasOwnProperty('zipFile') ||
1035
- typeof this.zipFile === 'undefined') {
1036
- this.zipFile = new JSZip();
1037
- }
1038
- try {
1039
- canvas.toDataURL(); // Just to make the catch trigger wihtout toBlob Error throw not catched
1040
- if (navigator.msSaveBlob) {
1041
- this.addFileToZip(name, canvas.msToBlob());
1042
- }
1043
- else {
1044
- canvas.toBlob((blob) => {
1045
- this.addFileToZip(name, blob);
1046
- }, blobFormat);
1047
- }
1048
- }
1049
- catch {
1050
- this.messageService.error('igo.geo.printForm.corsErrorMessageBody', 'igo.geo.printForm.corsErrorMessageHeader');
1051
- }
1052
- }
1053
- /**
1054
- * Add file to zip, if all file are zipped, download
1055
- * @param name - Name of the files
1056
- * @param blob - Contain of file
1057
- */
1058
- addFileToZip(name, blob) {
1059
- // add file to zip
1060
- this.zipFile.file(name, blob);
1061
- this.nbFileToProcess--;
1062
- // If all files are proccessed
1063
- if (this.nbFileToProcess === 0) {
1064
- // Download zip file
1065
- this.getZipFile();
1066
- // Stop loading
1067
- this.activityService.unregister(this.activityId);
1068
- }
1069
- }
1070
- saveFileProcessing() {
1071
- this.nbFileToProcess--;
1072
- // If all files are proccessed
1073
- if (this.nbFileToProcess === 0) {
1074
- // Stop loading
1075
- this.activityService.unregister(this.activityId);
1076
- }
1077
- }
1078
- /**
1079
- * Get the zipped file
1080
- * @return Retun a zip file
1081
- */
1082
- getZipFile() {
1083
- this.zipFile.generateAsync({ type: 'blob' }).then((blob) => {
1084
- // 1) generate the zip file
1085
- saveAs(blob, 'map.zip');
1086
- delete this.zipFile;
1087
- });
1088
- }
1089
- pdf_units2points(n, unit) {
1090
- let k = 1;
1091
- // this code is borrowed from jsPDF
1092
- // as it does not expose a public API
1093
- // for converting units to points.
1094
- switch (unit) {
1095
- case 'pt':
1096
- k = 1;
1097
- break;
1098
- case 'mm':
1099
- k = 72 / 25.4;
1100
- break;
1101
- case 'cm':
1102
- k = 72 / 2.54;
1103
- break;
1104
- case 'in':
1105
- k = 72;
1106
- break;
1107
- case 'px':
1108
- k = 96 / 72;
1109
- break;
1110
- case 'pc':
1111
- k = 12;
1112
- break;
1113
- case 'em':
1114
- k = 12;
1115
- break;
1116
- case 'ex':
1117
- k = 6;
1118
- break;
1119
- default:
1120
- throw new Error('Invalid unit: ' + unit);
1121
- }
1122
- return n * k;
1123
- }
1124
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, deps: [{ token: i1.HttpClient }, { token: i2.MessageService }, { token: i3.ActivityService }, { token: i4.LanguageService }, { token: i5.ConfigService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
1125
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, providedIn: 'root' });
1126
- }
1127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, decorators: [{
1128
- type: Injectable,
1129
- args: [{
1130
- providedIn: 'root'
1131
- }]
1132
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.MessageService }, { type: i3.ActivityService }, { type: i4.LanguageService }, { type: i5.ConfigService }, { type: Document, decorators: [{
1133
- type: Inject,
1134
- args: [DOCUMENT]
1135
- }] }] });
1136
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2dlby9zcmMvbGliL3ByaW50L3NoYXJlZC9wcmludC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTVDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxXQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsT0FBTyxJQUFJLEtBQUssRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckQsT0FBTyxFQUFFLEdBQUcsSUFBSSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUVsRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJB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QztJQUNmLENBQUM7d0dBMzhDVSxZQUFZLHFLQXVCYixRQUFROzRHQXZCUCxZQUFZLGNBRlgsTUFBTTs7NEZBRVAsWUFBWTtrQkFIeEIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQXdCSSxNQUFNOzJCQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFNlY3VyZUltYWdlUGlwZSB9IGZyb20gJ0BpZ28yL2NvbW1vbi9pbWFnZSc7XG5pbXBvcnQgeyBBY3Rpdml0eVNlcnZpY2UgfSBmcm9tICdAaWdvMi9jb3JlL2FjdGl2aXR5JztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICdAaWdvMi9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyBMYW5ndWFnZVNlcnZpY2UgfSBmcm9tICdAaWdvMi9jb3JlL2xhbmd1YWdlJztcbmltcG9ydCB7IE1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSAnQGlnbzIvY29yZS9tZXNzYWdlJztcbmltcG9ydCB7IFN1YmplY3RTdGF0dXMgfSBmcm9tICdAaWdvMi91dGlscyc7XG5cbmltcG9ydCB7IHNhdmVBcyB9IGZyb20gJ2ZpbGUtc2F2ZXInO1xuaW1wb3J0IGh0bWwyY2FudmFzIGZyb20gJ2h0bWwyY2FudmFzJztcbmltcG9ydCBqc1BERiBmcm9tICdqc3BkZic7XG5pbXBvcnQgeyBkZWZhdWx0IGFzIEpTWmlwIH0gZnJvbSAnanN6aXAnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgZm9ya0pvaW4gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCBhcyByeE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgZ2V0TGF5ZXJzTGVnZW5kcyB9IGZyb20gJy4uLy4uL2xheWVyL3V0aWxzL291dHB1dExlZ2VuZCc7XG5pbXBvcnQgeyBJZ29NYXAgfSBmcm9tICcuLi8uLi9tYXAvc2hhcmVkL21hcCc7XG5pbXBvcnQgeyBmb3JtYXRTY2FsZSB9IGZyb20gJy4uLy4uL21hcC9zaGFyZWQvbWFwLnV0aWxzJztcbmltcG9ydCBHZW9QZGZQbHVnaW4gZnJvbSAnLi9nZW9wZGYnO1xuaW1wb3J0IHsgUHJpbnRPcHRpb25zLCBUZXh0UGRmU2l6ZUFuZE1hcmdpbiB9IGZyb20gJy4vcHJpbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIFByaW50TGVnZW5kUG9zaXRpb24sXG4gIFByaW50UGFwZXJGb3JtYXQsXG4gIFByaW50UmVzb2x1dGlvblxufSBmcm9tICcuL3ByaW50LnR5cGUnO1xuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBOYXZpZ2F0b3Ige1xuICAgIG1zU2F2ZUJsb2I/OiAoYmxvYjogYW55LCBkZWZhdWx0TmFtZT86IHN0cmluZykgPT4gYm9vbGVhbjtcbiAgfVxufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBQcmludFNlcnZpY2Uge1xuICB6aXBGaWxlOiBKU1ppcDtcbiAgbmJGaWxlVG9Qcm9jZXNzOiBudW1iZXI7XG4gIGFjdGl2aXR5SWQ6IHN0cmluZztcbiAgbWFwUHJpbnRFeHRlbnQ6IG51bWJlcltdO1xuICBpbWdTaXplQWRkZWQ6IG51bWJlcltdO1xuXG4gIFRFWFRQREZGT05UID0ge1xuICAgIHRpdGxlRm9udDogJ3RpbWVzJyxcbiAgICB0aXRsZUZvbnRTdHlsZTogJ2JvbGQnLFxuICAgIHN1YnRpdGxlRm9udDogJ3RpbWVzJyxcbiAgICBzdWJ0aXRsZUZvbnRTdHlsZTogJ2JvbGQnLFxuICAgIGNvbW1lbnRGb250OiAndGltZXMnLFxuICAgIGNvbW1lbnRGb250U3R5bGU6ICdub3JtYWwnLFxuICAgIGNvbW1lbnRGb250U2l6ZTogMTJcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhY3Rpdml0eVNlcnZpY2U6IEFjdGl2aXR5U2VydmljZSxcbiAgICBwcml2YXRlIGxhbmd1YWdlU2VydmljZTogTGFuZ3VhZ2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudFxuICApIHt9XG5cbiAgcHJpbnQobWFwOiBJZ29NYXAsIG9wdGlvbnM6IFByaW50T3B0aW9ucyk6IFN1YmplY3Q8YW55PiB7XG4gICAgY29uc3Qgc3RhdHVzJCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY29uc3QgcGFwZXJGb3JtYXQ6IHN0cmluZyA9IG9wdGlvbnMucGFwZXJGb3JtYXQ7XG4gICAgY29uc3QgcmVzb2x1dGlvbiA9ICtvcHRpb25zLnJlc29sdXRpb247IC8vIERlZmF1bHQgaXMgOTZcbiAgICBjb25zdCBvcmllbnRhdGlvbiA9IG9wdGlvbnMub3JpZW50YXRpb247XG4gICAgY29uc3QgbGVnZW5kUG9zdGlvbiA9IG9wdGlvbnMubGVnZW5kUG9zaXRpb247XG4gICAgdGhpcy5hY3Rpdml0eUlkID0gdGhpcy5hY3Rpdml0eVNlcnZpY2UucmVnaXN0ZXIoKTtcblxuICAgIEdlb1BkZlBsdWdpbihqc1BERi5BUEkpO1xuXG4gICAgY29uc3QgZG9jID0gbmV3IGpzUERGKHtcbiAgICAgIG9yaWVudGF0aW9uLFxuICAgICAgZm9ybWF0OiBwYXBlckZvcm1hdC50b0xvd2VyQ2FzZSgpLFxuICAgICAgdW5pdDogJ21tJyAvLyBkZWZhdWx0XG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHdpZHRoOiBwYWdlV2lkdGgsIGhlaWdodDogcGFnZUhlaWdodCB9ID0gZG9jLmludGVybmFsLnBhZ2VTaXplO1xuXG4gICAgLyoqIHRvcCB8IHJpZ2h0IHwgYm90dG9tIHwgbGVmdCAqL1xuICAgIGNvbnN0IGJhc2VNYXJnaW5zOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxMCwgMTAsIDEwLCAxMF07XG5cbiAgICBsZXQgdGl0bGVTaXplczogVGV4dFBkZlNpemVBbmRNYXJnaW47XG4gICAgbGV0IHN1YnRpdGxlU2l6ZXM6IFRleHRQZGZTaXplQW5kTWFyZ2luO1xuXG4gICAgLy8gaWYgcGFwZXIgZm9ybWF0IEExIG9yIEEwIGFkZCBtYXJnaW4gdG9wXG4gICAgaWYgKFxuICAgICAgKG9wdGlvbnMudGl0bGUgIT09ICcnIHx8IG9wdGlvbnMuc3VidGl0bGUgIT09ICcnKSAmJlxuICAgICAgKHBhcGVyRm9ybWF0ID09PSBQcmludFBhcGVyRm9ybWF0LkExIHx8XG4gICAgICAgIHBhcGVyRm9ybWF0ID09PSBQcmludFBhcGVyRm9ybWF0LkEwKVxuICAgICkge1xuICAgICAgYmFzZU1hcmdpbnNbMF0gKz0gMTA7XG4gICAgfVxuICAgIC8vIFBERiB0aXRsZVxuICAgIGNvbnN0IGZvbnRTaXplSW5QdCA9IE1hdGgucm91bmQoMiAqIChwYWdlSGVpZ2h0ICsgMTQ1KSAqIDAuMDUpIC8gMjsgLy9jYWxjdWxhdGUgdGhlIGZvbnRTaXplIHRpdGxlIGZyb20gdGhlIHBhZ2UgaGVpZ2h0LlxuICAgIGlmIChvcHRpb25zLnRpdGxlICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50aXRsZSAhPT0gJycpIHtcbiAgICAgIHRpdGxlU2l6ZXMgPSB0aGlzLmdldFRleHRQZGZPYmplY3RTaXplQW5kTWFyZyhcbiAgICAgICAgb3B0aW9ucy50aXRsZSxcbiAgICAgICAgYmFzZU1hcmdpbnMsXG4gICAgICAgIHRoaXMuVEVYVFBERkZPTlQudGl0bGVGb250LFxuICAgICAgICBmb250U2l6ZUluUHQsXG4gICAgICAgIHRoaXMuVEVYVFBERkZPTlQudGl0bGVGb250U3R5bGUsXG4gICAgICAgIGRvY1xuICAgICAgKTtcblxuICAgICAgdGhpcy5hZGRUZXh0SW5QZGZEb2MoXG4gICAgICAgIGRvYyxcbiAgICAgICAgb3B0aW9ucy50aXRsZSxcbiAgICAgICAgdGhpcy5URVhUUERGRk9OVC50aXRsZUZvbnQsXG4gICAgICAgIHRoaXMuVEVYVFBERkZPTlQudGl0bGVGb250U3R5bGUsXG4gICAgICAgIHRpdGxlU2l6ZXMuZm9udFNpemUsXG4gICAgICAgIHRpdGxlU2l6ZXMubWFyZ2luTGVmdCArIGJhc2VNYXJnaW5zWzNdLFxuICAgICAgICBiYXNlTWFyZ2luc1swXVxuICAgICAgKTtcblxuICAgICAgYmFzZU1hcmdpbnNbMF0gPSB0aXRsZVNpemVzLmhlaWdodCArIGJhc2VNYXJnaW5zWzBdOyAvLyBjdW11bGF0aXZlIG1hcmdpbiB0b3AgZm9yIG5leHQgZWxlbSB0byBwbGFjZSBpbiBwZGYgZG9jXG4gICAgfVxuXG4gICAgLy8gUERGIHN1YnRpdGxlXG4gICAgaWYgKG9wdGlvbnMuc3VidGl0bGUgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnN1YnRpdGxlICE9PSAnJykge1xuICAgICAgc3VidGl0bGVTaXplcyA9IHRoaXMuZ2V0VGV4dFBkZk9iamVjdFNpemVBbmRNYXJnKFxuICAgICAgICBvcHRpb25zLnN1YnRpdGxlLFxuICAgICAgICBiYXNlTWFyZ2lucyxcbiAgICAgICAgdGhpcy5URVhUUERGRk9OVC5zdWJ0aXRsZUZvbnQsXG4gICAgICAgIG9wdGlvbnMudGl0bGUgIT09ICcnID8gdGl0bGVTaXplcy5mb250U2l6ZSAqIDAuNyA6IGZvbnRTaXplSW5QdCAqIDAuNywgLy8gNzAlIHNpemUgb2YgdGl0bGVcbiAgICAgICAgdGhpcy5URVhUUERGRk9OVC5zdWJ0aXRsZUZvbnRTdHlsZSxcbiAgICAgICAgZG9jXG4gICAgICApO1xuXG4gICAgICB0aGlzLmFkZFRleHRJblBkZkRvYyhcbiAgICAgICAgZG9jLFxuICAgICAgICBvcHRpb25zLnN1YnRpdGxlLFxuICAgICAgICB0aGlzLlRFWFRQREZGT05ULnN1YnRpdGxlRm9udCxcbiAgICAgICAgdGhpcy5URVhUUERGRk9OVC5zdWJ0aXRsZUZvbnRTdHlsZSxcbiAgICAgICAgc3VidGl0bGVTaXplcy5mb250U2l6ZSxcbiAgICAgICAgc3VidGl0bGVTaXplcy5tYXJnaW5MZWZ0ICsgYmFzZU1hcmdpbnNbM10sXG4gICAgICAgIGJhc2VNYXJnaW5zWzBdXG4gICAgICApO1xuXG4gICAgICBiYXNlTWFyZ2luc1swXSArPSA1OyAvLyBjdW11bGF0aXZlIG1hcmcgdG9wIGZvciBuZXh0IGVsZW0gdG8gcGxhY2UgaW4gcGRmIGRvYy4gNSBpcyBhIGZpeCBpdCBjb3VsZCBiZSBhZGp1c3RcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0aWNhbFNwYWNpbmcgPSA1O1xuICAgIGlmIChvcHRpb25zLmNvbW1lbnQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLmNvbW1lbnQgIT09ICcnKSB7XG4gICAgICB0aGlzLmFkZENvbW1lbnQoZG9jLCBvcHRpb25zLmNvbW1lbnQsIGJhc2VNYXJnaW5zLCB2ZXJ0aWNhbFNwYWNpbmcpO1xuICAgIH1cblxuICAgIHRoaXMuaGFuZGxlRm9vdGVyKFxuICAgICAgbWFwLFxuICAgICAgZG9jLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHJlc29sdXRpb24sXG4gICAgICB2ZXJ0aWNhbFNwYWNpbmcsXG4gICAgICBiYXNlTWFyZ2luc1xuICAgICk7XG5cbiAgICBjb25zdCB3aWR0aCA9IHBhZ2VXaWR0aCAtIGJhc2VNYXJnaW5zWzNdIC0gYmFzZU1hcmdpbnNbMV07XG4gICAgY29uc3QgaGVpZ2h0ID0gcGFnZUhlaWdodCAtIGJhc2VNYXJnaW5zWzBdIC0gYmFzZU1hcmdpbnNbMl07XG4gICAgY29uc3Qgc2l6ZTogW251bWJlciwgbnVtYmVyXSA9IFt3aWR0aCwgaGVpZ2h0XTtcblxuICAgIHRoaXMuYWRkTWFwKGRvYywgbWFwLCByZXNvbHV0aW9uLCBzaXplLCBiYXNlTWFyZ2lucykuc3Vic2NyaWJlKFxuICAgICAgYXN5bmMgKHN0YXR1czogU3ViamVjdFN0YXR1cykgPT4ge1xuICAgICAgICBpZiAoc3RhdHVzID09PSBTdWJqZWN0U3RhdHVzLkRvbmUpIHtcbiAgICAgICAgICBjb25zdCB3aWR0aCA9IHRoaXMuaW1nU2l6ZUFkZGVkWzBdO1xuICAgICAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuaW1nU2l6ZUFkZGVkWzFdO1xuICAgICAgICAgIHRoaXMuYWRkR2VvUmVmKGRvYywgbWFwLCB3aWR0aCwgaGVpZ2h0LCBiYXNlTWFyZ2lucyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVNZWFzdXJlTGF5ZXIoZG9jLCBtYXAsIGJhc2VNYXJnaW5zKTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5zaG93Tm9ydGhBcnJvdykge1xuICAgICAgICAgICAgY29uc3Qgbm9ydGhBcnJvd0NhbnZhcyA9IGF3YWl0IHRoaXMuY3JlYXRlTm9ydGhEaXJlY3Rpb25BcnJvdyhcbiAgICAgICAgICAgICAgbWFwLnZpZXdDb250cm9sbGVyLmdldFJvdGF0aW9uKClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFkZE5vcnRoQXJyb3dJbkRvYyhcbiAgICAgICAgICAgICAgZG9jLFxuICAgICAgICAgICAgICBub3J0aEFycm93Q2FudmFzLFxuICAgICAgICAgICAgICBiYXNlTWFyZ2lucyxcbiAgICAgICAgICAgICAgbGVnZW5kUG9zdGlvbixcbiAgICAgICAgICAgICAgd2lkdGhcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG9wdGlvbnMubGVnZW5kUG9zaXRpb24gIT09ICdub25lJykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBbJ3RvcGxlZnQnLCAndG9wcmlnaHQnLCAnYm90dG9tbGVmdCcsICdib3R0b21yaWdodCddLmluZGV4T2YoXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5sZWdlbmRQb3NpdGlvblxuICAgICAgICAgICAgICApID4gLTFcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmFkZExlZ2VuZFNhbWVQYWdlKFxuICAgICAgICAgICAgICAgIGRvYyxcbiAgICAgICAgICAgICAgICBtYXAsXG4gICAgICAgICAgICAgICAgYmFzZU1hcmdpbnMsXG4gICAgICAgICAgICAgICAgcmVzb2x1dGlvbixcbiAgICAgICAgICAgICAgICBvcHRpb25zLmxlZ2VuZFBvc2l0aW9uXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMubGVnZW5kUG9zaXRpb24gPT09ICduZXdwYWdlJykge1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmFkZExlZ2VuZChkb2MsIG1hcCwgYmFzZU1hcmdpbnMsIHJlc29sdXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNhdmVEb2MoZG9jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdHVzID09PSBTdWJqZWN0U3RhdHVzLkRvbmUgfHwgc3RhdHVzID09PSBTdWJqZWN0U3RhdHVzLkVycm9yKSB7XG4gICAgICAgICAgdGhpcy5hY3Rpdml0eVNlcnZpY2UudW5yZWdpc3Rlcih0aGlzLmFjdGl2aXR5SWQpO1xuICAgICAgICAgIHN0YXR1cyQubmV4dChTdWJqZWN0U3RhdHVzLkRvbmUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiBzdGF0dXMkO1xuICB9XG4gIC8vIHJlZiBHZW9Nb29zZSBodHRwczovL2dpdGh1Yi5jb20vZ2VvbW9vc2UvZ20zL3RyZWUvbWFpbi9zcmMvZ20zL2NvbXBvbmVudHMvcHJpbnRcbiAgYWRkR2VvUmVmKFxuICAgIGRvYyxcbiAgICBtYXA6IElnb01hcCxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGJhc2VNYXJnaW5zOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXVxuICApIHtcbiAgICBjb25zdCB1bml0ID0gJ21tJztcbiAgICBjb25zdCBkb2NIZWlnaHQgPSBkb2MuaW50ZXJuYWwucGFnZVNpemUuZ2V0SGVpZ2h0KCk7XG5cbiAgICAvLyB4LHkgPSBtYXJnaW4gbGVmdC1ib3R0b20gY29ybmVyIGZvciBpbWcgaW4gcGRmIGRvY1xuICAgIGNvbnN0IHggPSBiYXNlTWFyZ2luc1szXTtcbiAgICBjb25zdCB5ID0gZG9jSGVpZ2h0IC0gYmFzZU1hcmdpbnNbMF0gLSBoZWlnaHQ7XG5cbiAgICBjb25zdCBwZGZfZXh0ZW50cyA9IFt4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHRdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGRmX2V4dGVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHBkZl9leHRlbnRzW2ldID0gdGhpcy5wZGZfdW5pdHMycG9pbnRzKHBkZl9leHRlbnRzW2ldLCB1bml0KTtcbiAgICB9XG4gICAgZG9jLnNldEdlb0FyZWEocGRmX2V4dGVudHMsIHRoaXMubWFwUHJpbnRFeHRlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBtZWFzdXJlIG92ZXJsYXkgb24gdGhlIG1hcCBvbiB0aGUgZG9jdW1lbnQgd2hlbiB0aGUgbWVhc3VyZSBsYXllciBpcyBwcmVzZW50XG4gICAqIEBwYXJhbSAgZG9jIC0gUGRmIGRvY3VtZW50IHdoZXJlIG1lYXN1cmUgdG9vbHRpcCB3aWxsIGJlIGFkZGVkXG4gICAqIEBwYXJhbSAgbWFwIC0gTWFwIG9mIHRoZSBhcHBcbiAgICogQHBhcmFtICBiYXNlTWFyZ2lucyAtIFBhZ2UgbWFyZ2luc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVNZWFzdXJlTGF5ZXIoXG4gICAgZG9jOiBqc1BERixcbiAgICBtYXA6IElnb01hcCxcbiAgICBiYXNlTWFyZ2luczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgKSB7XG4gICAgaWYgKFxuICAgICAgbWFwLmxheWVyQ29udHJvbGxlci5hbGwuZmluZChcbiAgICAgICAgKGxheWVyKSA9PiBsYXllci52aXNpYmxlICYmIGxheWVyLmlkLnN0YXJ0c1dpdGgoJ2lnby1tZWFzdXJlcy0nKVxuICAgICAgKVxuICAgICkge1xuICAgICAgbGV0IGNhbnZhc092ZXJsYXlIVE1MTWVhc3VyZXM7XG4gICAgICBjb25zdCBtYXBPdmVybGF5TWVhc3VyZXNIVE1MID0gbWFwLm9sLmdldE92ZXJsYXlDb250YWluZXIoKTtcbiAgICAgIGF3YWl0IGh0bWwyY2FudmFzKG1hcE92ZXJsYXlNZWFzdXJlc0hUTUwsIHtcbiAgICAgICAgc2NhbGU6IDEsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogbnVsbFxuICAgICAgfSkudGhlbigoZSkgPT4ge1xuICAgICAgICBjYW52YXNPdmVybGF5SFRNTE1lYXN1cmVzID0gZTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRDYW52YXMoZG9jLCBjYW52YXNPdmVybGF5SFRNTE1lYXN1cmVzLCBiYXNlTWFyZ2lucyk7IC8vIHRoaXMgYWRkcyBtZWFzdXJlIG92ZXJsYXlzXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBodG1sIGNvZGUgZm9yIGFsbCBsYXllcnMgbGVnZW5kXG4gICAqIEBwYXJhbSAgbWFwIElnb01hcFxuICAgKiBAcGFyYW0gIHdpZHRoIFRoZSB3aWR0aCB0aGF0IHRoZSBsZWdlbmQgbmVlZCB0byBiZVxuICAgKiBAcmV0dXJuIEh0bWwgY29kZSBmb3IgdGhlIGxlZ2VuZFxuICAgKi9cbiAgZ2V0TGF5ZXJzTGVnZW5kSHRtbChtYXA6IElnb01hcCwgd2lkdGg6IG51bWJlcik6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgbGV0IGh0bWwgPSAnJztcbiAgICAgIGNvbnN0IGxlZ2VuZHMgPSBnZXRMYXllcnNMZWdlbmRzKG1hcC5sYXllckNvbnRyb2xsZXIuYWxsKTtcblxuICAgICAgaWYgKGxlZ2VuZHMuZmlsdGVyKChsKSA9PiBsLmRpc3BsYXkgPT09IHRydWUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBvYnNlcnZlci5uZXh0KGh0bWwpO1xuICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBEZWZpbmUgaW1wb3J0YW50IHN0eWxlIHRvIGJlIHN1cmUgdGhhdCBhbGwgY29udGFpbmVyIGlzIGNvbnZlcnRcbiAgICAgIC8vIHRvIGltYWdlIG5vdCBqdXN0IHZpc2libGUgcGFydFxuICAgICAgaHRtbCArPSAnPHN0eWxlIG1lZGlhPVwic2NyZWVuXCIgdHlwZT1cInRleHQvY3NzXCI+JztcbiAgICAgIGh0bWwgKz1cbiAgICAgICAgJy5odG1sMmNhbnZhcy1jb250YWluZXIgeyB3aWR0aDogJyArXG4gICAgICAgIHdpZHRoICtcbiAgICAgICAgJ21tICFpbXBvcnRhbnQ7IGhlaWdodDogMjAwMHB4ICFpbXBvcnRhbnQ7IH0nO1xuICAgICAgaHRtbCArPSAndGFibGUudGFibGVMZWdlbmQge3RhYmxlLWxheW91dDogYXV0bzt9JztcbiAgICAgIGh0bWwgKz1cbiAgICAgICAgJ2Rpdi5zdHlsZUxlZ2VuZCB7cGFkZGluZy10b3A6IDVweDsgcGFkZGluZy1yaWdodDo1cHg7cGFkZGluZy1sZWZ0OjVweDtwYWRkaW5nLWJvdHRvbTo1cHg7fSc7XG4gICAgICBodG1sICs9ICc8L3N0eWxlPic7XG4gICAgICAvLyBUaGUgZm9udCBzaXplIHdpbGwgYWxzbyBiZSBsb3dlcmVkIGFmdGVyd2FyZHMgKGdsb2JhbGx5IGFsb25nIHRoZSBsZWdlbmQgc2l6ZSlcbiAgICAgIC8vIHRoaXMgYWxsb3dzIGhhdmluZyBhIGdvb2QgcmVsYXRpdmUgZm9udCBzaXplIGhlcmUgYW5kIHRvIGtlZXAgYWp1c3RpbmcgdGhlIGxlZ2VuZCBzaXplXG4gICAgICAvLyB3aGlsZSBrZWVwaW5nIGdvb2QgcmVsYXRpdmUgZm9udCBzaXplXG4gICAgICBodG1sICs9ICc8Zm9udCBzaXplPVwiM1wiIGZhY2U9XCJUaW1lc1wiID4nO1xuICAgICAgaHRtbCArPSAnPGRpdiBjbGFzcz1cInN0eWxlTGVnZW5kXCI+JztcbiAgICAgIGh0bWwgKz0gJzx0YWJsZSBjbGFzcz1cInRhYmxlTGVnZW5kXCIgPic7XG5cbiAgICAgIC8vIEZvciBlYWNoIGxlZ2VuZCwgZGVmaW5lIGFuIGh0bWwgdGFibGUgY2VsbFxuICAgICAgY29uc3QgaW1hZ2VzJCA9IGxlZ2VuZHNcbiAgICAgICAgLmZpbHRlcigobCkgPT4gbC5kaXNwbGF5ICYmIGwuaXNJblJlc29sdXRpb25zUmFuZ2UgPT09IHRydWUpXG4gICAgICAgIC5tYXAoKGxlZ2VuZCkgPT5cbiAgICAgICAgICB0aGlzLmdldERhdGFJbWFnZShsZWdlbmQudXJsKS5waXBlKFxuICAgICAgICAgICAgcnhNYXAoKGRhdGFJbWFnZSkgPT4ge1xuICAgICAgICAgICAgICBsZXQgaHRtbEltZyA9XG4gICAgICAgICAgICAgICAgJzx0cj48dGQ+JyArIGxlZ2VuZC50aXRsZS50b1VwcGVyQ2FzZSgpICsgJzwvdGQ+PC90cj4nO1xuICAgICAgICAgICAgICBodG1sSW1nICs9ICc8dHI+PHRkPjxpbWcgc3JjPVwiJyArIGRhdGFJbWFnZSArICdcIj48L3RkPjwvdHI+JztcbiAgICAgICAgICAgICAgcmV0dXJuIGh0bWxJbWc7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIGZvcmtKb2luKGltYWdlcyQpLnN1YnNjcmliZSgoZGF0YUltYWdlcykgPT4ge1xuICAgICAgICBodG1sID0gZGF0YUltYWdlcy5yZWR1Y2UoKGFjYywgY3VycmVudCkgPT4gKGFjYyArPSBjdXJyZW50KSwgaHRtbCk7XG4gICAgICAgIGh0bWwgKz0gJzwvdGFibGU+JztcbiAgICAgICAgaHRtbCArPSAnPC9kaXY+JztcbiAgICAgICAgb2JzZXJ2ZXIubmV4dChodG1sKTtcbiAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RGF0YUltYWdlKHVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICBjb25zdCBzZWN1cmVJTUcgPSBuZXcgU2VjdXJlSW1hZ2VQaXBlKHRoaXMuaHR0cCwgdGhpcy5jb25maWdTZXJ2aWNlKTtcbiAgICByZXR1cm4gc2VjdXJlSU1HLnRyYW5zZm9ybSh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgdGhlIGxlZ2VuZCBpbiBhIHNpbmdsZSBpbWFnZVxuICAgKiAqIEBwYXJhbSAgZm9ybWF0IC0gSW1hZ2UgZm9ybWF0LiBkZWZhdWx0IHZhbHVlIHRvIFwicG5nXCJcbiAgICogQHJldHVybiBUaGUgaW1hZ2Ugb2YgdGhlIGxlZ2VuZFxuICAgKi9cbiAgYXN5bmMgZ2V0TGF5ZXJzTGVnZW5kSW1hZ2UobWFwLCBmb3JtYXQgPSAncG5nJywgZG9aaXBGaWxlOiBib29sZWFuKSB7XG4gICAgY29uc3Qgc3RhdHVzJCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgLy8gR2V0IGh0bWwgY29kZSBmb3IgdGhlIGxlZ2VuZFxuICAgIGNvbnN0IHdpZHRoID0gMjAwOyAvLyBtaWxpbWV0ZXJzIHVuaXQsIG9yaWdpbmFsbHkgZGVmaW5lIGZvciBkb2N1bWVudCBwZGZcbiAgICBsZXQgaHRtbCA9IGF3YWl0IHRoaXMuZ2V0TGF5ZXJzTGVnZW5kSHRtbChtYXAsIHdpZHRoKS50b1Byb21pc2UoKTtcbiAgICBmb3JtYXQgPSBmb3JtYXQudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIElmIG5vIGxlZ2VuZCBzaG93IE5vIExFR0VORCBpbiBhbiBpbWFnZVxuICAgIGlmIChodG1sLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaHRtbCA9ICc8Zm9udCBzaXplPVwiMTJcIiBmYWNlPVwiQ291cmllciBOZXdcIiA+JztcbiAgICAgIGh0bWwgKz0gJzxkaXYgYWxpZ249XCJjZW50ZXJcIj48Yj5OTyBMRUdFTkQ8L2I+PC9kaXY+JztcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGRpdiB0byBjb250YWluIGh0bWwgY29kZSBmb3IgbGVnZW5kXG4gICAgY29uc3QgZGl2ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZGl2LnN0eWxlLnRvcCA9ICcwJztcbiAgICBkaXYuc3R5bGUuekluZGV4ID0gJy0xJztcbiAgICAvLyBBZGQgaHRtbCBjb2RlIHRvIGNvbnZlcnQgaW4gdGhlIG5ldyB3aW5kb3dcbiAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgYXdhaXQgdGhpcy50aW1lb3V0KDEpO1xuICAgIGNvbnN0IGNhbnZhcyA9IGF3YWl0IGh0bWwyY2FudmFzKGRpdiwgeyB1c2VDT1JTOiB0cnVlIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICB9KTtcbiAgICB0aGlzLnJlbW92ZUh0bWxFbGVtZW50KGRpdik7XG4gICAgaWYgKGNhbnZhcykge1xuICAgICAgbGV0IHN0YXR1cyA9IFN1YmplY3RTdGF0dXMuRG9uZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghZG9aaXBGaWxlKSB7XG4gICAgICAgICAgLy8gU2F2ZSB0aGUgY2FudmFzIGFzIGZpbGVcbiAgICAgICAgICB0aGlzLnNhdmVDYW52YXNJbWFnZUFzRmlsZShjYW52YXMsICdsZWdlbmRJbWFnZScsIGZvcm1hdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gQWRkIHRoZSBjYW52YXMgdG8gemlwXG4gICAgICAgICAgdGhpcy5nZW5lcmF0ZUNhbnZhRmlsZVRvWmlwKGNhbnZhcywgJ2xlZ2VuZEltYWdlJyArICcuJyArIGZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBzdGF0dXMgPSBTdWJqZWN0U3RhdHVzLkVycm9yO1xuICAgICAgfVxuICAgICAgc3RhdHVzJC5uZXh0KHN0YXR1cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXR1cyQ7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUh0bWxFbGVtZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0VGV4dFBkZk9iamVjdFNpemVBbmRNYXJnKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBtYXJnaW5zLFxuICAgIGZvbnQ6IHN0cmluZyxcbiAgICBmb250U2l6ZUluUHQ6IG51bWJlcixcbiAgICBmb250U3R5bGU6IHN0cmluZyxcbiAgICBkb2M6IGpzUERGXG4gICk6IFRleHRQZGZTaXplQW5kTWFyZ2luIHtcbiAgICBjb25zdCBkb2NXaWR0aCA9IGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5nZXRXaWR0aCgpO1xuICAgIGNvbnN0IHBhZ2VXaWR0aCA9IGRvY1dpZHRoIC0gbWFyZ2luc1sxXSAtIG1hcmdpbnNbM107XG5cbiAgICAvLyBpbXBvcnRhbnQgdG8gc2V0IGl0IGZpcnN0LCB0aGUgdGV4dERpbWVuc2lvbiBjaGFuZ2Ugd2hlbiBmb250IGNoYW5nZSFcbiAgICBkb2Muc2V0Rm9udChmb250LCBmb250U3R5bGUpO1xuICAgIGRvYy5zZXRGb250U2l6ZShmb250U2l6ZUluUHQpO1xuXG4gICAgbGV0IHRleHREaW1lbnNpb25zID0gZG9jLmdldFRleHREaW1lbnNpb25zKHRleHQpO1xuICAgIGxldCB0ZXh0TWFyZ2luTGVmdDogbnVtYmVyO1xuXG4gICAgaWYgKHRleHREaW1lbnNpb25zLncgPiBwYWdlV2lkdGgpIHtcbiAgICAgIC8vIGlmIHRoZSB0ZXh0IGlzIHRvIGxvbmcsIHJlZHVjZSBmb250U2l6ZSA3MCUgYW5kIHRoZSBvdmVyZmxvdyB3aXRoIGJlIGN1dCBpbiBwcmludC4uLlxuICAgICAgdGV4dE1hcmdpbkxlZnQgPSAwO1xuICAgICAgZm9udFNpemVJblB0ID0gZm9udFNpemVJblB0ICogMC43O1xuICAgICAgZG9jLnNldEZvbnRTaXplKGZvbnRTaXplSW5QdCk7XG4gICAgICB0ZXh0RGltZW5zaW9ucyA9IGRvYy5nZXRUZXh0RGltZW5zaW9ucyh0ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGV4dE1hcmdpbkxlZnQgPSAocGFnZVdpZHRoIC0gdGV4dERpbWVuc2lvbnMudykgLyAyO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBmb250U2l6ZTogZm9udFNpemVJblB0LFxuICAgICAgbWFyZ2luTGVmdDogdGV4dE1hcmdpbkxlZnQsXG4gICAgICBoZWlnaHQ6IHRleHREaW1lbnNpb25zLmhcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBjb21tZW50IHRvIHRoZSBkb2N1bWVudFxuICAgKiBAcGFyYW0gIGRvYyAtIHBkZiBkb2N1bWVudFxuICAgKiBAcGFyYW0gIGNvbW1lbnQgLSBDb21tZW50IHRvIGFkZCBpbiB0aGUgZG9jdW1lbnRcbiAgICogQHBhcmFtIGJhc2VNYXJnaW5zIC0gdG9wIHwgcmlnaHQgfCBib3R0b20gfCBsZWZ0XG4gICAqIEBwYXJhbSB2ZXJ0aWNhbFNwYWNpbmcgLSBjYWxjdWxhdGUgdGV4dCBwb3NpdGlvbiBhbmQgbWFwIGhlaWdodFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRDb21tZW50KFxuICAgIGRvYzoganNQREYsXG4gICAgY29tbWVudDogc3RyaW5nLFxuICAgIGJhc2VNYXJnaW5zOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB2ZXJ0aWNhbFNwYWNpbmc6IG51bWJlclxuICApIHtcbiAgICAvLyBjYWxjdWxhdGUgbWFwIGltYWdlIGhlaWdodFxuICAgIGJhc2VNYXJnaW5zWzJdICs9IHZlcnRpY2FsU3BhY2luZztcblxuICAgIGNvbnN0IHhQb3NpdGlvbiA9IGJhc2VNYXJnaW5zWzNdOyAvL21hcmdpbiBsZWZ0IGFuZCBib3R0b20gaXMgZml4XG4gICAgY29uc3QgbWFyZ2luQm90dG9tID0gYmFzZU1hcmdpbnNbMl07XG4gICAgLy8gY2FsY3VsYXRlIHRleHQgcG9zaXRpb24gWVxuICAgIGNvbnN0IHlQb3NpdGlvbiA9XG4gICAgICBkb2MuaW50ZXJuYWwucGFnZVNpemUuaGVpZ2h0IC0gbWFyZ2luQm90dG9tICsgdmVydGljYWxTcGFjaW5nO1xuXG4gICAgdGhpcy5hZGRUZXh0SW5QZGZEb2MoXG4gICAgICBkb2MsXG4gICAgICBjb21tZW50LFxuICAgICAgdGhpcy5URVhUUERGRk9OVC5jb21tZW50Rm9udCxcbiAgICAgIHRoaXMuVEVYVFBERkZPTlQuY29tbWVudEZvbnRTdHlsZSxcbiAgICAgIHRoaXMuVEVYVFBERkZPTlQuY29tbWVudEZvbnRTaXplLFxuICAgICAgeFBvc2l0aW9uLFxuICAgICAgeVBvc2l0aW9uLFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRleHRJblBkZkRvYyhcbiAgICBkb2M6IGpzUERGLFxuICAgIHRleHRUb0FkZDogc3RyaW5nLFxuICAgIHRleHRGb250OiBzdHJpbmcsXG4gICAgdGV4dEZvbnRTdHlsZTogc3RyaW5nLFxuICAgIHRleHRGb250U2l6ZTogbnVtYmVyLFxuICAgIHRleHRNYXJnaW5MZWZ0OiBudW1iZXIsXG4gICAgdGV4dE1hcmdpblRvcDogbnVtYmVyLFxuICAgIGlzQ29tbWVudCA9IGZhbHNlXG4gICkge1xuICAgIGRvYy5zZXRGb250KHRleHRGb250LCB0ZXh0Rm9udFN0eWxlKTtcbiAgICBkb2Muc2V0Rm9udFNpemUodGV4dEZvbnRTaXplKTtcblxuICAgIGlmIChpc0NvbW1lbnQpIHtcbiAgICAgIHRleHRUb0FkZCA9IGRvYy5zcGxpdFRleHRUb1NpemUoXG4gICAgICAgIHRleHRUb0FkZCxcbiAgICAgICAgZG9jLmludGVybmFsLnBhZ2VTaXplLmdldFdpZHRoKCkgLSB0ZXh0TWFyZ2luTGVmdCAqIDNcbiAgICAgICk7XG4gICAgfVxuICAgIGRvYy50ZXh0KHRleHRUb0FkZCwgdGV4dE1hcmdpbkxlZnQsIHRleHRNYXJnaW5Ub3ApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhdHRyaWJ1dGlvbiBhbmQvb3IgKHByb2plY3Rpb24gYW5kL29yIHNjYWxlKSB0byB0aGUgZG9jdW1lbnRcbiAgICogQHBhcmFtICBtYXAgLSBNYXAgb2YgdGhlIGFwcFxuICAgKiBAcGFyYW0gIGRvYyAtIHBkZiBkb2N1bWVudFxuICAgKiBAcGFyYW0gIG9wdGlvbnMgLSBQcmludCBvcHRpb25zXG4gICAqIEBwYXJhbSAgcmVzb2x1dGlvbiAtIGNhcnQgcmVzb2x1dGlvblxuICAgKiBAcGFyYW0gYmFzZU1hcmdpbnMgLSB0b3AgfCByaWdodCB8IGJvdHRvbSB8IGxlZnRcbiAgICogQHBhcmFtIHZlcnRpY2FsU3BhY2luZyAtIGNhbGN1bGF0ZSB0ZXh0IHBvc2l0aW9uIGFuZCBtYXAgaGVpZ2h0XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUZvb3RlcihcbiAgICBtYXA6IElnb01hcCxcbiAgICBkb2M6IGpzUERGLFxuICAgIG9wdGlvbnM6IFByaW50T3B0aW9ucyxcbiAgICByZXNvbHV0aW9uOiBudW1iZXIsXG4gICAgdmVydGljYWxTcGFjaW5nOiBudW1iZXIsXG4gICAgYmFzZU1hcmdpbnM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICkge1xuICAgIGxldCB0ZXh0ID0gJyc7XG5cbiAgICBjb25zdCBhdHRyaWJ1dGlvblRleHQ6IHN0cmluZyA9IHRoaXMuZ2V0QXR0cmlidXRpb25UZXh0KG1hcCk7XG4gICAgaWYgKGF0dHJpYnV0aW9uVGV4dCkge1xuICAgICAgdGV4dCArPSBhdHRyaWJ1dGlvblRleHQgKyAnLiAnO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5zaG93UHJvamVjdGlvbiA9PT0gdHJ1ZSB8fCBvcHRpb25zLnNob3dTY2FsZSA9PT0gdHJ1ZSkge1xuICAgICAgdGV4dCArPSB0aGlzLmdldFByb2pTY2FsZShtYXAsIG9wdGlvbnMsIHJlc29sdXRpb24pO1xuICAgIH1cblxuICAgIGlmICh0ZXh0KSB7XG4gICAgICBiYXNlTWFyZ2luc1syXSArPSB2ZXJ0aWNhbFNwYWNpbmc7XG4gICAgfVxuXG4gICAgY29uc3QgeFBvc2l0aW9uID0gYmFzZU1hcmdpbnNbM107XG4gICAgY29uc3QgbWFyZ2luQm90dG9tID0gYmFzZU1hcmdpbnNbMl07XG4gICAgLy8gY2FsY3VsYXRlIHRleHQgcG9zaXRpb24gWVxuICAgIGNvbnN0IHlQb3NpdGlvbiA9XG4gICAgICBkb2MuaW50ZXJuYWwucGFnZVNpemUuaGVpZ2h0IC0gbWFyZ2luQm90dG9tICsgdmVydGljYWxTcGFjaW5nO1xuXG4gICAgdGhpcy5hZGRUZXh0SW5QZGZEb2MoXG4gICAgICBkb2MsXG4gICAgICB0ZXh0LFxuICAgICAgdGhpcy5URVhUUERGRk9OVC5jb21tZW50Rm9udCxcbiAgICAgIHRoaXMuVEVYVFBERkZPTlQuY29tbWVudEZvbnRTdHlsZSxcbiAgICAgIHRoaXMuVEVYVFBERkZPTlQuY29tbWVudEZvbnRTaXplLFxuICAgICAgeFBvc2l0aW9uLFxuICAgICAgeVBvc2l0aW9uXG4gICAgKTtcbiAgfVxuXG4gIGdldEF0dHJpYnV0aW9uVGV4dChtYXA6IElnb01hcCk6IHN0cmluZyB7XG4gICAgY29uc3QgbWFwT3ZlcmxheUh0bWwgPSBtYXAub2wuZ2V0T3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudCgpIGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IGh0bWxBdHRyaWJ1dGlvbiA9IG1hcE92ZXJsYXlIdG1sXG4gICAgICAuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnb2wtYXR0cmlidXRpb24nKVswXVxuICAgICAgLmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MRWxlbWVudDtcbiAgICBodG1sQXR0cmlidXRpb24uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2J1dHRvbicpWzBdLnJlbW92ZSgpO1xuICAgIHJldHVybiBodG1sQXR0cmlidXRpb24uaW5uZXJUZXh0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQcm9qU2NhbGUoXG4gICAgbWFwOiBJZ29NYXAsXG4gICAgb3B0aW9uczogUHJpbnRPcHRpb25zLFxuICAgIGRwaTogbnVtYmVyXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgdHJhbnNsYXRlID0gdGhpcy5sYW5ndWFnZVNlcnZpY2UudHJhbnNsYXRlO1xuICAgIGxldCB0ZXh0UHJvalNjYWxlID0gJyc7XG4gICAgaWYgKG9wdGlvbnMuc2hvd1Byb2plY3Rpb24gPT09IHRydWUpIHtcbiAgICAgIGNvbnN0IHByb2pUZXh0ID0gdHJhbnNsYXRlLmluc3RhbnQoJ2lnby5nZW8ucHJpbnRGb3JtLnByb2plY3Rpb24nKTtcbiAgICAgIHRleHRQcm9qU2NhbGUgKz0gcHJvalRleHQgKyAnOiAnICsgbWFwLnByb2plY3Rpb247XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnNob3dTY2FsZSA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKG9wdGlvbnMuc2hvd1Byb2plY3Rpb24gPT09IHRydWUpIHtcbiAgICAgICAgdGV4dFByb2pTY2FsZSArPSAnICAgJztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNjYWxlVGV4dCA9IHRyYW5zbGF0ZS5pbnN0YW50KCdpZ28uZ2VvLnByaW50Rm9ybS5zY2FsZScpO1xuICAgICAgY29uc3QgbWFwU2NhbGUgPSBtYXAudmlld0NvbnRyb2xsZXIuZ2V0U2NhbGUoZHBpKTtcbiAgICAgIHRleHRQcm9qU2NhbGUgKz0gc2NhbGVUZXh0ICsgJzogfiAxIC8gJyArIGZvcm1hdFNjYWxlKG1hcFNjYWxlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHRQcm9qU2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHRoZSBsZWdlbmQgdG8gdGhlIGRvY3VtZW50XG4gICAqIEBwYXJhbSAgZG9jIC0gUGRmIGRvY3VtZW50IHdoZXJlIGxlZ2VuZCB3aWxsIGJlIGFkZGVkXG4gICAqIEBwYXJhbSAgbWFwIC0gTWFwIG9mIHRoZSBhcHBcbiAgICogQHBhcmFtICBtYXJnaW5zIC0gUGFnZSBtYXJnaW5zXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFkZExlZ2VuZChcbiAgICBkb2M6IGpzUERGLFxuICAgIG1hcDogSWdvTWFwLFxuICAgIG1hcmdpbnM6IG51bWJlcltdLFxuICAgIHJlc29sdXRpb246IG51bWJlclxuICApIHtcbiAgICAvLyBHZXQgaHRtbCBjb2RlIGZvciB0aGUgbGVnZW5kXG4gICAgY29uc3Qgd2lkdGggPSBkb2MuaW50ZXJuYWwucGFnZVNpemUud2lkdGg7XG4gICAgY29uc3QgaHRtbCA9IGF3YWl0IHRoaXMuZ2V0TGF5ZXJzTGVnZW5kSHRtbChtYXAsIHdpZHRoKS50b1Byb21pc2UoKTtcbiAgICAvLyBJZiBubyBsZWdlbmQsIHNhdmUgdGhlIG1hcCBkaXJlY3RseVxuICAgIGlmIChodG1sID09PSAnJykge1xuICAgICAgYXdhaXQgdGhpcy5zYXZlRG9jKGRvYyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGRpdiB0byBjb250YWluIGh0bWwgY29kZSBmb3IgbGVnZW5kXG4gICAgY29uc3QgZGl2ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZGl2LnN0eWxlLnRvcCA9ICcwJztcbiAgICBkaXYuc3R5bGUuekluZGV4ID0gJy0xJztcblxuICAgIC8vIEFkZCBodG1sIGNvZGUgdG8gY29udmVydCBpbiB0aGUgbmV3IHdpbmRvd1xuICAgIHdpbmRvdy5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgZGl2LmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICBhd2FpdCB0aGlzLnRpbWVvdXQoMSk7XG4gICAgY29uc3QgY2FudmFzID0gYXdhaXQgaHRtbDJjYW52YXMoZGl2LCB7IHVzZUNPUlM6IHRydWUgfSkuY2F0Y2goKGUpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgIH0pO1xuICAgIHRoaXMucmVtb3ZlSHRtbEVsZW1lbnQoZGl2KTtcbiAgICBpZiAoY2FudmFzKSB7XG4gICAgICBjb25zdCBwb3VyY2VudGFnZVJlZHVjdGlvbiA9IDAuODU7XG4gICAgICBjb25zdCBpbWFnZVNpemUgPSBbXG4gICAgICAgIChwb3VyY2VudGFnZVJlZHVjdGlvbiAqICgyNS40ICogY2FudmFzLndpZHRoKSkgLyByZXNvbHV0aW9uLFxuICAgICAgICAocG91cmNlbnRhZ2VSZWR1Y3Rpb24gKiAoMjUuNCAqIGNhbnZhcy5oZWlnaHQpKSAvIHJlc29sdXRpb25cbiAgICAgIF07XG4gICAgICBkb2MuYWRkUGFnZSgpO1xuICAgICAgY29uc3QgaW1nRGF0YSA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xuICAgICAgZG9jLmFkZEltYWdlKGltZ0RhdGEsICdQTkcnLCAxMCwgMTAsIGltYWdlU2l6ZVswXSwgaW1hZ2VTaXplWzFdKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNhdmVEb2MoZG9jKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgdGhlIGxlZ2VuZCB0byB0aGUgZG9jdW1lbnRcbiAgICogQHBhcmFtICBkb2MgLSBQZGYgZG9jdW1lbnQgd2hlcmUgbGVnZW5kIHdpbGwgYmUgYWRkZWRcbiAgICogQHBhcmFtICBtYXAgLSBNYXAgb2YgdGhlIGFwcFxuICAgKiBAcGFyYW0gIGJhc2VNYXJnaW5zIC0gUGFnZSBtYXJnaW5zXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFkZExlZ2VuZFNhbWVQYWdlKFxuICAgIGRvYzoganNQREYsXG4gICAgbWFwOiBJZ29NYXAsXG4gICAgYmFzZU1hcmdpbnM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHJlc29sdXRpb246IG51bWJlcixcbiAgICBsZWdlbmRQb3NpdGlvbjogc3RyaW5nXG4gICkge1xuICAgIC8vIEdldCBodG1sIGNvZGUgZm9yIHRoZSBsZWdlbmRcbiAgICBjb25zdCB3aWR0aCA9IGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS53aWR0aDtcbiAgICBjb25zdCBodG1sID0gYXdhaXQgdGhpcy5nZXRMYXllcnNMZWdlbmRIdG1sKG1hcCwgd2lkdGgpLnRvUHJvbWlzZSgpO1xuICAgIC8vIElmIG5vIGxlZ2VuZCwgc2F2ZSB0aGUgbWFwIGRpcmVjdGx5XG4gICAgaWYgKGh0bWwgPT09ICcnKSB7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVEb2MoZG9jKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDcmVhdGUgZGl2IHRvIGNvbnRhaW4gaHRtbCBjb2RlIGZvciBsZWdlbmRcbiAgICBjb25zdCBkaXYgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBkaXYuc3R5bGUudG9wID0gJzAnO1xuICAgIGRpdi5zdHlsZS56SW5kZXggPSAnLTEnO1xuICAgIC8vIEFkZCBodG1sIGNvZGUgdG8gY29udmVydCBpbiB0aGUgbmV3IHdpbmRvd1xuICAgIHdpbmRvdy5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgZGl2LmlubmVySFRNTCA9IGh0bWw7XG4gICAgYXdhaXQgdGhpcy50aW1lb3V0KDEpO1xuICAgIGNvbnN0IGNhbnZhcyA9IGF3YWl0IGh0bWwyY2FudmFzKGRpdiwgeyB1c2VDT1JTOiB0cnVlIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICB9KTtcbiAgICB0aGlzLnJlbW92ZUh0bWxFbGVtZW50KGRpdik7XG4gICAgbGV0IG1hcmdpbnNMZWdlbmQ7XG4gICAgaWYgKGNhbnZhcykge1xuICAgICAgY29uc3QgcG91cmNlbnRhZ2VSZWR1Y3Rpb24gPSAwLjg1O1xuICAgICAgY29uc3QgaW1hZ2VTaXplID0gW1xuICAgICAgICAocG91cmNlbnRhZ2VSZWR1Y3Rpb24gKiAoMjUuNCAqIGNhbnZhcy53aWR0aCkpIC8gcmVzb2x1dGlvbixcbiAgICAgICAgKHBvdXJjZW50YWdlUmVkdWN0aW9uICogKDI1LjQgKiBjYW52YXMuaGVpZ2h0KSkgLyByZXNvbHV0aW9uXG4gICAgICBdO1xuICAgICAgLy8gTW92ZSB0aGUgbGVnZW5kIHRvIHRoZSBjb3JyZWN0IHBvc2l0aW9uIG9uIHRoZSBwYWdlXG4gICAgICBpZiAobGVnZW5kUG9zaXRpb24gPT09ICdib3R0b21yaWdodCcpIHtcbiAgICAgICAgbWFyZ2luc0xlZ2VuZCA9IFtcbiAgICAgICAgICBkb2MuaW50ZXJuYWwucGFnZVNpemUuaGVpZ2h0IC0gYmFzZU1hcmdpbnNbMl0gLSBpbWFnZVNpemVbMV0sXG4gICAgICAgICAgYmFzZU1hcmdpbnNbMV0sXG4gICAgICAgICAgYmFzZU1hcmdpbnNbMl0sXG4gICAgICAgICAgZG9jLmludGVybmFsLnBhZ2VTaXplLndpZHRoIC0gYmFzZU1hcmdpbnNbMV0gLSBpbWFnZVNpemVbMF1cbiAgICAgICAgXTtcbiAgICAgIH0gZWxzZSBpZiAobGVnZW5kUG9zaXRpb24gPT09ICd0b3ByaWdodCcpIHtcbiAgICAgICAgbWFyZ2luc0xlZ2VuZCA9IFtcbiAgICAgICAgICBiYXNlTWFyZ2luc1swXSxcbiAgICAgICAgICBiYXNlTWFyZ2luc1sxXSxcbiAgICAgICAgICBkb2MuaW50ZXJuYWwucGFnZVNpemUuaGVpZ2h0IC0gYmFzZU1hcmdpbnNbMF0gLSBpbWFnZVNpemVbMV0sXG4gICAgICAgICAgZG9jLmludGVybmFsLnBhZ2VTaXplLndpZHRoIC0gYmFzZU1hcmdpbnNbMV0gLSBpbWFnZVNpemVbMF1cbiAgICAgICAgXTtcbiAgICAgIH0gZWxzZSBpZiAobGVnZW5kUG9zaXRpb24gPT09ICdib3R0b21sZWZ0Jykge1xuICAgICAgICAvLyBXaGVuIHRoZSBsZWdlbmQgaXMgaW4gdGhlIGJvdHRvbSBsZWZ0LCByYWlzZSB0aGUgbGVnZW5kIHNsaWdodGx5IHVwd2FyZCBzbyB0aGF0IGF0dHJpYnV0aW9ucyBhcmUgdmlzaWJsZVxuICAgICAgICBtYXJnaW5zTGVnZW5kID0gW1xuICAgICAgICAgIGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5oZWlnaHQgLSBiYXNlTWFyZ2luc1syXSAtIGltYWdlU2l6ZVsxXSxcbiAgICAgICAgICBkb2MuaW50ZXJuYWwucGFnZVNpemUud2lkdGggLSBiYXNlTWFyZ2luc1szXSAtIGltYWdlU2l6ZVswXSxcbiAgICAgICAgICBiYXNlTWFyZ2luc1syXSxcbiAgICAgICAgICBiYXNlTWFyZ2luc1szXVxuICAgICAgICBdO1xuICAgICAgfSBlbHNlIGlmIChsZWdlbmRQb3NpdGlvbiA9PT0gJ3RvcGxlZnQnKSB7XG4gICAgICAgIG1hcmdpbnNMZWdlbmQgPSBbXG4gICAgICAgICAgYmFzZU1hcmdpbnNbMF0sXG4gICAgICAgICAgZG9jLmludGVybmFsLnBhZ2VTaXplLndpZHRoIC0gYmFzZU1hcmdpbnNbM10gLSBpbWFnZVNpemVbMF0sXG4gICAgICAgICAgZG9jLmludGVybmFsLnBhZ2VTaXplLmhlaWdodCAtIGJhc2VNYXJnaW5zWzBdIC0gaW1hZ2VTaXplWzFdLFxuICAgICAgICAgIGJhc2VNYXJnaW5zWzNdXG4gICAgICAgIF07XG4gICAgICB9XG4gICAgICB0aGlzLmFkZENhbnZhcyhkb2MsIGNhbnZhcywgbWFyZ2luc0xlZ2VuZCk7IC8vIHRoaXMgYWRkcyB0aGUgbGVnZW5kXG4gICAgICBhd2FpdCB0aGlzLnNhdmVEb2MoZG9jKTtcbiAgICB9XG4gIH1cblxuICBkZWZpbmVOYkZpbGVUb1Byb2Nlc3MobmJGaWxlVG9Qcm9jZXNzKSB7XG4gICAgdGhpcy5uYkZpbGVUb1Byb2Nlc3MgPSBuYkZpbGVUb1Byb2Nlc3M7XG4gIH1cblxuICBwcml2YXRlIHRpbWVvdXQobXMpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2FudmFzKFxuICAgIGRvYzoganNQREYsXG4gICAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCxcbiAgICBiYXNlTWFyZ2luczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgKSB7XG4gICAgbGV0IGltYWdlO1xuICAgIGlmIChjYW52YXMpIHtcbiAgICAgIGltYWdlID0gY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gICAgfVxuXG4gICAgaWYgKGltYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChpbWFnZS5sZW5ndGggPCAyMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnV2FybmluZzogQW4gaW1hZ2UgY2Fubm90IGJlIHByaW50IGluIHBkZiBmaWxlJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGltYWdlU2l6ZSA9IHRoaXMuZ2V0SW1hZ2VTaXplVG9GaXRQZGYoZG9jLCBjYW52YXMsIGJhc2VNYXJnaW5zKTtcbiAgICAgIGRvYy5hZGRJbWFnZShcbiAgICAgICAgaW1hZ2UsXG4gICAgICAgICdQTkcnLFxuICAgICAgICBiYXNlTWFyZ2luc1szXSxcbiAgICAgICAgYmFzZU1hcmdpbnNbMF0sXG4gICAgICAgIGltYWdlU2l6ZVswXSxcbiAgICAgICAgaW1hZ2VTaXplWzFdXG4gICAgICApO1xuICAgICAgZG9jLnJlY3QoYmFzZU1hcmdpbnNbM10sIGJhc2VNYXJnaW5zWzBdLCBpbWFnZVNpemVbMF0sIGltYWdlU2l6ZVsxXSk7XG4gICAgICB0aGlzLmltZ1NpemVBZGRlZCA9IGltYWdlU2l6ZTsgLy8ga2VlcCBpbWcgc2l6ZSBmb3IgZ2VvcmVmIGxhdGVyXG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETyBmaXggcHJpbnRpbmcgd2l0aCBpbWFnZSByZXNvbHV0aW9uXG4gIGFkZE1hcChcbiAgICBkb2M6IGpzUERGLFxuICAgIG1hcDogSWdvTWFwLFxuICAgIHJlc29sdXRpb246IG51bWJlcixcbiAgICBpbWFnZURpbWVuc2lvbnM6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgYmFzZU1hcmdpbnM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gICkge1xuICAgIGNvbnN0IG1hcFNpemU6IG51bWJlcltdID0gbWFwLm9sLmdldFNpemUoKTtcbiAgICBjb25zdCB2aWV3UmVzb2x1dGlvbjogbnVtYmVyID0gbWFwLm9sLmdldFZpZXcoKS5nZXRSZXNvbHV0aW9uKCk7XG4gICAgY29uc3QgZGltZW5zaW9uUGl4ZWxzID0gdGhpcy5zZXRNYXBSZXNvbHV0aW9uKFxuICAgICAgbWFwLFxuICAgICAgaW1hZ2VEaW1lbnNpb25zLFxuICAgICAgcmVzb2x1dGlvbixcbiAgICAgIHZpZXdSZXNvbHV0aW9uXG4gICAgKTtcbiAgICBjb25zdCBzdGF0dXMkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGxldCB0aW1lb3V0O1xuICAgIG1hcC5vbC5vbmNlKCdyZW5kZXJjb21wbGV0ZScsIGFzeW5jIChldmVudDogYW55KSA9PiB7XG4gICAgICBjb25zdCBtYXBDYW52YXMgPSBldmVudC50YXJnZXRcbiAgICAgICAgLmdldFZpZXdwb3J0KClcbiAgICAgICAgLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdjYW52YXMnKSBhcyBIVE1MQ29sbGVjdGlvbk9mPEhUTUxDYW52YXNFbGVtZW50PjtcblxuICAgICAgY29uc3QgbWFwUmVzdWx0Q2FudmFzID0gYXdhaXQgdGhpcy5kcmF3TWFwKGRpbWVuc2lvblBpeGVscywgbWFwQ2FudmFzKTtcblxuICAgICAgdGhpcy5tYXBQcmludEV4dGVudCA9IG1hcC52aWV3Q29udHJvbGxlci5nZXRFeHRlbnQoJ0VQU0c6Mzg1NycpO1xuXG4gICAgICB0aGlzLnJlc2V0T3JpZ2luYWxNYXBTaXplKG1hcCwgbWFwU2l6ZSwgdmlld1Jlc29sdXRpb24pO1xuICAgICAgYXdhaXQgdGhpcy5kcmF3TWFwQ29udHJvbHMobWFwLCBtYXBSZXN1bHRDYW52YXMpO1xuXG4gICAgICBjb25zdCBtYXBTdGF0dXMkJCA9IG1hcC5zdGF0dXMkLnN1YnNjcmliZSgobWFwU3RhdHVzOiBTdWJqZWN0U3RhdHVzKSA9PiB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgaWYgKG1hcFN0YXR1cyAhPT0gU3ViamVjdFN0YXR1cy5Eb25lKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG1hcFN0YXR1cyQkLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIGxldCBzdGF0dXMgPSBTdWJqZWN0U3RhdHVzLkRvbmU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKG1hcFJlc3VsdENhbnZhcy53aWR0aCAhPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5hZGRDYW52YXMoZG9jLCBtYXBSZXN1bHRDYW52YXMsIGJhc2VNYXJnaW5zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHN0YXR1cyA9IFN1YmplY3RTdGF0dXMuRXJyb3I7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5lcnJvcihcbiAgICAgICAgICAgICdpZ28uZ2VvLnByaW50Rm9ybS5jb3JzRXJyb3JNZXNzYWdlQm9keScsXG4gICAgICAgICAgICAnaWdvLmdlby5wcmludEZvcm0uY29yc0Vycm9yTWVzc2FnZUhlYWRlcidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyQubmV4dChzdGF0dXMpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIElmIG5vIGxvYWRpbmcgYXMgc3RhcnRlZCBhZnRlciAyMDBtcywgdGhlbiBwcm9iYWJseSBubyBsb2FkaW5nXG4gICAgICAvLyBpcyByZXF1aXJlZC5cbiAgICAgIHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIG1hcFN0YXR1cyQkLnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgbGV0IHN0YXR1cyA9IFN1YmplY3RTdGF0dXMuRG9uZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAobWFwUmVzdWx0Q2FudmFzLndpZHRoICE9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmFkZENhbnZhcyhkb2MsIG1hcFJlc3VsdENhbnZhcywgYmFzZU1hcmdpbnMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgc3RhdHVzID0gU3ViamVjdFN0YXR1cy5FcnJvcjtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmVycm9yKFxuICAgICAgICAgICAgJ2lnby5nZW8ucHJpbnRGb3JtLmNvcnNFcnJvck1lc3NhZ2VCb2R5JyxcbiAgICAgICAgICAgICdpZ28uZ2VvLnByaW50Rm9ybS5jb3JzRXJyb3JNZXNzYWdlSGVhZGVyJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXNldE9yaWdpbmFsTWFwU2l6ZShtYXAsIG1hcFNpemUsIHZpZXdSZXNvbHV0aW9uKTtcbiAgICAgICAgc3RhdHVzJC5uZXh0KHN0YXR1cyk7XG4gICAgICB9LCAyMDApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHN0YXR1cyQ7XG4gIH1cblxuICBwcml2YXRlIHNldE1hcFJlc29sdXRpb24oXG4gICAgbWFwOiBJZ29NYXAsXG4gICAgaW5pdGlhbFNpemU6IFtudW1iZXIsIG51bWJlcl0sXG4gICAgcmVzb2x1dGlvbjogbnVtYmVyLFxuICAgIHZpZXdSZXNvbHV0aW9uOiBudW1iZXJcbiAgKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgbWFwU2l6ZSA9IG1hcC5vbC5nZXRTaXplKCk7XG4gICAgY29uc3Qgd2lkdGhQaXhlbHMgPSBNYXRoLnJvdW5kKChpbml0aWFsU2l6ZVswXSAqIHJlc29sdXRpb24pIC8gMjUuNCk7XG4gICAgY29uc3QgaGVpZ2h0UGl4ZWxzID0gTWF0aC5yb3VuZCgoaW5pdGlhbFNpemVbMV0gKiByZXNvbHV0aW9uKSAvIDI1LjQpO1xuXG4gICAgLy8gU2V0IHByaW50IHNpemVcbiAgICBjb25zdCBwcmludFNpemUgPSBbd2lkdGhQaXhlbHMsIGhlaWdodFBpeGVsc107XG4gICAgbWFwLm9sLnNldFNpemUocHJpbnRTaXplKTtcbiAgICBjb25zdCBzY2FsaW5nID0gTWF0aC5taW4oXG4gICAgICB3aWR0aFBpeGVscyAvIG1hcFNpemVbMF0sXG4gICAgICBoZWlnaHRQaXhlbHMgLyBtYXBTaXplWzFdXG4gICAgKTtcbiAgICBtYXAub2wuZ2V0VmlldygpLnNldFJlc29sdXRpb24odmlld1Jlc29sdXRpb24gLyBzY2FsaW5nKTtcblxuICAgIHJldHVybiBbd2lkdGhQaXhlbHMsIGhlaWdodFBpeGVsc107XG4gIH1cblxuICBwcml2YXRlIHJlc2V0T3JpZ2luYWxNYXBTaXplKFxuICAgIG1hcDogSWdvTWFwLFxuICAgIGluaXRpYWxTaXplOiBudW1iZXJbXSxcbiAgICB2aWV3UmVzb2x1dGlvbjogbnVtYmVyXG4gICkge1xuICAgIG1hcC5vbC5zZXRTaXplKGluaXRpYWxTaXplKTtcbiAgICBtYXAub2wuZ2V0VmlldygpLnNldFJlc29sdXRpb24odmlld1Jlc29sdXRpb24pO1xuICAgIG1hcC5vbC51cGRhdGVTaXplKCk7XG4gICAgbWFwLm9sLnJlbmRlclN5bmMoKTtcbiAgfVxuXG4gIGFzeW5jIGRyYXdNYXAoXG4gICAgc2l6ZTogbnVtYmVyW10sXG4gICAgbWFwQ2FudmFzOiBIVE1MQ29sbGVjdGlvbk9mPEhUTUxDYW52YXNFbGVtZW50PlxuICApOiBQcm9taXNlPEhUTUxDYW52YXNFbGVtZW50PiB7XG4gICAgY29uc3QgbWFwUmVzdWx0Q2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgbWFwUmVzdWx0Q2FudmFzLndpZHRoID0gc2l6ZVswXTtcbiAgICBtYXBSZXN1bHRDYW52YXMuaGVpZ2h0ID0gc2l6ZVsxXTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLWZvci1vZlxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBtYXBDYW52YXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBjYW52YXMgPSBtYXBDYW52YXNbaW5kZXhdO1xuICAgICAgaWYgKGNhbnZhcy53aWR0aCA+IDApIHtcbiAgICAgICAgdGhpcy5oYW5kbGVDYW52YXMoY2FudmFzLCBtYXBSZXN1bHRDYW52YXMpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWFwUmVzdWx0Q2FudmFzO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDYW52YXMoXG4gICAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCxcbiAgICBtYXBSZXN1bHRDYW52YXM6IEhUTUxDYW52YXNFbGVtZW50XG4gICkge1xuICAgIGNvbnN0IG1hcENvbnRleHRSZXN1bHQgPSBtYXBSZXN1bHRDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjb25zdCBvcGFjaXR5ID0gY2FudmFzLnBhcmVudEVsZW1lbnQuc3R5bGUub3BhY2l0eSB8fCBjYW52YXMuc3R5bGUub3BhY2l0eTtcbiAgICBtYXBDb250ZXh0UmVzdWx0Lmdsb2JhbEFscGhhID0gb3BhY2l0eSA9PT0gJycgPyAxIDogTnVtYmVyKG9wYWNpdHkpO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNhbnZhcy5zdHlsZS50cmFuc2Zvcm07XG4gICAgbGV0IG1hdHJpeDogbnVtYmVyW107XG4gICAgaWYgKHRyYW5zZm9ybSkge1xuICAgICAgLy8gR2V0IHRoZSB0cmFuc2Zvcm0gcGFyYW1ldGVycyBmcm9tIHRoZSBzdHlsZSdzIHRyYW5zZm9ybSBtYXRyaXhcbiAgICAgIG1hdHJpeCA9IHRyYW5zZm9ybVxuICAgICAgICAubWF0Y2goL15tYXRyaXhcXCgoW15cXChdKilcXCkkLylbMV1cbiAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgLm1hcChOdW1iZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXRyaXggPSBbXG4gICAgICAgIHBhcnNlRmxvYXQoY2FudmFzLnN0eWxlLndpZHRoKSAvIGNhbnZhcy53aWR0aCxcbiAgICAgICAgMCxcbiAgICAgICAgMCxcbiAgICAgICAgcGFyc2VGbG9hdChjYW52YXMuc3R5bGUuaGVpZ2h0KSAvIGNhbnZhcy5oZWlnaHQsXG4gICAgICAgIDAsXG4gICAgICAgIDBcbiAgICAgIF07XG4gICAgfVxuICAgIENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuc2V0VHJhbnNmb3JtLmFwcGx5KFxuICAgICAgbWFwQ29udGV4dFJlc3VsdCxcbiAgICAgIG1hdHJpeFxuICAgICk7XG4gICAgY29uc3QgYmFja2dyb3VuZENvbG9yID0gY2FudmFzLnBhcmVudEVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yO1xuICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIG1hcENvbnRleHRSZXN1bHQuZmlsbFN0eWxlID0gYmFja2dyb3VuZENvbG9yO1xuICAgICAgbWFwQ29udGV4dFJlc3VsdC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgIH1cbiAgICBtYXBDb250ZXh0UmVzdWx0LmRyYXdJbWFnZShjYW52YXMsIDAsIDApO1xuICAgIG1hcENvbnRleHRSZXN1bHQuZ2xvYmFsQWxwaGEgPSAxO1xuICAgIC8vIHJlc2V0IGNhbnZhcyB0cmFuc2Zvcm0gdG8gaW5pdGlhbFxuICAgIG1hcENvbnRleHRSZXN1bHQuc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuICB9XG5cbiAgYXN5bmMgZHJhd01hcENvbnRyb2xzKG1hcDogSWdvTWFwLCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIC8vIEdldCB0aGUgc2NhbGUgYW5kIGF0dHJpYnV0aW9uXG4gICAgLy8gd2UgdXNlIGNsb25lTm9kZSB0byBtb2RpZnkgdGhlIG5vZGVzIHRvIHByaW50IHdpdGhvdXQgbW9kaWZ5aW5nIGl0IG9uIHRoZSBwYWdlLCB1c2luZyBkZWVwOnRydWUgdG8gZ2V0IGNoaWxkcmVuXG4gICAgY29uc3QgbWFwT3ZlcmxheUhUTUwgPSBtYXAub2xcbiAgICAgIC5nZXRPdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50KClcbiAgICAgIC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzZXQgJ092ZXJsYXlDb250YWluZXInIHNpemUgdG8gcHJpbnQgc2l6ZVxuICAgIG1hcE92ZXJsYXlIVE1MLnN0eWxlLndpZHRoID0gY2FudmFzLndpZHRoICsgJ3B4JztcbiAgICBtYXBPdmVybGF5SFRNTC5zdHlsZS5oZWlnaHQgPSBjYW52YXMuaGVpZ2h0ICsgJ3B4JztcbiAgICAvLyB3ZSBhZGQgemluZGV4IC0xIHRvIG5vdCBzaG93IG1vZGlmaWNhdGlvbiB0byB0aGUgdXNlclxuICAgIG1hcE92ZXJsYXlIVE1MLnN0eWxlLnpJbmRleCA9ICctMSc7XG4gICAgLy8gYW5kIG1ha2Ugc3VyZSBodG1sMmNhbnZhcyB0byByZW5kZXIgdGhlIGltYWdlIGNvcnJlY3RseVxuICAgIGRvY3VtZW50XG4gICAgICAuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnb2wtdmlld3BvcnQnKVswXVxuICAgICAgLmFwcGVuZENoaWxkKG1hcE92ZXJsYXlIVE1MKTtcbiAgICAvLyBDaGFuZ2UgdGhlIHN0eWxlcyBvZiBoeXBlcmxpbmsgaW4gdGhlIHByaW50ZWQgdmVyc2lvblxuICAgIC8vIFRyYW5zZm9ybSB0aGUgT3ZlcmxheSBpbnRvIGEgY2FudmFzXG4gICAgLy8gc2NhbGUgaXMgbmVjZXNzYXJ5IHRvIG1ha2UgaXQgaW4gZ29vZ2xlIGNocm9tZVxuICAgIC8vIGJhY2tncm91bmQgYXMgbnVsbCBiZWNhdXNlIG90aGVyd2lzZSBpdCBpcyB3aGl0ZSBhbmQgY292ZXIgdGhlIG1hcFxuICAgIC8vIGFsbG93dGFpbnQgaXMgdG8gYWxsb3cgcmVuZGVyaW5nIGltYWdlcyBpbiB0aGUgYXR0cmlidXRpb25zXG4gICAgLy8gdXNlQ09SUzogdHJ1ZSBwb3VyIHBlcm1ldHRyZSBkZSByZW5kZXJlciBsZXMgaW1hZ2VzIChuZSBtYXJjaGUgcGFzIGVuIGxvY2FsKVxuICAgIGNvbnN0IGNhbnZhc092ZXJsYXlIVE1MID0gYXdhaXQgaHRtbDJjYW52YXMobWFwT3ZlcmxheUhUTUwsIHtcbiAgICAgIHNjYWxlOiAxLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiBudWxsLFxuICAgICAgYWxsb3dUYWludDogdHJ1ZSxcbiAgICAgIHVzZUNPUlM6IHRydWUsXG4gICAgICBpZ25vcmVFbGVtZW50czogKGVsZW1lbnQ6IEVsZW1lbnQpID0+IHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudFxuICAgICAgICAgID8gZWxlbWVudC5jbGFzc05hbWUuaW5jbHVkZXMoJ29sLWF0dHJpYnV0aW9uJylcbiAgICAgICAgICA6IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGNhbnZhc092ZXJsYXlIVE1MLndpZHRoICE9PSAwICYmIGNhbnZhc092ZXJsYXlIVE1MLmhlaWdodCAhPT0gMCkge1xuICAgICAgY29udGV4dC5kcmF3SW1hZ2UoY2FudmFzT3ZlcmxheUhUTUwsIDAsIDApO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSAnbWFwT3ZlcmxheUhUTUwnIGFmdGVyIGdlbmVyYXRpbmcgY2FudmFzXG4gICAgbWFwT3ZlcmxheUhUTUwucmVtb3ZlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZE5vcnRoQXJyb3dJbkRvYyhcbiAgICBkb2M6IGpzUERGIHwgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICAgIGFycmF3Q2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCxcbiAgICBiYXNlTWFyZ2luczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgbGVnZW5kUG9zaXRpb246IFByaW50TGVnZW5kUG9zaXRpb24sXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICB5UG9zaXRpb24gPSAwXG4gICkge1xuICAgIGxldCB4UG9zaXRpb24gPSAwO1xuICAgIGxldCBub3J0aEFycm93RGltZW5zaW9uID0gMDtcbiAgICBpZiAoZG9jIGluc3RhbmNlb2YgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEKSB7XG4gICAgICBub3J0aEFycm93RGltZW5zaW9uID0gNTA7XG4gICAgICB4UG9zaXRpb24gPVxuICAgICAgICBsZWdlbmRQb3NpdGlvbiA9PT0gJ3RvcHJpZ2h0JyA/IDAgOiB3aWR0aCAtIG5vcnRoQXJyb3dEaW1lbnNpb247XG4gICAgICBkb2MuZHJhd0ltYWdlKFxuICAgICAgICBhcnJhd0NhbnZhcyxcbiAgICAgICAgeFBvc2l0aW9uLFxuICAgICAgICB5UG9zaXRpb24sXG4gICAgICAgIG5vcnRoQXJyb3dEaW1lbnNpb24sXG4gICAgICAgIG5vcnRoQXJyb3dEaW1lbnNpb25cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vcnRoQXJyb3dEaW1lbnNpb24gPSAxNjtcbiAgICAgIHhQb3NpdGlvbiA9IGxlZ2VuZFBvc2l0aW9uID09PSAndG9wcmlnaHQnID8gMTAgOiB3aWR0aCAtIGJhc2VNYXJnaW5zWzFdO1xuICAgICAgeVBvc2l0aW9uID0gYmFzZU1hcmdpbnNbMF07XG4gICAgICBkb2MuYWRkSW1hZ2UoXG4gICAgICAgIGFycmF3Q2FudmFzLnRvRGF0YVVSTCgpLFxuICAgICAgICB4UG9zaXRpb24sXG4gICAgICAgIHlQb3NpdGlvbixcbiAgICAgICAgbm9ydGhBcnJvd0RpbWVuc2lvbixcbiAgICAgICAgbm9ydGhBcnJvd0RpbWVuc2lvblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHJvdGF0aW9uIC0gbWFwIHJvdGF0aW9uICdyYWQnIHVuaXRcbiAgICpcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlTm9ydGhEaXJlY3Rpb25BcnJvdyhcbiAgICByb3RhdGlvbjogbnVtYmVyXG4gICk6IFByb21pc2U8SFRNTENhbnZhc0VsZW1lbnQ+IHtcbiAgICBjb25zdCBkaXYgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5zdHlsZS5tYXhXaWR0aCA9ICc1MG1tJztcbiAgICBkaXYuc3R5bGUubWF4SGVpZ2h0ID0gJzUwbW0nO1xuICAgIGRpdi5zdHlsZS50ZXh0QWxpZ24gPSAnY2VudGVyJztcblxuICAgIGNvbnN0IGltZyA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG4gICAgaW1nLnNyYyA9ICcuL2Fzc2V0cy9pZ28yL2dlby9pbWFnZXMvbm9ydGgtZGlyZWN0aW9uLnBuZyc7XG4gICAgaW1nLnN0eWxlLm1heFdpZHRoID0gJzUwbW0nO1xuICAgIGltZy5zdHlsZS5tYXhIZWlnaHQgPSAnNTBtbSc7XG4gICAgaW1nLnN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGUoJyArIHJvdGF0aW9uICsgJ3JhZCknO1xuICAgIGltZy5zdHlsZS5wYWRkaW5nID0gJzVtbSc7XG4gICAgZGl2LmFwcGVuZENoaWxkKGltZyk7XG4gICAgdGhpcy5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgY29uc3QgY2FudmFzID0gYXdhaXQgaHRtbDJjYW52YXMoZGl2LCB7IGJhY2tncm91bmRDb2xvcjogbnVsbCB9KTtcbiAgICB0aGlzLnJlbW92ZUh0bWxFbGVtZW50KGRpdik7XG4gICAgaWYgKGNhbnZhcykge1xuICAgICAgcmV0dXJuIGNhbnZhcztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRG93bmxvYWQgYW4gaW1hZ2Ugb2YgdGhlIG1hcCB3aXRoIGFkZGl0aW9uIG9mIGluZm9ybWF0aW9uc1xuICAgKiBAcGFyYW0gIG1hcCAtIE1hcCBvZiB0aGUgYXBwXG4gICAqIEBwYXJhbSAgZm9ybWF0IC0gSW1hZ2UgZm9ybWF0LiBkZWZhdWx0IHZhbHVlIHRvIFwicG5nXCJcbiAgICogQHBhcmFtICBwcm9qZWN0aW9uIC0gSW5kaWNhdGUgaWYgcHJvamVjdGlvbiBuZWVkIHRvIGJlIGFkZC4gRGVmYXVsdCB0byBmYWxzZVxuICAgKiBAcGFyYW0gIHNjYWxlIC0gSW5kaWNhdGUgaWYgc2NhbGUgbmVlZCB0byBiZSBhZGQuIERlZmF1bHQgdG8gZmFsc2VcbiAgICogQHBhcmFtICBsZWdlbmQgLSBJbmRpY2F0ZSBpZiB0aGUgbGVnZW5kIG9mIGxheWVycyBuZWVkIHRvIGJlIGRvd25sb2FkLiBEZWZhdWx0IHRvIGZhbHNlXG4gICAqIEBwYXJhbSAgdGl0bGUgLSBUaXRsZSB0byBhZGQgZm9yIHRoZSBtYXAgLSBEZWZhdWx0IHRvIGJsYW5rXG4gICAqIEBwYXJhbSAgc3VidGl0bGUgLSBTdWJ0aXRsZSB0byBhZGQgZm9yIHRoZSBtYXAgLSBEZWZhdWx0IHRvIGJsYW5rXG4gICAqIEBwYXJhbSAgY29tbWVudCAtIENvbW1lbnQgdG8gYWRkIGZvciB0aGUgbWFwIC0gRGVmYXVsdCB0byBibGFua1xuICAgKiBAcGFyYW0gIGRvWmlwRmlsZSAtIEluZGljYXRlIGlmIHdlIGRvIGEgemlwIHdpdGggdGhlIGZpbGVcbiAgICogQHJldHVybiBJbWFnZSBmaWxlIG9mIHRoZSBtYXAgd2l0aCBleHRlbnNpb24gZm9ybWF0IGdpdmVuIGFzIHBhcmFtZXRlclxuICAgKi9cbiAgZG93bmxvYWRNYXBJbWFnZShcbiAgICBtYXA6IElnb01hcCxcbiAgICBwcmludFJlc29sdXRpb246IFByaW50UmVzb2x1dGlvbixcbiAgICBmb3JtYXQgPSAncG5nJyxcbiAgICBwcm9qZWN0aW9uID0gZmFsc2UsXG4gICAgc2NhbGUgPSBmYWxzZSxcbiAgICB0aXRsZSA9ICcnLFxuICAgIHN1YnRpdGxlID0gJycsXG4gICAgY29tbWVudCA9ICcnLFxuICAgIGRvWmlwRmlsZSA9IHRydWUsXG4gICAgbGVnZW5kUG9zaXRpb246IFByaW50TGVnZW5kUG9zaXRpb24sXG4gICAgc2hvd05vcnRoQXJyb3c6IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3Qgc3RhdHVzJCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgdGhpcy5hY3Rpdml0eUlkID0gdGhpcy5hY3Rpdml0eVNlcnZpY2UucmVnaXN0ZXIoKTtcbiAgICBjb25zdCB0cmFuc2xhdGUgPSB0aGlzLmxhbmd1YWdlU2VydmljZS50cmFuc2xhdGU7XG4gICAgZm9ybWF0ID0gZm9ybWF0LnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgcmVzb2x1dGlvbiA9ICtwcmludFJlc29sdXRpb247XG4gICAgY29uc3QgaW5pdGlhbE1hcFNpemUgPSBtYXAub2wuZ2V0U2l6ZSgpIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgY29uc3Qgdmlld1Jlc29sdXRpb24gPSBtYXAub2wuZ2V0VmlldygpLmdldFJlc29sdXRpb24oKTtcblxuICAgIG1hcC5vbC5vbmNlKCdyZW5kZXJjb21wbGV0ZScsIGFzeW5jIChldmVudDogYW55KSA9PiB7XG4gICAgICBjb25zdCBzaXplID0gbWFwLm9sLmdldFNpemUoKTtcbiAgICAgIGNvbnN0IG1hcENhbnZhcyA9IGV2ZW50LnRhcmdldFxuICAgICAgICAuZ2V0Vmlld3BvcnQoKVxuICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2NhbnZhcycpIGFzIEhUTUxDb2xsZWN0aW9uT2Y8SFRNTENhbnZhc0VsZW1lbnQ+O1xuICAgICAgY29uc3QgbWFwUmVzdWx0Q2FudmFzID0gYXdhaXQgdGhpcy5kcmF3TWFwKHNpemUsIG1hcENhbnZhcyk7XG5cbiAgICAgIHRoaXMucmVzZXRPcmlnaW5hbE1hcFNpemUobWFwLCBpbml0aWFsTWFwU2l6ZSwgdmlld1Jlc29sdXRpb24pO1xuXG4gICAgICBhd2FpdCB0aGlzLmRyYXdNYXBDb250cm9scyhtYXAsIG1hcFJlc3VsdENhbnZhcyk7XG5cbiAgICAgIC8vIENoZWNrIHRoZSBsZWdlbmRQb3NpdGlvblxuICAgICAgaWYgKGxlZ2VuZFBvc2l0aW9uICE9PSAnbm9uZScpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIFsndG9wbGVmdCcsICd0b3ByaWdodCcsICdib3R0b21sZWZ0JywgJ2JvdHRvbXJpZ2h0J10uaW5kZXhPZihcbiAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uXG4gICAgICAgICAgKSA+IC0xXG4gICAgICAgICkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuYWRkTGVnZW5kVG9JbWFnZShcbiAgICAgICAgICAgIG1hcFJlc3VsdENhbnZhcyxcbiAgICAgICAgICAgIG1hcCxcbiAgICAgICAgICAgIHJlc29sdXRpb24sXG4gICAgICAgICAgICBsZWdlbmRQb3NpdGlvbixcbiAgICAgICAgICAgIGZvcm1hdFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAobGVnZW5kUG9zaXRpb24gPT09ICduZXdwYWdlJykge1xuICAgICAgICAgIGF3YWl0IHRoaXMuZ2V0TGF5ZXJzTGVnZW5kSW1hZ2UobWFwLCBmb3JtYXQsIGRvWmlwRmlsZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGFkZCBvdGhlciBpbmZvcm1hdGlvbiB0byBmaW5hbCBjYW52YXMgYmVmb3JlIGV4cG9ydGluZ1xuICAgICAgY29uc3QgbmV3Q2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICBjb25zdCBuZXdDb250ZXh0ID0gbmV3Q2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAvLyBQb3N0aW9uIGluIGhlaWdodCB0byBzZXQgdGhlIGNhbnZhcyBpbiBuZXcgY2FudmFzXG4gICAgICBsZXQgcG9zaXRpb25IQ2FudmFzID0gMDtcbiAgICAgIC8vIEdldCBoZWlnaHQvd2lkdGggb2YgbWFwIGNhbnZhc1xuICAgICAgY29uc3Qgd2lkdGggPSBtYXBSZXN1bHRDYW52YXMud2lkdGg7XG4gICAgICBsZXQgaGVpZ2h0ID0gbWFwUmVzdWx0Q2FudmFzLmhlaWdodDtcbiAgICAgIC8vIFNldCBGb250IHRvIGNhbGN1bGF0ZSBjb21tZW50IHdpZHRoXG4gICAgICBuZXdDb250ZXh0LmZvbnQgPSAnMjBweCBDYWxpYnJpJztcbiAgICAgIGNvbnN0IGNvbW1lbnRXaWR0aCA9IG5ld0NvbnRleHQubWVhc3VyZVRleHQoY29tbWVudCkud2lkdGg7XG4gICAgICAvLyBBZGQgaGVpZ2h0IGZvciB0aXRsZSBpZiBkZWZpbmVkXG4gICAgICBoZWlnaHQgPSB0aXRsZSAhPT0gJycgPyBoZWlnaHQgKyAzMCA6IGhlaWdodDtcbiAgICAgIC8vIEFkZCBoZWlnaHQgZm9yIHRpdGxlIGlmIGRlZmluZWRcbiAgICAgIGhlaWdodCA9IHN1YnRpdGxlICE9PSAnJyA/IGhlaWdodCArIDMwIDogaGVpZ2h0O1xuICAgICAgLy8gQWRkIGhlaWdodCBmb3IgcHJvamVjdGlvbiBvciBzY2FsZSAoc2FtZSBsaW5lKSBpZiBkZWZpbmVkXG4gICAgICBoZWlnaHQgPSBwcm9qZWN0aW9uICE9PSBmYWxzZSB8fCBzY2FsZSAhPT0gZmFsc2UgPyBoZWlnaHQgKyAzMCA6IGhlaWdodDtcbiAgICAgIGNvbnN0IHBvc2l0aW9uSFByb2pTY2FsZSA9IGhlaWdodCAtIDEwO1xuICAgICAgLy8gRGVmaW5lIG51bWJlciBvZiBsaW5lIGRlcGVuZGluZyBvZiB0aGUgY29tbWVudCBsZW5ndGhcbiAgICAgIGNvbnN0IGNvbW1lbnROYkxpbmUgPSBNYXRoLmNlaWwoY29tbWVudFdpZHRoIC8gd2lkdGgpO1xuICAgICAgLy8gQWRkIGhlaWdodCBmb3IgbXVsdGlsaW5lIGNvbW1lbnQgaWYgZGVmaW5lZFxuICAgICAgaGVpZ2h0ID0gY29tbWVudCAhPT0gJycgPyBoZWlnaHQgKyBjb21tZW50TmJMaW5lICogMzAgOiBoZWlnaHQ7XG4gICAgICBsZXQgcG9zaXRpb25IQ29tbWVudCA9IGhlaWdodCAtIGNvbW1lbnROYkxpbmUgKiAyMCArIDU7XG4gICAgICAvLyBTZXQgdGhlIG5ldyBjYW52YXMgd2l0aCB0aGUgbmV3IGNhbGN1bGF0ZWQgc2l6ZVxuICAgICAgbmV3Q2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBuZXdDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICBpZiAoWydibXAnLCAnZ2lmJywgJ2pwZWcnLCAncG5nJywgJ3RpZmYnXS5pbmRleE9mKGZvcm1hdCkgPiAtMSkge1xuICAgICAgICAvLyBQYXRjaCBKcGVnIGRlZmF1bHQgYmxhY2sgYmFja2dyb3VuZCB0byB3aGl0ZVxuICAgICAgICBpZiAoXG4gICAgICAgICAgZm9ybWF0ID09PSAnanBlZycgfHxcbiAgICAgICAgICB0aXRsZSAhPT0gJycgfHxcbiAgICAgICAgICBzdWJ0aXRsZSAhPT0gJycgfHxcbiAgICAgICAgICBjb21tZW50ICE9PSAnJyB8fFxuICAgICAgICAgIHByb2plY3Rpb24gIT09IGZhbHNlIHx8XG4gICAgICAgICAgc2NhbGUgIT09IGZhbHNlXG4gICAgICAgICkge1xuICAgICAgICAgIG5ld0NvbnRleHQuZmlsbFN0eWxlID0gJyNmZmZmZmYnO1xuICAgICAgICAgIG5ld0NvbnRleHQuZmlsbFJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgbmV3Q29udGV4dC5maWxsU3R5bGUgPSAnIzAwMDAwMCc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIElmIGEgdGl0bGUgbmVlZCB0byBiZSBhZGRlZCB0byBjYW52YXNcbiAgICAgIGlmICh0aXRsZSAhPT0gJycpIHtcbiAgICAgICAgLy8gU2V0IGZvbnQgZm9yIHRpdGxlXG4gICAgICAgIC8vIEFkanVzdCBhY2NvcmRpbmcgdG8gdGl0bGUgbGVuZ3RoXG4gICAgICAgIG5ld0NvbnRleHQuZm9udCA9ICcyNnB4IENhbGlicmknO1xuICAgICAgICBwb3NpdGlvbkhDYW52YXMgPSAzMDtcbiAgICAgICAgbmV3Q29udGV4dC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgbmV3Q29udGV4dC5maWxsVGV4dCh0aXRsZSwgd2lkdGggLyAyLCAyMCwgd2lkdGggKiAwLjkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3VidGl0bGUgIT09ICcnKSB7XG4gICAgICAgIC8vIFNldCBmb250IGZvciBzdWJ0aXRsZVxuICAgICAgICAvLyBBZGp1c3QgYWNjb3JkaW5nIHRvIHRpdGxlIGxlbmd0aFxuICAgICAgICBuZXdDb250ZXh0LmZvbnQgPSAnMjZweCBDYWxpYnJpJztcbiAgICAgICAgcG9zaXRpb25IQ2FudmFzID0gNjA7XG4gICAgICAgIG5ld0NvbnRleHQudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgIG5ld0NvbnRleHQuZmlsbFRleHQoc3VidGl0bGUsIHdpZHRoIC8gMiwgNTAsIHdpZHRoICogMC45KTtcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGZvbnQgZm9yIG5leHQgc2VjdGlvblxuICAgICAgbmV3Q29udGV4dC5mb250ID0gJzIwcHggQ2FsaWJyaSc7XG4gICAgICAvLyBJZiBwcm9qZWN0aW9uIG9yL2VuZCBzY2FsZSBuZWVkIHRvIGJlIGFkZGVkIHRvIGNhbnZhc1xuICAgICAgaWYgKHByb2plY3Rpb24gIT09IGZhbHNlIHx8IHNjYWxlICE9PSBmYWxzZSkge1xuICAgICAgICBsZXQgcHJvamVjdGlvblNjYWxlVGV4dCA9ICcnO1xuICAgICAgICBpZiAocHJvamVjdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICBjb25zdCBwcm9qVGV4dCA9IHRyYW5zbGF0ZS5pbnN0YW50KCdpZ28uZ2VvLnByaW50Rm9ybS5wcm9qZWN0aW9uJyk7XG4gICAgICAgICAgcHJvamVjdGlvblNjYWxlVGV4dCA9IHByb2pUZXh0ICsgJzogJyArIG1hcC5wcm9qZWN0aW9uICsgJyAgICAgICAgICc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NhbGUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgY29uc3Qgc2NhbGVUZXh0ID0gdHJhbnNsYXRlLmluc3RhbnQoJ2lnby5nZW8ucHJpbnRGb3JtLnNjYWxlJyk7XG4gICAgICAgICAgY29uc3QgbWFwU2NhbGUgPSBtYXAudmlld0NvbnRyb2xsZXIuZ2V0U2NhbGUocmVzb2x1dGlvbik7XG4gICAgICAgICAgcHJvamVjdGlvblNjYWxlVGV4dCArPSBzY2FsZVRleHQgKyAnOiB+IDEgLyAnICsgZm9ybWF0U2NhbGUobWFwU2NhbGUpO1xuICAgICAgICB9XG4gICAgICAgIG5ld0NvbnRleHQudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgIG5ld0NvbnRleHQuZmlsbFRleHQoXG4gICAgICAgICAgcHJvamVjdGlvblNjYWxlVGV4dCxcbiAgICAgICAgICB3aWR0aCAvIDIsXG4gICAgICAgICAgcG9zaXRpb25IUHJvalNjYWxlLFxuICAgICAgICAgIHdpZHRoICogMC45XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIGEgY29tbWVudCBuZWVkIHRvIGJlIGFkZGVkIHRvIGNhbnZhc1xuICAgICAgaWYgKGNvbW1lbnQgIT09ICcnKSB7XG4gICAgICAgIG5ld0NvbnRleHQudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgIC8vIElmIG9ubHkgb25lIGxpbmUsIG5vIG5lZWQgdG8gbXVsdGlsaW5lIHRoZSBjb21tZW50XG4gICAgICAgIGlmIChjb21tZW50TmJMaW5lID09PSAxKSB7XG4gICAgICAgICAgbmV3Q29udGV4dC5maWxsVGV4dChjb21tZW50LCB3aWR0aCAvIDIsIHBvc2l0aW9uSENvbW1lbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFNlcGFyYXRlIHRoZSBzZXRlbnNlcyB0byBiZSBhcHByb3guIHRoZSBzYW1lIGxlbmd0aFxuICAgICAgICAgIGNvbnN0IG5iQ29tbWVudENoYXIgPSBjb21tZW50Lmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBDb21tZW50TGVuZ3RoVG9DdXQgPSBNYXRoLmZsb29yKG5iQ29tbWVudENoYXIgLyBjb21tZW50TmJMaW5lKTtcbiAgICAgICAgICBsZXQgY29tbWVudEN1cnJlbnRMaW5lID0gJyc7XG4gICAgICAgICAgbGV0IHBvc2l0aW9uRmlyc3RDdXRDaGFyID0gMDtcbiAgICAgICAgICBsZXQgcG9zaXRpb25MYXN0Qmxhbms7XG4gICAgICAgICAgLy8gTG9vcCBmb3IgdGhlIG51bWJlciBvZiBsaW5lIGNhbGN1bGF0ZWRcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbW1lbnROYkxpbmU7IGkrKykge1xuICAgICAgICAgICAgLy8gRm9yIGFsbCBsaW5lIGV4Y2VwdCBsYXN0XG4gICAgICAgICAgICBpZiAoY29tbWVudE5iTGluZSAtIDEgPiBpKSB7XG4gICAgICAgICAgICAgIC8vIEdldCBjb21tZW50IGN1cnJlbnQgbGluZSB0byBmaW5kIHRoZSByaWdodCBwbGFjZSB0dSBjdXQgY29tbWVudFxuICAgICAgICAgICAgICBjb21tZW50Q3VycmVudExpbmUgPSBjb21tZW50LnN1YnN0cihcbiAgICAgICAgICAgICAgICBwb3NpdGlvbkZpcnN0Q3V0Q2hhcixcbiAgICAgICAgICAgICAgICBDb21tZW50TGVuZ3RoVG9DdXRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgLy8gQ3V0IHRoZSBzZXRlbmNlIGF0IGJsYW5rXG4gICAgICAgICAgICAgIHBvc2l0aW9uTGFzdEJsYW5rID0gY29tbWVudEN1cnJlbnRMaW5lLmxhc3RJbmRleE9mKCcgJyk7XG4gICAgICAgICAgICAgIG5ld0NvbnRleHQuZmlsbFRleHQoXG4gICAgICAgICAgICAgICAgY29tbWVudEN1cnJlbnRMaW5lLnN1YnN0cigwLCBwb3NpdGlvbkxhc3RCbGFuayksXG4gICAgICAgICAgICAgICAgd2lkdGggLyAyLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uSENvbW1lbnRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcG9zaXRpb25GaXJzdEN1dENoYXIgKz0gcG9zaXRpb25MYXN0Qmxhbms7XG4gICAgICAgICAgICAgIC8vIEdvIHRvIG5leHQgbGluZSBmb3IgaW5zZXJ0aW9uXG4gICAgICAgICAgICAgIHBvc2l0aW9uSENvbW1lbnQgKz0gMjA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBEb24ndCBjdXQgbGFzdCBwYXJ0XG4gICAgICAgICAgICAgIG5ld0NvbnRleHQuZmlsbFRleHQoXG4gICAgICAgICAgICAgICAgY29tbWVudC5zdWJzdHIocG9zaXRpb25GaXJzdEN1dENoYXIpLFxuICAgICAgICAgICAgICAgIHdpZHRoIC8gMixcbiAgICAgICAgICAgICAgICBwb3NpdGlvbkhDb21tZW50XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG5ld0NvbnRleHQuZHJhd0ltYWdlKG1hcFJlc3VsdENhbnZhcywgMCwgcG9zaXRpb25IQ2FudmFzKTtcblxuICAgICAgaWYgKHNob3dOb3J0aEFycm93KSB7XG4gICAgICAgIGNvbnN0IG5vcnRoQXJyb3dDYW52YXMgPSBhd2FpdCB0aGlzLmNyZWF0ZU5vcnRoRGlyZWN0aW9uQXJyb3coXG4gICAgICAgICAgbWFwLnZpZXdDb250cm9sbGVyLmdldFJvdGF0aW9uKClcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5hZGROb3J0aEFycm93SW5Eb2MoXG4gICAgICAgICAgbmV3Q29udGV4dCxcbiAgICAgICAgICBub3J0aEFycm93Q2FudmFzLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgbGVnZW5kUG9zaXRpb24sXG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgcG9zaXRpb25IQ2FudmFzXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGxldCBzdGF0dXMgPSBTdWJqZWN0U3RhdHVzLkRvbmU7XG4gICAgICBsZXQgZmlsZU5hbWVXaXRoRXh0ID0gJ21hcC4nICsgZm9ybWF0O1xuICAgICAgaWYgKGZvcm1hdC50b0xvd2VyQ2FzZSgpID09PSAndGlmZicpIHtcbiAgICAgICAgZmlsZU5hbWVXaXRoRXh0ID1cbiAgICAgICAgICAnbWFwJyArIG1hcC5wcm9qZWN0aW9uLnJlcGxhY2UoJzonLCAnXycpICsgJy4nICsgZm9ybWF0O1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBTYXZlIHRoZSBjYW52YXMgYXMgZmlsZVxuICAgICAgICBpZiAoIWRvWmlwRmlsZSkge1xuICAgICAgICAgIHRoaXMuc2F2ZUNhbnZhc0ltYWdlQXNGaWxlKG5ld0NhbnZhcywgZmlsZU5hbWVXaXRoRXh0LCBmb3JtYXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdC50b0xvd2VyQ2FzZSgpID09PSAndGlmZicpIHtcbiAgICAgICAgICAvLyBBZGQgdGhlIGNhbnZhcyB0byB6aXBcbiAgICAgICAgICB0aGlzLmdlbmVyYXRlQ2FudmFGaWxlVG9aaXAobmV3Q2FudmFzLCBmaWxlTmFtZVdpdGhFeHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFkZCB0aGUgY2FudmFzIHRvIHppcFxuICAgICAgICAgIHRoaXMuZ2VuZXJhdGVDYW52YUZpbGVUb1ppcChuZXdDYW52YXMsIGZpbGVOYW1lV2l0aEV4dCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBzdGF0dXMgPSBTdWJqZWN0U3RhdHVzLkVycm9yO1xuICAgICAgfVxuICAgICAgc3RhdHVzJC5uZXh0KHN0YXR1cyk7XG5cbiAgICAgIGlmIChmb3JtYXQudG9Mb3dlckNhc2UoKSA9PT0gJ3RpZmYnKSB7XG4gICAgICAgIGNvbnN0IHRmd0ZpbGVOYW1lV2l0aEV4dCA9XG4gICAgICAgICAgZmlsZU5hbWVXaXRoRXh0LnN1YnN0cmluZyhcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBmaWxlTmFtZVdpdGhFeHQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCcudGlmZicpXG4gICAgICAgICAgKSArICcudGZ3JztcbiAgICAgICAgY29uc3QgdGl3Q29udGVudCA9IHRoaXMuZ2V0V29ybGRGaWxlSW5mb3JtYXRpb24obWFwKTtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFt0aXdDb250ZW50XSwge1xuICAgICAgICAgIHR5cGU6ICd0ZXh0L3BsYWluO2NoYXJzZXQ9dXRmLTgnXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWRvWmlwRmlsZSkge1xuICAgICAgICAgIC8vIHNhdmVBcyBhdXRvbWF0aWNseSByZXBsYWNlICc6JyBmb3IgJ18nXG4gICAgICAgICAgc2F2ZUFzKGJsb2IsIHRmd0ZpbGVOYW1lV2l0aEV4dCk7XG4gICAgICAgICAgdGhpcy5zYXZlRmlsZVByb2Nlc3NpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBBZGQgdGhlIGNhbnZhcyB0byB6aXBcbiAgICAgICAgICB0aGlzLmFkZEZpbGVUb1ppcCh0ZndGaWxlTmFtZVdpdGhFeHQsIGJsb2IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldE1hcEltYWdlUmVzb2x1dGlvbihtYXAsIGluaXRpYWxNYXBTaXplLCByZXNvbHV0aW9uLCB2aWV3UmVzb2x1dGlvbik7XG5cbiAgICByZXR1cm4gc3RhdHVzJDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0TWFwSW1hZ2VSZXNvbHV0aW9uKFxuICAgIG1hcDogSWdvTWFwLFxuICAgIGluaXRpYWxNYXBTaXplOiBbbnVtYmVyLCBudW1iZXJdLFxuICAgIHJlc29sdXRpb246IG51bWJlcixcbiAgICB2aWV3UmVzb2x1dGlvbjogbnVtYmVyXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNjYWxlRmFjdG9yID0gcmVzb2x1dGlvbiAvIDk2O1xuICAgIGNvbnN0IG5ld01hcFNpemUgPSBbXG4gICAgICBNYXRoLnJvdW5kKGluaXRpYWxNYXBTaXplWzBdICogc2NhbGVGYWN0b3IpLCAvLyB3aWR0aFxuICAgICAgTWF0aC5yb3VuZChpbml0aWFsTWFwU2l6ZVsxXSAqIHNjYWxlRmFjdG9yKSAvLyBoZWlnaHRcbiAgICBdO1xuICAgIG1hcC5vbC5zZXRTaXplKG5ld01hcFNpemUpO1xuICAgIGNvbnN0IHNjYWxpbmcgPSBNYXRoLm1pbihcbiAgICAgIG5ld01hcFNpemVbMF0gLyBpbml0aWFsTWFwU2l6ZVswXSxcbiAgICAgIG5ld01hcFNpemVbMV0gLyBpbml0aWFsTWFwU2l6ZVsxXVxuICAgICk7XG4gICAgY29uc3QgdmlldyA9IG1hcC5vbC5nZXRWaWV3KCk7XG4gICAgdmlldy5zZXRSZXNvbHV0aW9uKHZpZXdSZXNvbHV0aW9uIC8gc2NhbGluZyk7XG4gICAgbWFwLm9sLnJlbmRlclN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW5kIEFkZCBMZWdlbmQgdG8gdGhlIG1hcCBjYW52YXNcbiAgICogQHBhcmFtICBjYW52YXMgQ2FudmFzIG9mIHRoZSBtYXBcbiAgICogQHBhcmFtICBtYXAgTWFwIG9mIHRoZSBhcHBcbiAgICogQHBhcmFtICByZXNvbHV0aW9uIFJlc29sdXRpb24gb2YgbWFwXG4gICAqIEBwYXJhbSAgbGVnZW5kUG9zaXRpb24gTGVnZW5kIHBvc2l0aW9uXG4gICAqIEBwYXJhbSAgZm9ybWF0IEltYWdlIGZvcm1hdFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhZGRMZWdlbmRUb0ltYWdlKFxuICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsXG4gICAgbWFwOiBJZ29NYXAsXG4gICAgcmVzb2x1dGlvbjogbnVtYmVyLFxuICAgIGxlZ2VuZFBvc2l0aW9uOiBzdHJpbmcsXG4gICAgZm9ybWF0OiBzdHJpbmdcbiAgKSB7XG4gICAgY29uc3QgZmlsZU5hbWVXaXRoRXh0ID0gJ21hcC4nICsgZm9ybWF0O1xuICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcblxuICAgIC8vIEdldCBodG1sIGNvZGUgZm9yIHRoZSBsZWdlbmRcbiAgICBjb25zdCBodG1sID0gYXdhaXQgdGhpcy5nZXRMYXllcnNMZWdlbmRIdG1sKG1hcCwgY2FudmFzLndpZHRoKS50b1Byb21pc2UoKTtcbiAgICAvLyBJZiBubyBsZWdlbmQsIHNhdmUgdGhlIG1hcCBkaXJlY3RseVxuICAgIGlmIChodG1sID09PSAnJykge1xuICAgICAgYXdhaXQgdGhpcy5zYXZlQ2FudmFzSW1hZ2VBc0ZpbGUoY2FudmFzLCBmaWxlTmFtZVdpdGhFeHQsIGZvcm1hdCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGRpdiB0byBjb250YWluIGh0bWwgY29kZSBmb3IgbGVnZW5kXG4gICAgY29uc3QgZGl2ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZGl2LnN0eWxlLnRvcCA9ICcwJztcbiAgICBkaXYuc3R5bGUuekluZGV4ID0gJy0xJztcbiAgICAvLyBBZGQgaHRtbCBjb2RlIHRvIGNvbnZlcnQgaW4gdGhlIG5ldyB3aW5kb3dcbiAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBodG1sO1xuICAgIGF3YWl0IHRoaXMudGltZW91dCgxKTtcbiAgICBjb25zdCBjYW52YXNMZWdlbmQgPSBhd2FpdCBodG1sMmNhbnZhcyhkaXYsIHsgdXNlQ09SUzogdHJ1ZSB9KS5jYXRjaChcbiAgICAgIChlKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBpZiAoY2FudmFzTGVnZW5kKSB7XG4gICAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuICAgICAgY29uc3QgY2FudmFzV2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgICBjb25zdCBsZWdlbmRIZWlnaHQgPSBjYW52YXNMZWdlbmQuaGVpZ2h0O1xuICAgICAgY29uc3QgbGVnZW5kV2lkdGggPSBjYW52YXNMZWdlbmQud2lkdGg7XG4gICAgICAvLyBNb3ZlIHRoZSBsZWdlbmQgdG8gdGhlIGNvcnJlY3QgcG9zaXRpb24gb24gdGhlIHBhZ2VcbiAgICAgIGNvbnN0IG9mZnNldCA9IGNhbnZhc0hlaWdodCAqIDAuMDE7XG4gICAgICBsZXQgbGVnZW5kWDogbnVtYmVyO1xuICAgICAgbGV0IGxlZ2VuZFk6IG51bWJlcjtcblxuICAgICAgaWYgKGxlZ2VuZFBvc2l0aW9uID09PSAnYm90dG9tcmlnaHQnKSB7XG4gICAgICAgIGxlZ2VuZFggPSBjYW52YXNXaWR0aCAtIGxlZ2VuZFdpZHRoIC0gb2Zmc2V0O1xuICAgICAgICBsZWdlbmRZID0gY2FudmFzSGVpZ2h0IC0gbGVnZW5kSGVpZ2h0IC0gb2Zmc2V0O1xuICAgICAgfSBlbHNlIGlmIChsZWdlbmRQb3NpdGlvbiA9PT0gJ3RvcHJpZ2h0Jykge1xuICAgICAgICBsZWdlbmRYID0gY2FudmFzV2lkdGggLSBsZWdlbmRXaWR0aCAtIG9mZnNldDtcbiAgICAgICAgbGVnZW5kWSA9IG9mZnNldDtcbiAgICAgIH0gZWxzZSBpZiAobGVnZW5kUG9zaXRpb24gPT09ICdib3R0b21sZWZ0Jykge1xuICAgICAgICBsZWdlbmRYID0gb2Zmc2V0O1xuICAgICAgICBsZWdlbmRZID0gY2FudmFzSGVpZ2h0IC0gbGVnZW5kSGVpZ2h0IC0gb2Zmc2V0IC0gMTU7XG4gICAgICB9IGVsc2UgaWYgKGxlZ2VuZFBvc2l0aW9uID09PSAndG9wbGVmdCcpIHtcbiAgICAgICAgbGVnZW5kWCA9IG9mZnNldDtcbiAgICAgICAgbGVnZW5kWSA9IG9mZnNldDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5kcmF3SW1hZ2UoXG4gICAgICAgIGNhbnZhc0xlZ2VuZCxcbiAgICAgICAgbGVnZW5kWCxcbiAgICAgICAgbGVnZW5kWSxcbiAgICAgICAgbGVnZW5kV2lkdGgsXG4gICAgICAgIGxlZ2VuZEhlaWdodFxuICAgICAgKTtcbiAgICAgIGNvbnRleHQuc3Ryb2tlUmVjdChsZWdlbmRYLCBsZWdlbmRZLCBsZWdlbmRXaWR0aCwgbGVnZW5kSGVpZ2h0KTtcbiAgICAgIHRoaXMucmVtb3ZlSHRtbEVsZW1lbnQoZGl2KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIGRvY3VtZW50XG4gICAqIEBwYXJhbSAgZG9jIC0gRG9jdW1lbnQgdG8gc2F2ZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHNhdmVEb2MoZG9jOiBqc1BERikge1xuICAgIGF3YWl0IGRvYy5zYXZlKCdtYXBfZ2VvcmVmLnBkZicsIHsgcmV0dXJuUHJvbWlzZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGJlc3QgSW1hZ2Ugc2l6ZSB0byBmaXQgaW4gcGRmXG4gICAqIEBwYXJhbSBkb2MgLSBQZGYgRG9jdW1lbnRcbiAgICogQHBhcmFtIGNhbnZhcyAtIENhbnZhcyBvZiBpbWFnZVxuICAgKiBAcGFyYW0gbWFyZ2lucyAtIFBhZ2UgbWFyZ2luc1xuICAgKi9cbiAgZ2V0SW1hZ2VTaXplVG9GaXRQZGYoZG9jLCBjYW52YXMsIG1hcmdpbnMpIHtcbiAgICAvLyBEZWZpbmUgdmFyaWFibGUgdG8gY2FsY3VsYXRlIGJlc3Qgc2l6ZSB0byBmaXQgaW4gb25lIHBhZ2VcbiAgICBjb25zdCBwYWdlSGVpZ2h0ID1cbiAgICAgIGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5nZXRIZWlnaHQoKSAtIChtYXJnaW5zWzBdICsgbWFyZ2luc1syXSk7XG4gICAgY29uc3QgcGFnZVdpZHRoID1cbiAgICAgIGRvYy5pbnRlcm5hbC5wYWdlU2l6ZS5nZXRXaWR0aCgpIC0gKG1hcmdpbnNbMV0gKyBtYXJnaW5zWzNdKTtcbiAgICBjb25zdCBjYW5IZWlnaHQgPSB0aGlzLnBkZl91bml0czJwb2ludHMoY2FudmFzLmhlaWdodCwgJ21tJyk7XG4gICAgY29uc3QgY2FuV2lkdGggPSB0aGlzLnBkZl91bml0czJwb2ludHMoY2FudmFzLndpZHRoLCAnbW0nKTtcblxuICAgIGNvbnN0IGhlaWdodFJhdGlvID0gY2FuSGVpZ2h0IC8gcGFnZUhlaWdodDtcbiAgICBjb25zdCB3aWR0aFJhdGlvID0gY2FuV2lkdGggLyBwYWdlV2lkdGg7XG4gICAgY29uc3QgbWF4UmF0aW8gPSBoZWlnaHRSYXRpbyA+IHdpZHRoUmF0aW8gPyBoZWlnaHRSYXRpbyA6IHdpZHRoUmF0aW87XG4gICAgY29uc3QgaW1nSGVpZ2ggPSBtYXhSYXRpbyA+IDEgPyBjYW5IZWlnaHQgLyBtYXhSYXRpbyA6IGNhbkhlaWdodDtcbiAgICBjb25zdCBpbWdXaWR0aCA9IG1heFJhdGlvID4gMSA/IGNhbldpZHRoIC8gbWF4UmF0aW8gOiBjYW5XaWR0aDtcbiAgICByZXR1cm4gW2ltZ1dpZHRoLCBpbWdIZWlnaF07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgd29ybGQgZmlsZSBpbmZvcm1hdGlvbiBmb3IgdGlmZlxuICAgKiBAcGFyYW0gIG1hcCAtIE1hcCBvZiB0aGUgYXBwXG4gICAqL1xuICBwcml2YXRlIGdldFdvcmxkRmlsZUluZm9ybWF0aW9uKG1hcCkge1xuICAgIGNvbnN0IGN1cnJlbnRSZXNvbHV0aW9uID0gbWFwLnZpZXdDb250cm9sbGVyLmdldFJlc29sdXRpb24oKTtcbiAgICBjb25zdCBjdXJyZW50RXh0ZW50ID0gbWFwLnZpZXdDb250cm9sbGVyLmdldEV4dGVudCgpOyAvLyBSZXR1cm4gW21pbngsIG1pbnksIG1heHgsIG1heHldXG4gICAgcmV0dXJuIFtcbiAgICAgIGN1cnJlbnRSZXNvbHV0aW9uLFxuICAgICAgMCxcbiAgICAgIDAsXG4gICAgICAtY3VycmVudFJlc29sdXRpb24sXG4gICAgICBjdXJyZW50RXh0ZW50WzBdICsgY3VycmVudFJlc29sdXRpb24gLyAwLjUsXG4gICAgICBjdXJyZW50RXh0ZW50WzNdIC0gY3VycmVudFJlc29sdXRpb24gLyAwLjVcbiAgICBdLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmUgY2FudmFzIGltYWdlIGFzIGZpbGVcbiAgICogQHBhcmFtIGNhbnZhcyAtIENhbnZhcyB0byBzYXZlXG4gICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBvZiB0aGUgZmlsZVxuICAgKiBAcGFyYW0gZm9ybWF0IC0gZmlsZSBmb3JtYXRcbiAgICovXG4gIHByaXZhdGUgc2F2ZUNhbnZhc0ltYWdlQXNGaWxlKGNhbnZhcywgbmFtZVdpdGhFeHQsIGZvcm1hdCkge1xuICAgIGNvbnN0IGJsb2JGb3JtYXQgPSAnaW1hZ2UvJyArIGZvcm1hdDtcblxuICAgIHRyeSB7XG4gICAgICBjYW52YXMudG9EYXRhVVJMKCk7IC8vIEp1c3QgdG8gbWFrZSB0aGUgY2F0Y2ggdHJpZ2dlciB3aWh0b3V0IHRvQmxvYiBFcnJvciB0aHJvdyBub3QgY2F0Y2hlZFxuICAgICAgY2FudmFzLnRvQmxvYigoYmxvYikgPT4ge1xuICAgICAgICAvLyBkb3dubG9hZCBpbWFnZVxuICAgICAgICBzYXZlQXMoYmxvYiwgbmFtZVdpdGhFeHQpO1xuICAgICAgICB0aGlzLnNhdmVGaWxlUHJvY2Vzc2luZygpO1xuICAgICAgfSwgYmxvYkZvcm1hdCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmVycm9yKFxuICAgICAgICAnaWdvLmdlby5wcmludEZvcm0uY29yc0Vycm9yTWVzc2FnZUJvZHknLFxuICAgICAgICAnaWdvLmdlby5wcmludEZvcm0uY29yc0Vycm9yTWVzc2FnZUhlYWRlcidcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBmaWxlIHRvIGEgemlwXG4gICAqIEBwYXJhbSBjYW52YXMgLSBGaWxlIHRvIGFkZCB0byB0aGUgemlwXG4gICAqIEBwYXJhbSAgbmFtZSAtTmFtZSBvZiB0aGUgZmlsZW92ZXJ2aWV3XG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQ2FudmFGaWxlVG9aaXAoY2FudmFzLCBuYW1lKSB7XG4gICAgY29uc3QgYmxvYkZvcm1hdCA9ICdpbWFnZS8nICsgJ2pwZWcnO1xuICAgIGlmIChcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICAgICF0aGlzLmhhc093blByb3BlcnR5KCd6aXBGaWxlJykgfHxcbiAgICAgIHR5cGVvZiB0aGlzLnppcEZpbGUgPT09ICd1bmRlZmluZWQnXG4gICAgKSB7XG4gICAgICB0aGlzLnppcEZpbGUgPSBuZXcgSlNaaXAoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY2FudmFzLnRvRGF0YVVSTCgpOyAvLyBKdXN0IHRvIG1ha2UgdGhlIGNhdGNoIHRyaWdnZXIgd2lodG91dCB0b0Jsb2IgRXJyb3IgdGhyb3cgbm90IGNhdGNoZWRcbiAgICAgIGlmIChuYXZpZ2F0b3IubXNTYXZlQmxvYikge1xuICAgICAgICB0aGlzLmFkZEZpbGVUb1ppcChuYW1lLCBjYW52YXMubXNUb0Jsb2IoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMudG9CbG9iKChibG9iKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRGaWxlVG9aaXAobmFtZSwgYmxvYik7XG4gICAgICAgIH0sIGJsb2JGb3JtYXQpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5lcnJvcihcbiAgICAgICAgJ2lnby5nZW8ucHJpbnRGb3JtLmNvcnNFcnJvck1lc3NhZ2VCb2R5JyxcbiAgICAgICAgJ2lnby5nZW8ucHJpbnRGb3JtLmNvcnNFcnJvck1lc3NhZ2VIZWFkZXInXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgZmlsZSB0byB6aXAsIGlmIGFsbCBmaWxlIGFyZSB6aXBwZWQsIGRvd25sb2FkXG4gICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBvZiB0aGUgZmlsZXNcbiAgICogQHBhcmFtIGJsb2IgLSBDb250YWluIG9mIGZpbGVcbiAgICovXG4gIHByaXZhdGUgYWRkRmlsZVRvWmlwKG5hbWUsIGJsb2IpIHtcbiAgICAvLyBhZGQgZmlsZSB0byB6aXBcbiAgICB0aGlzLnppcEZpbGUuZmlsZShuYW1lLCBibG9iKTtcbiAgICB0aGlzLm5iRmlsZVRvUHJvY2Vzcy0tO1xuXG4gICAgLy8gSWYgYWxsIGZpbGVzIGFyZSBwcm9jY2Vzc2VkXG4gICAgaWYgKHRoaXMubmJGaWxlVG9Qcm9jZXNzID09PSAwKSB7XG4gICAgICAvLyBEb3dubG9hZCB6aXAgZmlsZVxuICAgICAgdGhpcy5nZXRaaXBGaWxlKCk7XG4gICAgICAvLyBTdG9wIGxvYWRpbmdcbiAgICAgIHRoaXMuYWN0aXZpdHlTZXJ2aWNlLnVucmVnaXN0ZXIodGhpcy5hY3Rpdml0eUlkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNhdmVGaWxlUHJvY2Vzc2luZygpIHtcbiAgICB0aGlzLm5iRmlsZVRvUHJvY2Vzcy0tO1xuXG4gICAgLy8gSWYgYWxsIGZpbGVzIGFyZSBwcm9jY2Vzc2VkXG4gICAgaWYgKHRoaXMubmJGaWxlVG9Qcm9jZXNzID09PSAwKSB7XG4gICAgICAvLyBTdG9wIGxvYWRpbmdcbiAgICAgIHRoaXMuYWN0aXZpdHlTZXJ2aWNlLnVucmVnaXN0ZXIodGhpcy5hY3Rpdml0eUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB6aXBwZWQgZmlsZVxuICAgKiBAcmV0dXJuIFJldHVuIGEgemlwIGZpbGVcbiAgICovXG4gIHByaXZhdGUgZ2V0WmlwRmlsZSgpIHtcbiAgICB0aGlzLnppcEZpbGUuZ2VuZXJhdGVBc3luYyh7IHR5cGU6ICdibG9iJyB9KS50aGVuKChibG9iKSA9PiB7XG4gICAgICAvLyAxKSBnZW5lcmF0ZSB0aGUgemlwIGZpbGVcbiAgICAgIHNhdmVBcyhibG9iLCAnbWFwLnppcCcpO1xuICAgICAgZGVsZXRlIHRoaXMuemlwRmlsZTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcGRmX3VuaXRzMnBvaW50cyhuLCB1bml0KTogbnVtYmVyIHtcbiAgICBsZXQgayA9IDE7XG5cbiAgICAvLyB0aGlzIGNvZGUgaXMgYm9ycm93ZWQgZnJvbSBqc1BERlxuICAgIC8vICBhcyBpdCBkb2VzIG5vdCBleHBvc2UgYSBwdWJsaWMgQVBJXG4gICAgLy8gIGZvciBjb252ZXJ0aW5nIHVuaXRzIHRvIHBvaW50cy5cbiAgICBzd2l0Y2ggKHVuaXQpIHtcbiAgICAgIGNhc2UgJ3B0JzpcbiAgICAgICAgayA9IDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW0nOlxuICAgICAgICBrID0gNzIgLyAyNS40O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NtJzpcbiAgICAgICAgayA9IDcyIC8gMi41NDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbic6XG4gICAgICAgIGsgPSA3MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdweCc6XG4gICAgICAgIGsgPSA5NiAvIDcyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3BjJzpcbiAgICAgICAgayA9IDEyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2VtJzpcbiAgICAgICAgayA9IDEyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2V4JzpcbiAgICAgICAgayA9IDY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHVuaXQ6ICcgKyB1bml0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbiAqIGs7XG4gIH1cbn1cbiJdfQ==