@worktile/planet 12.1.1 → 14.0.0-next.0

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 (317) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/application/planet-application-loader.d.ts +73 -0
  3. package/application/planet-application-loader.d.ts.map +1 -0
  4. package/application/planet-application-ref.d.ts +36 -0
  5. package/application/planet-application-ref.d.ts.map +1 -0
  6. package/application/planet-application.service.d.ts +22 -0
  7. package/application/planet-application.service.d.ts.map +1 -0
  8. package/{packages/planet/src/application/portal-application.ts → application/portal-application.d.ts} +5 -18
  9. package/application/portal-application.d.ts.map +1 -0
  10. package/assets-loader.d.ts +36 -0
  11. package/assets-loader.d.ts.map +1 -0
  12. package/component/planet-component-loader.d.ts +31 -0
  13. package/component/planet-component-loader.d.ts.map +1 -0
  14. package/component/planet-component-ref.d.ts +8 -0
  15. package/component/planet-component-ref.d.ts.map +1 -0
  16. package/{packages/planet/src/component/plant-component.config.ts → component/plant-component.config.d.ts} +4 -4
  17. package/component/plant-component.config.d.ts.map +1 -0
  18. package/debug.d.ts +22 -0
  19. package/debug.d.ts.map +1 -0
  20. package/empty/empty.component.d.ts +6 -0
  21. package/empty/empty.component.d.ts.map +1 -0
  22. package/esm2020/application/planet-application-loader.mjs +454 -0
  23. package/esm2020/application/planet-application-ref.mjs +94 -0
  24. package/esm2020/application/planet-application.service.mjs +85 -0
  25. package/esm2020/application/portal-application.mjs +16 -0
  26. package/esm2020/assets-loader.mjs +216 -0
  27. package/esm2020/component/planet-component-loader.mjs +153 -0
  28. package/esm2020/component/planet-component-ref.mjs +3 -0
  29. package/esm2020/component/plant-component.config.mjs +7 -0
  30. package/esm2020/debug.mjs +33 -0
  31. package/esm2020/empty/empty.component.mjs +15 -0
  32. package/esm2020/global-event-dispatcher.mjs +70 -0
  33. package/esm2020/global-planet.mjs +53 -0
  34. package/esm2020/helpers.mjs +119 -0
  35. package/esm2020/module.mjs +31 -0
  36. package/esm2020/planet.class.mjs +9 -0
  37. package/esm2020/planet.mjs +91 -0
  38. package/esm2020/public-api.mjs +18 -0
  39. package/esm2020/sandbox/constants.mjs +7 -0
  40. package/esm2020/sandbox/exec.mjs +15 -0
  41. package/esm2020/sandbox/index.mjs +20 -0
  42. package/esm2020/sandbox/proxy/patches/document.mjs +12 -0
  43. package/esm2020/sandbox/proxy/patches/eventListener.mjs +41 -0
  44. package/esm2020/sandbox/proxy/patches/index.mjs +11 -0
  45. package/esm2020/sandbox/proxy/patches/storage.mjs +40 -0
  46. package/esm2020/sandbox/proxy/patches/timer.mjs +43 -0
  47. package/esm2020/sandbox/proxy/proxies/common.mjs +132 -0
  48. package/esm2020/sandbox/proxy/proxies/document.mjs +126 -0
  49. package/esm2020/sandbox/proxy/proxies/window.mjs +158 -0
  50. package/esm2020/sandbox/proxy/proxy-sandbox.mjs +49 -0
  51. package/esm2020/sandbox/proxy/types.mjs +2 -0
  52. package/esm2020/sandbox/sandbox.mjs +7 -0
  53. package/esm2020/sandbox/snapshot/snapshot-sandbox.mjs +12 -0
  54. package/esm2020/sandbox/types.mjs +2 -0
  55. package/esm2020/worktile-planet.mjs +5 -0
  56. package/fesm2015/worktile-planet.mjs +2049 -0
  57. package/fesm2015/worktile-planet.mjs.map +1 -0
  58. package/fesm2020/worktile-planet.mjs +2046 -0
  59. package/fesm2020/worktile-planet.mjs.map +1 -0
  60. package/global-event-dispatcher.d.ts +23 -0
  61. package/global-event-dispatcher.d.ts.map +1 -0
  62. package/global-planet.d.ts +23 -0
  63. package/global-planet.d.ts.map +1 -0
  64. package/helpers.d.ts +39 -0
  65. package/helpers.d.ts.map +1 -0
  66. package/index.d.ts +6 -0
  67. package/module.d.ts +12 -0
  68. package/module.d.ts.map +1 -0
  69. package/package.json +27 -120
  70. package/{packages/planet/src/planet.class.ts → planet.class.d.ts} +5 -26
  71. package/planet.class.d.ts.map +1 -0
  72. package/planet.d.ts +28 -0
  73. package/planet.d.ts.map +1 -0
  74. package/{packages/planet/src/public-api.ts → public-api.d.ts} +1 -4
  75. package/public-api.d.ts.map +1 -0
  76. package/sandbox/constants.d.ts +7 -0
  77. package/sandbox/constants.d.ts.map +1 -0
  78. package/sandbox/exec.d.ts +3 -0
  79. package/sandbox/exec.d.ts.map +1 -0
  80. package/sandbox/index.d.ts +7 -0
  81. package/sandbox/index.d.ts.map +1 -0
  82. package/sandbox/proxy/patches/document.d.ts +3 -0
  83. package/sandbox/proxy/patches/document.d.ts.map +1 -0
  84. package/sandbox/proxy/patches/eventListener.d.ts +3 -0
  85. package/sandbox/proxy/patches/eventListener.d.ts.map +1 -0
  86. package/sandbox/proxy/patches/index.d.ts +3 -0
  87. package/sandbox/proxy/patches/index.d.ts.map +1 -0
  88. package/sandbox/proxy/patches/storage.d.ts +15 -0
  89. package/sandbox/proxy/patches/storage.d.ts.map +1 -0
  90. package/sandbox/proxy/patches/timer.d.ts +3 -0
  91. package/sandbox/proxy/patches/timer.d.ts.map +1 -0
  92. package/sandbox/proxy/proxies/common.d.ts +13 -0
  93. package/sandbox/proxy/proxies/common.d.ts.map +1 -0
  94. package/sandbox/proxy/proxies/document.d.ts +14 -0
  95. package/sandbox/proxy/proxies/document.d.ts.map +1 -0
  96. package/sandbox/proxy/proxies/window.d.ts +13 -0
  97. package/sandbox/proxy/proxies/window.d.ts.map +1 -0
  98. package/sandbox/proxy/proxy-sandbox.d.ts +16 -0
  99. package/sandbox/proxy/proxy-sandbox.d.ts.map +1 -0
  100. package/{packages/planet/src/sandbox/proxy/types.ts → sandbox/proxy/types.d.ts} +2 -8
  101. package/sandbox/proxy/types.d.ts.map +1 -0
  102. package/sandbox/sandbox.d.ts +12 -0
  103. package/sandbox/sandbox.d.ts.map +1 -0
  104. package/sandbox/snapshot/snapshot-sandbox.d.ts +9 -0
  105. package/sandbox/snapshot/snapshot-sandbox.d.ts.map +1 -0
  106. package/sandbox/types.d.ts +2 -0
  107. package/sandbox/types.d.ts.map +1 -0
  108. package/worktile-planet.d.ts.map +1 -0
  109. package/.all-contributorsrc +0 -84
  110. package/.circleci/config.yml +0 -17
  111. package/.coveralls.yml +0 -1
  112. package/.docgeni/public/assets/favicon.ico +0 -0
  113. package/.docgeni/public/index.html +0 -13
  114. package/.docgenirc.js +0 -35
  115. package/.dockerignore +0 -1
  116. package/.editorconfig +0 -22
  117. package/.github/FUNDING.yml +0 -12
  118. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  119. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  120. package/.prettierignore +0 -7
  121. package/.prettierrc +0 -28
  122. package/.travis.yml +0 -26
  123. package/.wpmrc.js +0 -11
  124. package/CODE_OF_CONDUCT.md +0 -76
  125. package/Dockerfile +0 -11
  126. package/README.zh-CN.md +0 -307
  127. package/SECURITY.md +0 -21
  128. package/angular.json +0 -373
  129. package/commitlint.config.js +0 -6
  130. package/docs/api/defineApplication.md +0 -46
  131. package/docs/api/globalEventDispatcher.md +0 -51
  132. package/docs/api/index.md +0 -5
  133. package/docs/api/planet.md +0 -117
  134. package/docs/guides/getting-started.md +0 -174
  135. package/docs/guides/index.md +0 -5
  136. package/docs/guides/intro.md +0 -216
  137. package/examples/app1/browserslist +0 -11
  138. package/examples/app1/extra-webpack.config.js +0 -33
  139. package/examples/app1/karma.conf.js +0 -31
  140. package/examples/app1/postcss.config.js +0 -1
  141. package/examples/app1/src/app/app.module.ts +0 -44
  142. package/examples/app1/src/app/app.routing.ts +0 -49
  143. package/examples/app1/src/app/counter.service.ts +0 -16
  144. package/examples/app1/src/app/dashboard/dashboard.component.html +0 -51
  145. package/examples/app1/src/app/dashboard/dashboard.component.ts +0 -70
  146. package/examples/app1/src/app/detail/detail.component.html +0 -8
  147. package/examples/app1/src/app/detail/detail.component.ts +0 -18
  148. package/examples/app1/src/app/overlay.ts +0 -26
  149. package/examples/app1/src/app/projects/dialog/projects-dialog.component.html +0 -10
  150. package/examples/app1/src/app/projects/dialog/projects-dialog.component.ts +0 -41
  151. package/examples/app1/src/app/projects/projects.component.ts +0 -33
  152. package/examples/app1/src/app/root/root.component.css +0 -3
  153. package/examples/app1/src/app/root/root.component.html +0 -16
  154. package/examples/app1/src/app/root/root.component.ts +0 -35
  155. package/examples/app1/src/app/services/initialized-data.resolver.ts +0 -15
  156. package/examples/app1/src/app/shared.module.ts +0 -57
  157. package/examples/app1/src/app/user/detail/user-detail.component.html +0 -5
  158. package/examples/app1/src/app/user/detail/user-detail.component.ts +0 -20
  159. package/examples/app1/src/app/user/user-list.component.html +0 -7
  160. package/examples/app1/src/app/user/user-list.component.ts +0 -20
  161. package/examples/app1/src/app/user/user.module.ts +0 -31
  162. package/examples/app1/src/assets/.gitkeep +0 -0
  163. package/examples/app1/src/assets/github.png +0 -0
  164. package/examples/app1/src/assets/main.css +0 -3
  165. package/examples/app1/src/environments/environment.prod.ts +0 -3
  166. package/examples/app1/src/environments/environment.ts +0 -16
  167. package/examples/app1/src/favicon.ico +0 -0
  168. package/examples/app1/src/index.html +0 -14
  169. package/examples/app1/src/main.ts +0 -35
  170. package/examples/app1/src/polyfills.ts +0 -84
  171. package/examples/app1/src/styles.scss +0 -35
  172. package/examples/app1/src/test.ts +0 -14
  173. package/examples/app1/temp.js +0 -221
  174. package/examples/app1/tsconfig.app.json +0 -10
  175. package/examples/app1/tsconfig.spec.json +0 -18
  176. package/examples/app1/tslint.json +0 -17
  177. package/examples/app1/webpack.config.js +0 -127
  178. package/examples/app2/browserslist +0 -11
  179. package/examples/app2/extra-webpack.config.js +0 -32
  180. package/examples/app2/karma.conf.js +0 -31
  181. package/examples/app2/src/app/app.module.ts +0 -90
  182. package/examples/app2/src/app/dashboard/dashboard.component.html +0 -21
  183. package/examples/app2/src/app/dashboard/dashboard.component.ts +0 -27
  184. package/examples/app2/src/app/overlay.ts +0 -26
  185. package/examples/app2/src/app/projects/detail/detail.component.html +0 -16
  186. package/examples/app2/src/app/projects/detail/detail.component.ts +0 -21
  187. package/examples/app2/src/app/projects/project-list.component.html +0 -29
  188. package/examples/app2/src/app/projects/project-list.component.ts +0 -58
  189. package/examples/app2/src/app/projects/project.resolver.ts +0 -15
  190. package/examples/app2/src/app/projects/projects.service.ts +0 -28
  191. package/examples/app2/src/app/projects/tasks/tasks.component.html +0 -10
  192. package/examples/app2/src/app/projects/tasks/tasks.component.ts +0 -16
  193. package/examples/app2/src/app/projects/view/view.component.html +0 -1
  194. package/examples/app2/src/app/projects/view/view.component.ts +0 -20
  195. package/examples/app2/src/app/root/root.component.html +0 -14
  196. package/examples/app2/src/app/root/root.component.scss +0 -12
  197. package/examples/app2/src/app/root/root.component.ts +0 -28
  198. package/examples/app2/src/app/shared.module.ts +0 -59
  199. package/examples/app2/src/assets/.gitkeep +0 -0
  200. package/examples/app2/src/environments/environment.prod.ts +0 -3
  201. package/examples/app2/src/environments/environment.ts +0 -16
  202. package/examples/app2/src/favicon.ico +0 -0
  203. package/examples/app2/src/index.html +0 -14
  204. package/examples/app2/src/main.ts +0 -36
  205. package/examples/app2/src/polyfills.ts +0 -84
  206. package/examples/app2/src/styles.scss +0 -28
  207. package/examples/app2/src/test.ts +0 -14
  208. package/examples/app2/tsconfig.app.json +0 -10
  209. package/examples/app2/tsconfig.spec.json +0 -18
  210. package/examples/app2/tslint.json +0 -7
  211. package/examples/app2/webpack.config.js +0 -92
  212. package/examples/common/app-root-context.ts +0 -10
  213. package/examples/common/cache.ts +0 -82
  214. package/examples/common/index.ts +0 -13
  215. package/examples/common/module.ts +0 -10
  216. package/examples/common/overlay-container.service.ts +0 -28
  217. package/examples/common/section-card/section-card.component.html +0 -5
  218. package/examples/common/section-card/section-card.component.scss +0 -15
  219. package/examples/common/section-card/section-card.component.ts +0 -11
  220. package/examples/common/utils.ts +0 -0
  221. package/examples/portal/src/app/a-detail/a-detail.component.html +0 -8
  222. package/examples/portal/src/app/a-detail/a-detail.component.ts +0 -18
  223. package/examples/portal/src/app/about/about.component.html +0 -27
  224. package/examples/portal/src/app/about/about.component.scss +0 -0
  225. package/examples/portal/src/app/about/about.component.spec.ts +0 -26
  226. package/examples/portal/src/app/about/about.component.ts +0 -26
  227. package/examples/portal/src/app/app-routing.module.ts +0 -57
  228. package/examples/portal/src/app/app.component.html +0 -73
  229. package/examples/portal/src/app/app.component.scss +0 -58
  230. package/examples/portal/src/app/app.component.spec.ts +0 -33
  231. package/examples/portal/src/app/app.component.ts +0 -111
  232. package/examples/portal/src/app/app.module.ts +0 -64
  233. package/examples/portal/src/app/custom-settings.service.ts +0 -44
  234. package/examples/portal/src/app/overlay.ts +0 -26
  235. package/examples/portal/src/app/settings/settings.component.html +0 -31
  236. package/examples/portal/src/app/settings/settings.component.scss +0 -3
  237. package/examples/portal/src/app/settings/settings.component.ts +0 -43
  238. package/examples/portal/src/assets/.gitkeep +0 -0
  239. package/examples/portal/src/assets/apps.json +0 -29
  240. package/examples/portal/src/assets/icons/sprite.defs.svg +0 -1
  241. package/examples/portal/src/assets/images/logo.svg +0 -16
  242. package/examples/portal/src/assets/ngx-planet-micro-front-end.gif +0 -0
  243. package/examples/portal/src/browserslist +0 -11
  244. package/examples/portal/src/environments/environment.prod.ts +0 -3
  245. package/examples/portal/src/environments/environment.ts +0 -16
  246. package/examples/portal/src/extra-webpack.config.js +0 -32
  247. package/examples/portal/src/favicon.ico +0 -0
  248. package/examples/portal/src/index.html +0 -14
  249. package/examples/portal/src/karma.conf.js +0 -31
  250. package/examples/portal/src/main.ts +0 -18
  251. package/examples/portal/src/polyfills.ts +0 -84
  252. package/examples/portal/src/reboot.scss +0 -14
  253. package/examples/portal/src/styles.scss +0 -14
  254. package/examples/portal/src/test.ts +0 -14
  255. package/examples/portal/src/tsconfig.app.json +0 -10
  256. package/examples/portal/src/tsconfig.spec.json +0 -9
  257. package/examples/portal/src/tslint.json +0 -7
  258. package/extra-webpack.config.js +0 -5
  259. package/nginx.conf +0 -17
  260. package/packages/planet/karma.conf.js +0 -37
  261. package/packages/planet/ng-package.json +0 -7
  262. package/packages/planet/package.json +0 -10
  263. package/packages/planet/src/application/planet-application-loader.spec.ts +0 -1102
  264. package/packages/planet/src/application/planet-application-loader.ts +0 -549
  265. package/packages/planet/src/application/planet-application-ref.spec.ts +0 -233
  266. package/packages/planet/src/application/planet-application-ref.ts +0 -131
  267. package/packages/planet/src/application/planet-application.service.spec.ts +0 -145
  268. package/packages/planet/src/application/planet-application.service.ts +0 -88
  269. package/packages/planet/src/application/portal-application.spec.ts +0 -53
  270. package/packages/planet/src/assets-loader.spec.ts +0 -689
  271. package/packages/planet/src/assets-loader.ts +0 -247
  272. package/packages/planet/src/component/planet-component-loader.spec.ts +0 -187
  273. package/packages/planet/src/component/planet-component-loader.ts +0 -173
  274. package/packages/planet/src/component/planet-component-ref.ts +0 -8
  275. package/packages/planet/src/debug.spec.ts +0 -58
  276. package/packages/planet/src/debug.ts +0 -66
  277. package/packages/planet/src/empty/empty.component.spec.ts +0 -34
  278. package/packages/planet/src/empty/empty.component.ts +0 -7
  279. package/packages/planet/src/global-event-dispatcher.spec.ts +0 -81
  280. package/packages/planet/src/global-event-dispatcher.ts +0 -82
  281. package/packages/planet/src/global-planet.spec.ts +0 -39
  282. package/packages/planet/src/global-planet.ts +0 -73
  283. package/packages/planet/src/helpers.spec.ts +0 -242
  284. package/packages/planet/src/helpers.ts +0 -125
  285. package/packages/planet/src/module.spec.ts +0 -79
  286. package/packages/planet/src/module.ts +0 -25
  287. package/packages/planet/src/planet.spec.ts +0 -226
  288. package/packages/planet/src/planet.ts +0 -113
  289. package/packages/planet/src/sandbox/constants.ts +0 -6
  290. package/packages/planet/src/sandbox/exec.ts +0 -22
  291. package/packages/planet/src/sandbox/index.ts +0 -24
  292. package/packages/planet/src/sandbox/proxy/patches/document.ts +0 -13
  293. package/packages/planet/src/sandbox/proxy/patches/eventListener.ts +0 -49
  294. package/packages/planet/src/sandbox/proxy/patches/index.ts +0 -13
  295. package/packages/planet/src/sandbox/proxy/patches/storage.ts +0 -53
  296. package/packages/planet/src/sandbox/proxy/patches/timer.ts +0 -50
  297. package/packages/planet/src/sandbox/proxy/proxies/common.ts +0 -137
  298. package/packages/planet/src/sandbox/proxy/proxies/document.ts +0 -140
  299. package/packages/planet/src/sandbox/proxy/proxies/window.ts +0 -176
  300. package/packages/planet/src/sandbox/proxy/proxy-sandbox.ts +0 -59
  301. package/packages/planet/src/sandbox/sandbox.ts +0 -20
  302. package/packages/planet/src/sandbox/snapshot/snapshot-sandbox.ts +0 -12
  303. package/packages/planet/src/sandbox/types.ts +0 -1
  304. package/packages/planet/src/test.ts +0 -16
  305. package/packages/planet/src/testing/app1.module.ts +0 -34
  306. package/packages/planet/src/testing/app2.module.ts +0 -24
  307. package/packages/planet/src/testing/applications.ts +0 -58
  308. package/packages/planet/src/testing/index.ts +0 -2
  309. package/packages/planet/src/testing/utils.ts +0 -31
  310. package/packages/planet/tsconfig.lib.json +0 -27
  311. package/packages/planet/tsconfig.lib.prod.json +0 -9
  312. package/packages/planet/tsconfig.spec.json +0 -17
  313. package/packages/planet/tslint.json +0 -7
  314. package/postcss.config.js +0 -3
  315. package/proxy.conf.js +0 -15
  316. package/tsconfig.json +0 -23
  317. package/tslint.json +0 -80
