aril 1.2.18 → 2.0.1-dev.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 (122) hide show
  1. package/boot/bridge/src/mfe-bridge.d.ts +42 -2
  2. package/boot/config/apps/index.d.ts +7 -1
  3. package/boot/config/apps/src/custom-reuse-outlet.component.d.ts +37 -0
  4. package/boot/config/apps/src/custom-route-reuse-strategy.class.d.ts +156 -0
  5. package/boot/config/apps/src/nav-link-context-menu.service.d.ts +33 -0
  6. package/boot/config/apps/src/nav-link.directive.d.ts +29 -0
  7. package/boot/config/apps/src/nav.service.d.ts +198 -0
  8. package/boot/config/apps/src/route-close.service.d.ts +9 -0
  9. package/boot/config/apps/src/safe-navigate.d.ts +17 -0
  10. package/boot/config/apps/src/tab-aware-url-serializer.d.ts +22 -0
  11. package/boot/config/plugins/src/getNgZone.d.ts +9 -1
  12. package/boot/mfe/src/app.component.d.ts +15 -4
  13. package/boot/mfe/src/isolated-location-strategy.d.ts +57 -0
  14. package/esm2022/boot/bridge/src/mfe-bridge.mjs +36 -5
  15. package/esm2022/boot/config/api/src/api.service.mjs +12 -3
  16. package/esm2022/boot/config/apps/index.mjs +8 -2
  17. package/esm2022/boot/config/apps/src/apps.service.mjs +14 -6
  18. package/esm2022/boot/config/apps/src/custom-reuse-outlet.component.mjs +207 -0
  19. package/esm2022/boot/config/apps/src/custom-route-reuse-strategy.class.mjs +540 -0
  20. package/esm2022/boot/config/apps/src/nav-link-context-menu.service.mjs +105 -0
  21. package/esm2022/boot/config/apps/src/nav-link.directive.mjs +45 -0
  22. package/esm2022/boot/config/apps/src/nav.service.mjs +675 -0
  23. package/esm2022/boot/config/apps/src/route-close.service.mjs +19 -0
  24. package/esm2022/boot/config/apps/src/safe-navigate.mjs +50 -0
  25. package/esm2022/boot/config/apps/src/tab-aware-url-serializer.mjs +50 -0
  26. package/esm2022/boot/config/plugins/src/getNgZone.mjs +13 -5
  27. package/esm2022/boot/host/src/app.component.mjs +1 -2
  28. package/esm2022/boot/host/src/bootstrap.mjs +22 -7
  29. package/esm2022/boot/mfe/src/app.component.mjs +143 -39
  30. package/esm2022/boot/mfe/src/bootstrap.mjs +197 -20
  31. package/esm2022/boot/mfe/src/isolated-location-strategy.mjs +142 -0
  32. package/esm2022/keycloak/src/auth.interceptor.mjs +17 -2
  33. package/esm2022/provider/src/prodiveHost.mjs +3 -5
  34. package/esm2022/provider/src/prodiveHostRouter.mjs +88 -9
  35. package/esm2022/theme/layout/app/expandableMenu/expandable-menu.component.mjs +81 -19
  36. package/esm2022/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.mjs +6 -4
  37. package/esm2022/theme/layout/app/general-search/general-search.component.mjs +4 -4
  38. package/esm2022/theme/layout/app/history/history-sidebar.component.mjs +6 -4
  39. package/esm2022/theme/layout/app/layout/app.layout.component.mjs +422 -20
  40. package/esm2022/theme/layout/app/layout/mfe.layout.component.mjs +24 -35
  41. package/esm2022/theme/layout/app/site-map/site-map-sidebar.component.mjs +6 -4
  42. package/esm2022/theme/layout/app/static-sidebar/static-sidebar.component.mjs +85 -27
  43. package/esm2022/theme/layout/app/topbar/app.topbar.component.mjs +3 -3
  44. package/esm2022/theme/layout/service/breadcrumb-publisher.service.mjs +86 -0
  45. package/esm2022/theme/layout/service/tab-session.service.mjs +126 -0
  46. package/esm2022/ui-business/ref-value/src/ref-value.component.mjs +15 -7
  47. package/esm2022/util/sync-active-tab-route/src/sync-active-tab-route.directive.mjs +29 -9
  48. package/fesm2022/aril-app.component-s14ruALV.mjs +183 -0
  49. package/fesm2022/aril-app.component-s14ruALV.mjs.map +1 -0
  50. package/fesm2022/aril-boot-bridge.mjs +35 -4
  51. package/fesm2022/aril-boot-bridge.mjs.map +1 -1
  52. package/fesm2022/aril-boot-config-api.mjs +11 -2
  53. package/fesm2022/aril-boot-config-api.mjs.map +1 -1
  54. package/fesm2022/aril-boot-config-apps.mjs +1678 -10
  55. package/fesm2022/aril-boot-config-apps.mjs.map +1 -1
  56. package/fesm2022/aril-boot-config-plugins.mjs +12 -4
  57. package/fesm2022/aril-boot-config-plugins.mjs.map +1 -1
  58. package/fesm2022/aril-boot-host.mjs +21 -7
  59. package/fesm2022/aril-boot-host.mjs.map +1 -1
  60. package/fesm2022/aril-boot-mfe-app.component-a34GeuUv.mjs +183 -0
  61. package/fesm2022/aril-boot-mfe-app.component-a34GeuUv.mjs.map +1 -0
  62. package/fesm2022/aril-boot-mfe-aril-boot-mfe-KFO_X7yR.mjs +631 -0
  63. package/fesm2022/aril-boot-mfe-aril-boot-mfe-KFO_X7yR.mjs.map +1 -0
  64. package/fesm2022/aril-boot-mfe.mjs +5 -3
  65. package/fesm2022/aril-boot-mfe.mjs.map +1 -1
  66. package/fesm2022/aril-keycloak.mjs +16 -1
  67. package/fesm2022/aril-keycloak.mjs.map +1 -1
  68. package/fesm2022/aril-provider.mjs +90 -12
  69. package/fesm2022/aril-provider.mjs.map +1 -1
  70. package/fesm2022/aril-theme-layout.mjs +2630 -2017
  71. package/fesm2022/aril-theme-layout.mjs.map +1 -1
  72. package/fesm2022/aril-ui-business-ref-value.mjs +14 -6
  73. package/fesm2022/aril-ui-business-ref-value.mjs.map +1 -1
  74. package/fesm2022/aril-util-sync-active-tab-route.mjs +28 -8
  75. package/fesm2022/aril-util-sync-active-tab-route.mjs.map +1 -1
  76. package/fesm2022/aril.mjs +354 -25
  77. package/fesm2022/aril.mjs.map +1 -1
  78. package/keycloak/src/auth.interceptor.d.ts +7 -0
  79. package/package.json +216 -216
  80. package/provider/src/prodiveHost.d.ts +1 -0
  81. package/theme/layout/app/expandableMenu/expandable-menu.component.d.ts +21 -4
  82. package/theme/layout/app/expandableMenu/expandable-menu.component.html +19 -5
  83. package/theme/layout/app/expandableMenu/expandable-menu.component.ts +69 -9
  84. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.html +1 -0
  85. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.ts +3 -1
  86. package/theme/layout/app/general-search/general-search.component.html +2 -1
  87. package/theme/layout/app/general-search/general-search.component.ts +2 -2
  88. package/theme/layout/app/history/history-sidebar.component.html +3 -1
  89. package/theme/layout/app/history/history-sidebar.component.ts +3 -1
  90. package/theme/layout/app/layout/app.layout.component.d.ts +105 -5
  91. package/theme/layout/app/layout/app.layout.component.html +102 -1
  92. package/theme/layout/app/layout/app.layout.component.scss +372 -0
  93. package/theme/layout/app/layout/app.layout.component.ts +452 -13
  94. package/theme/layout/app/layout/mfe.layout.component.d.ts +7 -5
  95. package/theme/layout/app/layout/mfe.layout.component.ts +13 -39
  96. package/theme/layout/app/site-map/site-map-sidebar.component.html +1 -0
  97. package/theme/layout/app/site-map/site-map-sidebar.component.ts +3 -1
  98. package/theme/layout/app/static-sidebar/static-sidebar.component.d.ts +26 -5
  99. package/theme/layout/app/static-sidebar/static-sidebar.component.html +11 -5
  100. package/theme/layout/app/static-sidebar/static-sidebar.component.ts +68 -13
  101. package/theme/layout/app/topbar/app.topbar.component.html +0 -1
  102. package/theme/layout/app/topbar/app.topbar.component.scss +1 -1
  103. package/theme/layout/service/breadcrumb-publisher.service.d.ts +24 -0
  104. package/theme/layout/service/breadcrumb-publisher.service.ts +95 -0
  105. package/theme/layout/service/tab-session.service.d.ts +52 -0
  106. package/theme/layout/service/tab-session.service.ts +138 -0
  107. package/theme/styles/layout/_breadcrumb.scss +95 -0
  108. package/theme/styles/layout/_content.scss +2 -2
  109. package/ui-business/ref-value/src/ref-value.component.d.ts +4 -2
  110. package/util/sync-active-tab-route/src/sync-active-tab-route.directive.d.ts +15 -2
  111. package/boot/config/apps/src/reuse-strategy.d.ts +0 -4
  112. package/esm2022/boot/config/apps/src/reuse-strategy.mjs +0 -9
  113. package/esm2022/theme/layout/app/breadcrumb/app.breadcrumb.component.mjs +0 -107
  114. package/fesm2022/aril-app.component-wxP3y8dg.mjs +0 -81
  115. package/fesm2022/aril-app.component-wxP3y8dg.mjs.map +0 -1
  116. package/fesm2022/aril-boot-mfe-app.component-7IjAmjz0.mjs +0 -80
  117. package/fesm2022/aril-boot-mfe-app.component-7IjAmjz0.mjs.map +0 -1
  118. package/fesm2022/aril-boot-mfe-aril-boot-mfe-KXDpUyv7.mjs +0 -315
  119. package/fesm2022/aril-boot-mfe-aril-boot-mfe-KXDpUyv7.mjs.map +0 -1
  120. package/theme/layout/app/breadcrumb/app.breadcrumb.component.d.ts +0 -25
  121. package/theme/layout/app/breadcrumb/app.breadcrumb.component.html +0 -8
  122. package/theme/layout/app/breadcrumb/app.breadcrumb.component.ts +0 -127
@@ -1,35 +1,392 @@
1
+ import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
1
2
  import { NgClass } from '@angular/common';
2
- import { Component, ViewChild } from '@angular/core';
3
- import { NavigationEnd, RouterOutlet } from '@angular/router';
3
+ import { Component, HostListener, ViewChild, computed, effect, inject, signal, untracked } from '@angular/core';
4
+ import { NavigationEnd, RouterLink, RouterOutlet } from '@angular/router';
5
+ import { BreadcrumbModule } from 'primeng/breadcrumb';
4
6
  import { ConfirmDialogModule } from 'primeng/confirmdialog';
5
7
  import { ConfirmPopupModule } from 'primeng/confirmpopup';
8
+ import { ContextMenuModule } from 'primeng/contextmenu';
6
9
  import { DialogModule } from 'primeng/dialog';
7
10
  import { MessagesModule } from 'primeng/messages';
8
11
  import { ToastModule } from 'primeng/toast';
12
+ import { TooltipModule } from 'primeng/tooltip';
13
+ import { TranslocoModule, TranslocoService } from '@ngneat/transloco';
9
14
  import { filter } from 'rxjs';
10
- import { AppProfileSidebarComponent } from '../profileSidebar/app.profilesidebar.component';
15
+ import { bridge } from 'aril/boot/bridge';
16
+ import { NavLinkContextMenuService, NavLinkDirective, NavService } from 'aril/boot/config/apps';
17
+ import { TranslateJsonPipe } from 'aril/util/pipes';
18
+ import { TabSessionService } from '../../service/tab-session.service';
19
+ import { ExpandableMenuComponent } from '../expandableMenu/expandable-menu.component';
20
+ import { FavoritePagesSidebarComponent } from '../favorite-pages/favorite-pages-sidebar.component';
11
21
  import { HistorySidebarComponent } from '../history/history-sidebar.component';
22
+ import { NotificationsSidebarComponent } from '../notifications/notifications-sidebar.component';
23
+ import { AppProfileSidebarComponent } from '../profileSidebar/app.profilesidebar.component';
12
24
  import { SiteMapSidebarComponent } from '../site-map/site-map-sidebar.component';
13
- import { FavoritePagesSidebarComponent } from '../favorite-pages/favorite-pages-sidebar.component';
14
- import { AppTopbarComponent } from '../topbar/app.topbar.component';
15
- import { ExpandableMenuComponent } from '../expandableMenu/expandable-menu.component';
16
25
  import { StaticSidebarComponent } from '../static-sidebar/static-sidebar.component';
17
- import { NotificationsSidebarComponent } from '../notifications/notifications-sidebar.component';
26
+ import { AppTopbarComponent } from '../topbar/app.topbar.component';
18
27
  import * as i0 from "@angular/core";
19
28
  import * as i1 from "../../service/app.menu.service";
20
29
  import * as i2 from "../../service/app.layout.service";
21
30
  import * as i3 from "@angular/router";
22
- import * as i4 from "primeng/confirmdialog";
23
- import * as i5 from "primeng/confirmpopup";
24
- import * as i6 from "primeng/dialog";
25
- import * as i7 from "primeng/messages";
26
- import * as i8 from "primeng/toast";
31
+ import * as i4 from "aril/util/pipes";
32
+ import * as i5 from "primeng/confirmdialog";
33
+ import * as i6 from "primeng/api";
34
+ import * as i7 from "primeng/confirmpopup";
35
+ import * as i8 from "primeng/dialog";
36
+ import * as i9 from "primeng/messages";
37
+ import * as i10 from "primeng/toast";
38
+ import * as i11 from "@angular/cdk/drag-drop";
39
+ import * as i12 from "primeng/breadcrumb";
40
+ import * as i13 from "primeng/tooltip";
41
+ import * as i14 from "primeng/contextmenu";
42
+ import * as i15 from "@ngneat/transloco";
27
43
  export class AppLayoutComponent {
28
- constructor(menuService, layoutService, renderer, router) {
44
+ /**
45
+ * Aktif olmayan breadcrumb segmentine tıklama → mevcut tab'ı parent route ile günceller.
46
+ * `<a [routerLink]>` directive'i `href`'i Router'ın location strategy'sine göre
47
+ * (hash/path) doğru formatlar — sağ tık "linki kopyala" davranışı çalışır.
48
+ * Default Router navigate'ini `preventDefault()` ile durdurup `navigateInCurrentTab`
49
+ * üzerinden ilerletiyoruz; böylece yeni sekme açılmaz.
50
+ */
51
+ onBreadcrumbClick(event, item) {
52
+ event.preventDefault();
53
+ if (!item.url)
54
+ return;
55
+ const navLink = item.url.startsWith('/') ? item.url.slice(1) : item.url;
56
+ this.navService.navigateInCurrentTab({
57
+ tabId: '',
58
+ navLink,
59
+ navName: item.label ?? ''
60
+ });
61
+ }
62
+ /**
63
+ * Home icon → root menu item (`apps.service.ts:51`'de tanımlı `{ root: true, routerLink: '/' }`).
64
+ * Tek source-of-truth — etiket çevirisi `TranslateJsonPipe` ile aktif dilden okunur.
65
+ * Mevcut tab güncellenir, yeni sekme açılmaz.
66
+ */
67
+ onHomeClick(event) {
68
+ event.preventDefault();
69
+ this.navService.navigateInCurrentTab(this.homeNavItem());
70
+ }
71
+ /**
72
+ * Tab icon resolution sırası:
73
+ * 1. NavItem.icon (sidebar click'inden iletilmişse — en doğru)
74
+ * 2. Menu config'inde navLink'i en uzun prefix olarak match eden item.icon
75
+ * 3. Generic fallback (`pi pi-file`)
76
+ *
77
+ * Best-match için longest-prefix kullanılır: `wdm/meters/123` için hem `wdm` hem
78
+ * `wdm/meters` match'lerse, daha spesifik `wdm/meters` kazanır. Böylece deep link
79
+ * refresh'inde (NavService.firstCheckForRoute path'inde icon set edilemediği zaman)
80
+ * doğru remote/section ikonu otomatik bulunur.
81
+ */
82
+ getTabIcon(item) {
83
+ if (item.icon)
84
+ return item.icon;
85
+ if (!item.navLink)
86
+ return 'pi pi-file';
87
+ // `bridge.hostMenuItems()` — homeNavItem/NavService ile aynı menü kaynağı. `menuService`
88
+ // host `root`/MFE menüsünü içermediği için (boş kaynak) buradaki ikon eşleşmesi de oradan.
89
+ return this.findIconForRoute(bridge.hostMenuItems(), item.navLink) ?? 'pi pi-file';
90
+ }
91
+ findIconForRoute(items, navLink) {
92
+ // Path leading slash içerebilir (Router URL), menu config routerLink'leri genelde
93
+ // leading slash'sız — ikisini normalize edip karşılaştır.
94
+ const normalize = (p) => (p.startsWith('/') ? p.slice(1) : p);
95
+ const normalizedPath = normalize(navLink);
96
+ let best;
97
+ const visit = (list) => {
98
+ for (const it of list) {
99
+ if (it.routerLink && it.icon) {
100
+ const r = normalize(it.routerLink);
101
+ if (r && (normalizedPath === r || normalizedPath.startsWith(r + '/'))) {
102
+ const length = r.length;
103
+ if (!best || length > best.length)
104
+ best = { length, icon: it.icon };
105
+ }
106
+ }
107
+ if (it.items?.length)
108
+ visit(it.items);
109
+ }
110
+ };
111
+ visit(items);
112
+ return best?.icon;
113
+ }
114
+ drop(event) {
115
+ const currentRoutes = [...this.navService.activeRoutes()];
116
+ moveItemInArray(currentRoutes, event.previousIndex, event.currentIndex);
117
+ this.navService.reorderActiveRoutes(currentRoutes);
118
+ }
119
+ isActive(item) {
120
+ // Aynı `navLink`'in birden fazla tab'i olabileceği için tabId tek doğru kimlik.
121
+ // `activeTabId` history.state üzerinden NavService tarafından senkronize edilir.
122
+ return this.navService.activeTabId() === item.tabId;
123
+ }
124
+ closeTab(event, item) {
125
+ event.stopPropagation();
126
+ if (item.pinned)
127
+ return;
128
+ this.navService.closeNavigation(item);
129
+ }
130
+ /** Tab sol-click → o tab'a geç. NavService Router'a `?_tab` URL'i ve history state'i verir. */
131
+ onTabClick(event, item) {
132
+ if (event.button !== 0)
133
+ return; // sadece sol tık
134
+ this.navService.navigateToTab(item);
135
+ }
136
+ /** Middle click (button 1) → tab kapat (Chrome standardı). Sabit tab'lar kapatılmaz. */
137
+ onTabAuxClick(event, item) {
138
+ if (event.button !== 1)
139
+ return;
140
+ event.preventDefault();
141
+ if (item.pinned)
142
+ return;
143
+ this.navService.closeNavigation(item);
144
+ }
145
+ /** Middle click default scroll davranışını engelle. */
146
+ onTabMousedown(event) {
147
+ if (event.button === 1)
148
+ event.preventDefault();
149
+ }
150
+ /**
151
+ * Tab right-click → context menu. Sabit tab'larda "Kapat" disabled; pin/unpin item'ı
152
+ * Chrome'daki gibi en üstte yer alır. `closeOthers`/`closeToRight`/`closeAll` zaten
153
+ * NavService seviyesinde pinned'i koruyor — UI'da ekstra disabled gerekmez.
154
+ */
155
+ onTabContextMenu(event, item) {
156
+ event.preventDefault();
157
+ const t = (key) => this.translocoService.translate(key);
158
+ const pinLabel = item.pinned ? t('tab.unpin') : t('tab.pin');
159
+ this.tabContextMenuItems = [
160
+ { label: pinLabel, icon: 'pi pi-thumbtack', command: () => this.navService.togglePin(item) },
161
+ { label: t('tab.duplicate'), icon: 'pi pi-clone', command: () => this.navService.duplicateTab(item) },
162
+ { separator: true },
163
+ {
164
+ label: t('tab.close'),
165
+ icon: 'pi pi-times',
166
+ command: () => this.navService.closeNavigation(item),
167
+ disabled: !!item.pinned
168
+ },
169
+ {
170
+ label: t('tab.closeOthers'),
171
+ icon: 'pi pi-times-circle',
172
+ command: () => this.navService.closeOthers(item),
173
+ disabled: this.navService.activeRoutes().filter((r) => !r.pinned && r.tabId !== item.tabId).length === 0
174
+ },
175
+ {
176
+ label: t('tab.closeToRight'),
177
+ icon: 'pi pi-angle-double-right',
178
+ command: () => this.navService.closeToRight(item),
179
+ disabled: this.isLastTab(item)
180
+ },
181
+ { separator: true },
182
+ {
183
+ label: t('tab.closeAll'),
184
+ icon: 'pi pi-trash',
185
+ command: () => this.navService.closeAll(),
186
+ disabled: this.navService.activeRoutes().every((r) => r.pinned)
187
+ }
188
+ ];
189
+ this.tabContextMenu?.show(event);
190
+ }
191
+ isLastTab(item) {
192
+ const routes = this.navService.activeRoutes();
193
+ // `tabId` ile karşılaştır — aynı navLink'in birden fazla tab'i olabileceği için
194
+ // `navLink` ambiguous olur, kimlik bazlı arama tek doğru yöntem.
195
+ return routes[routes.length - 1]?.tabId === item.tabId;
196
+ }
197
+ /**
198
+ * Tek kalan tab anasayfaysa true → kapatma (✕) butonu gizlenir (NavService de kapatmayı
199
+ * reddeder). "Her zaman en az 1 tab açık" kuralının UI tarafı.
200
+ */
201
+ isLastHomeTab(item) {
202
+ const routes = this.navService.activeRoutes();
203
+ return routes.length === 1 && item.navLink === (this.homeNavItem().navLink || '/');
204
+ }
205
+ /** "+" butonu → ana sayfaya navigate (yeni tab varsa onu aç, yoksa eklenir). */
206
+ onAddTab() {
207
+ this.router.navigateByUrl('');
208
+ }
209
+ scrollTabsLeft() {
210
+ this.tabsContainer?.nativeElement.scrollBy({ left: -200, behavior: 'smooth' });
211
+ }
212
+ scrollTabsRight() {
213
+ this.tabsContainer?.nativeElement.scrollBy({ left: 200, behavior: 'smooth' });
214
+ }
215
+ updateScrollState() {
216
+ const el = this.tabsContainer?.nativeElement;
217
+ if (!el)
218
+ return;
219
+ this.canScrollLeft.set(el.scrollLeft > 0);
220
+ this.canScrollRight.set(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
221
+ }
222
+ /**
223
+ * Klavye kısayolları (Chrome paritesi):
224
+ * - `Alt+W` → aktif tab kapat (Ctrl+W browser-reserved)
225
+ * - `Ctrl+Tab` / `Ctrl+Shift+Tab` → sonraki/önceki tab (denemeli — bazı tarayıcılar override etmez)
226
+ * - `Ctrl+PageDown` / `Ctrl+PageUp` → sonraki/önceki tab (yedek)
227
+ * - `Alt+1..9` → ilgili index'teki tab (Ctrl+1..9 browser-reserved)
228
+ * - `Ctrl+Shift+T` veya `Alt+Shift+T` → son kapatılan tab'ı geri aç
229
+ */
230
+ onDocumentKeydown(event) {
231
+ if (this.isTypingInInput(event))
232
+ return;
233
+ const key = event.key;
234
+ const lower = key.toLowerCase();
235
+ if (event.altKey && !event.shiftKey && !event.ctrlKey && lower === 'w') {
236
+ const current = this.navService.activeRoute();
237
+ const item = current ? this.navService.activeRoutes().find((r) => r.navLink === current) : undefined;
238
+ if (item) {
239
+ event.preventDefault();
240
+ this.navService.closeNavigation(item);
241
+ }
242
+ return;
243
+ }
244
+ if (event.ctrlKey && (key === 'Tab' || key === 'PageDown' || key === 'PageUp')) {
245
+ event.preventDefault();
246
+ if (key === 'PageUp' || (key === 'Tab' && event.shiftKey)) {
247
+ this.navService.goToPrevTab();
248
+ }
249
+ else {
250
+ this.navService.goToNextTab();
251
+ }
252
+ return;
253
+ }
254
+ if (event.altKey && !event.ctrlKey && !event.shiftKey && /^[1-9]$/.test(key)) {
255
+ event.preventDefault();
256
+ this.navService.goToTabByIndex(parseInt(key, 10) - 1);
257
+ return;
258
+ }
259
+ }
260
+ isTypingInInput(event) {
261
+ const target = event.target;
262
+ if (!target)
263
+ return false;
264
+ const tag = target.tagName?.toLowerCase();
265
+ return tag === 'input' || tag === 'textarea' || tag === 'select' || !!target.isContentEditable;
266
+ }
267
+ ngAfterViewInit() {
268
+ this.updateScrollState();
269
+ const el = this.tabsContainer?.nativeElement;
270
+ if (el) {
271
+ el.addEventListener('scroll', () => this.updateScrollState(), { passive: true });
272
+ if (typeof ResizeObserver !== 'undefined') {
273
+ const ro = new ResizeObserver(() => this.updateScrollState());
274
+ ro.observe(el);
275
+ this.resizeObserver = ro;
276
+ }
277
+ }
278
+ // Global nav-link context menu'yu service'e tanıt — tüm `[arilNavLink]` directive'leri
279
+ // bu instance'ı paylaşır. ngAfterViewInit'te yapılır çünkü ViewChild burada kesin hazırdır.
280
+ if (this.navLinkContextMenu) {
281
+ this.navLinkContextMenuService.register(this.navLinkContextMenu);
282
+ }
283
+ }
284
+ constructor(menuService, layoutService, renderer, router, translateJsonPipe) {
29
285
  this.menuService = menuService;
30
286
  this.layoutService = layoutService;
31
287
  this.renderer = renderer;
32
288
  this.router = router;
289
+ this.translateJsonPipe = translateJsonPipe;
290
+ this.navService = inject(NavService);
291
+ this.translocoService = inject(TranslocoService);
292
+ this.navLinkContextMenuService = inject(NavLinkContextMenuService);
293
+ this.tabSession = inject(TabSessionService);
294
+ this.tabContextMenuItems = [];
295
+ /** Tab bar yatay scroll konum/genişlik durumu. Chevron butonlarının görünürlüğünü kontrol eder. */
296
+ this.canScrollLeft = signal(false);
297
+ this.canScrollRight = signal(false);
298
+ /**
299
+ * Breadcrumb segmentleri — `bridge.breadcrumbs()` üzerinden okunur.
300
+ * Source-of-truth aktif MFE'de çalışan `BreadcrumbPublisherService`'tir;
301
+ * MFE her NavigationEnd'de kendi route ağacından zinciri çıkarıp bridge'e yazar.
302
+ * Shell yalnızca presenter — başa "Anasayfa" item'ı ekleyip son item'ı aktif işaretler.
303
+ */
304
+ this.breadcrumbItems = computed(() => {
305
+ const crumbs = bridge.breadcrumbs();
306
+ const homeItem = {
307
+ icon: 'pi pi-home',
308
+ isHome: true
309
+ };
310
+ if (!crumbs.length) {
311
+ return [homeItem];
312
+ }
313
+ return [
314
+ homeItem,
315
+ ...crumbs.map((c, idx) => {
316
+ const isLast = idx === crumbs.length - 1;
317
+ return {
318
+ label: c.label,
319
+ // Aktif (son) item'da url verme — PrimeNG dış `.p-menuitem-link`'e href eklemesin,
320
+ // kullanıcı zaten o sayfada, tekrar tıklanmasının anlamı yok.
321
+ url: isLast ? undefined : c.url,
322
+ active: isLast
323
+ };
324
+ })
325
+ ];
326
+ });
327
+ /**
328
+ * Anasayfa için NavItem — breadcrumb home ikonunun hem `(click)` handler'ı hem
329
+ * `[arilNavLink]` context menu directive'i tarafından paylaşılır.
330
+ */
331
+ this.homeNavItem = computed(() => {
332
+ // NavService ile AYNI menü kaynağı (`bridge.hostMenuItems`) — `menuService.menuItems()`
333
+ // host `root` öğesini içermiyor (farklı/boş kaynak); `setMenuItemsProvider` de bridge'i kullanıyor.
334
+ const items = bridge.hostMenuItems();
335
+ const rootItem = items.find((i) => i.root);
336
+ // Pipe runtime'da object kabul ediyor (translate-json.pipe.ts:18) ama tip imzası `string` —
337
+ // static-sidebar'ın `getLocalText(any)` pattern'iyle aynı şekilde cast.
338
+ const navName = rootItem ? this.translateJsonPipe.transform(rootItem.label) : '';
339
+ return {
340
+ tabId: '',
341
+ navLink: rootItem?.routerLink || '/',
342
+ navName,
343
+ icon: rootItem?.icon
344
+ };
345
+ });
346
+ this.resizeObserver = null;
347
+ // NavService bridge'i doğrudan bilmez (cyclic dep önlemi); host shell `bridge.hostMenuItems()`
348
+ // üzerinden provider bağlar. Refresh sonrası adres çubuğuna yapıştırılmış URL'in tab adı/ikonu
349
+ // menüdeki gerçek değerlere göre çözülsün diye.
350
+ this.navService.setMenuItemsProvider(() => bridge.hostMenuItems());
351
+ this.navService.setHomeNavItemProvider(() => this.homeNavItem());
352
+ // Pinned tab'ları localStorage'dan geri yükle. Provider'lar set edildikten SONRA
353
+ // (restore edilen tab'lar reconcileTabsWithMenu ile menüden revize edilebilsin),
354
+ // ilk NavigationEnd handler'ından ÖNCE (senkron) — knownTab guard restore'u görsün.
355
+ this.tabSession.restore();
356
+ // Menü (bridge.hostMenuItems) async yüklenir; ilk açılış/refresh path'inde home tab
357
+ // fallback isim/iconla eklenmiş olabilir. Menü signal'i değişince tab'ları menüyle revize
358
+ // et → anasayfa adı/ikonu gerçek `root` öğesinden gelir, `tab.home` fallback'inde kalmaz.
359
+ effect(() => {
360
+ bridge.hostMenuItems();
361
+ // `untracked`: reconcileTabsWithMenu içinde `activeRoutes()` okunuyor; reactive
362
+ // context'te kalırsa effect activeRoutes'a da abone olur → her tab mutasyonunda
363
+ // (aç/kapat/sürükle/pin) gereksiz menü-DFS çalışır. Yalnız hostMenuItems'a bağlı kalsın.
364
+ untracked(() => this.navService.reconcileTabsWithMenu());
365
+ }, { allowSignalWrites: true });
366
+ // NavService.activeTabId → bridge.activeTabId mirror. Plugin'lerin Router proxy'leri
367
+ // (provideHostRouter) bu signal'ı okuyup navigate çağrılarına _tab state enjekte ediyor.
368
+ effect(() => {
369
+ bridge.activeTabId.set(this.navService.activeTabId());
370
+ }, { allowSignalWrites: true });
371
+ // MFE içi sayfa navigation'ları host Router'a yansımıyor (IsolatedLocationStrategy
372
+ // browser hash'ı değiştirmiyor) → NavService tab navLink'i güncel kalmıyordu. MFE
373
+ // AppComponent `bridge.activeMFEUrl`'a (kaynak tabId ile) yazıyor; bu effect ile
374
+ // dinleyip `syncActiveTabNavLinkForTab(tabId, url)` ile SADECE kaynak tab'ı update
375
+ // ederiz. Tab değiştirip geri dönüldüğünde doğru URL'e gidilir, cross-tab yok.
376
+ //
377
+ // **`untracked`**: `syncActiveTabNavLinkForTab` içinde `activeRoutes()` okunur;
378
+ // reactive context'te kalırsa effect activeRoutes'a da abone olur → tab.navLink
379
+ // değişikliği effect'i tekrar tetikler → eski `activeMFEUrl` değeriyle navLink'i
380
+ // geri çevirir (kullanıcının anasayfaya geçişi sürekli detail/meters'a dönerdi).
381
+ // Untracked sarması bu recursive loop'u kırar.
382
+ // `allowSignalWrites`: `activeRoutes.update` (signal write), effect içinden default
383
+ // `NG0600` yasaklı — bilinçli izin.
384
+ effect(() => {
385
+ const data = bridge.activeMFEUrl();
386
+ if (data?.tabId && data?.url) {
387
+ untracked(() => this.navService.syncActiveTabNavLinkForTab(data.tabId, data.url, data.title));
388
+ }
389
+ }, { allowSignalWrites: true });
33
390
  this.overlayMenuOpenSubscription = this.layoutService.overlayOpen$.subscribe(() => {
34
391
  if (!this.menuOutsideClickListener) {
35
392
  this.menuOutsideClickListener = this.renderer.listen('document', 'click', (event) => {
@@ -46,10 +403,35 @@ export class AppLayoutComponent {
46
403
  this.blockBodyScroll();
47
404
  }
48
405
  });
49
- this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
406
+ this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe((event) => {
50
407
  if (!this.layoutService.mfeAppItemClicked())
51
408
  this.hideMenu();
409
+ // Shell root route'a geçince (örn. `/`) MFE Router tetiklenmediği için
410
+ // `BreadcrumbPublisherService` set yapmaz, eski breadcrumb kalır. Manuel temizle.
411
+ // URL `?_tab=...` içerebileceği için query string'i sıyırıp path karşılaştır.
412
+ const url = event.urlAfterRedirects;
413
+ const path = url.split('?')[0];
414
+ if (path === '/' || path === '') {
415
+ bridge.breadcrumbs.set([]);
416
+ }
417
+ });
418
+ // Tab listesi değiştiğinde scroll state'ini yeniden hesapla — DOM güncellemesinden sonra
419
+ // `queueMicrotask` ile bir sonraki frame'i bekliyoruz (yeni eklenen tab clientWidth/scrollWidth'i etkiler).
420
+ effect(() => {
421
+ this.navService.activeRoutes();
422
+ queueMicrotask(() => this.updateScrollState());
52
423
  });
424
+ // Tab geçişinde breadcrumb'ı geçici olarak boşalt — yeni aktif MFE'nin
425
+ // `BreadcrumbPublisherService`'i yayın yapana kadar eski tab'ın breadcrumb'ı
426
+ // kullanıcıya görünmesin (kısa süreli stale UI'yi engeller).
427
+ let prevTabId;
428
+ effect(() => {
429
+ const tabId = this.navService.activeTabId();
430
+ if (prevTabId !== undefined && prevTabId !== tabId) {
431
+ bridge.breadcrumbs.set([]);
432
+ }
433
+ prevTabId = tabId;
434
+ }, { allowSignalWrites: true });
53
435
  }
54
436
  blockBodyScroll() {
55
437
  if (document.body.classList) {
@@ -121,15 +503,17 @@ export class AppLayoutComponent {
121
503
  if (this.menuOutsideClickListener) {
122
504
  this.menuOutsideClickListener();
123
505
  }
506
+ this.resizeObserver?.disconnect();
124
507
  }
125
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: AppLayoutComponent, deps: [{ token: i1.AppMenuService }, { token: i2.LayoutService }, { token: i0.Renderer2 }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component }); }
126
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.2", type: AppLayoutComponent, isStandalone: true, selector: "app-layout", viewQueries: [{ propertyName: "expandableMenuComponent", first: true, predicate: ExpandableMenuComponent, descendants: true }, { propertyName: "staticSidebarComponent", first: true, predicate: StaticSidebarComponent, descendants: true }, { propertyName: "appTopbar", first: true, predicate: AppTopbarComponent, descendants: true }], ngImport: i0, template: "<div class=\"layout-container\" [ngClass]=\"containerClass\">\r\n\t@if (layoutService.shouldShowStaticSidebar()) {\r\n\t\t<app-static-sidebar />\r\n\t} @else if (layoutService.shouldShowExpandableMenu()) {\r\n\t\t<app-expandable-menu />\r\n\t}\r\n\t<div class=\"layout-content-wrapper\">\r\n\t\t<app-topbar />\r\n\t\t<div class=\"layout-content\">\r\n\t\t\t<router-outlet />\r\n\t\t</div>\r\n\t</div>\r\n\t<app-profilemenu />\r\n\t<app-history-sidebar />\r\n\t<app-site-map-sidebar />\r\n\t<app-favorite-pages-sidebar />\r\n\t<app-notifications-sidebar />\r\n\t<!--<app-config></app-config>-->\r\n\t<div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\r\n</div>\r\n\r\n<p-toast key=\"toast-root\" />\r\n<p-dialog key=\"dialog-root\" />\r\n<p-messages key=\"messages-root\" />\r\n<p-confirmPopup key=\"confirmPopup-root\" />\r\n<p-confirmDialog key=\"confirmDialog-root\" />\r\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i4.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "ngmodule", type: ConfirmPopupModule }, { kind: "component", type: i5.ConfirmPopup, selector: "p-confirmPopup", inputs: ["key", "defaultFocus", "showTransitionOptions", "hideTransitionOptions", "autoZIndex", "baseZIndex", "style", "styleClass", "visible"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i6.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: MessagesModule }, { kind: "component", type: i7.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i8.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: AppTopbarComponent, selector: "app-topbar" }, { kind: "component", type: AppProfileSidebarComponent, selector: "app-profilemenu" }, { kind: "component", type: HistorySidebarComponent, selector: "app-history-sidebar" }, { kind: "component", type: SiteMapSidebarComponent, selector: "app-site-map-sidebar" }, { kind: "component", type: FavoritePagesSidebarComponent, selector: "app-favorite-pages-sidebar" }, { kind: "component", type: ExpandableMenuComponent, selector: "app-expandable-menu" }, { kind: "component", type: StaticSidebarComponent, selector: "app-static-sidebar" }, { kind: "component", type: NotificationsSidebarComponent, selector: "app-notifications-sidebar" }] }); }
508
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: AppLayoutComponent, deps: [{ token: i1.AppMenuService }, { token: i2.LayoutService }, { token: i0.Renderer2 }, { token: i3.Router }, { token: i4.TranslateJsonPipe }], target: i0.ɵɵFactoryTarget.Component }); }
509
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.2", type: AppLayoutComponent, isStandalone: true, selector: "app-layout", host: { listeners: { "document:keydown": "onDocumentKeydown($event)" } }, providers: [TranslateJsonPipe], viewQueries: [{ propertyName: "expandableMenuComponent", first: true, predicate: ExpandableMenuComponent, descendants: true }, { propertyName: "staticSidebarComponent", first: true, predicate: StaticSidebarComponent, descendants: true }, { propertyName: "appTopbar", first: true, predicate: AppTopbarComponent, descendants: true }, { propertyName: "tabsContainer", first: true, predicate: ["tabsContainer"], descendants: true }, { propertyName: "tabContextMenu", first: true, predicate: ["tabContextMenu"], descendants: true }, { propertyName: "navLinkContextMenu", first: true, predicate: ["navLinkContextMenu"], descendants: true }], ngImport: i0, template: "<div class=\"layout-container\" [ngClass]=\"containerClass\">\r\n\t@if (layoutService.shouldShowStaticSidebar()) {\r\n\t\t<app-static-sidebar />\r\n\t} @else if (layoutService.shouldShowExpandableMenu()) {\r\n\t\t<app-expandable-menu />\r\n\t}\r\n\t<div class=\"layout-content-wrapper\">\r\n\t\t<app-topbar />\r\n\t\t<div class=\"layout-content\">\r\n\t\t\t<p-breadcrumb styleClass=\"breadcrumb-strip\" [model]=\"breadcrumbItems()\">\r\n\t\t\t\t<ng-template pTemplate=\"item\" let-item>\r\n\t\t\t\t\t@if (item.isHome) {\r\n\t\t\t\t\t\t<a class=\"breadcrumb-home\"\r\n\t\t\t\t\t\t\t[routerLink]=\"'/'\"\r\n\t\t\t\t\t\t\t[arilNavLink]=\"homeNavItem()\"\r\n\t\t\t\t\t\t\t(click)=\"onHomeClick($event)\"\r\n\t\t\t\t\t\t\t[attr.aria-label]=\"'breadcrumb.home' | transloco\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-home\" aria-hidden=\"true\"></i>\r\n\t\t\t\t\t\t</a>\r\n\t\t\t\t\t} @else if (item.active || !item.url) {\r\n\t\t\t\t\t\t<span class=\"breadcrumb-item active\">{{ item.label }}</span>\r\n\t\t\t\t\t} @else {\r\n\t\t\t\t\t\t<a\r\n\t\t\t\t\t\t\tclass=\"breadcrumb-item breadcrumb-link\"\r\n\t\t\t\t\t\t\t[routerLink]=\"item.url\"\r\n\t\t\t\t\t\t\t[arilNavLink]=\"{ tabId: '', navLink: item.url, navName: item.label }\"\r\n\t\t\t\t\t\t\t(click)=\"onBreadcrumbClick($event, item)\">\r\n\t\t\t\t\t\t\t{{ item.label }}\r\n\t\t\t\t\t\t</a>\r\n\t\t\t\t\t}\r\n\t\t\t\t</ng-template>\r\n\t\t\t\t<ng-template pTemplate=\"separator\">\r\n\t\t\t\t\t<i class=\"breadcrumb-sep pi pi-angle-right text-base\" aria-hidden=\"true\"></i>\r\n\t\t\t\t</ng-template>\r\n\t\t\t</p-breadcrumb>\r\n\t\t\t<div class=\"tabs-bar\">\r\n\t\t\t\t@if (canScrollLeft()) {\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclass=\"tabs-scroll-btn tabs-scroll-left\"\r\n\t\t\t\t\t\t(click)=\"scrollTabsLeft()\"\r\n\t\t\t\t\t\t[pTooltip]=\"'tab.scrollLeft' | transloco\"\r\n\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t[attr.aria-label]=\"'tab.scrollLeft' | transloco\">\r\n\t\t\t\t\t\t<i class=\"pi pi-chevron-left\"></i>\r\n\t\t\t\t\t</button>\r\n\t\t\t\t}\r\n\t\t\t\t<div\r\n\t\t\t\t\t#tabsContainer\r\n\t\t\t\t\tclass=\"tabs-container\"\r\n\t\t\t\t\tcdkDropList\r\n\t\t\t\t\tcdkDropListOrientation=\"horizontal\"\r\n\t\t\t\t\t(cdkDropListDropped)=\"drop($event)\">\r\n\t\t\t\t\t@for (item of navService.activeRoutes(); track item.tabId; let i = $index) {\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclass=\"tab-item\"\r\n\t\t\t\t\t\t\tcdkDrag\r\n\t\t\t\t\t\t\t[class.active]=\"isActive(item)\"\r\n\t\t\t\t\t\t\t[class.pinned]=\"item.pinned\"\r\n\t\t\t\t\t\t\t[pTooltip]=\"item.navName\"\r\n\t\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t\t[tooltipDisabled]=\"isActive(item) && !item.pinned\"\r\n\t\t\t\t\t\t\t[showDelay]=\"500\"\r\n\t\t\t\t\t\t\t(click)=\"onTabClick($event, item)\"\r\n\t\t\t\t\t\t\t(auxclick)=\"onTabAuxClick($event, item)\"\r\n\t\t\t\t\t\t\t(mousedown)=\"onTabMousedown($event)\"\r\n\t\t\t\t\t\t\t(contextmenu)=\"onTabContextMenu($event, item)\">\r\n\t\t\t\t\t\t\t<i class=\"tab-icon\" [ngClass]=\"getTabIcon(item)\"></i>\r\n\t\t\t\t\t\t\t@if (!item.pinned) {\r\n\t\t\t\t\t\t\t\t<span class=\"tab-title\">{{ item.navName }}</span>\r\n\t\t\t\t\t\t\t\t@if (!isLastHomeTab(item)) {\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclass=\"tab-close-btn\"\r\n\t\t\t\t\t\t\t\t\t\t(click)=\"closeTab($event, item)\"\r\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'tab.close' | transloco\">\r\n\t\t\t\t\t\t\t\t\t\t<i class=\"pi pi-times\"></i>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t}\r\n\t\t\t\t</div>\r\n\t\t\t\t@if (canScrollRight()) {\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclass=\"tabs-scroll-btn tabs-scroll-right\"\r\n\t\t\t\t\t\t(click)=\"scrollTabsRight()\"\r\n\t\t\t\t\t\t[pTooltip]=\"'tab.scrollRight' | transloco\"\r\n\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t[attr.aria-label]=\"'tab.scrollRight' | transloco\">\r\n\t\t\t\t\t\t<i class=\"pi pi-chevron-right\"></i>\r\n\t\t\t\t\t</button>\r\n\t\t\t\t}\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclass=\"tabs-add-btn\"\r\n\t\t\t\t\t(click)=\"onAddTab()\"\r\n\t\t\t\t\t[pTooltip]=\"'tab.newTab' | transloco\"\r\n\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t[attr.aria-label]=\"'tab.newTab' | transloco\">\r\n\t\t\t\t\t<i class=\"pi pi-plus\"></i>\r\n\t\t\t\t</button>\r\n\t\t\t</div>\r\n\t\t\t<p-contextMenu #tabContextMenu [model]=\"tabContextMenuItems\" appendTo=\"body\"></p-contextMenu>\r\n\t\t\t<!-- Global nav-link context menu: t\u00FCm linkli yap\u0131larda `[arilNavLink]` directive'i bu instance'\u0131 payla\u015F\u0131r. -->\r\n\t\t\t<p-contextMenu #navLinkContextMenu [model]=\"[]\" appendTo=\"body\"></p-contextMenu>\r\n\r\n\t\t\t<div class=\"layout-page\">\r\n\t\t\t\t<router-outlet />\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<app-profilemenu />\r\n\t<app-history-sidebar />\r\n\t<app-site-map-sidebar />\r\n\t<app-favorite-pages-sidebar />\r\n\t<app-notifications-sidebar />\r\n\t<!--<app-config></app-config>-->\r\n\t<div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\r\n</div>\r\n\r\n<p-toast key=\"toast-root\" />\r\n<p-dialog key=\"dialog-root\" />\r\n<p-messages key=\"messages-root\" />\r\n<p-confirmPopup key=\"confirmPopup-root\" />\r\n<p-confirmDialog key=\"confirmDialog-root\" />\r\n", styles: [":host{display:flex;flex-direction:column;height:100vh}.layout-content{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.tabs-bar{position:relative;display:flex;align-items:center;background:var(--surface-section, #f4f6fb);border-bottom:1px solid var(--surface-border, #e5e7eb);padding:0 12px;min-height:48px;flex-shrink:0;z-index:1;gap:4px}.tabs-container{display:flex;align-items:center;gap:4px;flex:1;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:none;min-width:0;padding:8px 0}.tabs-container::-webkit-scrollbar{display:none}.layout-page{flex:1;min-height:0;overflow:auto;padding:16px}.tab-item{position:relative;display:flex;align-items:center;gap:8px;height:32px;min-width:130px;max-width:240px;padding:0 10px 0 12px;margin:0 4px;background:transparent;color:var(--text-color-secondary, #6b7280);cursor:pointer;-webkit-user-select:none;user-select:none;font-family:inherit;font-size:.8125rem;font-weight:500;line-height:1;border-radius:10px;transition:background-color .14s cubic-bezier(.4,0,.2,1),color .14s cubic-bezier(.4,0,.2,1),box-shadow .14s cubic-bezier(.4,0,.2,1)}.tab-item:hover:not(.active){background:var(--surface-hover, rgba(15, 23, 42, .04));color:var(--text-color, #475569)}.tab-item:hover:not(.active) .tab-close-btn,.tab-item:hover:not(.active) .tab-icon{opacity:1}.tab-item.active{background:var(--surface-card, #ffffff);color:var(--text-color, #1e293b);font-weight:600;box-shadow:0 1px 2px #0f172a0f,0 0 0 1px #d9ddfc80}.tab-item.active .tab-close-btn{opacity:1}.tab-item.active .tab-icon{opacity:1;color:var(--primary-color, #6366f1)}.tab-item .tab-icon{flex-shrink:0;font-size:.875rem;opacity:.7;transition:opacity .14s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.tab-item .tab-title{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.tab-item .tab-close-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:0;line-height:1;transition:opacity .14s cubic-bezier(.4,0,.2,1),background-color .14s cubic-bezier(.4,0,.2,1)}.tab-item .tab-close-btn:hover{background:#0f172a14}.tab-item .tab-close-btn i{font-size:10px}.tab-item.pinned{min-width:36px;max-width:36px;padding:0;justify-content:center;gap:0}.tab-item.pinned .tab-icon{opacity:1;margin:0}.tabs-container .tab-item.pinned+.tab-item:not(.pinned){margin-left:12px;position:relative}.tabs-container .tab-item.pinned+.tab-item:not(.pinned):before{content:\"\";position:absolute;left:-8px;top:6px;bottom:6px;width:1px;background:var(--surface-border, #e5e7eb)}.tabs-scroll-btn,.tabs-add-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--text-color-secondary, #6b7280);cursor:pointer;transition:background-color .14s cubic-bezier(.4,0,.2,1),color .14s cubic-bezier(.4,0,.2,1)}.tabs-scroll-btn:hover,.tabs-add-btn:hover{background:var(--surface-hover, rgba(15, 23, 42, .04));color:var(--text-color, #475569)}.tabs-scroll-btn i,.tabs-add-btn i{font-size:11px}.tabs-add-btn{margin-left:4px}.cdk-drag-preview{box-sizing:border-box;height:32px;padding:0 12px;display:flex;align-items:center;gap:8px;background:var(--surface-card, #ffffff);color:var(--text-color, #1e293b);border:1px solid var(--surface-border, #e5e7eb);border-radius:10px;box-shadow:0 4px 30px #dde0ff8a,0 2px 6px #0f172a0f;font-size:.8125rem;font-weight:600;line-height:1;opacity:.96;z-index:1000}.cdk-drag-preview .tab-icon{font-size:.875rem;opacity:.85;flex-shrink:0}.cdk-drag-preview .tab-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.cdk-drag-preview .tab-close-btn{display:none}.cdk-drag-placeholder{opacity:.5;background:var(--surface-section, #f4f6fb);border:1px dashed var(--primary-color, #6366f1);box-shadow:none}.cdk-drag-placeholder .tab-icon,.cdk-drag-placeholder .tab-title{opacity:.55}.cdk-drag-placeholder .tab-close-btn{visibility:hidden}.cdk-drag-animating{transition:transform .2s cubic-bezier(.4,0,.2,1)}.tabs-container.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(.4,0,.2,1)}:host-context(.layout-dark) .tabs-bar,:host-context(.layout-dim) .tabs-bar{background:var(--surface-section, #111827);border-bottom-color:var(--surface-border, #334155)}:host-context(.layout-dark) .tab-item,:host-context(.layout-dim) .tab-item{color:var(--text-color-secondary, rgba(255, 255, 255, .6))}:host-context(.layout-dark) .tab-item:hover:not(.active),:host-context(.layout-dim) .tab-item:hover:not(.active){background:var(--surface-hover, rgba(255, 255, 255, .05));color:var(--text-color, rgba(255, 255, 255, .87))}:host-context(.layout-dark) .tab-item.active,:host-context(.layout-dim) .tab-item.active{background:var(--surface-card, #1e293b);color:var(--text-color, rgba(255, 255, 255, .87));box-shadow:0 1px 2px #0000004d,0 0 0 1px #ffffff0f}:host-context(.layout-dark) .tab-item .tab-close-btn:hover,:host-context(.layout-dim) .tab-item .tab-close-btn:hover{background:#ffffff1a}:host-context(.layout-dark) .tabs-scroll-btn,:host-context(.layout-dark) .tabs-add-btn,:host-context(.layout-dim) .tabs-scroll-btn,:host-context(.layout-dim) .tabs-add-btn{color:var(--text-color-secondary, rgba(255, 255, 255, .6))}:host-context(.layout-dark) .tabs-scroll-btn:hover,:host-context(.layout-dark) .tabs-add-btn:hover,:host-context(.layout-dim) .tabs-scroll-btn:hover,:host-context(.layout-dim) .tabs-add-btn:hover{background:var(--surface-hover, rgba(255, 255, 255, .05));color:var(--text-color, rgba(255, 255, 255, .87))}:host-context(.layout-dark) .cdk-drag-preview,:host-context(.layout-dim) .cdk-drag-preview{background:var(--surface-card, #1e293b);color:var(--text-color, rgba(255, 255, 255, .87));border-color:var(--surface-border, #334155);box-shadow:0 10px 28px #0006,0 2px 6px #0003}:host-context(.layout-dark) .cdk-drag-placeholder,:host-context(.layout-dim) .cdk-drag-placeholder{background:var(--surface-section, #111827);border-color:var(--primary-color, #818cf8)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: ConfirmDialogModule }, { kind: "component", type: i5.ConfirmDialog, selector: "p-confirmDialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "directive", type: i6.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ConfirmPopupModule }, { kind: "component", type: i7.ConfirmPopup, selector: "p-confirmPopup", inputs: ["key", "defaultFocus", "showTransitionOptions", "hideTransitionOptions", "autoZIndex", "baseZIndex", "style", "styleClass", "visible"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i8.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: MessagesModule }, { kind: "component", type: i9.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i10.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: AppTopbarComponent, selector: "app-topbar" }, { kind: "component", type: AppProfileSidebarComponent, selector: "app-profilemenu" }, { kind: "component", type: HistorySidebarComponent, selector: "app-history-sidebar" }, { kind: "component", type: SiteMapSidebarComponent, selector: "app-site-map-sidebar" }, { kind: "component", type: FavoritePagesSidebarComponent, selector: "app-favorite-pages-sidebar" }, { kind: "component", type: ExpandableMenuComponent, selector: "app-expandable-menu" }, { kind: "component", type: StaticSidebarComponent, selector: "app-static-sidebar" }, { kind: "component", type: NotificationsSidebarComponent, selector: "app-notifications-sidebar" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: BreadcrumbModule }, { kind: "component", type: i12.Breadcrumb, selector: "p-breadcrumb", inputs: ["model", "style", "styleClass", "home", "homeAriaLabel"], outputs: ["onItemClick"] }, { kind: "directive", type: i13.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i14.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i15.TranslocoPipe, name: "transloco" }, { kind: "directive", type: NavLinkDirective, selector: "[arilNavLink]", inputs: ["arilNavLink"] }] }); }
127
510
  }