@@ -0,0 +1,454 @@
1
+ import { Injectable, NgZone, ApplicationRef, Injector } from '@angular/core';
2
+ import { of, Subject, forkJoin, from } from 'rxjs';
3
+ import { AssetsLoader } from '../assets-loader';
4
+ import { SwitchModes } from '../planet.class';
5
+ import { switchMap, share, map, tap, distinctUntilChanged, take, filter, catchError } from 'rxjs/operators';
6
+ import { getHTMLElement, coerceArray, createElementByTemplate } from '../helpers';
7
+ import { PlanetPortalApplication } from './portal-application';
8
+ import { PlanetApplicationService } from './planet-application.service';
9
+ import { GlobalEventDispatcher } from '../global-event-dispatcher';
10
+ import { Router } from '@angular/router';
11
+ import { globalPlanet, getPlanetApplicationRef, getApplicationLoader } from '../global-planet';
12
+ import { createDebug } from '../debug';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "../assets-loader";
15
+ import * as i2 from "./planet-application.service";
16
+ import * as i3 from "@angular/router";
17
+ const debug = createDebug('app-loader');
18
+ export var ApplicationStatus;
19
+ (function (ApplicationStatus) {
20
+ ApplicationStatus[ApplicationStatus["assetsLoading"] = 1] = "assetsLoading";
21
+ ApplicationStatus[ApplicationStatus["assetsLoaded"] = 2] = "assetsLoaded";
22
+ ApplicationStatus[ApplicationStatus["bootstrapping"] = 3] = "bootstrapping";
23
+ ApplicationStatus[ApplicationStatus["bootstrapped"] = 4] = "bootstrapped";
24
+ ApplicationStatus[ApplicationStatus["active"] = 5] = "active";
25
+ ApplicationStatus[ApplicationStatus["loadError"] = 10] = "loadError";
26
+ })(ApplicationStatus || (ApplicationStatus = {}));
27
+ export class PlanetApplicationLoader {
28
+ constructor(assetsLoader, planetApplicationService, ngZone, router, injector, applicationRef) {
29
+ this.assetsLoader = assetsLoader;
30
+ this.planetApplicationService = planetApplicationService;
31
+ this.ngZone = ngZone;
32
+ this.firstLoad = true;
33
+ this.inProgressAppAssetsLoads = new Map();
34
+ this.appsStatus = new Map();
35
+ this.portalApp = new PlanetPortalApplication();
36
+ this.routeChange$ = new Subject();
37
+ this.appStatusChange$ = new Subject();
38
+ this.appsLoadingStart$ = new Subject();
39
+ this.loadingDone = false;
40
+ if (getApplicationLoader()) {
41
+ throw new Error('PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed');
42
+ }
43
+ this.options = {
44
+ switchMode: SwitchModes.default,
45
+ errorHandler: (error) => {
46
+ console.error(error);
47
+ }
48
+ };
49
+ this.portalApp.ngZone = ngZone;
50
+ this.portalApp.applicationRef = applicationRef;
51
+ this.portalApp.router = router;
52
+ this.portalApp.injector = injector;
53
+ this.portalApp.globalEventDispatcher = injector.get(GlobalEventDispatcher);
54
+ globalPlanet.portalApplication = this.portalApp;
55
+ this.setupRouteChange();
56
+ }
57
+ get appStatusChange() {
58
+ return this.appStatusChange$.asObservable();
59
+ }
60
+ get appsLoadingStart() {
61
+ return this.appsLoadingStart$.asObservable();
62
+ }
63
+ setAppStatus(app, status) {
64
+ this.ngZone.run(() => {
65
+ const fromStatus = this.appsStatus.get(app);
66
+ debug(`app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${ApplicationStatus[status]}`);
67
+ this.appsStatus.set(app, status);
68
+ this.appStatusChange$.next({
69
+ app: app,
70
+ status: status
71
+ });
72
+ });
73
+ }
74
+ getAppStatusChange$(app, status = ApplicationStatus.bootstrapped) {
75
+ return this.appStatusChange.pipe(filter(event => {
76
+ return event.app === app && event.status === status;
77
+ }), map(() => {
78
+ return app;
79
+ }));
80
+ }
81
+ switchModeIsCoexist(app) {
82
+ if (app && app.switchMode) {
83
+ return app.switchMode === SwitchModes.coexist;
84
+ }
85
+ else {
86
+ return this.options.switchMode === SwitchModes.coexist;
87
+ }
88
+ }
89
+ errorHandler(error) {
90
+ this.ngZone.run(() => {
91
+ this.options.errorHandler(error);
92
+ });
93
+ }
94
+ setLoadingDone() {
95
+ this.ngZone.run(() => {
96
+ this.loadingDone = true;
97
+ });
98
+ }
99
+ getAppNames(apps) {
100
+ return apps.length === 0
101
+ ? `[]`
102
+ : apps.map(item => {
103
+ return item.name;
104
+ });
105
+ }
106
+ setupRouteChange() {
107
+ this.routeChange$
108
+ .pipe(distinctUntilChanged((x, y) => {
109
+ return (x && x.url) === (y && y.url);
110
+ }),
111
+ // Using switchMap so we cancel executing loading when a new one comes in
112
+ switchMap(event => {
113
+ // Return new observable use of and catchError,
114
+ // in order to prevent routeChange$ completed which never trigger new route change
115
+ return of(event).pipe(
116
+ // unload apps and return should load apps
117
+ map(() => {
118
+ debug(`route change, url is: ${event.url}`);
119
+ this.startRouteChangeEvent = event;
120
+ const shouldLoadApps = this.planetApplicationService.getAppsByMatchedUrl(event.url);
121
+ debug(`should load apps: ${this.getAppNames(shouldLoadApps)}`);
122
+ const shouldUnloadApps = this.getUnloadApps(shouldLoadApps);
123
+ this.appsLoadingStart$.next({
124
+ shouldLoadApps,
125
+ shouldUnloadApps
126
+ });
127
+ this.unloadApps(shouldUnloadApps, event);
128
+ debug(`unload apps: ${this.getAppNames(shouldUnloadApps)}`);
129
+ return shouldLoadApps;
130
+ }),
131
+ // Load app assets (static resources)
132
+ switchMap(shouldLoadApps => {
133
+ let hasAppsNeedLoadingAssets = false;
134
+ const loadApps$ = shouldLoadApps.map(app => {
135
+ const appStatus = this.appsStatus.get(app);
136
+ if (!appStatus ||
137
+ appStatus === ApplicationStatus.assetsLoading ||
138
+ appStatus === ApplicationStatus.loadError) {
139
+ debug(`app(${app.name}) status is ${ApplicationStatus[appStatus]}, start load assets`);
140
+ hasAppsNeedLoadingAssets = true;
141
+ return this.ngZone.runOutsideAngular(() => {
142
+ return this.startLoadAppAssets(app);
143
+ });
144
+ }
145
+ else {
146
+ return of(app);
147
+ }
148
+ });
149
+ if (hasAppsNeedLoadingAssets) {
150
+ this.loadingDone = false;
151
+ }
152
+ return loadApps$.length > 0 ? forkJoin(loadApps$) : of([]);
153
+ }),
154
+ // Bootstrap or show apps
155
+ map(apps => {
156
+ const apps$ = apps.map(app => {
157
+ return of(app).pipe(switchMap(app => {
158
+ const appStatus = this.appsStatus.get(app);
159
+ if (appStatus === ApplicationStatus.bootstrapped) {
160
+ debug(`[routeChange] app(${app.name}) status is bootstrapped, show app and active`);
161
+ this.showApp(app);
162
+ const appRef = getPlanetApplicationRef(app.name);
163
+ appRef?.navigateByUrl(event.url);
164
+ this.setAppStatus(app, ApplicationStatus.active);
165
+ this.setLoadingDone();
166
+ return of(app);
167
+ }
168
+ else if (appStatus === ApplicationStatus.assetsLoaded) {
169
+ debug(`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`);
170
+ return this.bootstrapApp(app).pipe(map(() => {
171
+ debug(`app(${app.name}) bootstrapped success, active it`);
172
+ this.setAppStatus(app, ApplicationStatus.active);
173
+ this.setLoadingDone();
174
+ return app;
175
+ }));
176
+ }
177
+ else if (appStatus === ApplicationStatus.active) {
178
+ debug(`[routeChange] app(${app.name}) is active, do nothings`);
179
+ const appRef = getPlanetApplicationRef(app.name);
180
+ // Backwards compatibility sub app use old version which has not getCurrentRouterStateUrl
181
+ const currentUrl = appRef?.getCurrentRouterStateUrl
182
+ ? appRef.getCurrentRouterStateUrl()
183
+ : '';
184
+ if (currentUrl !== event.url) {
185
+ appRef?.navigateByUrl(event.url);
186
+ }
187
+ return of(app);
188
+ }
189
+ else {
190
+ debug(`[routeChange] app(${app.name}) status is ${ApplicationStatus[appStatus]}`);
191
+ return this.getAppStatusChange$(app).pipe(take(1), map(() => {
192
+ debug(`app(${app.name}) status is bootstrapped by subscribe status change, active it`);
193
+ this.setAppStatus(app, ApplicationStatus.active);
194
+ this.showApp(app);
195
+ return app;
196
+ }));
197
+ }
198
+ }));
199
+ });
200
+ if (apps$.length > 0) {
201
+ debug(`start load and active apps: ${this.getAppNames(apps)}`);
202
+ // 切换到应用后会有闪烁现象,所以使用 setTimeout 后启动应用
203
+ // example: redirect to app1's dashboard from portal's about page
204
+ // If app's route has redirect, it doesn't work, it ok just in setTimeout, I don't know why.
205
+ // TODO:: remove it, it is ok in version Angular 9.x
206
+ setTimeout(() => {
207
+ // 此处判断是因为如果静态资源加载完毕还未启动被取消,还是会启动之前的应用,虽然可能性比较小,但是无法排除这种可能性,所以只有当 Event 是最后一个才会启动
208
+ if (this.startRouteChangeEvent === event) {
209
+ // runOutsideAngular for fix error: `Expected to not be in Angular Zone, but it is!`
210
+ this.ngZone.runOutsideAngular(() => {
211
+ forkJoin(apps$).subscribe(() => {
212
+ this.setLoadingDone();
213
+ this.ensurePreloadApps(apps);
214
+ });
215
+ });
216
+ }
217
+ });
218
+ }
219
+ else {
220
+ debug(`no apps need to be loaded, ensure preload apps`);
221
+ this.ensurePreloadApps(apps);
222
+ this.setLoadingDone();
223
+ }
224
+ }),
225
+ // Error handler
226
+ catchError(error => {
227
+ debug(`apps loader error: ${error}`);
228
+ this.errorHandler(error);
229
+ return [];
230
+ }));
231
+ }))
232
+ .subscribe();
233
+ }
234
+ startLoadAppAssets(app) {
235
+ if (this.inProgressAppAssetsLoads.get(app.name)) {
236
+ return this.inProgressAppAssetsLoads.get(app.name);
237
+ }
238
+ else {
239
+ const loadApp$ = this.assetsLoader.loadAppAssets(app).pipe(tap(() => {
240
+ this.inProgressAppAssetsLoads.delete(app.name);
241
+ this.setAppStatus(app, ApplicationStatus.assetsLoaded);
242
+ }), map(() => {
243
+ return app;
244
+ }), catchError(error => {
245
+ this.inProgressAppAssetsLoads.delete(app.name);
246
+ this.setAppStatus(app, ApplicationStatus.loadError);
247
+ throw error;
248
+ }), share());
249
+ this.inProgressAppAssetsLoads.set(app.name, loadApp$);
250
+ this.setAppStatus(app, ApplicationStatus.assetsLoading);
251
+ return loadApp$;
252
+ }
253
+ }
254
+ hideApp(planetApp) {
255
+ const appRef = getPlanetApplicationRef(planetApp.name);
256
+ const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
257
+ if (appRootElement) {
258
+ appRootElement.setAttribute('style', 'display:none;');
259
+ }
260
+ }
261
+ showApp(planetApp) {
262
+ const appRef = getPlanetApplicationRef(planetApp.name);
263
+ const appRootElement = document.querySelector(appRef?.selector || planetApp.selector);
264
+ if (appRootElement) {
265
+ appRootElement.setAttribute('style', '');
266
+ }
267
+ }
268
+ destroyApp(planetApp) {
269
+ const appRef = getPlanetApplicationRef(planetApp.name);
270
+ if (appRef) {
271
+ appRef.destroy();
272
+ }
273
+ const container = getHTMLElement(planetApp.hostParent);
274
+ const appRootElement = container?.querySelector((appRef && appRef.selector) || planetApp.selector);
275
+ if (appRootElement) {
276
+ container?.removeChild(appRootElement);
277
+ }
278
+ }
279
+ bootstrapApp(app, defaultStatus = 'display') {
280
+ debug(`app(${app.name}) start bootstrapping`);
281
+ this.setAppStatus(app, ApplicationStatus.bootstrapping);
282
+ const appRef = getPlanetApplicationRef(app.name);
283
+ if (appRef && appRef.bootstrap) {
284
+ const container = getHTMLElement(app.hostParent);
285
+ let appRootElement;
286
+ if (container) {
287
+ appRootElement = container.querySelector(appRef.selector || app.selector);
288
+ if (!appRootElement) {
289
+ if (appRef.template) {
290
+ appRootElement = createElementByTemplate(appRef.template);
291
+ }
292
+ else {
293
+ appRootElement = document.createElement(app.selector);
294
+ }
295
+ appRootElement.setAttribute('style', 'display:none;');
296
+ if (app.hostClass) {
297
+ appRootElement.classList.add(...coerceArray(app.hostClass));
298
+ }
299
+ if (app.stylePrefix) {
300
+ appRootElement.classList.add(...coerceArray(app.stylePrefix));
301
+ }
302
+ container.appendChild(appRootElement);
303
+ }
304
+ }
305
+ let result = appRef.bootstrap(this.portalApp);
306
+ // Backwards compatibility promise for bootstrap
307
+ if (result['then']) {
308
+ result = from(result);
309
+ }
310
+ return result.pipe(tap(() => {
311
+ debug(`app(${app.name}) bootstrapped success for ${defaultStatus}`);
312
+ this.setAppStatus(app, ApplicationStatus.bootstrapped);
313
+ if (defaultStatus === 'display' && appRootElement) {
314
+ appRootElement.removeAttribute('style');
315
+ }
316
+ }), map(() => {
317
+ return appRef;
318
+ }));
319
+ }
320
+ else {
321
+ throw new Error(`[${app.name}] not found, make sure that the app has the correct name defined use defineApplication(${app.name}) and runtimeChunk and vendorChunk are set to true, details see https://github.com/worktile/ngx-planet#throw-error-cannot-read-property-call-of-undefined-at-__webpack_require__-bootstrap79`);
322
+ }
323
+ }
324
+ getUnloadApps(activeApps) {
325
+ const unloadApps = [];
326
+ this.appsStatus.forEach((value, app) => {
327
+ if (value === ApplicationStatus.active && !activeApps.find(item => item.name === app.name)) {
328
+ unloadApps.push(app);
329
+ }
330
+ });
331
+ return unloadApps;
332
+ }
333
+ unloadApps(shouldUnloadApps, event) {
334
+ const hideApps = [];
335
+ const destroyApps = [];
336
+ shouldUnloadApps.forEach(app => {
337
+ if (this.switchModeIsCoexist(app)) {
338
+ debug(`hide app(${app.name}) for coexist mode`);
339
+ hideApps.push(app);
340
+ this.hideApp(app);
341
+ this.setAppStatus(app, ApplicationStatus.bootstrapped);
342
+ }
343
+ else {
344
+ destroyApps.push(app);
345
+ // 销毁之前先隐藏,否则会出现闪烁,因为 destroy 是延迟执行的
346
+ // 如果销毁不延迟执行,会出现切换到主应用的时候会有视图卡顿现象
347
+ this.hideApp(app);
348
+ this.setAppStatus(app, ApplicationStatus.assetsLoaded);
349
+ }
350
+ });
351
+ if (hideApps.length > 0 || destroyApps.length > 0) {
352
+ // 从其他应用切换到主应用的时候会有视图卡顿现象,所以先等主应用渲染完毕后再加载其他应用
353
+ // 此处尝试使用 this.ngZone.onStable.pipe(take(1)) 应用之间的切换会出现闪烁
354
+ setTimeout(() => {
355
+ hideApps.forEach(app => {
356
+ const appRef = getPlanetApplicationRef(app.name);
357
+ if (appRef) {
358
+ appRef.navigateByUrl(event.url);
359
+ }
360
+ });
361
+ destroyApps.forEach(app => {
362
+ debug(`destroy app(${app.name})`);
363
+ this.destroyApp(app);
364
+ });
365
+ });
366
+ }
367
+ }
368
+ preloadApps(activeApps) {
369
+ setTimeout(() => {
370
+ const toPreloadApps = this.planetApplicationService.getAppsToPreload(activeApps ? activeApps.map(item => item.name) : undefined);
371
+ debug(`start preload apps: ${this.getAppNames(toPreloadApps)}`);
372
+ const loadApps$ = toPreloadApps.map(preloadApp => {
373
+ return this.preloadInternal(preloadApp);
374
+ });
375
+ forkJoin(loadApps$).subscribe({
376
+ error: error => {
377
+ this.errorHandler(error);
378
+ }
379
+ });
380
+ });
381
+ }
382
+ ensurePreloadApps(activeApps) {
383
+ // Start preload apps
384
+ // Start preload when first time app loaded
385
+ if (this.firstLoad) {
386
+ this.preloadApps(activeApps);
387
+ this.firstLoad = false;
388
+ }
389
+ }
390
+ setOptions(options) {
391
+ this.options = {
392
+ ...this.options,
393
+ ...options
394
+ };
395
+ }
396
+ /**
397
+ * reset route by current router
398
+ */
399
+ reroute(event) {
400
+ this.routeChange$.next(event);
401
+ }
402
+ preloadInternal(app, immediate) {
403
+ const status = this.appsStatus.get(app);
404
+ if (!status || status === ApplicationStatus.loadError) {
405
+ debug(`preload app(${app.name}), status is empty, start to load assets`);
406
+ return this.startLoadAppAssets(app).pipe(switchMap(() => {
407
+ debug(`preload app(${app.name}), assets loaded, start bootstrap app, immediate: ${!!immediate}`);
408
+ if (immediate) {
409
+ return this.bootstrapApp(app, 'hidden');
410
+ }
411
+ else {
412
+ return this.ngZone.runOutsideAngular(() => {
413
+ return this.bootstrapApp(app, 'hidden');
414
+ });
415
+ }
416
+ }), catchError(error => {
417
+ this.errorHandler(error);
418
+ return of(null);
419
+ }), map(() => {
420
+ return getPlanetApplicationRef(app.name);
421
+ }));
422
+ }
423
+ else if ([ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(status)) {
424
+ debug(`preload app(${app.name}), status is ${ApplicationStatus[status]}, return until bootstrapped`);
425
+ return this.getAppStatusChange$(app).pipe(take(1), map(() => {
426
+ return getPlanetApplicationRef(app.name);
427
+ }));
428
+ }
429
+ else {
430
+ const appRef = getPlanetApplicationRef(app.name);
431
+ if (!appRef) {
432
+ throw new Error(`${app.name}'s status is ${ApplicationStatus[status]}, planetApplicationRef is null.`);
433
+ }
434
+ return of(appRef);
435
+ }
436
+ }
437
+ /**
438
+ * Preload planet application
439
+ * @param app app
440
+ * @param immediate bootstrap on stable by default, setting immediate is true, it will bootstrap immediate
441
+ */
442
+ preload(app, immediate) {
443
+ return this.preloadInternal(app, immediate);
444
+ }
445
+ }
446
+ PlanetApplicationLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, deps: [{ token: i1.AssetsLoader }, { token: i2.PlanetApplicationService }, { token: i0.NgZone }, { token: i3.Router }, { token: i0.Injector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
447
+ PlanetApplicationLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, providedIn: 'root' });
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: PlanetApplicationLoader, decorators: [{
449
+ type: Injectable,
450
+ args: [{
451
+ providedIn: 'root'
452
+ }]
453
+ }], ctorParameters: function () { return [{ type: i1.AssetsLoader }, { type: i2.PlanetApplicationService }, { type: i0.NgZone }, { type: i3.Router }, { type: i0.Injector }, { type: i0.ApplicationRef }]; } });
454
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbmV0LWFwcGxpY2F0aW9uLWxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYW5ldC9zcmMvYXBwbGljYXRpb24vcGxhbmV0LWFwcGxpY2F0aW9uLWxvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxFQUFFLEVBQWMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBd0MsV0FBVyxFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ25HLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVsRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9GLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxVQUFVLENBQUM7Ozs7O0FBQ3ZDLE1BQU0sS0FBSyxHQUFHLFdBQVcs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QyxJQUFJLGdCQUFnQixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsaUNBQWlDLENBQUMsQ0FBQzthQUMxRztZQUNELE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3JCO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxPQUFPLENBQUMsR0FBc0IsRUFBRSxTQUFtQjtRQUN0RCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7O29IQTlmUSx1QkFBdUI7d0hBQXZCLHVCQUF1QixjQUZwQixNQUFNOzJGQUVULHVCQUF1QjtrQkFIbkMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUsIEFwcGxpY2F0aW9uUmVmLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgb2YsIE9ic2VydmFibGUsIFN1YmplY3QsIGZvcmtKb2luLCBmcm9tLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBc3NldHNMb2FkZXIgfSBmcm9tICcuLi9hc3NldHMtbG9hZGVyJztcbmltcG9ydCB7IFBsYW5ldEFwcGxpY2F0aW9uLCBQbGFuZXRSb3V0ZXJFdmVudCwgU3dpdGNoTW9kZXMsIFBsYW5ldE9wdGlvbnMgfSBmcm9tICcuLi9wbGFuZXQuY2xhc3MnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCBzaGFyZSwgbWFwLCB0YXAsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YWtlLCBmaWx0ZXIsIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBnZXRIVE1MRWxlbWVudCwgY29lcmNlQXJyYXksIGNyZWF0ZUVsZW1lbnRCeVRlbXBsYXRlIH0gZnJvbSAnLi4vaGVscGVycyc7XG5pbXBvcnQgeyBQbGFuZXRBcHBsaWNhdGlvblJlZiB9IGZyb20gJy4vcGxhbmV0LWFwcGxpY2F0aW9uLXJlZic7XG5pbXBvcnQgeyBQbGFuZXRQb3J0YWxBcHBsaWNhdGlvbiB9IGZyb20gJy4vcG9ydGFsLWFwcGxpY2F0aW9uJztcbmltcG9ydCB7IFBsYW5ldEFwcGxpY2F0aW9uU2VydmljZSB9IGZyb20gJy4vcGxhbmV0LWFwcGxpY2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgR2xvYmFsRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi4vZ2xvYmFsLWV2ZW50LWRpc3BhdGNoZXInO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGdsb2JhbFBsYW5ldCwgZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYsIGdldEFwcGxpY2F0aW9uTG9hZGVyIH0gZnJvbSAnLi4vZ2xvYmFsLXBsYW5ldCc7XG5pbXBvcnQgeyBjcmVhdGVEZWJ1ZyB9IGZyb20gJy4uL2RlYnVnJztcbmNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoJ2FwcC1sb2FkZXInKTtcblxuZXhwb3J0IGVudW0gQXBwbGljYXRpb25TdGF0dXMge1xuICAgIGFzc2V0c0xvYWRpbmcgPSAxLFxuICAgIGFzc2V0c0xvYWRlZCA9IDIsXG4gICAgYm9vdHN0cmFwcGluZyA9IDMsXG4gICAgYm9vdHN0cmFwcGVkID0gNCxcbiAgICBhY3RpdmUgPSA1LFxuICAgIGxvYWRFcnJvciA9IDEwXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwc0xvYWRpbmdTdGFydEV2ZW50IHtcbiAgICBzaG91bGRMb2FkQXBwczogUGxhbmV0QXBwbGljYXRpb25bXTtcbiAgICBzaG91bGRVbmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFwcFN0YXR1c0NoYW5nZUV2ZW50IHtcbiAgICBhcHA6IFBsYW5ldEFwcGxpY2F0aW9uO1xuICAgIHN0YXR1czogQXBwbGljYXRpb25TdGF0dXM7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgUGxhbmV0QXBwbGljYXRpb25Mb2FkZXIge1xuICAgIHByaXZhdGUgZmlyc3RMb2FkID0gdHJ1ZTtcblxuICAgIHByaXZhdGUgc3RhcnRSb3V0ZUNoYW5nZUV2ZW50ITogUGxhbmV0Um91dGVyRXZlbnQ7XG5cbiAgICBwcml2YXRlIG9wdGlvbnM6IFBsYW5ldE9wdGlvbnM7XG5cbiAgICBwcml2YXRlIGluUHJvZ3Jlc3NBcHBBc3NldHNMb2FkcyA9IG5ldyBNYXA8c3RyaW5nLCBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uPj4oKTtcblxuICAgIHByaXZhdGUgYXBwc1N0YXR1cyA9IG5ldyBNYXA8UGxhbmV0QXBwbGljYXRpb24sIEFwcGxpY2F0aW9uU3RhdHVzPigpO1xuXG4gICAgcHJpdmF0ZSBwb3J0YWxBcHAgPSBuZXcgUGxhbmV0UG9ydGFsQXBwbGljYXRpb24oKTtcblxuICAgIHByaXZhdGUgcm91dGVDaGFuZ2UkID0gbmV3IFN1YmplY3Q8UGxhbmV0Um91dGVyRXZlbnQ+KCk7XG5cbiAgICBwcml2YXRlIGFwcFN0YXR1c0NoYW5nZSQgPSBuZXcgU3ViamVjdDxBcHBTdGF0dXNDaGFuZ2VFdmVudD4oKTtcblxuICAgIHByaXZhdGUgYXBwc0xvYWRpbmdTdGFydCQgPSBuZXcgU3ViamVjdDxBcHBzTG9hZGluZ1N0YXJ0RXZlbnQ+KCk7XG5cbiAgICBwdWJsaWMgZ2V0IGFwcFN0YXR1c0NoYW5nZSgpOiBPYnNlcnZhYmxlPEFwcFN0YXR1c0NoYW5nZUV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcFN0YXR1c0NoYW5nZSQuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhcHBzTG9hZGluZ1N0YXJ0KCk6IE9ic2VydmFibGU8QXBwc0xvYWRpbmdTdGFydEV2ZW50PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcHNMb2FkaW5nU3RhcnQkLmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkaW5nRG9uZSA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgYXNzZXRzTG9hZGVyOiBBc3NldHNMb2FkZXIsXG4gICAgICAgIHByaXZhdGUgcGxhbmV0QXBwbGljYXRpb25TZXJ2aWNlOiBQbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgIHJvdXRlcjogUm91dGVyLFxuICAgICAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIGFwcGxpY2F0aW9uUmVmOiBBcHBsaWNhdGlvblJlZlxuICAgICkge1xuICAgICAgICBpZiAoZ2V0QXBwbGljYXRpb25Mb2FkZXIoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdQbGFuZXRBcHBsaWNhdGlvbkxvYWRlciBoYXMgYmVlbiBpbmplY3RlZCBpbiB0aGUgcG9ydGFsLCByZXBlYXRlZCBpbmplY3Rpb24gaXMgbm90IGFsbG93ZWQnXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgc3dpdGNoTW9kZTogU3dpdGNoTW9kZXMuZGVmYXVsdCxcbiAgICAgICAgICAgIGVycm9ySGFuZGxlcjogKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnBvcnRhbEFwcC5uZ1pvbmUgPSBuZ1pvbmU7XG4gICAgICAgIHRoaXMucG9ydGFsQXBwLmFwcGxpY2F0aW9uUmVmID0gYXBwbGljYXRpb25SZWY7XG4gICAgICAgIHRoaXMucG9ydGFsQXBwLnJvdXRlciA9IHJvdXRlcjtcbiAgICAgICAgdGhpcy5wb3J0YWxBcHAuaW5qZWN0b3IgPSBpbmplY3RvcjtcbiAgICAgICAgdGhpcy5wb3J0YWxBcHAuZ2xvYmFsRXZlbnREaXNwYXRjaGVyID0gaW5qZWN0b3IuZ2V0KEdsb2JhbEV2ZW50RGlzcGF0Y2hlcik7XG4gICAgICAgIGdsb2JhbFBsYW5ldC5wb3J0YWxBcHBsaWNhdGlvbiA9IHRoaXMucG9ydGFsQXBwO1xuICAgICAgICB0aGlzLnNldHVwUm91dGVDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEFwcFN0YXR1cyhhcHA6IFBsYW5ldEFwcGxpY2F0aW9uLCBzdGF0dXM6IEFwcGxpY2F0aW9uU3RhdHVzKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmcm9tU3RhdHVzID0gdGhpcy5hcHBzU3RhdHVzLmdldChhcHApO1xuICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgYGFwcCgke2FwcC5uYW1lfSkgc3RhdHVzIGNoYW5nZTogJHtmcm9tU3RhdHVzID8gQXBwbGljYXRpb25TdGF0dXNbZnJvbVN0YXR1c10gOiAnZW1wdHknfSA9PiAke1xuICAgICAgICAgICAgICAgICAgICBBcHBsaWNhdGlvblN0YXR1c1tzdGF0dXNdXG4gICAgICAgICAgICAgICAgfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmFwcHNTdGF0dXMuc2V0KGFwcCwgc3RhdHVzKTtcbiAgICAgICAgICAgIHRoaXMuYXBwU3RhdHVzQ2hhbmdlJC5uZXh0KHtcbiAgICAgICAgICAgICAgICBhcHA6IGFwcCxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1c1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0QXBwU3RhdHVzQ2hhbmdlJChcbiAgICAgICAgYXBwOiBQbGFuZXRBcHBsaWNhdGlvbixcbiAgICAgICAgc3RhdHVzID0gQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkXG4gICAgKTogT2JzZXJ2YWJsZTxQbGFuZXRBcHBsaWNhdGlvbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBTdGF0dXNDaGFuZ2UucGlwZShcbiAgICAgICAgICAgIGZpbHRlcihldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmFwcCA9PT0gYXBwICYmIGV2ZW50LnN0YXR1cyA9PT0gc3RhdHVzO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3dpdGNoTW9kZUlzQ29leGlzdChhcHA6IFBsYW5ldEFwcGxpY2F0aW9uKSB7XG4gICAgICAgIGlmIChhcHAgJiYgYXBwLnN3aXRjaE1vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHAuc3dpdGNoTW9kZSA9PT0gU3dpdGNoTW9kZXMuY29leGlzdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuc3dpdGNoTW9kZSA9PT0gU3dpdGNoTW9kZXMuY29leGlzdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZXJyb3JIYW5kbGVyKGVycm9yOiBFcnJvcikge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0TG9hZGluZ0RvbmUoKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmdEb25lID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRBcHBOYW1lcyhhcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gYXBwcy5sZW5ndGggPT09IDBcbiAgICAgICAgICAgID8gYFtdYFxuICAgICAgICAgICAgOiBhcHBzLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLm5hbWU7XG4gICAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBSb3V0ZUNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5yb3V0ZUNoYW5nZSRcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCh4LCB5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoeCAmJiB4LnVybCkgPT09ICh5ICYmIHkudXJsKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAvLyBVc2luZyBzd2l0Y2hNYXAgc28gd2UgY2FuY2VsIGV4ZWN1dGluZyBsb2FkaW5nIHdoZW4gYSBuZXcgb25lIGNvbWVzIGluXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIG5ldyBvYnNlcnZhYmxlIHVzZSBvZiBhbmQgY2F0Y2hFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgLy8gaW4gb3JkZXIgdG8gcHJldmVudCByb3V0ZUNoYW5nZSQgY29tcGxldGVkIHdoaWNoIG5ldmVyIHRyaWdnZXIgbmV3IHJvdXRlIGNoYW5nZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YoZXZlbnQpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmxvYWQgYXBwcyBhbmQgcmV0dXJuIHNob3VsZCBsb2FkIGFwcHNcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYHJvdXRlIGNoYW5nZSwgdXJsIGlzOiAke2V2ZW50LnVybH1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0Um91dGVDaGFuZ2VFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZExvYWRBcHBzID0gdGhpcy5wbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UuZ2V0QXBwc0J5TWF0Y2hlZFVybChldmVudC51cmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKGBzaG91bGQgbG9hZCBhcHBzOiAke3RoaXMuZ2V0QXBwTmFtZXMoc2hvdWxkTG9hZEFwcHMpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFVubG9hZEFwcHMgPSB0aGlzLmdldFVubG9hZEFwcHMoc2hvdWxkTG9hZEFwcHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwc0xvYWRpbmdTdGFydCQubmV4dCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZExvYWRBcHBzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRVbmxvYWRBcHBzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmxvYWRBcHBzKHNob3VsZFVubG9hZEFwcHMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhgdW5sb2FkIGFwcHM6ICR7dGhpcy5nZXRBcHBOYW1lcyhzaG91bGRVbmxvYWRBcHBzKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2hvdWxkTG9hZEFwcHM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIExvYWQgYXBwIGFzc2V0cyAoc3RhdGljIHJlc291cmNlcylcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcChzaG91bGRMb2FkQXBwcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0FwcHNOZWVkTG9hZGluZ0Fzc2V0cyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRBcHBzJCA9IHNob3VsZExvYWRBcHBzLm1hcChhcHAgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBTdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFhcHBTdGF0dXMgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcFN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMuYXNzZXRzTG9hZGluZyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5sb2FkRXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYXBwKCR7YXBwLm5hbWV9KSBzdGF0dXMgaXMgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbGljYXRpb25TdGF0dXNbYXBwU3RhdHVzIGFzIEFwcGxpY2F0aW9uU3RhdHVzXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIHN0YXJ0IGxvYWQgYXNzZXRzYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0FwcHNOZWVkTG9hZGluZ0Fzc2V0cyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0TG9hZEFwcEFzc2V0cyhhcHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNBcHBzTmVlZExvYWRpbmdBc3NldHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nRG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbG9hZEFwcHMkLmxlbmd0aCA+IDAgPyBmb3JrSm9pbihsb2FkQXBwcyQpIDogb2YoW10gYXMgUGxhbmV0QXBwbGljYXRpb25bXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJvb3RzdHJhcCBvciBzaG93IGFwcHNcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcChhcHBzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBzJDogT2JzZXJ2YWJsZTxQbGFuZXRBcHBsaWNhdGlvbj5bXSA9IGFwcHMubWFwKGFwcCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihhcHApLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoYXBwID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBTdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcFN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFtyb3V0ZUNoYW5nZV0gYXBwKCR7YXBwLm5hbWV9KSBzdGF0dXMgaXMgYm9vdHN0cmFwcGVkLCBzaG93IGFwcCBhbmQgYWN0aXZlYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dBcHAoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBSZWY/Lm5hdmlnYXRlQnlVcmwoZXZlbnQudXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5hY3RpdmUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldExvYWRpbmdEb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihhcHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5hc3NldHNMb2FkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgW3JvdXRlQ2hhbmdlXSBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyBhc3NldHNMb2FkZWQsIHN0YXJ0IGJvb3RzdHJhcHBpbmdgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJvb3RzdHJhcEFwcChhcHApLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKGBhcHAoJHthcHAubmFtZX0pIGJvb3RzdHJhcHBlZCBzdWNjZXNzLCBhY3RpdmUgaXRgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFjdGl2ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRMb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBwU3RhdHVzID09PSBBcHBsaWNhdGlvblN0YXR1cy5hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYFtyb3V0ZUNoYW5nZV0gYXBwKCR7YXBwLm5hbWV9KSBpcyBhY3RpdmUsIGRvIG5vdGhpbmdzYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFwcFJlZiA9IGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHkgc3ViIGFwcCB1c2Ugb2xkIHZlcnNpb24gd2hpY2ggaGFzIG5vdCBnZXRDdXJyZW50Um91dGVyU3RhdGVVcmxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFVybCA9IGFwcFJlZj8uZ2V0Q3VycmVudFJvdXRlclN0YXRlVXJsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFwcFJlZi5nZXRDdXJyZW50Um91dGVyU3RhdGVVcmwoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRVcmwgIT09IGV2ZW50LnVybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwUmVmPy5uYXZpZ2F0ZUJ5VXJsKGV2ZW50LnVybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKGFwcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgW3JvdXRlQ2hhbmdlXSBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyAke1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwcGxpY2F0aW9uU3RhdHVzW2FwcFN0YXR1cyBhcyBBcHBsaWNhdGlvblN0YXR1c11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEFwcFN0YXR1c0NoYW5nZSQoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBhcHAoJHthcHAubmFtZX0pIHN0YXR1cyBpcyBib290c3RyYXBwZWQgYnkgc3Vic2NyaWJlIHN0YXR1cyBjaGFuZ2UsIGFjdGl2ZSBpdGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXBwU3RhdHVzKGFwcCwgQXBwbGljYXRpb25TdGF0dXMuYWN0aXZlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dBcHAoYXBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXBwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcHMkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYHN0YXJ0IGxvYWQgYW5kIGFjdGl2ZSBhcHBzOiAke3RoaXMuZ2V0QXBwTmFtZXMoYXBwcyl9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIOWIh+aNouWIsOW6lOeUqOWQjuS8muaciemXqueDgeeOsOixoe+8jOaJgOS7peS9v+eUqCBzZXRUaW1lb3V0IOWQjuWQr+WKqOW6lOeUqFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleGFtcGxlOiByZWRpcmVjdCB0byBhcHAxJ3MgZGFzaGJvYXJkIGZyb20gcG9ydGFsJ3MgYWJvdXQgcGFnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBhcHAncyByb3V0ZSBoYXMgcmVkaXJlY3QsIGl0IGRvZXNuJ3Qgd29yaywgaXQgb2sganVzdCBpbiBzZXRUaW1lb3V0LCBJIGRvbid0IGtub3cgd2h5LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOjogcmVtb3ZlIGl0LCBpdCBpcyBvayBpbiB2ZXJzaW9uIEFuZ3VsYXIgOS54XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g5q2k5aSE5Yik5pat5piv5Zug5Li65aaC5p6c6Z2Z5oCB6LWE5rqQ5Yqg6L295a6M5q+V6L+Y5pyq5ZCv5Yqo6KKr5Y+W5raI77yM6L+Y5piv5Lya5ZCv5Yqo5LmL5YmN55qE5bqU55So77yM6Jm954S25Y+v6IO95oCn5q+U6L6D5bCP77yM5L2G5piv5peg5rOV5o6S6Zmk6L+Z56eN5Y+v6IO95oCn77yM5omA5Lul5Y+q5pyJ5b2TIEV2ZW50IOaYr+acgOWQjuS4gOS4quaJjeS8muWQr+WKqFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhcnRSb3V0ZUNoYW5nZUV2ZW50ID09PSBldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJ1bk91dHNpZGVBbmd1bGFyIGZvciBmaXggZXJyb3I6IGBFeHBlY3RlZCB0byBub3QgYmUgaW4gQW5ndWxhciBab25lLCBidXQgaXQgaXMhYFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ya0pvaW4oYXBwcyQpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldExvYWRpbmdEb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVuc3VyZVByZWxvYWRBcHBzKGFwcHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYG5vIGFwcHMgbmVlZCB0byBiZSBsb2FkZWQsIGVuc3VyZSBwcmVsb2FkIGFwcHNgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnN1cmVQcmVsb2FkQXBwcyhhcHBzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRMb2FkaW5nRG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoYGFwcHMgbG9hZGVyIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGFydExvYWRBcHBBc3NldHMoYXBwOiBQbGFuZXRBcHBsaWNhdGlvbik6IE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb24+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5Qcm9ncmVzc0FwcEFzc2V0c0xvYWRzLmdldChhcHAubmFtZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluUHJvZ3Jlc3NBcHBBc3NldHNMb2Fkcy5nZXQoYXBwLm5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbG9hZEFwcCQgPSB0aGlzLmFzc2V0c0xvYWRlci5sb2FkQXBwQXNzZXRzKGFwcCkucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluUHJvZ3Jlc3NBcHBBc3NldHNMb2Fkcy5kZWxldGUoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRlZCk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFwcDtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pblByb2dyZXNzQXBwQXNzZXRzTG9hZHMuZGVsZXRlKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5sb2FkRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBzaGFyZSgpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5pblByb2dyZXNzQXBwQXNzZXRzTG9hZHMuc2V0KGFwcC5uYW1lLCBsb2FkQXBwJCk7XG4gICAgICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIGxvYWRBcHAkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoaWRlQXBwKHBsYW5ldEFwcDogUGxhbmV0QXBwbGljYXRpb24pIHtcbiAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYocGxhbmV0QXBwLm5hbWUpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYXBwUmVmPy5zZWxlY3RvciB8fCAocGxhbmV0QXBwLnNlbGVjdG9yIGFzIHN0cmluZykpO1xuICAgICAgICBpZiAoYXBwUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZGlzcGxheTpub25lOycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaG93QXBwKHBsYW5ldEFwcDogUGxhbmV0QXBwbGljYXRpb24pIHtcbiAgICAgICAgY29uc3QgYXBwUmVmID0gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYocGxhbmV0QXBwLm5hbWUpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYXBwUmVmPy5zZWxlY3RvciB8fCAocGxhbmV0QXBwLnNlbGVjdG9yIGFzIHN0cmluZykpO1xuICAgICAgICBpZiAoYXBwUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lBcHAocGxhbmV0QXBwOiBQbGFuZXRBcHBsaWNhdGlvbikge1xuICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihwbGFuZXRBcHAubmFtZSk7XG4gICAgICAgIGlmIChhcHBSZWYpIHtcbiAgICAgICAgICAgIGFwcFJlZi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gZ2V0SFRNTEVsZW1lbnQocGxhbmV0QXBwLmhvc3RQYXJlbnQpO1xuICAgICAgICBjb25zdCBhcHBSb290RWxlbWVudCA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvcigoYXBwUmVmICYmIGFwcFJlZi5zZWxlY3RvcikgfHwgKHBsYW5ldEFwcC5zZWxlY3RvciBhcyBzdHJpbmcpKTtcbiAgICAgICAgaWYgKGFwcFJvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICBjb250YWluZXI/LnJlbW92ZUNoaWxkKGFwcFJvb3RFbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYm9vdHN0cmFwQXBwKFxuICAgICAgICBhcHA6IFBsYW5ldEFwcGxpY2F0aW9uLFxuICAgICAgICBkZWZhdWx0U3RhdHVzOiAnaGlkZGVuJyB8ICdkaXNwbGF5JyA9ICdkaXNwbGF5J1xuICAgICk6IE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb25SZWY+IHtcbiAgICAgICAgZGVidWcoYGFwcCgke2FwcC5uYW1lfSkgc3RhcnQgYm9vdHN0cmFwcGluZ2ApO1xuICAgICAgICB0aGlzLnNldEFwcFN0YXR1cyhhcHAsIEFwcGxpY2F0aW9uU3RhdHVzLmJvb3RzdHJhcHBpbmcpO1xuICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihhcHAubmFtZSk7XG4gICAgICAgIGlmIChhcHBSZWYgJiYgYXBwUmVmLmJvb3RzdHJhcCkge1xuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gZ2V0SFRNTEVsZW1lbnQoYXBwLmhvc3RQYXJlbnQpO1xuICAgICAgICAgICAgbGV0IGFwcFJvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICBhcHBSb290RWxlbWVudCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGFwcFJlZi5zZWxlY3RvciB8fCBhcHAuc2VsZWN0b3IhKSE7XG4gICAgICAgICAgICAgICAgaWYgKCFhcHBSb290RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwUmVmLnRlbXBsYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBSb290RWxlbWVudCA9IGNyZWF0ZUVsZW1lbnRCeVRlbXBsYXRlKGFwcFJlZi50ZW1wbGF0ZSkhO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGFwcC5zZWxlY3RvciEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFwcFJvb3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZGlzcGxheTpub25lOycpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwLmhvc3RDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5jb2VyY2VBcnJheShhcHAuaG9zdENsYXNzKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcC5zdHlsZVByZWZpeCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5jb2VyY2VBcnJheShhcHAuc3R5bGVQcmVmaXgpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoYXBwUm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCByZXN1bHQgPSBhcHBSZWYuYm9vdHN0cmFwKHRoaXMucG9ydGFsQXBwKTtcbiAgICAgICAgICAgIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHByb21pc2UgZm9yIGJvb3RzdHJhcFxuICAgICAgICAgICAgaWYgKChyZXN1bHQgYXMgYW55KVsndGhlbiddKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZnJvbShyZXN1bHQpIGFzIE9ic2VydmFibGU8UGxhbmV0QXBwbGljYXRpb25SZWY+O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5waXBlKFxuICAgICAgICAgICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBhcHAoJHthcHAubmFtZX0pIGJvb3RzdHJhcHBlZCBzdWNjZXNzIGZvciAke2RlZmF1bHRTdGF0dXN9YCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXBwU3RhdHVzKGFwcCwgQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGVkKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRTdGF0dXMgPT09ICdkaXNwbGF5JyAmJiBhcHBSb290RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwUm9vdEVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFwcFJlZjtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgWyR7YXBwLm5hbWV9XSBub3QgZm91bmQsIG1ha2Ugc3VyZSB0aGF0IHRoZSBhcHAgaGFzIHRoZSBjb3JyZWN0IG5hbWUgZGVmaW5lZCB1c2UgZGVmaW5lQXBwbGljYXRpb24oJHthcHAubmFtZX0pIGFuZCBydW50aW1lQ2h1bmsgYW5kIHZlbmRvckNodW5rIGFyZSBzZXQgdG8gdHJ1ZSwgZGV0YWlscyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3dvcmt0aWxlL25neC1wbGFuZXQjdGhyb3ctZXJyb3ItY2Fubm90LXJlYWQtcHJvcGVydHktY2FsbC1vZi11bmRlZmluZWQtYXQtX193ZWJwYWNrX3JlcXVpcmVfXy1ib290c3RyYXA3OWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFVubG9hZEFwcHMoYWN0aXZlQXBwczogUGxhbmV0QXBwbGljYXRpb25bXSkge1xuICAgICAgICBjb25zdCB1bmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdID0gW107XG4gICAgICAgIHRoaXMuYXBwc1N0YXR1cy5mb3JFYWNoKCh2YWx1ZSwgYXBwKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IEFwcGxpY2F0aW9uU3RhdHVzLmFjdGl2ZSAmJiAhYWN0aXZlQXBwcy5maW5kKGl0ZW0gPT4gaXRlbS5uYW1lID09PSBhcHAubmFtZSkpIHtcbiAgICAgICAgICAgICAgICB1bmxvYWRBcHBzLnB1c2goYXBwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bmxvYWRBcHBzO1xuICAgIH1cblxuICAgIHByaXZhdGUgdW5sb2FkQXBwcyhzaG91bGRVbmxvYWRBcHBzOiBQbGFuZXRBcHBsaWNhdGlvbltdLCBldmVudDogUGxhbmV0Um91dGVyRXZlbnQpIHtcbiAgICAgICAgY29uc3QgaGlkZUFwcHM6IFBsYW5ldEFwcGxpY2F0aW9uW10gPSBbXTtcbiAgICAgICAgY29uc3QgZGVzdHJveUFwcHM6IFBsYW5ldEFwcGxpY2F0aW9uW10gPSBbXTtcbiAgICAgICAgc2hvdWxkVW5sb2FkQXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zd2l0Y2hNb2RlSXNDb2V4aXN0KGFwcCkpIHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyhgaGlkZSBhcHAoJHthcHAubmFtZX0pIGZvciBjb2V4aXN0IG1vZGVgKTtcbiAgICAgICAgICAgICAgICBoaWRlQXBwcy5wdXNoKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5ib290c3RyYXBwZWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXN0cm95QXBwcy5wdXNoKGFwcCk7XG4gICAgICAgICAgICAgICAgLy8g6ZSA5q+B5LmL5YmN5YWI6ZqQ6JeP77yM5ZCm5YiZ5Lya5Ye6546w6Zeq54OB77yM5Zug5Li6IGRlc3Ryb3kg5piv5bu26L+f5omn6KGM55qEXG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c6ZSA5q+B5LiN5bu26L+f5omn6KGM77yM5Lya5Ye6546w5YiH5o2i5Yiw5Li75bqU55So55qE5pe25YCZ5Lya5pyJ6KeG5Zu+5Y2h6aG/546w6LGhXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBcHBTdGF0dXMoYXBwLCBBcHBsaWNhdGlvblN0YXR1cy5hc3NldHNMb2FkZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaGlkZUFwcHMubGVuZ3RoID4gMCB8fCBkZXN0cm95QXBwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyDku47lhbbku5blupTnlKjliIfmjaLliLDkuLvlupTnlKjnmoTml7blgJnkvJrmnInop4blm77ljaHpob/njrDosaHvvIzmiYDku6XlhYjnrYnkuLvlupTnlKjmuLLmn5Plrozmr5XlkI7lho3liqDovb3lhbbku5blupTnlKhcbiAgICAgICAgICAgIC8vIOatpOWkhOWwneivleS9v+eUqCB0aGlzLm5nWm9uZS5vblN0YWJsZS5waXBlKHRha2UoMSkpIOW6lOeUqOS5i+mXtOeahOWIh+aNouS8muWHuueOsOmXqueDgVxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaGlkZUFwcHMuZm9yRWFjaChhcHAgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBSZWYgPSBnZXRQbGFuZXRBcHBsaWNhdGlvblJlZihhcHAubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBSZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcFJlZi5uYXZpZ2F0ZUJ5VXJsKGV2ZW50LnVybCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBkZXN0cm95QXBwcy5mb3JFYWNoKGFwcCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBkZXN0cm95IGFwcCgke2FwcC5uYW1lfSlgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95QXBwKGFwcCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcHJlbG9hZEFwcHMoYWN0aXZlQXBwcz86IFBsYW5ldEFwcGxpY2F0aW9uW10pIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b1ByZWxvYWRBcHBzID0gdGhpcy5wbGFuZXRBcHBsaWNhdGlvblNlcnZpY2UuZ2V0QXBwc1RvUHJlbG9hZChcbiAgICAgICAgICAgICAgICBhY3RpdmVBcHBzID8gYWN0aXZlQXBwcy5tYXAoaXRlbSA9PiBpdGVtLm5hbWUpIDogdW5kZWZpbmVkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZGVidWcoYHN0YXJ0IHByZWxvYWQgYXBwczogJHt0aGlzLmdldEFwcE5hbWVzKHRvUHJlbG9hZEFwcHMpfWApO1xuICAgICAgICAgICAgY29uc3QgbG9hZEFwcHMkID0gdG9QcmVsb2FkQXBwcy5tYXAocHJlbG9hZEFwcCA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJlbG9hZEludGVybmFsKHByZWxvYWRBcHApO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGZvcmtKb2luKGxvYWRBcHBzJCkuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZW5zdXJlUHJlbG9hZEFwcHMoYWN0aXZlQXBwcz86IFBsYW5ldEFwcGxpY2F0aW9uW10pIHtcbiAgICAgICAgLy8gU3RhcnQgcHJlbG9hZCBhcHBzXG4gICAgICAgIC8vIFN0YXJ0IHByZWxvYWQgd2hlbiBmaXJzdCB0aW1lIGFwcCBsb2FkZWRcbiAgICAgICAgaWYgKHRoaXMuZmlyc3RMb2FkKSB7XG4gICAgICAgICAgICB0aGlzLnByZWxvYWRBcHBzKGFjdGl2ZUFwcHMpO1xuICAgICAgICAgICAgdGhpcy5maXJzdExvYWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8UGxhbmV0T3B0aW9ucz4pIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlc2V0IHJvdXRlIGJ5IGN1cnJlbnQgcm91dGVyXG4gICAgICovXG4gICAgcHVibGljIHJlcm91dGUoZXZlbnQ6IFBsYW5ldFJvdXRlckV2ZW50KSB7XG4gICAgICAgIHRoaXMucm91dGVDaGFuZ2UkLm5leHQoZXZlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJlbG9hZEludGVybmFsKGFwcDogUGxhbmV0QXBwbGljYXRpb24sIGltbWVkaWF0ZT86IGJvb2xlYW4pOiBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uUmVmIHwgbnVsbD4ge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSB0aGlzLmFwcHNTdGF0dXMuZ2V0KGFwcCk7XG4gICAgICAgIGlmICghc3RhdHVzIHx8IHN0YXR1cyA9PT0gQXBwbGljYXRpb25TdGF0dXMubG9hZEVycm9yKSB7XG4gICAgICAgICAgICBkZWJ1ZyhgcHJlbG9hZCBhcHAoJHthcHAubmFtZX0pLCBzdGF0dXMgaXMgZW1wdHksIHN0YXJ0IHRvIGxvYWQgYXNzZXRzYCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydExvYWRBcHBBc3NldHMoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKGBwcmVsb2FkIGFwcCgke2FwcC5uYW1lfSksIGFzc2V0cyBsb2FkZWQsIHN0YXJ0IGJvb3RzdHJhcCBhcHAsIGltbWVkaWF0ZTogJHshIWltbWVkaWF0ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGltbWVkaWF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYm9vdHN0cmFwQXBwKGFwcCwgJ2hpZGRlbicpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ib290c3RyYXBBcHAoYXBwLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UGxhbmV0QXBwbGljYXRpb25SZWYoYXBwLm5hbWUpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgW0FwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRpbmcsIEFwcGxpY2F0aW9uU3RhdHVzLmFzc2V0c0xvYWRlZCwgQXBwbGljYXRpb25TdGF0dXMuYm9vdHN0cmFwcGluZ10uaW5jbHVkZXMoXG4gICAgICAgICAgICAgICAgc3RhdHVzXG4gICAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGVidWcoYHByZWxvYWQgYXBwKCR7YXBwLm5hbWV9KSwgc3RhdHVzIGlzICR7QXBwbGljYXRpb25TdGF0dXNbc3RhdHVzXX0sIHJldHVybiB1bnRpbCBib290c3RyYXBwZWRgKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEFwcFN0YXR1c0NoYW5nZSQoYXBwKS5waXBlKFxuICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGFwcFJlZiA9IGdldFBsYW5ldEFwcGxpY2F0aW9uUmVmKGFwcC5uYW1lKTtcbiAgICAgICAgICAgIGlmICghYXBwUmVmKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2FwcC5uYW1lfSdzIHN0YXR1cyBpcyAke0FwcGxpY2F0aW9uU3RhdHVzW3N0YXR1c119LCBwbGFuZXRBcHBsaWNhdGlvblJlZiBpcyBudWxsLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9mKGFwcFJlZik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmVsb2FkIHBsYW5ldCBhcHBsaWNhdGlvblxuICAgICAqIEBwYXJhbSBhcHAgYXBwXG4gICAgICogQHBhcmFtIGltbWVkaWF0ZSBib290c3RyYXAgb24gc3RhYmxlIGJ5IGRlZmF1bHQsIHNldHRpbmcgaW1tZWRpYXRlIGlzIHRydWUsIGl0IHdpbGwgYm9vdHN0cmFwIGltbWVkaWF0ZVxuICAgICAqL1xuICAgIHB1YmxpYyBwcmVsb2FkKGFwcDogUGxhbmV0QXBwbGljYXRpb24sIGltbWVkaWF0ZT86IGJvb2xlYW4pOiBPYnNlcnZhYmxlPFBsYW5ldEFwcGxpY2F0aW9uUmVmPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByZWxvYWRJbnRlcm5hbChhcHAsIGltbWVkaWF0ZSk7XG4gICAgfVxufVxuIl19