128
511
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: AppLayoutComponent, decorators: [{
129
512
  type: Component,
130
513
  args: [{ standalone: true, selector: 'app-layout', imports: [
131
514
  NgClass,
132
515
  RouterOutlet,
516
+ RouterLink,
133
517
  ConfirmDialogModule,
134
518
  ConfirmPopupModule,
135
519
  DialogModule,
@@ -142,9 +526,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImpor
142
526
  FavoritePagesSidebarComponent,
143
527
  ExpandableMenuComponent,
144
528
  StaticSidebarComponent,
145
- NotificationsSidebarComponent
146
- ], template: "<div class=\"layout-container\" [ngClass]=\"containerClass\">\r\n\t@if (layoutService.shouldShowStaticSidebar()) {\r\n\t\t<app-static-sidebar />\r\n\t} @else if (layoutService.shouldShowExpandableMenu()) {\r\n\t\t<app-expandable-menu />\r\n\t}\r\n\t<div class=\"layout-content-wrapper\">\r\n\t\t<app-topbar />\r\n\t\t<div class=\"layout-content\">\r\n\t\t\t<router-outlet />\r\n\t\t</div>\r\n\t</div>\r\n\t<app-profilemenu />\r\n\t<app-history-sidebar />\r\n\t<app-site-map-sidebar />\r\n\t<app-favorite-pages-sidebar />\r\n\t<app-notifications-sidebar />\r\n\t<!--<app-config></app-config>-->\r\n\t<div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\r\n</div>\r\n\r\n<p-toast key=\"toast-root\" />\r\n<p-dialog key=\"dialog-root\" />\r\n<p-messages key=\"messages-root\" />\r\n<p-confirmPopup key=\"confirmPopup-root\" />\r\n<p-confirmDialog key=\"confirmDialog-root\" />\r\n" }]
147
- }], ctorParameters: () => [{ type: i1.AppMenuService }, { type: i2.LayoutService }, { type: i0.Renderer2 }, { type: i3.Router }], propDecorators: { expandableMenuComponent: [{
529
+ NotificationsSidebarComponent,
530
+ DragDropModule,
531
+ BreadcrumbModule,
532
+ ContextMenuModule,
533
+ TooltipModule,
534
+ TranslocoModule,
535
+ NavLinkDirective
536
+ ], providers: [TranslateJsonPipe], template: "<div class=\"layout-container\" [ngClass]=\"containerClass\">\r\n\t@if (layoutService.shouldShowStaticSidebar()) {\r\n\t\t<app-static-sidebar />\r\n\t} @else if (layoutService.shouldShowExpandableMenu()) {\r\n\t\t<app-expandable-menu />\r\n\t}\r\n\t<div class=\"layout-content-wrapper\">\r\n\t\t<app-topbar />\r\n\t\t<div class=\"layout-content\">\r\n\t\t\t<p-breadcrumb styleClass=\"breadcrumb-strip\" [model]=\"breadcrumbItems()\">\r\n\t\t\t\t<ng-template pTemplate=\"item\" let-item>\r\n\t\t\t\t\t@if (item.isHome) {\r\n\t\t\t\t\t\t<a class=\"breadcrumb-home\"\r\n\t\t\t\t\t\t\t[routerLink]=\"'/'\"\r\n\t\t\t\t\t\t\t[arilNavLink]=\"homeNavItem()\"\r\n\t\t\t\t\t\t\t(click)=\"onHomeClick($event)\"\r\n\t\t\t\t\t\t\t[attr.aria-label]=\"'breadcrumb.home' | transloco\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-home\" aria-hidden=\"true\"></i>\r\n\t\t\t\t\t\t</a>\r\n\t\t\t\t\t} @else if (item.active || !item.url) {\r\n\t\t\t\t\t\t<span class=\"breadcrumb-item active\">{{ item.label }}</span>\r\n\t\t\t\t\t} @else {\r\n\t\t\t\t\t\t<a\r\n\t\t\t\t\t\t\tclass=\"breadcrumb-item breadcrumb-link\"\r\n\t\t\t\t\t\t\t[routerLink]=\"item.url\"\r\n\t\t\t\t\t\t\t[arilNavLink]=\"{ tabId: '', navLink: item.url, navName: item.label }\"\r\n\t\t\t\t\t\t\t(click)=\"onBreadcrumbClick($event, item)\">\r\n\t\t\t\t\t\t\t{{ item.label }}\r\n\t\t\t\t\t\t</a>\r\n\t\t\t\t\t}\r\n\t\t\t\t</ng-template>\r\n\t\t\t\t<ng-template pTemplate=\"separator\">\r\n\t\t\t\t\t<i class=\"breadcrumb-sep pi pi-angle-right text-base\" aria-hidden=\"true\"></i>\r\n\t\t\t\t</ng-template>\r\n\t\t\t</p-breadcrumb>\r\n\t\t\t<div class=\"tabs-bar\">\r\n\t\t\t\t@if (canScrollLeft()) {\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclass=\"tabs-scroll-btn tabs-scroll-left\"\r\n\t\t\t\t\t\t(click)=\"scrollTabsLeft()\"\r\n\t\t\t\t\t\t[pTooltip]=\"'tab.scrollLeft' | transloco\"\r\n\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t[attr.aria-label]=\"'tab.scrollLeft' | transloco\">\r\n\t\t\t\t\t\t<i class=\"pi pi-chevron-left\"></i>\r\n\t\t\t\t\t</button>\r\n\t\t\t\t}\r\n\t\t\t\t<div\r\n\t\t\t\t\t#tabsContainer\r\n\t\t\t\t\tclass=\"tabs-container\"\r\n\t\t\t\t\tcdkDropList\r\n\t\t\t\t\tcdkDropListOrientation=\"horizontal\"\r\n\t\t\t\t\t(cdkDropListDropped)=\"drop($event)\">\r\n\t\t\t\t\t@for (item of navService.activeRoutes(); track item.tabId; let i = $index) {\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclass=\"tab-item\"\r\n\t\t\t\t\t\t\tcdkDrag\r\n\t\t\t\t\t\t\t[class.active]=\"isActive(item)\"\r\n\t\t\t\t\t\t\t[class.pinned]=\"item.pinned\"\r\n\t\t\t\t\t\t\t[pTooltip]=\"item.navName\"\r\n\t\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t\t[tooltipDisabled]=\"isActive(item) && !item.pinned\"\r\n\t\t\t\t\t\t\t[showDelay]=\"500\"\r\n\t\t\t\t\t\t\t(click)=\"onTabClick($event, item)\"\r\n\t\t\t\t\t\t\t(auxclick)=\"onTabAuxClick($event, item)\"\r\n\t\t\t\t\t\t\t(mousedown)=\"onTabMousedown($event)\"\r\n\t\t\t\t\t\t\t(contextmenu)=\"onTabContextMenu($event, item)\">\r\n\t\t\t\t\t\t\t<i class=\"tab-icon\" [ngClass]=\"getTabIcon(item)\"></i>\r\n\t\t\t\t\t\t\t@if (!item.pinned) {\r\n\t\t\t\t\t\t\t\t<span class=\"tab-title\">{{ item.navName }}</span>\r\n\t\t\t\t\t\t\t\t@if (!isLastHomeTab(item)) {\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclass=\"tab-close-btn\"\r\n\t\t\t\t\t\t\t\t\t\t(click)=\"closeTab($event, item)\"\r\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'tab.close' | transloco\">\r\n\t\t\t\t\t\t\t\t\t\t<i class=\"pi pi-times\"></i>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t}\r\n\t\t\t\t</div>\r\n\t\t\t\t@if (canScrollRight()) {\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclass=\"tabs-scroll-btn tabs-scroll-right\"\r\n\t\t\t\t\t\t(click)=\"scrollTabsRight()\"\r\n\t\t\t\t\t\t[pTooltip]=\"'tab.scrollRight' | transloco\"\r\n\t\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t\t[attr.aria-label]=\"'tab.scrollRight' | transloco\">\r\n\t\t\t\t\t\t<i class=\"pi pi-chevron-right\"></i>\r\n\t\t\t\t\t</button>\r\n\t\t\t\t}\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclass=\"tabs-add-btn\"\r\n\t\t\t\t\t(click)=\"onAddTab()\"\r\n\t\t\t\t\t[pTooltip]=\"'tab.newTab' | transloco\"\r\n\t\t\t\t\ttooltipPosition=\"bottom\"\r\n\t\t\t\t\t[attr.aria-label]=\"'tab.newTab' | transloco\">\r\n\t\t\t\t\t<i class=\"pi pi-plus\"></i>\r\n\t\t\t\t</button>\r\n\t\t\t</div>\r\n\t\t\t<p-contextMenu #tabContextMenu [model]=\"tabContextMenuItems\" appendTo=\"body\"></p-contextMenu>\r\n\t\t\t<!-- Global nav-link context menu: t\u00FCm linkli yap\u0131larda `[arilNavLink]` directive'i bu instance'\u0131 payla\u015F\u0131r. -->\r\n\t\t\t<p-contextMenu #navLinkContextMenu [model]=\"[]\" appendTo=\"body\"></p-contextMenu>\r\n\r\n\t\t\t<div class=\"layout-page\">\r\n\t\t\t\t<router-outlet />\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<app-profilemenu />\r\n\t<app-history-sidebar />\r\n\t<app-site-map-sidebar />\r\n\t<app-favorite-pages-sidebar />\r\n\t<app-notifications-sidebar />\r\n\t<!--<app-config></app-config>-->\r\n\t<div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\r\n</div>\r\n\r\n<p-toast key=\"toast-root\" />\r\n<p-dialog key=\"dialog-root\" />\r\n<p-messages key=\"messages-root\" />\r\n<p-confirmPopup key=\"confirmPopup-root\" />\r\n<p-confirmDialog key=\"confirmDialog-root\" />\r\n", styles: [":host{display:flex;flex-direction:column;height:100vh}.layout-content{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.tabs-bar{position:relative;display:flex;align-items:center;background:var(--surface-section, #f4f6fb);border-bottom:1px solid var(--surface-border, #e5e7eb);padding:0 12px;min-height:48px;flex-shrink:0;z-index:1;gap:4px}.tabs-container{display:flex;align-items:center;gap:4px;flex:1;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scrollbar-width:none;min-width:0;padding:8px 0}.tabs-container::-webkit-scrollbar{display:none}.layout-page{flex:1;min-height:0;overflow:auto;padding:16px}.tab-item{position:relative;display:flex;align-items:center;gap:8px;height:32px;min-width:130px;max-width:240px;padding:0 10px 0 12px;margin:0 4px;background:transparent;color:var(--text-color-secondary, #6b7280);cursor:pointer;-webkit-user-select:none;user-select:none;font-family:inherit;font-size:.8125rem;font-weight:500;line-height:1;border-radius:10px;transition:background-color .14s cubic-bezier(.4,0,.2,1),color .14s cubic-bezier(.4,0,.2,1),box-shadow .14s cubic-bezier(.4,0,.2,1)}.tab-item:hover:not(.active){background:var(--surface-hover, rgba(15, 23, 42, .04));color:var(--text-color, #475569)}.tab-item:hover:not(.active) .tab-close-btn,.tab-item:hover:not(.active) .tab-icon{opacity:1}.tab-item.active{background:var(--surface-card, #ffffff);color:var(--text-color, #1e293b);font-weight:600;box-shadow:0 1px 2px #0f172a0f,0 0 0 1px #d9ddfc80}.tab-item.active .tab-close-btn{opacity:1}.tab-item.active .tab-icon{opacity:1;color:var(--primary-color, #6366f1)}.tab-item .tab-icon{flex-shrink:0;font-size:.875rem;opacity:.7;transition:opacity .14s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.tab-item .tab-title{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}.tab-item .tab-close-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;cursor:pointer;opacity:0;line-height:1;transition:opacity .14s cubic-bezier(.4,0,.2,1),background-color .14s cubic-bezier(.4,0,.2,1)}.tab-item .tab-close-btn:hover{background:#0f172a14}.tab-item .tab-close-btn i{font-size:10px}.tab-item.pinned{min-width:36px;max-width:36px;padding:0;justify-content:center;gap:0}.tab-item.pinned .tab-icon{opacity:1;margin:0}.tabs-container .tab-item.pinned+.tab-item:not(.pinned){margin-left:12px;position:relative}.tabs-container .tab-item.pinned+.tab-item:not(.pinned):before{content:\"\";position:absolute;left:-8px;top:6px;bottom:6px;width:1px;background:var(--surface-border, #e5e7eb)}.tabs-scroll-btn,.tabs-add-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--text-color-secondary, #6b7280);cursor:pointer;transition:background-color .14s cubic-bezier(.4,0,.2,1),color .14s cubic-bezier(.4,0,.2,1)}.tabs-scroll-btn:hover,.tabs-add-btn:hover{background:var(--surface-hover, rgba(15, 23, 42, .04));color:var(--text-color, #475569)}.tabs-scroll-btn i,.tabs-add-btn i{font-size:11px}.tabs-add-btn{margin-left:4px}.cdk-drag-preview{box-sizing:border-box;height:32px;padding:0 12px;display:flex;align-items:center;gap:8px;background:var(--surface-card, #ffffff);color:var(--text-color, #1e293b);border:1px solid var(--surface-border, #e5e7eb);border-radius:10px;box-shadow:0 4px 30px #dde0ff8a,0 2px 6px #0f172a0f;font-size:.8125rem;font-weight:600;line-height:1;opacity:.96;z-index:1000}.cdk-drag-preview .tab-icon{font-size:.875rem;opacity:.85;flex-shrink:0}.cdk-drag-preview .tab-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.cdk-drag-preview .tab-close-btn{display:none}.cdk-drag-placeholder{opacity:.5;background:var(--surface-section, #f4f6fb);border:1px dashed var(--primary-color, #6366f1);box-shadow:none}.cdk-drag-placeholder .tab-icon,.cdk-drag-placeholder .tab-title{opacity:.55}.cdk-drag-placeholder .tab-close-btn{visibility:hidden}.cdk-drag-animating{transition:transform .2s cubic-bezier(.4,0,.2,1)}.tabs-container.cdk-drop-list-dragging .tab-item:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(.4,0,.2,1)}:host-context(.layout-dark) .tabs-bar,:host-context(.layout-dim) .tabs-bar{background:var(--surface-section, #111827);border-bottom-color:var(--surface-border, #334155)}:host-context(.layout-dark) .tab-item,:host-context(.layout-dim) .tab-item{color:var(--text-color-secondary, rgba(255, 255, 255, .6))}:host-context(.layout-dark) .tab-item:hover:not(.active),:host-context(.layout-dim) .tab-item:hover:not(.active){background:var(--surface-hover, rgba(255, 255, 255, .05));color:var(--text-color, rgba(255, 255, 255, .87))}:host-context(.layout-dark) .tab-item.active,:host-context(.layout-dim) .tab-item.active{background:var(--surface-card, #1e293b);color:var(--text-color, rgba(255, 255, 255, .87));box-shadow:0 1px 2px #0000004d,0 0 0 1px #ffffff0f}:host-context(.layout-dark) .tab-item .tab-close-btn:hover,:host-context(.layout-dim) .tab-item .tab-close-btn:hover{background:#ffffff1a}:host-context(.layout-dark) .tabs-scroll-btn,:host-context(.layout-dark) .tabs-add-btn,:host-context(.layout-dim) .tabs-scroll-btn,:host-context(.layout-dim) .tabs-add-btn{color:var(--text-color-secondary, rgba(255, 255, 255, .6))}:host-context(.layout-dark) .tabs-scroll-btn:hover,:host-context(.layout-dark) .tabs-add-btn:hover,:host-context(.layout-dim) .tabs-scroll-btn:hover,:host-context(.layout-dim) .tabs-add-btn:hover{background:var(--surface-hover, rgba(255, 255, 255, .05));color:var(--text-color, rgba(255, 255, 255, .87))}:host-context(.layout-dark) .cdk-drag-preview,:host-context(.layout-dim) .cdk-drag-preview{background:var(--surface-card, #1e293b);color:var(--text-color, rgba(255, 255, 255, .87));border-color:var(--surface-border, #334155);box-shadow:0 10px 28px #0006,0 2px 6px #0003}:host-context(.layout-dark) .cdk-drag-placeholder,:host-context(.layout-dim) .cdk-drag-placeholder{background:var(--surface-section, #111827);border-color:var(--primary-color, #818cf8)}\n"] }]
537
+ }], ctorParameters: () => [{ type: i1.AppMenuService }, { type: i2.LayoutService }, { type: i0.Renderer2 }, { type: i3.Router }, { type: i4.TranslateJsonPipe }], propDecorators: { expandableMenuComponent: [{
148
538
  type: ViewChild,
149
539
  args: [ExpandableMenuComponent]
150
540
  }], staticSidebarComponent: [{
@@ -153,5 +543,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImpor
153
543
  }], appTopbar: [{
154
544
  type: ViewChild,
155
545
  args: [AppTopbarComponent]
546
+ }], tabsContainer: [{
547
+ type: ViewChild,
548
+ args: ['tabsContainer', { static: false }]
549
+ }], tabContextMenu: [{
550
+ type: ViewChild,
551
+ args: ['tabContextMenu']
552
+ }], navLinkContextMenu: [{
553
+ type: ViewChild,
554
+ args: ['navLinkContextMenu']
555
+ }], onDocumentKeydown: [{
556
+ type: HostListener,
557
+ args: ['document:keydown', ['$event']]
156
558
  }] } });
157
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmxheW91dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hcmlsL3RoZW1lL2xheW91dC9hcHAvbGF5b3V0L2FwcC5sYXlvdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXJpbC90aGVtZS9sYXlvdXQvYXBwL2xheW91dC9hcHAubGF5b3V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEVBQUUsU0FBUyxFQUF3QixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUFFLGFBQWEsRUFBVSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFNUMsT0FBTyxFQUFnQixNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJNUMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDNUYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDL0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDakYsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFDbkcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEUs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QUN2QixzQkFBc0I7d0JBQ3RCLDZCQUE2QjtxQkFDN0I7NEpBUW1DLHVCQUF1QjtzQkFBMUQsU0FBUzt1QkFBQyx1QkFBdUI7Z0JBQ0Msc0JBQXNCO3NCQUF4RCxTQUFTO3VCQUFDLHNCQUFzQjtnQkFDRixTQUFTO3NCQUF2QyxTQUFTO3VCQUFDLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uRGVzdHJveSwgUmVuZGVyZXIyLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTmF2aWdhdGlvbkVuZCwgUm91dGVyLCBSb3V0ZXJPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5cclxuaW1wb3J0IHsgQ29uZmlybURpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY29uZmlybWRpYWxvZyc7XHJcbmltcG9ydCB7IENvbmZpcm1Qb3B1cE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY29uZmlybXBvcHVwJztcclxuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xyXG5pbXBvcnQgeyBNZXNzYWdlc01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvbWVzc2FnZXMnO1xyXG5pbXBvcnQgeyBUb2FzdE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9hc3QnO1xyXG5cclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCBmaWx0ZXIgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IExheW91dFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlL2FwcC5sYXlvdXQuc2VydmljZSc7XHJcbmltcG9ydCB7IEFwcE1lbnVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZS9hcHAubWVudS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQXBwUHJvZmlsZVNpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9wcm9maWxlU2lkZWJhci9hcHAucHJvZmlsZXNpZGViYXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgSGlzdG9yeVNpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9oaXN0b3J5L2hpc3Rvcnktc2lkZWJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBTaXRlTWFwU2lkZWJhckNvbXBvbmVudCB9IGZyb20gJy4uL3NpdGUtbWFwL3NpdGUtbWFwLXNpZGViYXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRmF2b3JpdGVQYWdlc1NpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9mYXZvcml0ZS1wYWdlcy9mYXZvcml0ZS1wYWdlcy1zaWRlYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEFwcFRvcGJhckNvbXBvbmVudCB9IGZyb20gJy4uL3RvcGJhci9hcHAudG9wYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEV4cGFuZGFibGVNZW51Q29tcG9uZW50IH0gZnJvbSAnLi4vZXhwYW5kYWJsZU1lbnUvZXhwYW5kYWJsZS1tZW51LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFN0YXRpY1NpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9zdGF0aWMtc2lkZWJhci9zdGF0aWMtc2lkZWJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25zU2lkZWJhckNvbXBvbmVudCB9IGZyb20gJy4uL25vdGlmaWNhdGlvbnMvbm90aWZpY2F0aW9ucy1zaWRlYmFyLmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHRzdGFuZGFsb25lOiB0cnVlLFxyXG5cdHNlbGVjdG9yOiAnYXBwLWxheW91dCcsXHJcblx0aW1wb3J0czogW1xyXG5cdFx0TmdDbGFzcyxcclxuXHRcdFJvdXRlck91dGxldCxcclxuXHRcdENvbmZpcm1EaWFsb2dNb2R1bGUsXHJcblx0XHRDb25maXJtUG9wdXBNb2R1bGUsXHJcblx0XHREaWFsb2dNb2R1bGUsXHJcblx0XHRNZXNzYWdlc01vZHVsZSxcclxuXHRcdFRvYXN0TW9kdWxlLFxyXG5cdFx0QXBwVG9wYmFyQ29tcG9uZW50LFxyXG5cdFx0QXBwUHJvZmlsZVNpZGViYXJDb21wb25lbnQsXHJcblx0XHRIaXN0b3J5U2lkZWJhckNvbXBvbmVudCxcclxuXHRcdFNpdGVNYXBTaWRlYmFyQ29tcG9uZW50LFxyXG5cdFx0RmF2b3JpdGVQYWdlc1NpZGViYXJDb21wb25lbnQsXHJcblx0XHRFeHBhbmRhYmxlTWVudUNvbXBvbmVudCxcclxuXHRcdFN0YXRpY1NpZGViYXJDb21wb25lbnQsXHJcblx0XHROb3RpZmljYXRpb25zU2lkZWJhckNvbXBvbmVudFxyXG5cdF0sXHJcblx0dGVtcGxhdGVVcmw6ICcuL2FwcC5sYXlvdXQuY29tcG9uZW50Lmh0bWwnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBcHBMYXlvdXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG5cdG92ZXJsYXlNZW51T3BlblN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xyXG5cdG1lbnVPdXRzaWRlQ2xpY2tMaXN0ZW5lcjogYW55O1xyXG5cdG1lbnVTY3JvbGxMaXN0ZW5lcjogYW55O1xyXG5cclxuXHRAVmlld0NoaWxkKEV4cGFuZGFibGVNZW51Q29tcG9uZW50KSBleHBhbmRhYmxlTWVudUNvbXBvbmVudCE6IEV4cGFuZGFibGVNZW51Q29tcG9uZW50O1xyXG5cdEBWaWV3Q2hpbGQoU3RhdGljU2lkZWJhckNvbXBvbmVudCkgc3RhdGljU2lkZWJhckNvbXBvbmVudCE6IFN0YXRpY1NpZGViYXJDb21wb25lbnQ7XHJcblx0QFZpZXdDaGlsZChBcHBUb3BiYXJDb21wb25lbnQpIGFwcFRvcGJhciE6IEFwcFRvcGJhckNvbXBvbmVudDtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRwcml2YXRlIG1lbnVTZXJ2aWNlOiBBcHBNZW51U2VydmljZSxcclxuXHRcdHB1YmxpYyBsYXlvdXRTZXJ2aWNlOiBMYXlvdXRTZXJ2aWNlLFxyXG5cdFx0cHVibGljIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcblx0XHRwdWJsaWMgcm91dGVyOiBSb3V0ZXJcclxuXHQpIHtcclxuXHRcdHRoaXMub3ZlcmxheU1lbnVPcGVuU3Vic2NyaXB0aW9uID0gdGhpcy5sYXlvdXRTZXJ2aWNlLm92ZXJsYXlPcGVuJC5zdWJzY3JpYmUoKCkgPT4ge1xyXG5cdFx0XHRpZiAoIXRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyKSB7XHJcblx0XHRcdFx0dGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3RlbignZG9jdW1lbnQnLCAnY2xpY2snLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGlzT3V0c2lkZUNsaWNrZWQgPSAhKFxyXG5cdFx0XHRcdFx0XHR0aGlzLmFwcFRvcGJhci5tZW51QnV0dG9uLm5hdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShldmVudC50YXJnZXQpIHx8XHJcblx0XHRcdFx0XHRcdHRoaXMuYXBwVG9wYmFyLm1lbnVCdXR0b24ubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpIHx8XHJcblx0XHRcdFx0XHRcdCh0aGlzLmV4cGFuZGFibGVNZW51Q29tcG9uZW50ICYmIHRoaXMuaXNFbGVtZW50SW5zaWRlKGV2ZW50LnRhcmdldCwgJ2FwcC1leHBhbmRhYmxlLW1lbnUnKSkgfHxcclxuXHRcdFx0XHRcdFx0KHRoaXMuc3RhdGljU2lkZWJhckNvbXBvbmVudCAmJiB0aGlzLmlzRWxlbWVudEluc2lkZShldmVudC50YXJnZXQsICdhcHAtc3RhdGljLXNpZGViYXInKSlcclxuXHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHRpZiAoaXNPdXRzaWRlQ2xpY2tlZCkge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmhpZGVNZW51KCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICh0aGlzLmxheW91dFNlcnZpY2Uuc3RhdGUuc3RhdGljTWVudU1vYmlsZUFjdGl2ZSkge1xyXG5cdFx0XHRcdHRoaXMuYmxvY2tCb2R5U2Nyb2xsKCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHRoaXMucm91dGVyLmV2ZW50cy5waXBlKGZpbHRlcigoZXZlbnQpID0+IGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkpLnN1YnNjcmliZSgoKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5sYXlvdXRTZXJ2aWNlLm1mZUFwcEl0ZW1DbGlja2VkKCkpIHRoaXMuaGlkZU1lbnUoKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YmxvY2tCb2R5U2Nyb2xsKCk6IHZvaWQge1xyXG5cdFx0aWYgKGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0KSB7XHJcblx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnYmxvY2tlZC1zY3JvbGwnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NOYW1lICs9ICcgYmxvY2tlZC1zY3JvbGwnO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0dW5ibG9ja0JvZHlTY3JvbGwoKTogdm9pZCB7XHJcblx0XHRpZiAoZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QpIHtcclxuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdibG9ja2VkLXNjcm9sbCcpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc05hbWUgPSBkb2N1bWVudC5ib2R5LmNsYXNzTmFtZS5yZXBsYWNlKFxyXG5cdFx0XHRcdG5ldyBSZWdFeHAoJyhefFxcXFxiKScgKyAnYmxvY2tlZC1zY3JvbGwnLnNwbGl0KCcgJykuam9pbignfCcpICsgJyhcXFxcYnwkKScsICdnaScpLFxyXG5cdFx0XHRcdCcgJ1xyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gSGVscGVyIG1ldGhvZCB0byBjaGVjayBpZiBlbGVtZW50IGlzIGluc2lkZSBhIHNwZWNpZmljIGNvbXBvbmVudFxyXG5cdHByaXZhdGUgaXNFbGVtZW50SW5zaWRlKGVsZW1lbnQ6IGFueSwgc2VsZWN0b3I6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFlbGVtZW50KSByZXR1cm4gZmFsc2U7XHJcblx0XHRcclxuXHRcdGxldCBjdXJyZW50RWxlbWVudCA9IGVsZW1lbnQ7XHJcblx0XHR3aGlsZSAoY3VycmVudEVsZW1lbnQgJiYgY3VycmVudEVsZW1lbnQgIT09IGRvY3VtZW50KSB7XHJcblx0XHRcdGlmIChjdXJyZW50RWxlbWVudC50YWdOYW1lICYmIGN1cnJlbnRFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gc2VsZWN0b3IpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjdXJyZW50RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHRoaWRlTWVudSgpIHtcclxuXHRcdHRoaXMubGF5b3V0U2VydmljZS5zdGF0ZS5zdGF0aWNNZW51TW9iaWxlQWN0aXZlID0gZmFsc2U7XHJcblx0XHR0aGlzLm1lbnVTZXJ2aWNlLnJlc2V0KCk7XHJcblxyXG5cdFx0aWYgKHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyKSB7XHJcblx0XHRcdHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyKCk7XHJcblx0XHRcdHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIpIHtcclxuXHRcdFx0dGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIoKTtcclxuXHRcdFx0dGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIgPSBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMudW5ibG9ja0JvZHlTY3JvbGwoKTtcclxuXHR9XHJcblxyXG5cdGdldCBjb250YWluZXJDbGFzcygpIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdCdsYXlvdXQtbGlnaHQnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkuY29sb3JTY2hlbWUgPT09ICdsaWdodCcsXHJcblx0XHRcdCdsYXlvdXQtZGltJzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLmNvbG9yU2NoZW1lID09PSAnZGltJyxcclxuXHRcdFx0J2xheW91dC1kYXJrJzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLmNvbG9yU2NoZW1lID09PSAnZGFyaycsXHJcblx0XHRcdCdsYXlvdXQtY29sb3JzY2hlbWUtbWVudSc6IHRoaXMubGF5b3V0U2VydmljZS5jb25maWcoKS5tZW51VGhlbWUgPT09ICdjb2xvclNjaGVtZScsXHJcblx0XHRcdCdsYXlvdXQtcHJpbWFyeWNvbG9yLW1lbnUnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudVRoZW1lID09PSAncHJpbWFyeUNvbG9yJyxcclxuXHRcdFx0J2xheW91dC10cmFuc3BhcmVudC1tZW51JzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVUaGVtZSA9PT0gJ3RyYW5zcGFyZW50JyxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdzdGF0aWMnLFxyXG5cdFx0XHQnbGF5b3V0LWV4cGFuZGFibGUnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdleHBhbmRhYmxlJyxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMtaW5hY3RpdmUnOiBcclxuXHRcdFx0XHR0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdzdGF0aWMnICYmIFxyXG5cdFx0XHRcdCF0aGlzLmxheW91dFNlcnZpY2Uuc2hvdWxkU2hvd1N0YXRpY1NpZGViYXIoKSxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMtY29sbGFwc2VkJzogXHJcblx0XHRcdFx0dGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVNb2RlID09PSAnc3RhdGljJyAmJiBcclxuXHRcdFx0XHR0aGlzLmxheW91dFNlcnZpY2UuaXNTdGF0aWNTaWRlYmFyQ29sbGFwc2VkKCksXHJcblx0XHRcdCdsYXlvdXQtbW9iaWxlLWFjdGl2ZSc6IHRoaXMubGF5b3V0U2VydmljZS5zdGF0ZS5zdGF0aWNNZW51TW9iaWxlQWN0aXZlLFxyXG5cdFx0XHQncC1pbnB1dC1maWxsZWQnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkuaW5wdXRTdHlsZSA9PT0gJ2ZpbGxlZCcsXHJcblx0XHRcdCdwLXJpcHBsZS1kaXNhYmxlZCc6ICF0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkucmlwcGxlLFxyXG5cdFx0XHQnbmV3LXNpZGViYXItbGF5b3V0JzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVNb2RlID09PSAnZXhwYW5kYWJsZScsXHJcblx0XHRcdCdzZWNvbmRhcnktZXhwYW5kZWQnOiB0aGlzLmxheW91dFNlcnZpY2Uuc3RhdGUuc2Vjb25kYXJ5U2lkZWJhckV4cGFuZGVkXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0bmdPbkRlc3Ryb3koKSB7XHJcblx0XHRpZiAodGhpcy5vdmVybGF5TWVudU9wZW5TdWJzY3JpcHRpb24pIHtcclxuXHRcdFx0dGhpcy5vdmVybGF5TWVudU9wZW5TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIpIHtcclxuXHRcdFx0dGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIoKTtcclxuXHRcdH1cclxuXHR9XHJcbn0iLCI8ZGl2IGNsYXNzPVwibGF5b3V0LWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cImNvbnRhaW5lckNsYXNzXCI+XHJcblx0QGlmIChsYXlvdXRTZXJ2aWNlLnNob3VsZFNob3dTdGF0aWNTaWRlYmFyKCkpIHtcclxuXHRcdDxhcHAtc3RhdGljLXNpZGViYXIgLz5cclxuXHR9IEBlbHNlIGlmIChsYXlvdXRTZXJ2aWNlLnNob3VsZFNob3dFeHBhbmRhYmxlTWVudSgpKSB7XHJcblx0XHQ8YXBwLWV4cGFuZGFibGUtbWVudSAvPlxyXG5cdH1cclxuXHQ8ZGl2IGNsYXNzPVwibGF5b3V0LWNvbnRlbnQtd3JhcHBlclwiPlxyXG5cdFx0PGFwcC10b3BiYXIgLz5cclxuXHRcdDxkaXYgY2xhc3M9XCJsYXlvdXQtY29udGVudFwiPlxyXG5cdFx0XHQ8cm91dGVyLW91dGxldCAvPlxyXG5cdFx0PC9kaXY+XHJcblx0PC9kaXY+XHJcblx0PGFwcC1wcm9maWxlbWVudSAvPlxyXG5cdDxhcHAtaGlzdG9yeS1zaWRlYmFyIC8+XHJcblx0PGFwcC1zaXRlLW1hcC1zaWRlYmFyIC8+XHJcblx0PGFwcC1mYXZvcml0ZS1wYWdlcy1zaWRlYmFyIC8+XHJcblx0PGFwcC1ub3RpZmljYXRpb25zLXNpZGViYXIgLz5cclxuXHQ8IS0tPGFwcC1jb25maWc+PC9hcHAtY29uZmlnPi0tPlxyXG5cdDxkaXYgY2xhc3M9XCJsYXlvdXQtbWFza1wiIChjbGljayk9XCJoaWRlTWVudSgpXCI+PC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPHAtdG9hc3Qga2V5PVwidG9hc3Qtcm9vdFwiIC8+XHJcbjxwLWRpYWxvZyBrZXk9XCJkaWFsb2ctcm9vdFwiIC8+XHJcbjxwLW1lc3NhZ2VzIGtleT1cIm1lc3NhZ2VzLXJvb3RcIiAvPlxyXG48cC1jb25maXJtUG9wdXAga2V5PVwiY29uZmlybVBvcHVwLXJvb3RcIiAvPlxyXG48cC1jb25maXJtRGlhbG9nIGtleT1cImNvbmZpcm1EaWFsb2ctcm9vdFwiIC8+XHJcbiJdfQ==
559
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmxheW91dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hcmlsL3RoZW1lL2xheW91dC9hcHAvbGF5b3V0L2FwcC5sYXlvdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXJpbC90aGVtZS9sYXlvdXQvYXBwL2xheW91dC9hcHAubGF5b3V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFFTixTQUFTLEVBRVQsWUFBWSxFQUdaLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQVUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR2xGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFELE9BQU8sRUFBZSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEQsT0FBTyxFQUFFLGVB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QUNYLGtCQUFrQjt3QkFDbEIsMEJBQTBCO3dCQUMxQix1QkFBdUI7d0JBQ3ZCLHVCQUF1Qjt3QkFDdkIsNkJBQTZCO3dCQUM3Qix1QkFBdUI7d0JBQ3ZCLHNCQUFzQjt3QkFDdEIsNkJBQTZCO3dCQUM3QixjQUFjO3dCQUNkLGdCQUFnQjt3QkFDaEIsaUJBQWlCO3dCQUNqQixhQUFhO3dCQUNiLGVBQWU7d0JBQ2YsZ0JBQWdCO3FCQUNoQixhQUdVLENBQUMsaUJBQWlCLENBQUM7NExBT00sdUJBQXVCO3NCQUExRCxTQUFTO3VCQUFDLHVCQUF1QjtnQkFDQyxzQkFBc0I7c0JBQXhELFNBQVM7dUJBQUMsc0JBQXNCO2dCQUNGLFNBQVM7c0JBQXZDLFNBQVM7dUJBQUMsa0JBQWtCO2dCQUNrQixhQUFhO3NCQUEzRCxTQUFTO3VCQUFDLGVBQWUsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBQ2hCLGNBQWM7c0JBQTFDLFNBQVM7dUJBQUMsZ0JBQWdCO2dCQUNNLGtCQUFrQjtzQkFBbEQsU0FBUzt1QkFBQyxvQkFBb0I7Z0JBK1AvQixpQkFBaUI7c0JBRGhCLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtEcmFnRHJvcCwgRHJhZ0Ryb3BNb2R1bGUsIG1vdmVJdGVtSW5BcnJheSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9kcmFnLWRyb3AnO1xyXG5pbXBvcnQgeyBOZ0NsYXNzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtcclxuXHRBZnRlclZpZXdJbml0LFxyXG5cdENvbXBvbmVudCxcclxuXHRFbGVtZW50UmVmLFxyXG5cdEhvc3RMaXN0ZW5lcixcclxuXHRPbkRlc3Ryb3ksXHJcblx0UmVuZGVyZXIyLFxyXG5cdFZpZXdDaGlsZCxcclxuXHRjb21wdXRlZCxcclxuXHRlZmZlY3QsXHJcblx0aW5qZWN0LFxyXG5cdHNpZ25hbCxcclxuXHR1bnRyYWNrZWRcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTmF2aWdhdGlvbkVuZCwgUm91dGVyLCBSb3V0ZXJMaW5rLCBSb3V0ZXJPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5cclxuaW1wb3J0IHsgTWVudUl0ZW0gfSBmcm9tICdwcmltZW5nL2FwaSc7XHJcbmltcG9ydCB7IEJyZWFkY3J1bWJNb2R1bGUgfSBmcm9tICdwcmltZW5nL2JyZWFkY3J1bWInO1xyXG5pbXBvcnQgeyBDb25maXJtRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jb25maXJtZGlhbG9nJztcclxuaW1wb3J0IHsgQ29uZmlybVBvcHVwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jb25maXJtcG9wdXAnO1xyXG5pbXBvcnQgeyBDb250ZXh0TWVudSwgQ29udGV4dE1lbnVNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NvbnRleHRtZW51JztcclxuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xyXG5pbXBvcnQgeyBNZXNzYWdlc01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvbWVzc2FnZXMnO1xyXG5pbXBvcnQgeyBUb2FzdE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9hc3QnO1xyXG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcclxuXHJcbmltcG9ydCB7IFRyYW5zbG9jb01vZHVsZSwgVHJhbnNsb2NvU2VydmljZSB9IGZyb20gJ0BuZ25lYXQvdHJhbnNsb2NvJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCBmaWx0ZXIgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IGJyaWRnZSB9IGZyb20gJ2FyaWwvYm9vdC9icmlkZ2UnO1xyXG5pbXBvcnQgeyBOYXZJdGVtLCBOYXZMaW5rQ29udGV4dE1lbnVTZXJ2aWNlLCBOYXZMaW5rRGlyZWN0aXZlLCBOYXZTZXJ2aWNlLCBQbHVnaW5NZW51SXRlbSB9IGZyb20gJ2FyaWwvYm9vdC9jb25maWcvYXBwcyc7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZUpzb25QaXBlIH0gZnJvbSAnYXJpbC91dGlsL3BpcGVzJztcclxuXHJcbmltcG9ydCB7IExheW91dFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlL2FwcC5sYXlvdXQuc2VydmljZSc7XHJcbmltcG9ydCB7IEFwcE1lbnVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZS9hcHAubWVudS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVGFiU2Vzc2lvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlL3RhYi1zZXNzaW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBFeHBhbmRhYmxlTWVudUNvbXBvbmVudCB9IGZyb20gJy4uL2V4cGFuZGFibGVNZW51L2V4cGFuZGFibGUtbWVudS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBGYXZvcml0ZVBhZ2VzU2lkZWJhckNvbXBvbmVudCB9IGZyb20gJy4uL2Zhdm9yaXRlLXBhZ2VzL2Zhdm9yaXRlLXBhZ2VzLXNpZGViYXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgSGlzdG9yeVNpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9oaXN0b3J5L2hpc3Rvcnktc2lkZWJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25zU2lkZWJhckNvbXBvbmVudCB9IGZyb20gJy4uL25vdGlmaWNhdGlvbnMvbm90aWZpY2F0aW9ucy1zaWRlYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEFwcFByb2ZpbGVTaWRlYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vcHJvZmlsZVNpZGViYXIvYXBwLnByb2ZpbGVzaWRlYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFNpdGVNYXBTaWRlYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vc2l0ZS1tYXAvc2l0ZS1tYXAtc2lkZWJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBTdGF0aWNTaWRlYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vc3RhdGljLXNpZGViYXIvc3RhdGljLXNpZGViYXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgQXBwVG9wYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vdG9wYmFyL2FwcC50b3BiYXIuY29tcG9uZW50JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cdHN0YW5kYWxvbmU6IHRydWUsXHJcblx0c2VsZWN0b3I6ICdhcHAtbGF5b3V0JyxcclxuXHRpbXBvcnRzOiBbXHJcblx0XHROZ0NsYXNzLFxyXG5cdFx0Um91dGVyT3V0bGV0LFxyXG5cdFx0Um91dGVyTGluayxcclxuXHRcdENvbmZpcm1EaWFsb2dNb2R1bGUsXHJcblx0XHRDb25maXJtUG9wdXBNb2R1bGUsXHJcblx0XHREaWFsb2dNb2R1bGUsXHJcblx0XHRNZXNzYWdlc01vZHVsZSxcclxuXHRcdFRvYXN0TW9kdWxlLFxyXG5cdFx0QXBwVG9wYmFyQ29tcG9uZW50LFxyXG5cdFx0QXBwUHJvZmlsZVNpZGViYXJDb21wb25lbnQsXHJcblx0XHRIaXN0b3J5U2lkZWJhckNvbXBvbmVudCxcclxuXHRcdFNpdGVNYXBTaWRlYmFyQ29tcG9uZW50LFxyXG5cdFx0RmF2b3JpdGVQYWdlc1NpZGViYXJDb21wb25lbnQsXHJcblx0XHRFeHBhbmRhYmxlTWVudUNvbXBvbmVudCxcclxuXHRcdFN0YXRpY1NpZGViYXJDb21wb25lbnQsXHJcblx0XHROb3RpZmljYXRpb25zU2lkZWJhckNvbXBvbmVudCxcclxuXHRcdERyYWdEcm9wTW9kdWxlLFxyXG5cdFx0QnJlYWRjcnVtYk1vZHVsZSxcclxuXHRcdENvbnRleHRNZW51TW9kdWxlLFxyXG5cdFx0VG9vbHRpcE1vZHVsZSxcclxuXHRcdFRyYW5zbG9jb01vZHVsZSxcclxuXHRcdE5hdkxpbmtEaXJlY3RpdmVcclxuXHRdLFxyXG5cdHRlbXBsYXRlVXJsOiAnLi9hcHAubGF5b3V0LmNvbXBvbmVudC5odG1sJyxcclxuXHRzdHlsZVVybHM6IFsnLi9hcHAubGF5b3V0LmNvbXBvbmVudC5zY3NzJ10sXHJcblx0cHJvdmlkZXJzOiBbVHJhbnNsYXRlSnNvblBpcGVdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBcHBMYXlvdXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xyXG5cdG92ZXJsYXlNZW51T3BlblN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xyXG5cdG1lbnVPdXRzaWRlQ2xpY2tMaXN0ZW5lcjogYW55O1xyXG5cdG1lbnVTY3JvbGxMaXN0ZW5lcjogYW55O1xyXG5cclxuXHRAVmlld0NoaWxkKEV4cGFuZGFibGVNZW51Q29tcG9uZW50KSBleHBhbmRhYmxlTWVudUNvbXBvbmVudCE6IEV4cGFuZGFibGVNZW51Q29tcG9uZW50O1xyXG5cdEBWaWV3Q2hpbGQoU3RhdGljU2lkZWJhckNvbXBvbmVudCkgc3RhdGljU2lkZWJhckNvbXBvbmVudCE6IFN0YXRpY1NpZGViYXJDb21wb25lbnQ7XHJcblx0QFZpZXdDaGlsZChBcHBUb3BiYXJDb21wb25lbnQpIGFwcFRvcGJhciE6IEFwcFRvcGJhckNvbXBvbmVudDtcclxuXHRAVmlld0NoaWxkKCd0YWJzQ29udGFpbmVyJywgeyBzdGF0aWM6IGZhbHNlIH0pIHRhYnNDb250YWluZXI/OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuXHRAVmlld0NoaWxkKCd0YWJDb250ZXh0TWVudScpIHRhYkNvbnRleHRNZW51PzogQ29udGV4dE1lbnU7XHJcblx0QFZpZXdDaGlsZCgnbmF2TGlua0NvbnRleHRNZW51JykgbmF2TGlua0NvbnRleHRNZW51PzogQ29udGV4dE1lbnU7XHJcblx0bmF2U2VydmljZTogTmF2U2VydmljZSA9IGluamVjdChOYXZTZXJ2aWNlKTtcclxuXHRwcml2YXRlIHJlYWRvbmx5IHRyYW5zbG9jb1NlcnZpY2U6IFRyYW5zbG9jb1NlcnZpY2UgPSBpbmplY3QoVHJhbnNsb2NvU2VydmljZSk7XHJcblx0cHJpdmF0ZSByZWFkb25seSBuYXZMaW5rQ29udGV4dE1lbnVTZXJ2aWNlOiBOYXZMaW5rQ29udGV4dE1lbnVTZXJ2aWNlID0gaW5qZWN0KE5hdkxpbmtDb250ZXh0TWVudVNlcnZpY2UpO1xyXG5cdHByaXZhdGUgcmVhZG9ubHkgdGFiU2Vzc2lvbjogVGFiU2Vzc2lvblNlcnZpY2UgPSBpbmplY3QoVGFiU2Vzc2lvblNlcnZpY2UpO1xyXG5cclxuXHR0YWJDb250ZXh0TWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XHJcblx0LyoqIFRhYiBiYXIgeWF0YXkgc2Nyb2xsIGtvbnVtL2dlbmnFn2xpayBkdXJ1bXUuIENoZXZyb24gYnV0b25sYXLEsW7EsW4gZ8O2csO8bsO8cmzDvMSfw7xuw7wga29udHJvbCBlZGVyLiAqL1xyXG5cdGNhblNjcm9sbExlZnQgPSBzaWduYWwoZmFsc2UpO1xyXG5cdGNhblNjcm9sbFJpZ2h0ID0gc2lnbmFsKGZhbHNlKTtcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEJyZWFkY3J1bWIgc2VnbWVudGxlcmkg4oCUIGBicmlkZ2UuYnJlYWRjcnVtYnMoKWAgw7x6ZXJpbmRlbiBva3VudXIuXHJcblx0ICogU291cmNlLW9mLXRydXRoIGFrdGlmIE1GRSdkZSDDp2FsxLHFn2FuIGBCcmVhZGNydW1iUHVibGlzaGVyU2VydmljZWAndGlyO1xyXG5cdCAqIE1GRSBoZXIgTmF2aWdhdGlvbkVuZCdkZSBrZW5kaSByb3V0ZSBhxJ9hY8SxbmRhbiB6aW5jaXJpIMOnxLFrYXLEsXAgYnJpZGdlJ2UgeWF6YXIuXHJcblx0ICogU2hlbGwgeWFsbsSxemNhIHByZXNlbnRlciDigJQgYmHFn2EgXCJBbmFzYXlmYVwiIGl0ZW0nxLEgZWtsZXlpcCBzb24gaXRlbSfEsSBha3RpZiBpxZ9hcmV0bGVyLlxyXG5cdCAqL1xyXG5cdGJyZWFkY3J1bWJJdGVtcyA9IGNvbXB1dGVkPChNZW51SXRlbSAmIHsgYWN0aXZlPzogYm9vbGVhbjsgaXNIb21lPzogYm9vbGVhbiB9KVtdPigoKSA9PiB7XHJcblx0XHRjb25zdCBjcnVtYnMgPSBicmlkZ2UuYnJlYWRjcnVtYnMoKTtcclxuXHRcdGNvbnN0IGhvbWVJdGVtOiBNZW51SXRlbSAmIHsgaXNIb21lOiBib29sZWFuIH0gPSB7XHJcblx0XHRcdGljb246ICdwaSBwaS1ob21lJyxcclxuXHRcdFx0aXNIb21lOiB0cnVlXHJcblx0XHR9O1xyXG5cdFx0aWYgKCFjcnVtYnMubGVuZ3RoKSB7XHJcblx0XHRcdHJldHVybiBbaG9tZUl0ZW1dO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIFtcclxuXHRcdFx0aG9tZUl0ZW0sXHJcblx0XHRcdC4uLmNydW1icy5tYXAoKGMsIGlkeCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGlzTGFzdCA9IGlkeCA9PT0gY3J1bWJzLmxlbmd0aCAtIDE7XHJcblx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdGxhYmVsOiBjLmxhYmVsLFxyXG5cdFx0XHRcdFx0Ly8gQWt0aWYgKHNvbikgaXRlbSdkYSB1cmwgdmVybWUg4oCUIFByaW1lTkcgZMSxxZ8gYC5wLW1lbnVpdGVtLWxpbmtgJ2UgaHJlZiBla2xlbWVzaW4sXHJcblx0XHRcdFx0XHQvLyBrdWxsYW7EsWPEsSB6YXRlbiBvIHNheWZhZGEsIHRla3JhciB0xLFrbGFubWFzxLFuxLFuIGFubGFtxLEgeW9rLlxyXG5cdFx0XHRcdFx0dXJsOiBpc0xhc3QgPyB1bmRlZmluZWQgOiBjLnVybCxcclxuXHRcdFx0XHRcdGFjdGl2ZTogaXNMYXN0XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fSlcclxuXHRcdF07XHJcblx0fSk7XHJcblxyXG5cdC8qKlxyXG5cdCAqIEFrdGlmIG9sbWF5YW4gYnJlYWRjcnVtYiBzZWdtZW50aW5lIHTEsWtsYW1hIOKGkiBtZXZjdXQgdGFiJ8SxIHBhcmVudCByb3V0ZSBpbGUgZ8O8bmNlbGxlci5cclxuXHQgKiBgPGEgW3JvdXRlckxpbmtdPmAgZGlyZWN0aXZlJ2kgYGhyZWZgJ2kgUm91dGVyJ8SxbiBsb2NhdGlvbiBzdHJhdGVneSdzaW5lIGfDtnJlXHJcblx0ICogKGhhc2gvcGF0aCkgZG/En3J1IGZvcm1hdGxhciDigJQgc2HEnyB0xLFrIFwibGlua2kga29weWFsYVwiIGRhdnJhbsSxxZ/EsSDDp2FsxLHFn8Sxci5cclxuXHQgKiBEZWZhdWx0IFJvdXRlciBuYXZpZ2F0ZSdpbmkgYHByZXZlbnREZWZhdWx0KClgIGlsZSBkdXJkdXJ1cCBgbmF2aWdhdGVJbkN1cnJlbnRUYWJgXHJcblx0ICogw7x6ZXJpbmRlbiBpbGVybGV0aXlvcnV6OyBiw7Z5bGVjZSB5ZW5pIHNla21lIGHDp8SxbG1hei5cclxuXHQgKi9cclxuXHRvbkJyZWFkY3J1bWJDbGljayhldmVudDogTW91c2VFdmVudCwgaXRlbTogeyBsYWJlbD86IHN0cmluZzsgdXJsPzogc3RyaW5nIH0pOiB2b2lkIHtcclxuXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRpZiAoIWl0ZW0udXJsKSByZXR1cm47XHJcblx0XHRjb25zdCBuYXZMaW5rID0gaXRlbS51cmwuc3RhcnRzV2l0aCgnLycpID8gaXRlbS51cmwuc2xpY2UoMSkgOiBpdGVtLnVybDtcclxuXHRcdHRoaXMubmF2U2VydmljZS5uYXZpZ2F0ZUluQ3VycmVudFRhYih7XHJcblx0XHRcdHRhYklkOiAnJyxcclxuXHRcdFx0bmF2TGluayxcclxuXHRcdFx0bmF2TmFtZTogaXRlbS5sYWJlbCA/PyAnJ1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBIb21lIGljb24g4oaSIHJvb3QgbWVudSBpdGVtIChgYXBwcy5zZXJ2aWNlLnRzOjUxYCdkZSB0YW7EsW1sxLEgYHsgcm9vdDogdHJ1ZSwgcm91dGVyTGluazogJy8nIH1gKS5cclxuXHQgKiBUZWsgc291cmNlLW9mLXRydXRoIOKAlCBldGlrZXQgw6dldmlyaXNpIGBUcmFuc2xhdGVKc29uUGlwZWAgaWxlIGFrdGlmIGRpbGRlbiBva3VudXIuXHJcblx0ICogTWV2Y3V0IHRhYiBnw7xuY2VsbGVuaXIsIHllbmkgc2VrbWUgYcOnxLFsbWF6LlxyXG5cdCAqL1xyXG5cdG9uSG9tZUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0dGhpcy5uYXZTZXJ2aWNlLm5hdmlnYXRlSW5DdXJyZW50VGFiKHRoaXMuaG9tZU5hdkl0ZW0oKSk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBBbmFzYXlmYSBpw6dpbiBOYXZJdGVtIOKAlCBicmVhZGNydW1iIGhvbWUgaWtvbnVudW4gaGVtIGAoY2xpY2spYCBoYW5kbGVyJ8SxIGhlbVxyXG5cdCAqIGBbYXJpbE5hdkxpbmtdYCBjb250ZXh0IG1lbnUgZGlyZWN0aXZlJ2kgdGFyYWbEsW5kYW4gcGF5bGHFn8SxbMSxci5cclxuXHQgKi9cclxuXHRyZWFkb25seSBob21lTmF2SXRlbSA9IGNvbXB1dGVkPE5hdkl0ZW0+KCgpID0+IHtcclxuXHRcdC8vIE5hdlNlcnZpY2UgaWxlIEFZTkkgbWVuw7wga2F5bmHEn8SxIChgYnJpZGdlLmhvc3RNZW51SXRlbXNgKSDigJQgYG1lbnVTZXJ2aWNlLm1lbnVJdGVtcygpYFxyXG5cdFx0Ly8gaG9zdCBgcm9vdGAgw7bEn2VzaW5pIGnDp2VybWl5b3IgKGZhcmtsxLEvYm/FnyBrYXluYWspOyBgc2V0TWVudUl0ZW1zUHJvdmlkZXJgIGRlIGJyaWRnZSdpIGt1bGxhbsSxeW9yLlxyXG5cdFx0Y29uc3QgaXRlbXMgPSBicmlkZ2UuaG9zdE1lbnVJdGVtcygpO1xyXG5cdFx0Y29uc3Qgcm9vdEl0ZW0gPSBpdGVtcy5maW5kKChpOiBQbHVnaW5NZW51SXRlbSkgPT4gaS5yb290KTtcclxuXHRcdC8vIFBpcGUgcnVudGltZSdkYSBvYmplY3Qga2FidWwgZWRpeW9yICh0cmFuc2xhdGUtanNvbi5waXBlLnRzOjE4KSBhbWEgdGlwIGltemFzxLEgYHN0cmluZ2Ag4oCUXHJcblx0XHQvLyBzdGF0aWMtc2lkZWJhcifEsW4gYGdldExvY2FsVGV4dChhbnkpYCBwYXR0ZXJuJ2l5bGUgYXluxLEgxZ9la2lsZGUgY2FzdC5cclxuXHRcdGNvbnN0IG5hdk5hbWUgPSByb290SXRlbSA/IHRoaXMudHJhbnNsYXRlSnNvblBpcGUudHJhbnNmb3JtKHJvb3RJdGVtLmxhYmVsIGFzIGFueSkgOiAnJztcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRhYklkOiAnJyxcclxuXHRcdFx0bmF2TGluazogcm9vdEl0ZW0/LnJvdXRlckxpbmsgfHwgJy8nLFxyXG5cdFx0XHRuYXZOYW1lLFxyXG5cdFx0XHRpY29uOiByb290SXRlbT8uaWNvblxyXG5cdFx0fTtcclxuXHR9KTtcclxuXHJcblx0LyoqXHJcblx0ICogVGFiIGljb24gcmVzb2x1dGlvbiBzxLFyYXPEsTpcclxuXHQgKiAgIDEuIE5hdkl0ZW0uaWNvbiAoc2lkZWJhciBjbGljaydpbmRlbiBpbGV0aWxtacWfc2Ug4oCUIGVuIGRvxJ9ydSlcclxuXHQgKiAgIDIuIE1lbnUgY29uZmlnJ2luZGUgbmF2TGluaydpIGVuIHV6dW4gcHJlZml4IG9sYXJhayBtYXRjaCBlZGVuIGl0ZW0uaWNvblxyXG5cdCAqICAgMy4gR2VuZXJpYyBmYWxsYmFjayAoYHBpIHBpLWZpbGVgKVxyXG5cdCAqXHJcblx0ICogQmVzdC1tYXRjaCBpw6dpbiBsb25nZXN0LXByZWZpeCBrdWxsYW7EsWzEsXI6IGB3ZG0vbWV0ZXJzLzEyM2AgacOnaW4gaGVtIGB3ZG1gIGhlbVxyXG5cdCAqIGB3ZG0vbWV0ZXJzYCBtYXRjaCdsZXJzZSwgZGFoYSBzcGVzaWZpayBgd2RtL21ldGVyc2Aga2F6YW7EsXIuIELDtnlsZWNlIGRlZXAgbGlua1xyXG5cdCAqIHJlZnJlc2gnaW5kZSAoTmF2U2VydmljZS5maXJzdENoZWNrRm9yUm91dGUgcGF0aCdpbmRlIGljb24gc2V0IGVkaWxlbWVkacSfaSB6YW1hbilcclxuXHQgKiBkb8SfcnUgcmVtb3RlL3NlY3Rpb24gaWtvbnUgb3RvbWF0aWsgYnVsdW51ci5cclxuXHQgKi9cclxuXHRnZXRUYWJJY29uKGl0ZW06IE5hdkl0ZW0pOiBzdHJpbmcge1xyXG5cdFx0aWYgKGl0ZW0uaWNvbikgcmV0dXJuIGl0ZW0uaWNvbjtcclxuXHRcdGlmICghaXRlbS5uYXZMaW5rKSByZXR1cm4gJ3BpIHBpLWZpbGUnO1xyXG5cdFx0Ly8gYGJyaWRnZS5ob3N0TWVudUl0ZW1zKClgIOKAlCBob21lTmF2SXRlbS9OYXZTZXJ2aWNlIGlsZSBheW7EsSBtZW7DvCBrYXluYcSfxLEuIGBtZW51U2VydmljZWBcclxuXHRcdC8vIGhvc3QgYHJvb3RgL01GRSBtZW7DvHPDvG7DvCBpw6dlcm1lZGnEn2kgacOnaW4gKGJvxZ8ga2F5bmFrKSBidXJhZGFraSBpa29uIGXFn2xlxZ9tZXNpIGRlIG9yYWRhbi5cclxuXHRcdHJldHVybiB0aGlzLmZpbmRJY29uRm9yUm91dGUoYnJpZGdlLmhvc3RNZW51SXRlbXMoKSwgaXRlbS5uYXZMaW5rKSA/PyAncGkgcGktZmlsZSc7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGZpbmRJY29uRm9yUm91dGUoaXRlbXM6IFBsdWdpbk1lbnVJdGVtW10sIG5hdkxpbms6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcblx0XHQvLyBQYXRoIGxlYWRpbmcgc2xhc2ggacOnZXJlYmlsaXIgKFJvdXRlciBVUkwpLCBtZW51IGNvbmZpZyByb3V0ZXJMaW5rJ2xlcmkgZ2VuZWxkZVxyXG5cdFx0Ly8gbGVhZGluZyBzbGFzaCdzxLF6IOKAlCBpa2lzaW5pIG5vcm1hbGl6ZSBlZGlwIGthcsWfxLFsYcWfdMSxci5cclxuXHRcdGNvbnN0IG5vcm1hbGl6ZSA9IChwOiBzdHJpbmcpOiBzdHJpbmcgPT4gKHAuc3RhcnRzV2l0aCgnLycpID8gcC5zbGljZSgxKSA6IHApO1xyXG5cdFx0Y29uc3Qgbm9ybWFsaXplZFBhdGggPSBub3JtYWxpemUobmF2TGluayk7XHJcblx0XHRsZXQgYmVzdDogeyBsZW5ndGg6IG51bWJlcjsgaWNvbjogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XHJcblx0XHRjb25zdCB2aXNpdCA9IChsaXN0OiBQbHVnaW5NZW51SXRlbVtdKTogdm9pZCA9PiB7XHJcblx0XHRcdGZvciAoY29uc3QgaXQgb2YgbGlzdCkge1xyXG5cdFx0XHRcdGlmIChpdC5yb3V0ZXJMaW5rICYmIGl0Lmljb24pIHtcclxuXHRcdFx0XHRcdGNvbnN0IHIgPSBub3JtYWxpemUoaXQucm91dGVyTGluayk7XHJcblx0XHRcdFx0XHRpZiAociAmJiAobm9ybWFsaXplZFBhdGggPT09IHIgfHwgbm9ybWFsaXplZFBhdGguc3RhcnRzV2l0aChyICsgJy8nKSkpIHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgbGVuZ3RoID0gci5sZW5ndGg7XHJcblx0XHRcdFx0XHRcdGlmICghYmVzdCB8fCBsZW5ndGggPiBiZXN0Lmxlbmd0aCkgYmVzdCA9IHsgbGVuZ3RoLCBpY29uOiBpdC5pY29uIH07XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmIChpdC5pdGVtcz8ubGVuZ3RoKSB2aXNpdChpdC5pdGVtcyk7XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblx0XHR2aXNpdChpdGVtcyk7XHJcblx0XHRyZXR1cm4gYmVzdD8uaWNvbjtcclxuXHR9XHJcblxyXG5cdGRyb3AoZXZlbnQ6IENka0RyYWdEcm9wPGFueVtdPikge1xyXG5cdFx0Y29uc3QgY3VycmVudFJvdXRlcyA9IFsuLi50aGlzLm5hdlNlcnZpY2UuYWN0aXZlUm91dGVzKCldO1xyXG5cdFx0bW92ZUl0ZW1JbkFycmF5KGN1cnJlbnRSb3V0ZXMsIGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XHJcblx0XHR0aGlzLm5hdlNlcnZpY2UucmVvcmRlckFjdGl2ZVJvdXRlcyhjdXJyZW50Um91dGVzKTtcclxuXHR9XHJcblxyXG5cdGlzQWN0aXZlKGl0ZW06IE5hdkl0ZW0pOiBib29sZWFuIHtcclxuXHRcdC8vIEF5bsSxIGBuYXZMaW5rYCdpbiBiaXJkZW4gZmF6bGEgdGFiJ2kgb2xhYmlsZWNlxJ9pIGnDp2luIHRhYklkIHRlayBkb8SfcnUga2ltbGlrLlxyXG5cdFx0Ly8gYGFjdGl2ZVRhYklkYCBoaXN0b3J5LnN0YXRlIMO8emVyaW5kZW4gTmF2U2VydmljZSB0YXJhZsSxbmRhbiBzZW5rcm9uaXplIGVkaWxpci5cclxuXHRcdHJldHVybiB0aGlzLm5hdlNlcnZpY2UuYWN0aXZlVGFiSWQoKSA9PT0gaXRlbS50YWJJZDtcclxuXHR9XHJcblxyXG5cdGNsb3NlVGFiKGV2ZW50OiBFdmVudCwgaXRlbTogTmF2SXRlbSkge1xyXG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0XHRpZiAoaXRlbS5waW5uZWQpIHJldHVybjtcclxuXHRcdHRoaXMubmF2U2VydmljZS5jbG9zZU5hdmlnYXRpb24oaXRlbSk7XHJcblx0fVxyXG5cclxuXHQvKiogVGFiIHNvbC1jbGljayDihpIgbyB0YWInYSBnZcOnLiBOYXZTZXJ2aWNlIFJvdXRlcidhIGA/X3RhYmAgVVJMJ2kgdmUgaGlzdG9yeSBzdGF0ZSdpIHZlcmlyLiAqL1xyXG5cdG9uVGFiQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGl0ZW06IE5hdkl0ZW0pOiB2b2lkIHtcclxuXHRcdGlmIChldmVudC5idXR0b24gIT09IDApIHJldHVybjsgLy8gc2FkZWNlIHNvbCB0xLFrXHJcblx0XHR0aGlzLm5hdlNlcnZpY2UubmF2aWdhdGVUb1RhYihpdGVtKTtcclxuXHR9XHJcblxyXG5cdC8qKiBNaWRkbGUgY2xpY2sgKGJ1dHRvbiAxKSDihpIgdGFiIGthcGF0IChDaHJvbWUgc3RhbmRhcmTEsSkuIFNhYml0IHRhYidsYXIga2FwYXTEsWxtYXouICovXHJcblx0b25UYWJBdXhDbGljayhldmVudDogTW91c2VFdmVudCwgaXRlbTogTmF2SXRlbSk6IHZvaWQge1xyXG5cdFx0aWYgKGV2ZW50LmJ1dHRvbiAhPT0gMSkgcmV0dXJuO1xyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdGlmIChpdGVtLnBpbm5lZCkgcmV0dXJuO1xyXG5cdFx0dGhpcy5uYXZTZXJ2aWNlLmNsb3NlTmF2aWdhdGlvbihpdGVtKTtcclxuXHR9XHJcblxyXG5cdC8qKiBNaWRkbGUgY2xpY2sgZGVmYXVsdCBzY3JvbGwgZGF2cmFuxLHFn8SxbsSxIGVuZ2VsbGUuICovXHJcblx0b25UYWJNb3VzZWRvd24oZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuXHRcdGlmIChldmVudC5idXR0b24gPT09IDEpIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBUYWIgcmlnaHQtY2xpY2sg4oaSIGNvbnRleHQgbWVudS4gU2FiaXQgdGFiJ2xhcmRhIFwiS2FwYXRcIiBkaXNhYmxlZDsgcGluL3VucGluIGl0ZW0nxLFcclxuXHQgKiBDaHJvbWUnZGFraSBnaWJpIGVuIMO8c3R0ZSB5ZXIgYWzEsXIuIGBjbG9zZU90aGVyc2AvYGNsb3NlVG9SaWdodGAvYGNsb3NlQWxsYCB6YXRlblxyXG5cdCAqIE5hdlNlcnZpY2Ugc2V2aXllc2luZGUgcGlubmVkJ2kga29ydXlvciDigJQgVUknZGEgZWtzdHJhIGRpc2FibGVkIGdlcmVrbWV6LlxyXG5cdCAqL1xyXG5cdG9uVGFiQ29udGV4dE1lbnUoZXZlbnQ6IE1vdXNlRXZlbnQsIGl0ZW06IE5hdkl0ZW0pOiB2b2lkIHtcclxuXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRjb25zdCB0ID0gKGtleTogc3RyaW5nKTogc3RyaW5nID0+IHRoaXMudHJhbnNsb2NvU2VydmljZS50cmFuc2xhdGUoa2V5KTtcclxuXHRcdGNvbnN0IHBpbkxhYmVsID0gaXRlbS5waW5uZWQgPyB0KCd0YWIudW5waW4nKSA6IHQoJ3RhYi5waW4nKTtcclxuXHRcdHRoaXMudGFiQ29udGV4dE1lbnVJdGVtcyA9IFtcclxuXHRcdFx0eyBsYWJlbDogcGluTGFiZWwsIGljb246ICdwaSBwaS10aHVtYnRhY2snLCBjb21tYW5kOiAoKSA9PiB0aGlzLm5hdlNlcnZpY2UudG9nZ2xlUGluKGl0ZW0pIH0sXHJcblx0XHRcdHsgbGFiZWw6IHQoJ3RhYi5kdXBsaWNhdGUnKSwgaWNvbjogJ3BpIHBpLWNsb25lJywgY29tbWFuZDogKCkgPT4gdGhpcy5uYXZTZXJ2aWNlLmR1cGxpY2F0ZVRhYihpdGVtKSB9LFxyXG5cdFx0XHR7IHNlcGFyYXRvcjogdHJ1ZSB9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bGFiZWw6IHQoJ3RhYi5jbG9zZScpLFxyXG5cdFx0XHRcdGljb246ICdwaSBwaS10aW1lcycsXHJcblx0XHRcdFx0Y29tbWFuZDogKCkgPT4gdGhpcy5uYXZTZXJ2aWNlLmNsb3NlTmF2aWdhdGlvbihpdGVtKSxcclxuXHRcdFx0XHRkaXNhYmxlZDogISFpdGVtLnBpbm5lZFxyXG5cdFx0XHR9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bGFiZWw6IHQoJ3RhYi5jbG9zZU90aGVycycpLFxyXG5cdFx0XHRcdGljb246ICdwaSBwaS10aW1lcy1jaXJjbGUnLFxyXG5cdFx0XHRcdGNvbW1hbmQ6ICgpID0+IHRoaXMubmF2U2VydmljZS5jbG9zZU90aGVycyhpdGVtKSxcclxuXHRcdFx0XHRkaXNhYmxlZDogdGhpcy5uYXZTZXJ2aWNlLmFjdGl2ZVJvdXRlcygpLmZpbHRlcigocikgPT4gIXIucGlubmVkICYmIHIudGFiSWQgIT09IGl0ZW0udGFiSWQpLmxlbmd0aCA9PT0gMFxyXG5cdFx0XHR9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bGFiZWw6IHQoJ3RhYi5jbG9zZVRvUmlnaHQnKSxcclxuXHRcdFx0XHRpY29uOiAncGkgcGktYW5nbGUtZG91YmxlLXJpZ2h0JyxcclxuXHRcdFx0XHRjb21tYW5kOiAoKSA9PiB0aGlzLm5hdlNlcnZpY2UuY2xvc2VUb1JpZ2h0KGl0ZW0pLFxyXG5cdFx0XHRcdGRpc2FibGVkOiB0aGlzLmlzTGFzdFRhYihpdGVtKVxyXG5cdFx0XHR9LFxyXG5cdFx0XHR7IHNlcGFyYXRvcjogdHJ1ZSB9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bGFiZWw6IHQoJ3RhYi5jbG9zZUFsbCcpLFxyXG5cdFx0XHRcdGljb246ICdwaSBwaS10cmFzaCcsXHJcblx0XHRcdFx0Y29tbWFuZDogKCkgPT4gdGhpcy5uYXZTZXJ2aWNlLmNsb3NlQWxsKCksXHJcblx0XHRcdFx0ZGlzYWJsZWQ6IHRoaXMubmF2U2VydmljZS5hY3RpdmVSb3V0ZXMoKS5ldmVyeSgocikgPT4gci5waW5uZWQpXHJcblx0XHRcdH1cclxuXHRcdF07XHJcblx0XHR0aGlzLnRhYkNvbnRleHRNZW51Py5zaG93KGV2ZW50KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgaXNMYXN0VGFiKGl0ZW06IE5hdkl0ZW0pOiBib29sZWFuIHtcclxuXHRcdGNvbnN0IHJvdXRlcyA9IHRoaXMubmF2U2VydmljZS5hY3RpdmVSb3V0ZXMoKTtcclxuXHRcdC8vIGB0YWJJZGAgaWxlIGthcsWfxLFsYcWfdMSxciDigJQgYXluxLEgbmF2TGluaydpbiBiaXJkZW4gZmF6bGEgdGFiJ2kgb2xhYmlsZWNlxJ9pIGnDp2luXHJcblx0XHQvLyBgbmF2TGlua2AgYW1iaWd1b3VzIG9sdXIsIGtpbWxpayBiYXpsxLEgYXJhbWEgdGVrIGRvxJ9ydSB5w7ZudGVtLlxyXG5cdFx0cmV0dXJuIHJvdXRlc1tyb3V0ZXMubGVuZ3RoIC0gMV0/LnRhYklkID09PSBpdGVtLnRhYklkO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogVGVrIGthbGFuIHRhYiBhbmFzYXlmYXlzYSB0cnVlIOKGkiBrYXBhdG1hICjinJUpIGJ1dG9udSBnaXpsZW5pciAoTmF2U2VydmljZSBkZSBrYXBhdG1hecSxXHJcblx0ICogcmVkZGVkZXIpLiBcIkhlciB6YW1hbiBlbiBheiAxIHRhYiBhw6fEsWtcIiBrdXJhbMSxbsSxbiBVSSB0YXJhZsSxLlxyXG5cdCAqL1xyXG5cdGlzTGFzdEhvbWVUYWIoaXRlbTogTmF2SXRlbSk6IGJvb2xlYW4ge1xyXG5cdFx0Y29uc3Qgcm91dGVzID0gdGhpcy5uYXZTZXJ2aWNlLmFjdGl2ZVJvdXRlcygpO1xyXG5cdFx0cmV0dXJuIHJvdXRlcy5sZW5ndGggPT09IDEgJiYgaXRlbS5uYXZMaW5rID09PSAodGhpcy5ob21lTmF2SXRlbSgpLm5hdkxpbmsgfHwgJy8nKTtcclxuXHR9XHJcblxyXG5cdC8qKiBcIitcIiBidXRvbnUg4oaSIGFuYSBzYXlmYXlhIG5hdmlnYXRlICh5ZW5pIHRhYiB2YXJzYSBvbnUgYcOnLCB5b2tzYSBla2xlbmlyKS4gKi9cclxuXHRvbkFkZFRhYigpOiB2b2lkIHtcclxuXHRcdHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwoJycpO1xyXG5cdH1cclxuXHJcblx0c2Nyb2xsVGFic0xlZnQoKTogdm9pZCB7XHJcblx0XHR0aGlzLnRhYnNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsQnkoeyBsZWZ0OiAtMjAwLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XHJcblx0fVxyXG5cclxuXHRzY3JvbGxUYWJzUmlnaHQoKTogdm9pZCB7XHJcblx0XHR0aGlzLnRhYnNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsQnkoeyBsZWZ0OiAyMDAsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgdXBkYXRlU2Nyb2xsU3RhdGUoKTogdm9pZCB7XHJcblx0XHRjb25zdCBlbCA9IHRoaXMudGFic0NvbnRhaW5lcj8ubmF0aXZlRWxlbWVudDtcclxuXHRcdGlmICghZWwpIHJldHVybjtcclxuXHRcdHRoaXMuY2FuU2Nyb2xsTGVmdC5zZXQoZWwuc2Nyb2xsTGVmdCA+IDApO1xyXG5cdFx0dGhpcy5jYW5TY3JvbGxSaWdodC5zZXQoZWwuc2Nyb2xsTGVmdCArIGVsLmNsaWVudFdpZHRoIDwgZWwuc2Nyb2xsV2lkdGggLSAxKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEtsYXZ5ZSBrxLFzYXlvbGxhcsSxIChDaHJvbWUgcGFyaXRlc2kpOlxyXG5cdCAqIC0gYEFsdCtXYCDihpIgYWt0aWYgdGFiIGthcGF0IChDdHJsK1cgYnJvd3Nlci1yZXNlcnZlZClcclxuXHQgKiAtIGBDdHJsK1RhYmAgLyBgQ3RybCtTaGlmdCtUYWJgIOKGkiBzb25yYWtpL8O2bmNla2kgdGFiIChkZW5lbWVsaSDigJQgYmF6xLEgdGFyYXnEsWPEsWxhciBvdmVycmlkZSBldG1leilcclxuXHQgKiAtIGBDdHJsK1BhZ2VEb3duYCAvIGBDdHJsK1BhZ2VVcGAg4oaSIHNvbnJha2kvw7ZuY2VraSB0YWIgKHllZGVrKVxyXG5cdCAqIC0gYEFsdCsxLi45YCDihpIgaWxnaWxpIGluZGV4J3Rla2kgdGFiIChDdHJsKzEuLjkgYnJvd3Nlci1yZXNlcnZlZClcclxuXHQgKiAtIGBDdHJsK1NoaWZ0K1RgIHZleWEgYEFsdCtTaGlmdCtUYCDihpIgc29uIGthcGF0xLFsYW4gdGFiJ8SxIGdlcmkgYcOnXHJcblx0ICovXHJcblx0QEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bicsIFsnJGV2ZW50J10pXHJcblx0b25Eb2N1bWVudEtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmlzVHlwaW5nSW5JbnB1dChldmVudCkpIHJldHVybjtcclxuXHRcdGNvbnN0IGtleSA9IGV2ZW50LmtleTtcclxuXHRcdGNvbnN0IGxvd2VyID0ga2V5LnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdFx0aWYgKGV2ZW50LmFsdEtleSAmJiAhZXZlbnQuc2hpZnRLZXkgJiYgIWV2ZW50LmN0cmxLZXkgJiYgbG93ZXIgPT09ICd3Jykge1xyXG5cdFx0XHRjb25zdCBjdXJyZW50ID0gdGhpcy5uYXZTZXJ2aWNlLmFjdGl2ZVJvdXRlKCk7XHJcblx0XHRcdGNvbnN0IGl0ZW0gPSBjdXJyZW50ID8gdGhpcy5uYXZTZXJ2aWNlLmFjdGl2ZVJvdXRlcygpLmZpbmQoKHIpID0+IHIubmF2TGluayA9PT0gY3VycmVudCkgOiB1bmRlZmluZWQ7XHJcblx0XHRcdGlmIChpdGVtKSB7XHJcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHR0aGlzLm5hdlNlcnZpY2UuY2xvc2VOYXZpZ2F0aW9uKGl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoZXZlbnQuY3RybEtleSAmJiAoa2V5ID09PSAnVGFiJyB8fCBrZXkgPT09ICdQYWdlRG93bicgfHwga2V5ID09PSAnUGFnZVVwJykpIHtcclxuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0aWYgKGtleSA9PT0gJ1BhZ2VVcCcgfHwgKGtleSA9PT0gJ1RhYicgJiYgZXZlbnQuc2hpZnRLZXkpKSB7XHJcblx0XHRcdFx0dGhpcy5uYXZTZXJ2aWNlLmdvVG9QcmV2VGFiKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGhpcy5uYXZTZXJ2aWNlLmdvVG9OZXh0VGFiKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChldmVudC5hbHRLZXkgJiYgIWV2ZW50LmN0cmxLZXkgJiYgIWV2ZW50LnNoaWZ0S2V5ICYmIC9eWzEtOV0kLy50ZXN0KGtleSkpIHtcclxuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0dGhpcy5uYXZTZXJ2aWNlLmdvVG9UYWJCeUluZGV4KHBhcnNlSW50KGtleSwgMTApIC0gMSk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHByaXZhdGUgaXNUeXBpbmdJbklucHV0KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XHJcblx0XHRjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xyXG5cdFx0aWYgKCF0YXJnZXQpIHJldHVybiBmYWxzZTtcclxuXHRcdGNvbnN0IHRhZyA9IHRhcmdldC50YWdOYW1lPy50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0cmV0dXJuIHRhZyA9PT0gJ2lucHV0JyB8fCB0YWcgPT09ICd0ZXh0YXJlYScgfHwgdGFnID09PSAnc2VsZWN0JyB8fCAhIXRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZTtcclxuXHR9XHJcblxyXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuXHRcdHRoaXMudXBkYXRlU2Nyb2xsU3RhdGUoKTtcclxuXHRcdGNvbnN0IGVsID0gdGhpcy50YWJzQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xyXG5cdFx0aWYgKGVsKSB7XHJcblx0XHRcdGVsLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsICgpID0+IHRoaXMudXBkYXRlU2Nyb2xsU3RhdGUoKSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xyXG5cdFx0XHRpZiAodHlwZW9mIFJlc2l6ZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xyXG5cdFx0XHRcdGNvbnN0IHJvID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHRoaXMudXBkYXRlU2Nyb2xsU3RhdGUoKSk7XHJcblx0XHRcdFx0cm8ub2JzZXJ2ZShlbCk7XHJcblx0XHRcdFx0dGhpcy5yZXNpemVPYnNlcnZlciA9IHJvO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHQvLyBHbG9iYWwgbmF2LWxpbmsgY29udGV4dCBtZW51J3l1IHNlcnZpY2UnZSB0YW7EsXQg4oCUIHTDvG0gYFthcmlsTmF2TGlua11gIGRpcmVjdGl2ZSdsZXJpXHJcblx0XHQvLyBidSBpbnN0YW5jZSfEsSBwYXlsYcWfxLFyLiBuZ0FmdGVyVmlld0luaXQndGUgeWFwxLFsxLFyIMOnw7xua8O8IFZpZXdDaGlsZCBidXJhZGEga2VzaW4gaGF6xLFyZMSxci5cclxuXHRcdGlmICh0aGlzLm5hdkxpbmtDb250ZXh0TWVudSkge1xyXG5cdFx0XHR0aGlzLm5hdkxpbmtDb250ZXh0TWVudVNlcnZpY2UucmVnaXN0ZXIodGhpcy5uYXZMaW5rQ29udGV4dE1lbnUpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcclxuXHRjb25zdHJ1Y3RvcihcclxuXHRcdHByaXZhdGUgcmVhZG9ubHkgbWVudVNlcnZpY2U6IEFwcE1lbnVTZXJ2aWNlLFxyXG5cdFx0cHVibGljIGxheW91dFNlcnZpY2U6IExheW91dFNlcnZpY2UsXHJcblx0XHRwdWJsaWMgcmVuZGVyZXI6IFJlbmRlcmVyMixcclxuXHRcdHB1YmxpYyByb3V0ZXI6IFJvdXRlcixcclxuXHRcdHByaXZhdGUgcmVhZG9ubHkgdHJhbnNsYXRlSnNvblBpcGU6IFRyYW5zbGF0ZUpzb25QaXBlXHJcblx0KSB7XHJcblx0XHQvLyBOYXZTZXJ2aWNlIGJyaWRnZSdpIGRvxJ9ydWRhbiBiaWxtZXogKGN5Y2xpYyBkZXAgw7ZubGVtaSk7IGhvc3Qgc2hlbGwgYGJyaWRnZS5ob3N0TWVudUl0ZW1zKClgXHJcblx0XHQvLyDDvHplcmluZGVuIHByb3ZpZGVyIGJhxJ9sYXIuIFJlZnJlc2ggc29ucmFzxLEgYWRyZXMgw6d1YnXEn3VuYSB5YXDEscWfdMSxcsSxbG3EscWfIFVSTCdpbiB0YWIgYWTEsS9pa29udVxyXG5cdFx0Ly8gbWVuw7xkZWtpIGdlcsOnZWsgZGXEn2VybGVyZSBnw7ZyZSDDp8O2esO8bHPDvG4gZGl5ZS5cclxuXHRcdHRoaXMubmF2U2VydmljZS5zZXRNZW51SXRlbXNQcm92aWRlcigoKSA9PiBicmlkZ2UuaG9zdE1lbnVJdGVtcygpKTtcclxuXHRcdHRoaXMubmF2U2VydmljZS5zZXRIb21lTmF2SXRlbVByb3ZpZGVyKCgpID0+IHRoaXMuaG9tZU5hdkl0ZW0oKSk7XHJcblxyXG5cdFx0Ly8gUGlubmVkIHRhYidsYXLEsSBsb2NhbFN0b3JhZ2UnZGFuIGdlcmkgecO8a2xlLiBQcm92aWRlcidsYXIgc2V0IGVkaWxkaWt0ZW4gU09OUkFcclxuXHRcdC8vIChyZXN0b3JlIGVkaWxlbiB0YWInbGFyIHJlY29uY2lsZVRhYnNXaXRoTWVudSBpbGUgbWVuw7xkZW4gcmV2aXplIGVkaWxlYmlsc2luKSxcclxuXHRcdC8vIGlsayBOYXZpZ2F0aW9uRW5kIGhhbmRsZXInxLFuZGFuIMOWTkNFIChzZW5rcm9uKSDigJQga25vd25UYWIgZ3VhcmQgcmVzdG9yZSd1IGfDtnJzw7xuLlxyXG5cdFx0dGhpcy50YWJTZXNzaW9uLnJlc3RvcmUoKTtcclxuXHJcblx0XHQvLyBNZW7DvCAoYnJpZGdlLmhvc3RNZW51SXRlbXMpIGFzeW5jIHnDvGtsZW5pcjsgaWxrIGHDp8SxbMSxxZ8vcmVmcmVzaCBwYXRoJ2luZGUgaG9tZSB0YWJcclxuXHRcdC8vIGZhbGxiYWNrIGlzaW0vaWNvbmxhIGVrbGVubWnFnyBvbGFiaWxpci4gTWVuw7wgc2lnbmFsJ2kgZGXEn2nFn2luY2UgdGFiJ2xhcsSxIG1lbsO8eWxlIHJldml6ZVxyXG5cdFx0Ly8gZXQg4oaSIGFuYXNheWZhIGFkxLEvaWtvbnUgZ2Vyw6dlayBgcm9vdGAgw7bEn2VzaW5kZW4gZ2VsaXIsIGB0YWIuaG9tZWAgZmFsbGJhY2snaW5kZSBrYWxtYXouXHJcblx0XHRlZmZlY3QoXHJcblx0XHRcdCgpID0+IHtcclxuXHRcdFx0XHRicmlkZ2UuaG9zdE1lbnVJdGVtcygpO1xyXG5cdFx0XHRcdC8vIGB1bnRyYWNrZWRgOiByZWNvbmNpbGVUYWJzV2l0aE1lbnUgacOnaW5kZSBgYWN0aXZlUm91dGVzKClgIG9rdW51eW9yOyByZWFjdGl2ZVxyXG5cdFx0XHRcdC8vIGNvbnRleHQndGUga2FsxLFyc2EgZWZmZWN0IGFjdGl2ZVJvdXRlcydhIGRhIGFib25lIG9sdXIg4oaSIGhlciB0YWIgbXV0YXN5b251bmRhXHJcblx0XHRcdFx0Ly8gKGHDpy9rYXBhdC9zw7xyw7xrbGUvcGluKSBnZXJla3NpeiBtZW7DvC1ERlMgw6dhbMSxxZ/EsXIuIFlhbG7EsXogaG9zdE1lbnVJdGVtcydhIGJhxJ9sxLEga2Fsc8Sxbi5cclxuXHRcdFx0XHR1bnRyYWNrZWQoKCkgPT4gdGhpcy5uYXZTZXJ2aWNlLnJlY29uY2lsZVRhYnNXaXRoTWVudSgpKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0eyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XHJcblx0XHQpO1xyXG5cclxuXHRcdC8vIE5hdlNlcnZpY2UuYWN0aXZlVGFiSWQg4oaSIGJyaWRnZS5hY3RpdmVUYWJJZCBtaXJyb3IuIFBsdWdpbidsZXJpbiBSb3V0ZXIgcHJveHknbGVyaVxyXG5cdFx0Ly8gKHByb3ZpZGVIb3N0Um91dGVyKSBidSBzaWduYWwnxLEgb2t1eXVwIG5hdmlnYXRlIMOnYcSfcsSxbGFyxLFuYSBfdGFiIHN0YXRlIGVuamVrdGUgZWRpeW9yLlxyXG5cdFx0ZWZmZWN0KFxyXG5cdFx0XHQoKSA9PiB7XHJcblx0XHRcdFx0YnJpZGdlLmFjdGl2ZVRhYklkLnNldCh0aGlzLm5hdlNlcnZpY2UuYWN0aXZlVGFiSWQoKSk7XHJcblx0XHRcdH0sXHJcblx0XHRcdHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxyXG5cdFx0KTtcclxuXHJcblx0XHQvLyBNRkUgacOnaSBzYXlmYSBuYXZpZ2F0aW9uJ2xhcsSxIGhvc3QgUm91dGVyJ2EgeWFuc8SxbcSxeW9yIChJc29sYXRlZExvY2F0aW9uU3RyYXRlZ3lcclxuXHRcdC8vIGJyb3dzZXIgaGFzaCfEsSBkZcSfacWfdGlybWl5b3IpIOKGkiBOYXZTZXJ2aWNlIHRhYiBuYXZMaW5rJ2kgZ8O8bmNlbCBrYWxtxLF5b3JkdS4gTUZFXHJcblx0XHQvLyBBcHBDb21wb25lbnQgYGJyaWRnZS5hY3RpdmVNRkVVcmxgJ2EgKGtheW5hayB0YWJJZCBpbGUpIHlhesSxeW9yOyBidSBlZmZlY3QgaWxlXHJcblx0XHQvLyBkaW5sZXlpcCBgc3luY0FjdGl2ZVRhYk5hdkxpbmtGb3JUYWIodGFiSWQsIHVybClgIGlsZSBTQURFQ0Uga2F5bmFrIHRhYifEsSB1cGRhdGVcclxuXHRcdC8vIGVkZXJpei4gVGFiIGRlxJ9pxZ90aXJpcCBnZXJpIGTDtm7DvGxkw7zEn8O8bmRlIGRvxJ9ydSBVUkwnZSBnaWRpbGlyLCBjcm9zcy10YWIgeW9rLlxyXG5cdFx0Ly9cclxuXHRcdC8vICoqYHVudHJhY2tlZGAqKjogYHN5bmNBY3RpdmVUYWJOYXZMaW5rRm9yVGFiYCBpw6dpbmRlIGBhY3RpdmVSb3V0ZXMoKWAgb2t1bnVyO1xyXG5cdFx0Ly8gcmVhY3RpdmUgY29udGV4dCd0ZSBrYWzEsXJzYSBlZmZlY3QgYWN0aXZlUm91dGVzJ2EgZGEgYWJvbmUgb2x1ciDihpIgdGFiLm5hdkxpbmtcclxuXHRcdC8vIGRlxJ9pxZ9pa2xpxJ9pIGVmZmVjdCdpIHRla3JhciB0ZXRpa2xlciDihpIgZXNraSBgYWN0aXZlTUZFVXJsYCBkZcSfZXJpeWxlIG5hdkxpbmsnaVxyXG5cdFx0Ly8gZ2VyaSDDp2V2aXJpciAoa3VsbGFuxLFjxLFuxLFuIGFuYXNheWZheWEgZ2XDp2nFn2kgc8O8cmVrbGkgZGV0YWlsL21ldGVycydhIGTDtm5lcmRpKS5cclxuXHRcdC8vIFVudHJhY2tlZCBzYXJtYXPEsSBidSByZWN1cnNpdmUgbG9vcCd1IGvEsXJhci5cclxuXHRcdC8vIGBhbGxvd1NpZ25hbFdyaXRlc2A6IGBhY3RpdmVSb3V0ZXMudXBkYXRlYCAoc2lnbmFsIHdyaXRlKSwgZWZmZWN0IGnDp2luZGVuIGRlZmF1bHRcclxuXHRcdC8vIGBORzA2MDBgIHlhc2FrbMSxIOKAlCBiaWxpbsOnbGkgaXppbi5cclxuXHRcdGVmZmVjdChcclxuXHRcdFx0KCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGRhdGEgPSBicmlkZ2UuYWN0aXZlTUZFVXJsKCk7XHJcblx0XHRcdFx0aWYgKGRhdGE/LnRhYklkICYmIGRhdGE/LnVybCkge1xyXG5cdFx0XHRcdFx0dW50cmFja2VkKCgpID0+XHJcblx0XHRcdFx0XHRcdHRoaXMubmF2U2VydmljZS5zeW5jQWN0aXZlVGFiTmF2TGlua0ZvclRhYihkYXRhLnRhYklkLCBkYXRhLnVybCwgZGF0YS50aXRsZSlcclxuXHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cdFx0XHR7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cclxuXHRcdCk7XHJcblxyXG5cdFx0dGhpcy5vdmVybGF5TWVudU9wZW5TdWJzY3JpcHRpb24gPSB0aGlzLmxheW91dFNlcnZpY2Uub3ZlcmxheU9wZW4kLnN1YnNjcmliZSgoKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIpIHtcclxuXHRcdFx0XHR0aGlzLm1lbnVPdXRzaWRlQ2xpY2tMaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICdjbGljaycsIChldmVudCkgPT4ge1xyXG5cdFx0XHRcdFx0Y29uc3QgaXNPdXRzaWRlQ2xpY2tlZCA9ICEoXHJcblx0XHRcdFx0XHRcdHRoaXMuYXBwVG9wYmFyLm1lbnVCdXR0b24ubmF0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGV2ZW50LnRhcmdldCkgfHxcclxuXHRcdFx0XHRcdFx0dGhpcy5hcHBUb3BiYXIubWVudUJ1dHRvbi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgfHxcclxuXHRcdFx0XHRcdFx0KHRoaXMuZXhwYW5kYWJsZU1lbnVDb21wb25lbnQgJiYgdGhpcy5pc0VsZW1lbnRJbnNpZGUoZXZlbnQudGFyZ2V0LCAnYXBwLWV4cGFuZGFibGUtbWVudScpKSB8fFxyXG5cdFx0XHRcdFx0XHQodGhpcy5zdGF0aWNTaWRlYmFyQ29tcG9uZW50ICYmIHRoaXMuaXNFbGVtZW50SW5zaWRlKGV2ZW50LnRhcmdldCwgJ2FwcC1zdGF0aWMtc2lkZWJhcicpKVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdGlmIChpc091dHNpZGVDbGlja2VkKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMuaGlkZU1lbnUoKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRoaXMubGF5b3V0U2VydmljZS5zdGF0ZS5zdGF0aWNNZW51TW9iaWxlQWN0aXZlKSB7XHJcblx0XHRcdFx0dGhpcy5ibG9ja0JvZHlTY3JvbGwoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5yb3V0ZXIuZXZlbnRzLnBpcGUoZmlsdGVyKChldmVudCkgPT4gZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKSkuc3Vic2NyaWJlKChldmVudCkgPT4ge1xyXG5cdFx0XHRpZiAoIXRoaXMubGF5b3V0U2VydmljZS5tZmVBcHBJdGVtQ2xpY2tlZCgpKSB0aGlzLmhpZGVNZW51KCk7XHJcblx0XHRcdC8vIFNoZWxsIHJvb3Qgcm91dGUnYSBnZcOnaW5jZSAow7Zybi4gYC9gKSBNRkUgUm91dGVyIHRldGlrbGVubWVkacSfaSBpw6dpblxyXG5cdFx0XHQvLyBgQnJlYWRjcnVtYlB1Ymxpc2hlclNlcnZpY2VgIHNldCB5YXBtYXosIGVza2kgYnJlYWRjcnVtYiBrYWzEsXIuIE1hbnVlbCB0ZW1pemxlLlxyXG5cdFx0XHQvLyBVUkwgYD9fdGFiPS4uLmAgacOnZXJlYmlsZWNlxJ9pIGnDp2luIHF1ZXJ5IHN0cmluZydpIHPEsXnEsXLEsXAgcGF0aCBrYXLFn8SxbGHFn3TEsXIuXHJcblx0XHRcdGNvbnN0IHVybCA9IChldmVudCBhcyBOYXZpZ2F0aW9uRW5kKS51cmxBZnRlclJlZGlyZWN0cztcclxuXHRcdFx0Y29uc3QgcGF0aCA9IHVybC5zcGxpdCgnPycpWzBdO1xyXG5cdFx0XHRpZiAocGF0aCA9PT0gJy8nIHx8IHBhdGggPT09ICcnKSB7XHJcblx0XHRcdFx0YnJpZGdlLmJyZWFkY3J1bWJzLnNldChbXSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFRhYiBsaXN0ZXNpIGRlxJ9pxZ90acSfaW5kZSBzY3JvbGwgc3RhdGUnaW5pIHllbmlkZW4gaGVzYXBsYSDigJQgRE9NIGfDvG5jZWxsZW1lc2luZGVuIHNvbnJhXHJcblx0XHQvLyBgcXVldWVNaWNyb3Rhc2tgIGlsZSBiaXIgc29ucmFraSBmcmFtZSdpIGJla2xpeW9ydXogKHllbmkgZWtsZW5lbiB0YWIgY2xpZW50V2lkdGgvc2Nyb2xsV2lkdGgnaSBldGtpbGVyKS5cclxuXHRcdGVmZmVjdCgoKSA9PiB7XHJcblx0XHRcdHRoaXMubmF2U2VydmljZS5hY3RpdmVSb3V0ZXMoKTtcclxuXHRcdFx0cXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy51cGRhdGVTY3JvbGxTdGF0ZSgpKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdC8vIFRhYiBnZcOnacWfaW5kZSBicmVhZGNydW1iJ8SxIGdlw6dpY2kgb2xhcmFrIGJvxZ9hbHQg4oCUIHllbmkgYWt0aWYgTUZFJ25pblxyXG5cdFx0Ly8gYEJyZWFkY3J1bWJQdWJsaXNoZXJTZXJ2aWNlYCdpIHlhecSxbiB5YXBhbmEga2FkYXIgZXNraSB0YWInxLFuIGJyZWFkY3J1bWInxLFcclxuXHRcdC8vIGt1bGxhbsSxY8SxeWEgZ8O2csO8bm1lc2luIChrxLFzYSBzw7xyZWxpIHN0YWxlIFVJJ3lpIGVuZ2VsbGVyKS5cclxuXHRcdGxldCBwcmV2VGFiSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuXHRcdGVmZmVjdChcclxuXHRcdFx0KCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRhYklkID0gdGhpcy5uYXZTZXJ2aWNlLmFjdGl2ZVRhYklkKCk7XHJcblx0XHRcdFx0aWYgKHByZXZUYWJJZCAhPT0gdW5kZWZpbmVkICYmIHByZXZUYWJJZCAhPT0gdGFiSWQpIHtcclxuXHRcdFx0XHRcdGJyaWRnZS5icmVhZGNydW1icy5zZXQoW10pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRwcmV2VGFiSWQgPSB0YWJJZDtcclxuXHRcdFx0fSxcclxuXHRcdFx0eyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XHJcblx0XHQpO1xyXG5cdH1cclxuXHJcblx0YmxvY2tCb2R5U2Nyb2xsKCk6IHZvaWQge1xyXG5cdFx0aWYgKGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0KSB7XHJcblx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnYmxvY2tlZC1zY3JvbGwnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NOYW1lICs9ICcgYmxvY2tlZC1zY3JvbGwnO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0dW5ibG9ja0JvZHlTY3JvbGwoKTogdm9pZCB7XHJcblx0XHRpZiAoZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QpIHtcclxuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdibG9ja2VkLXNjcm9sbCcpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc05hbWUgPSBkb2N1bWVudC5ib2R5LmNsYXNzTmFtZS5yZXBsYWNlKFxyXG5cdFx0XHRcdG5ldyBSZWdFeHAoJyhefFxcXFxiKScgKyAnYmxvY2tlZC1zY3JvbGwnLnNwbGl0KCcgJykuam9pbignfCcpICsgJyhcXFxcYnwkKScsICdnaScpLFxyXG5cdFx0XHRcdCcgJ1xyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gSGVscGVyIG1ldGhvZCB0byBjaGVjayBpZiBlbGVtZW50IGlzIGluc2lkZSBhIHNwZWNpZmljIGNvbXBvbmVudFxyXG5cdHByaXZhdGUgaXNFbGVtZW50SW5zaWRlKGVsZW1lbnQ6IGFueSwgc2VsZWN0b3I6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFlbGVtZW50KSByZXR1cm4gZmFsc2U7XHJcblx0XHRcclxuXHRcdGxldCBjdXJyZW50RWxlbWVudCA9IGVsZW1lbnQ7XHJcblx0XHR3aGlsZSAoY3VycmVudEVsZW1lbnQgJiYgY3VycmVudEVsZW1lbnQgIT09IGRvY3VtZW50KSB7XHJcblx0XHRcdGlmIChjdXJyZW50RWxlbWVudC50YWdOYW1lICYmIGN1cnJlbnRFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gc2VsZWN0b3IpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjdXJyZW50RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHRoaWRlTWVudSgpIHtcclxuXHRcdHRoaXMubGF5b3V0U2VydmljZS5zdGF0ZS5zdGF0aWNNZW51TW9iaWxlQWN0aXZlID0gZmFsc2U7XHJcblx0XHR0aGlzLm1lbnVTZXJ2aWNlLnJlc2V0KCk7XHJcblxyXG5cdFx0aWYgKHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyKSB7XHJcblx0XHRcdHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyKCk7XHJcblx0XHRcdHRoaXMubWVudU91dHNpZGVDbGlja0xpc3RlbmVyID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIpIHtcclxuXHRcdFx0dGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIoKTtcclxuXHRcdFx0dGhpcy5tZW51U2Nyb2xsTGlzdGVuZXIgPSBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMudW5ibG9ja0JvZHlTY3JvbGwoKTtcclxuXHR9XHJcblxyXG5cdGdldCBjb250YWluZXJDbGFzcygpIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdCdsYXlvdXQtbGlnaHQnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkuY29sb3JTY2hlbWUgPT09ICdsaWdodCcsXHJcblx0XHRcdCdsYXlvdXQtZGltJzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLmNvbG9yU2NoZW1lID09PSAnZGltJyxcclxuXHRcdFx0J2xheW91dC1kYXJrJzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLmNvbG9yU2NoZW1lID09PSAnZGFyaycsXHJcblx0XHRcdCdsYXlvdXQtY29sb3JzY2hlbWUtbWVudSc6IHRoaXMubGF5b3V0U2VydmljZS5jb25maWcoKS5tZW51VGhlbWUgPT09ICdjb2xvclNjaGVtZScsXHJcblx0XHRcdCdsYXlvdXQtcHJpbWFyeWNvbG9yLW1lbnUnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudVRoZW1lID09PSAncHJpbWFyeUNvbG9yJyxcclxuXHRcdFx0J2xheW91dC10cmFuc3BhcmVudC1tZW51JzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVUaGVtZSA9PT0gJ3RyYW5zcGFyZW50JyxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdzdGF0aWMnLFxyXG5cdFx0XHQnbGF5b3V0LWV4cGFuZGFibGUnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdleHBhbmRhYmxlJyxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMtaW5hY3RpdmUnOiBcclxuXHRcdFx0XHR0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkubWVudU1vZGUgPT09ICdzdGF0aWMnICYmIFxyXG5cdFx0XHRcdCF0aGlzLmxheW91dFNlcnZpY2Uuc2hvdWxkU2hvd1N0YXRpY1NpZGViYXIoKSxcclxuXHRcdFx0J2xheW91dC1zdGF0aWMtY29sbGFwc2VkJzogXHJcblx0XHRcdFx0dGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVNb2RlID09PSAnc3RhdGljJyAmJiBcclxuXHRcdFx0XHR0aGlzLmxheW91dFNlcnZpY2UuaXNTdGF0aWNTaWRlYmFyQ29sbGFwc2VkKCksXHJcblx0XHRcdCdsYXlvdXQtbW9iaWxlLWFjdGl2ZSc6IHRoaXMubGF5b3V0U2VydmljZS5zdGF0ZS5zdGF0aWNNZW51TW9iaWxlQWN0aXZlLFxyXG5cdFx0XHQncC1pbnB1dC1maWxsZWQnOiB0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkuaW5wdXRTdHlsZSA9PT0gJ2ZpbGxlZCcsXHJcblx0XHRcdCdwLXJpcHBsZS1kaXNhYmxlZCc6ICF0aGlzLmxheW91dFNlcnZpY2UuY29uZmlnKCkucmlwcGxlLFxyXG5cdFx0XHQnbmV3LXNpZGViYXItbGF5b3V0JzogdGhpcy5sYXlvdXRTZXJ2aWNlLmNvbmZpZygpLm1lbnVNb2RlID09PSAnZXhwYW5kYWJsZScsXHJcblx0XHRcdCdzZWNvbmRhcnktZXhwYW5kZWQnOiB0aGlzLmxheW91dFNlcnZpY2Uuc3RhdGUuc2Vjb25kYXJ5U2lkZWJhckV4cGFuZGVkXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0bmdPbkRlc3Ryb3koKSB7XHJcblx0XHRpZiAodGhpcy5vdmVybGF5TWVudU9wZW5TdWJzY3JpcHRpb24pIHtcclxuXHRcdFx0dGhpcy5vdmVybGF5TWVudU9wZW5TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIpIHtcclxuXHRcdFx0dGhpcy5tZW51T3V0c2lkZUNsaWNrTGlzdGVuZXIoKTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XHJcblx0fVxyXG59IiwiPGRpdiBjbGFzcz1cImxheW91dC1jb250YWluZXJcIiBbbmdDbGFzc109XCJjb250YWluZXJDbGFzc1wiPlxyXG5cdEBpZiAobGF5b3V0U2VydmljZS5zaG91bGRTaG93U3RhdGljU2lkZWJhcigpKSB7XHJcblx0XHQ8YXBwLXN0YXRpYy1zaWRlYmFyIC8+XHJcblx0fSBAZWxzZSBpZiAobGF5b3V0U2VydmljZS5zaG91bGRTaG93RXhwYW5kYWJsZU1lbnUoKSkge1xyXG5cdFx0PGFwcC1leHBhbmRhYmxlLW1lbnUgLz5cclxuXHR9XHJcblx0PGRpdiBjbGFzcz1cImxheW91dC1jb250ZW50LXdyYXBwZXJcIj5cclxuXHRcdDxhcHAtdG9wYmFyIC8+XHJcblx0XHQ8ZGl2IGNsYXNzPVwibGF5b3V0LWNvbnRlbnRcIj5cclxuXHRcdFx0PHAtYnJlYWRjcnVtYiBzdHlsZUNsYXNzPVwiYnJlYWRjcnVtYi1zdHJpcFwiIFttb2RlbF09XCJicmVhZGNydW1iSXRlbXMoKVwiPlxyXG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJpdGVtXCIgbGV0LWl0ZW0+XHJcblx0XHRcdFx0XHRAaWYgKGl0ZW0uaXNIb21lKSB7XHJcblx0XHRcdFx0XHRcdDxhIGNsYXNzPVwiYnJlYWRjcnVtYi1ob21lXCJcclxuXHRcdFx0XHRcdFx0XHRbcm91dGVyTGlua109XCInLydcIlxyXG5cdFx0XHRcdFx0XHRcdFthcmlsTmF2TGlua109XCJob21lTmF2SXRlbSgpXCJcclxuXHRcdFx0XHRcdFx0XHQoY2xpY2spPVwib25Ib21lQ2xpY2soJGV2ZW50KVwiXHJcblx0XHRcdFx0XHRcdFx0W2F0dHIuYXJpYS1sYWJlbF09XCInYnJlYWRjcnVtYi5ob21lJyB8IHRyYW5zbG9jb1wiPlxyXG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzPVwicGkgcGktaG9tZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cclxuXHRcdFx0XHRcdFx0PC9hPlxyXG5cdFx0XHRcdFx0fSBAZWxzZSBpZiAoaXRlbS5hY3RpdmUgfHwgIWl0ZW0udXJsKSB7XHJcblx0XHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwiYnJlYWRjcnVtYi1pdGVtIGFjdGl2ZVwiPnt7IGl0ZW0ubGFiZWwgfX08L3NwYW4+XHJcblx0XHRcdFx0XHR9IEBlbHNlIHtcclxuXHRcdFx0XHRcdFx0PGFcclxuXHRcdFx0XHRcdFx0XHRjbGFzcz1cImJyZWFkY3J1bWItaXRlbSBicmVhZGNydW1iLWxpbmtcIlxyXG5cdFx0XHRcdFx0XHRcdFtyb3V0ZXJMaW5rXT1cIml0ZW0udXJsXCJcclxuXHRcdFx0XHRcdFx0XHRbYXJpbE5hdkxpbmtdPVwieyB0YWJJZDogJycsIG5hdkxpbms6IGl0ZW0udXJsLCBuYXZOYW1lOiBpdGVtLmxhYmVsIH1cIlxyXG5cdFx0XHRcdFx0XHRcdChjbGljayk9XCJvbkJyZWFkY3J1bWJDbGljaygkZXZlbnQsIGl0ZW0pXCI+XHJcblx0XHRcdFx0XHRcdFx0e3sgaXRlbS5sYWJlbCB9fVxyXG5cdFx0XHRcdFx0XHQ8L2E+XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0PC9uZy10ZW1wbGF0ZT5cclxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwic2VwYXJhdG9yXCI+XHJcblx0XHRcdFx0XHQ8aSBjbGFzcz1cImJyZWFkY3J1bWItc2VwIHBpIHBpLWFuZ2xlLXJpZ2h0IHRleHQtYmFzZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cclxuXHRcdFx0XHQ8L25nLXRlbXBsYXRlPlxyXG5cdFx0XHQ8L3AtYnJlYWRjcnVtYj5cclxuXHRcdFx0PGRpdiBjbGFzcz1cInRhYnMtYmFyXCI+XHJcblx0XHRcdFx0QGlmIChjYW5TY3JvbGxMZWZ0KCkpIHtcclxuXHRcdFx0XHRcdDxidXR0b25cclxuXHRcdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXHJcblx0XHRcdFx0XHRcdGNsYXNzPVwidGFicy1zY3JvbGwtYnRuIHRhYnMtc2Nyb2xsLWxlZnRcIlxyXG5cdFx0XHRcdFx0XHQoY2xpY2spPVwic2Nyb2xsVGFic0xlZnQoKVwiXHJcblx0XHRcdFx0XHRcdFtwVG9vbHRpcF09XCIndGFiLnNjcm9sbExlZnQnIHwgdHJhbnNsb2NvXCJcclxuXHRcdFx0XHRcdFx0dG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcclxuXHRcdFx0XHRcdFx0W2F0dHIuYXJpYS1sYWJlbF09XCIndGFiLnNjcm9sbExlZnQnIHwgdHJhbnNsb2NvXCI+XHJcblx0XHRcdFx0XHRcdDxpIGNsYXNzPVwicGkgcGktY2hldnJvbi1sZWZ0XCI+PC9pPlxyXG5cdFx0XHRcdFx0PC9idXR0b24+XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdDxkaXZcclxuXHRcdFx0XHRcdCN0YWJzQ29udGFpbmVyXHJcblx0XHRcdFx0XHRjbGFzcz1cInRhYnMtY29udGFpbmVyXCJcclxuXHRcdFx0XHRcdGNka0Ryb3BMaXN0XHJcblx0XHRcdFx0XHRjZGtEcm9wTGlzdE9yaWVudGF0aW9uPVwiaG9yaXpvbnRhbFwiXHJcblx0XHRcdFx0XHQoY2RrRHJvcExpc3REcm9wcGVkKT1cImRyb3AoJGV2ZW50KVwiPlxyXG5cdFx0XHRcdFx0QGZvciAoaXRlbSBvZiBuYXZTZXJ2aWNlLmFjdGl2ZVJvdXRlcygpOyB0cmFjayBpdGVtLnRhYklkOyBsZXQgaSA9ICRpbmRleCkge1xyXG5cdFx0XHRcdFx0XHQ8ZGl2XHJcblx0XHRcdFx0XHRcdFx0Y2xhc3M9XCJ0YWItaXRlbVwiXHJcblx0XHRcdFx0XHRcdFx0Y2RrRHJhZ1xyXG5cdFx0XHRcdFx0XHRcdFtjbGFzcy5hY3RpdmVdPVwiaXNBY3RpdmUoaXRlbSlcIlxyXG5cdFx0XHRcdFx0XHRcdFtjbGFzcy5waW5uZWRdPVwiaXRlbS5waW5uZWRcIlxyXG5cdFx0XHRcdFx0XHRcdFtwVG9vbHRpcF09XCJpdGVtLm5hdk5hbWVcIlxyXG5cdFx0XHRcdFx0XHRcdHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcblx0XHRcdFx0XHRcdFx0W3Rvb2x0aXBEaXNhYmxlZF09XCJpc0FjdGl2ZShpdGVtKSAmJiAhaXRlbS5waW5uZWRcIlxyXG5cdFx0XHRcdFx0XHRcdFtzaG93RGVsYXldPVwiNTAwXCJcclxuXHRcdFx0XHRcdFx0XHQoY2xpY2spPVwib25UYWJDbGljaygkZXZlbnQsIGl0ZW0pXCJcclxuXHRcdFx0XHRcdFx0XHQoYXV4Y2xpY2spPVwib25UYWJBdXhDbGljaygkZXZlbnQsIGl0ZW0pXCJcclxuXHRcdFx0XHRcdFx0XHQobW91c2Vkb3duKT1cIm9uVGFiTW91c2Vkb3duKCRldmVudClcIlxyXG5cdFx0XHRcdFx0XHRcdChjb250ZXh0bWVudSk9XCJvblRhYkNvbnRleHRNZW51KCRldmVudCwgaXRlbSlcIj5cclxuXHRcdFx0XHRcdFx0XHQ8aSBjbGFzcz1cInRhYi1pY29uXCIgW25nQ2xhc3NdPVwiZ2V0VGFiSWNvbihpdGVtKVwiPjwvaT5cclxuXHRcdFx0XHRcdFx0XHRAaWYgKCFpdGVtLnBpbm5lZCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJ0YWItdGl0bGVcIj57eyBpdGVtLm5hdk5hbWUgfX08L3NwYW4+XHJcblx0XHRcdFx0XHRcdFx0XHRAaWYgKCFpc0xhc3RIb21lVGFiKGl0ZW0pKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdDxidXR0b25cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0eXBlPVwiYnV0dG9uXCJcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRjbGFzcz1cInRhYi1jbG9zZS1idG5cIlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdChjbGljayk9XCJjbG9zZVRhYigkZXZlbnQsIGl0ZW0pXCJcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cIid0YWIuY2xvc2UnIHwgdHJhbnNsb2NvXCI+XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0PGkgY2xhc3M9XCJwaSBwaS10aW1lc1wiPjwvaT5cclxuXHRcdFx0XHRcdFx0XHRcdFx0PC9idXR0b24+XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRAaWYgKGNhblNjcm9sbFJpZ2h0KCkpIHtcclxuXHRcdFx0XHRcdDxidXR0b25cclxuXHRcdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXHJcblx0XHRcdFx0XHRcdGNsYXNzPVwidGFicy1zY3JvbGwtYnRuIHRhYnMtc2Nyb2xsLXJpZ2h0XCJcclxuXHRcdFx0XHRcdFx0KGNsaWNrKT1cInNjcm9sbFRhYnNSaWdodCgpXCJcclxuXHRcdFx0XHRcdFx0W3BUb29sdGlwXT1cIid0YWIuc2Nyb2xsUmlnaHQnIHwgdHJhbnNsb2NvXCJcclxuXHRcdFx0XHRcdFx0dG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcclxuXHRcdFx0XHRcdFx0W2F0dHIuYXJpYS1sYWJlbF09XCIndGFiLnNjcm9sbFJpZ2h0JyB8IHRyYW5zbG9jb1wiPlxyXG5cdFx0XHRcdFx0XHQ8aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tcmlnaHRcIj48L2k+XHJcblx0XHRcdFx0XHQ8L2J1dHRvbj5cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0PGJ1dHRvblxyXG5cdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXHJcblx0XHRcdFx0XHRjbGFzcz1cInRhYnMtYWRkLWJ0blwiXHJcblx0XHRcdFx0XHQoY2xpY2spPVwib25BZGRUYWIoKVwiXHJcblx0XHRcdFx0XHRbcFRvb2x0aXBdPVwiJ3RhYi5uZXdUYWInIHwgdHJhbnNsb2NvXCJcclxuXHRcdFx0XHRcdHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXHJcblx0XHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cIid0YWIubmV3VGFiJyB8IHRyYW5zbG9jb1wiPlxyXG5cdFx0XHRcdFx0PGkgY2xhc3M9XCJwaSBwaS1wbHVzXCI+PC9pPlxyXG5cdFx0XHRcdDwvYnV0dG9uPlxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdFx0PHAtY29udGV4dE1lbnUgI3RhYkNvbnRleHRNZW51IFttb2RlbF09XCJ0YWJDb250ZXh0TWVudUl0ZW1zXCIgYXBwZW5kVG89XCJib2R5XCI+PC9wLWNvbnRleHRNZW51PlxyXG5cdFx0XHQ8IS0tIEdsb2JhbCBuYXYtbGluayBjb250ZXh0IG1lbnU6IHTDvG0gbGlua2xpIHlhcMSxbGFyZGEgYFthcmlsTmF2TGlua11gIGRpcmVjdGl2ZSdpIGJ1IGluc3RhbmNlJ8SxIHBheWxhxZ/EsXIuIC0tPlxyXG5cdFx0XHQ8cC1jb250ZXh0TWVudSAjbmF2TGlua0NvbnRleHRNZW51IFttb2RlbF09XCJbXVwiIGFwcGVuZFRvPVwiYm9keVwiPjwvcC1jb250ZXh0TWVudT5cclxuXHJcblx0XHRcdDxkaXYgY2xhc3M9XCJsYXlvdXQtcGFnZVwiPlxyXG5cdFx0XHRcdDxyb3V0ZXItb3V0bGV0IC8+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0PC9kaXY+XHJcblx0PC9kaXY+XHJcblx0PGFwcC1wcm9maWxlbWVudSAvPlxyXG5cdDxhcHAtaGlzdG9yeS1zaWRlYmFyIC8+XHJcblx0PGFwcC1zaXRlLW1hcC1zaWRlYmFyIC8+XHJcblx0PGFwcC1mYXZvcml0ZS1wYWdlcy1zaWRlYmFyIC8+XHJcblx0PGFwcC1ub3RpZmljYXRpb25zLXNpZGViYXIgLz5cclxuXHQ8IS0tPGFwcC1jb25maWc+PC9hcHAtY29uZmlnPi0tPlxyXG5cdDxkaXYgY2xhc3M9XCJsYXlvdXQtbWFza1wiIChjbGljayk9XCJoaWRlTWVudSgpXCI+PC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPHAtdG9hc3Qga2V5PVwidG9hc3Qtcm9vdFwiIC8+XHJcbjxwLWRpYWxvZyBrZXk9XCJkaWFsb2ctcm9vdFwiIC8+XHJcbjxwLW1lc3NhZ2VzIGtleT1cIm1lc3NhZ2VzLXJvb3RcIiAvPlxyXG48cC1jb25maXJtUG9wdXAga2V5PVwiY29uZmlybVBvcHVwLXJvb3RcIiAvPlxyXG48cC1jb25maXJtRGlhbG9nIGtleT1cImNvbmZpcm1EaWFsb2ctcm9vdFwiIC8+XHJcbiJdfQ==