@openelement/ui 0.41.0-alpha.1
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.
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/package.json +142 -0
- package/src/daisy-classes.d.ts +7 -0
- package/src/daisy-classes.js +770 -0
- package/src/index.d.ts +57 -0
- package/src/index.js +62 -0
- package/src/manifest.d.ts +8 -0
- package/src/manifest.js +255 -0
- package/src/open-badge.d.ts +15 -0
- package/src/open-badge.js +88 -0
- package/src/open-brand-mark.d.ts +14 -0
- package/src/open-brand-mark.js +107 -0
- package/src/open-button.d.ts +38 -0
- package/src/open-button.js +219 -0
- package/src/open-callout.d.ts +26 -0
- package/src/open-callout.js +99 -0
- package/src/open-card.d.ts +33 -0
- package/src/open-card.js +107 -0
- package/src/open-code-block.d.ts +44 -0
- package/src/open-code-block.js +267 -0
- package/src/open-dialog.d.ts +47 -0
- package/src/open-dialog.js +235 -0
- package/src/open-dropdown.d.ts +25 -0
- package/src/open-dropdown.js +45 -0
- package/src/open-hero-ping.d.ts +27 -0
- package/src/open-hero-ping.js +136 -0
- package/src/open-input.d.ts +51 -0
- package/src/open-input.js +233 -0
- package/src/open-lab-panel.d.ts +16 -0
- package/src/open-lab-panel.js +151 -0
- package/src/open-lab-stage.d.ts +15 -0
- package/src/open-lab-stage.js +622 -0
- package/src/open-layout.d.ts +111 -0
- package/src/open-layout.js +1377 -0
- package/src/open-modal.d.ts +25 -0
- package/src/open-modal.js +48 -0
- package/src/open-props-tokens.d.ts +7 -0
- package/src/open-props-tokens.js +474 -0
- package/src/open-standards-visual.d.ts +20 -0
- package/src/open-standards-visual.js +425 -0
- package/src/open-step-card.d.ts +34 -0
- package/src/open-step-card.js +117 -0
- package/src/open-tabs.d.ts +27 -0
- package/src/open-tabs.js +56 -0
- package/src/open-theme-toggle.d.ts +38 -0
- package/src/open-theme-toggle.js +223 -0
|
@@ -0,0 +1,1377 @@
|
|
|
1
|
+
/** @jsxImportSource @openelement/core */ /**
|
|
2
|
+
* @openelement/ui - open-layout
|
|
3
|
+
*
|
|
4
|
+
* App layout component with header, sidebar, and footer.
|
|
5
|
+
* Web Standards Lab: light-first, restrained, documentation-focused.
|
|
6
|
+
*
|
|
7
|
+
* v0.20.0: Migrated from DsdLitElement to DsdElement (Ocean component).
|
|
8
|
+
* - CSSStyleSheet replaces Lit css``
|
|
9
|
+
* - render() returns string
|
|
10
|
+
* - @click bindings for mobile menu toggle
|
|
11
|
+
* - SPA navigation via Navigation API (navigate/fetch/swap) preserved
|
|
12
|
+
* - Event delegation at shadow root level for nav clicks
|
|
13
|
+
* v0.24.1: Migrated from html`` template to JSX (ADR-0057).
|
|
14
|
+
*
|
|
15
|
+
* @csspart container - The app-layout root div
|
|
16
|
+
* @csspart header - The sticky header element
|
|
17
|
+
* @csspart sidebar - The docs-sidebar nav
|
|
18
|
+
* @csspart main - The layout-main element
|
|
19
|
+
* @csspart footer - The app-footer element
|
|
20
|
+
* @csspart nav - The header-nav element
|
|
21
|
+
* @csspart nav-toggle - The mobile menu toggle button
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* ```html
|
|
25
|
+
* <open-layout current-path="/guide/getting-started"
|
|
26
|
+
* nav-items='[{"section":"Guide","items":[{"path":"/guide/getting-started","label":"Getting Started"}]}]'>
|
|
27
|
+
* </open-layout>
|
|
28
|
+
* ```
|
|
29
|
+
*/ import { OpenElement } from '@openelement/element';
|
|
30
|
+
import { StyleSheet } from '@openelement/core/style-sheet';
|
|
31
|
+
import { createContext, provideContext } from '@openelement/core';
|
|
32
|
+
import { escapeAttr, escapeHtml } from '@openelement/core';
|
|
33
|
+
import { createLogger } from '@openelement/core/logger';
|
|
34
|
+
import '.\/open-theme-toggle.js';
|
|
35
|
+
import './open-brand-mark.js';
|
|
36
|
+
export const tagName = 'open-layout';
|
|
37
|
+
const SAFE_URL_SCHEMES = new Set([
|
|
38
|
+
'http:',
|
|
39
|
+
'https:',
|
|
40
|
+
'mailto:',
|
|
41
|
+
'tel:',
|
|
42
|
+
'sms:'
|
|
43
|
+
]);
|
|
44
|
+
const log = createLogger('ui');
|
|
45
|
+
function isSafeLayoutUrl(url) {
|
|
46
|
+
const trimmed = url.trim();
|
|
47
|
+
if (!trimmed) return false;
|
|
48
|
+
if (trimmed.startsWith('//')) return false;
|
|
49
|
+
if (trimmed.startsWith('/') || trimmed.startsWith('#') || trimmed.startsWith('./') || trimmed.startsWith('../')) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const parsed = new URL(trimmed, 'https://openelement.org/');
|
|
54
|
+
return SAFE_URL_SCHEMES.has(parsed.protocol);
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/* --- Locale/path helpers (inlined from @openelement/router) --- */ const LOCALE_LABELS = {
|
|
60
|
+
en: '中文',
|
|
61
|
+
zh: 'English'
|
|
62
|
+
};
|
|
63
|
+
function parsePathWithoutLocale(pathname, locales) {
|
|
64
|
+
const segs = pathname.split('/').filter(Boolean);
|
|
65
|
+
if (segs.length > 0 && locales.includes(segs[0])) {
|
|
66
|
+
return '/' + segs.slice(1).join('/') || '/';
|
|
67
|
+
}
|
|
68
|
+
return pathname || '/';
|
|
69
|
+
}
|
|
70
|
+
function detectLocale(pathname, locales, defaultLocale) {
|
|
71
|
+
const segs = pathname.split('/').filter(Boolean);
|
|
72
|
+
if (segs.length > 0 && locales.includes(segs[0])) return segs[0];
|
|
73
|
+
return defaultLocale;
|
|
74
|
+
}
|
|
75
|
+
function localizePath(path1, locale) {
|
|
76
|
+
if (isSafeLayoutUrl(path1) && /^https?:/i.test(path1)) return path1;
|
|
77
|
+
return `/${locale}${path1}`;
|
|
78
|
+
}
|
|
79
|
+
function switchPath(currentPath, currentLocale, locales) {
|
|
80
|
+
const other = locales.find((l)=>l !== currentLocale) || currentLocale;
|
|
81
|
+
return `/${other}${currentPath}`;
|
|
82
|
+
}
|
|
83
|
+
function switchLabel(currentLocale) {
|
|
84
|
+
return LOCALE_LABELS[currentLocale] || currentLocale;
|
|
85
|
+
}
|
|
86
|
+
/** SignalContext key: theme state shared across all components */ export const THEME_CTX = createContext(Symbol('theme'), 'light');
|
|
87
|
+
const sheet = new StyleSheet();
|
|
88
|
+
sheet.replaceSync(`
|
|
89
|
+
:host {
|
|
90
|
+
display: block;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
* { font-family: var(--font-sans); }
|
|
94
|
+
|
|
95
|
+
.app-layout {
|
|
96
|
+
display: flex;
|
|
97
|
+
flex-direction: column;
|
|
98
|
+
min-height: 100vh;
|
|
99
|
+
background: var(--bg-base);
|
|
100
|
+
color: var(--text-primary);
|
|
101
|
+
font-family: var(--font-sans);
|
|
102
|
+
-webkit-font-smoothing: antialiased;
|
|
103
|
+
-moz-osx-font-smoothing: grayscale;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.layout-body {
|
|
107
|
+
display: flex;
|
|
108
|
+
flex: 1;
|
|
109
|
+
max-width: 1400px;
|
|
110
|
+
margin: 0 auto;
|
|
111
|
+
width: 100%;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.layout-main {
|
|
115
|
+
flex: 1;
|
|
116
|
+
min-width: 0;
|
|
117
|
+
width: 100%;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.app-layout[home] .layout-body,
|
|
121
|
+
.app-layout[full-width] .layout-body {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
max-width: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.app-layout[home] .layout-main,
|
|
128
|
+
.app-layout[full-width] .layout-main {
|
|
129
|
+
flex: 1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Header */
|
|
133
|
+
.app-header {
|
|
134
|
+
position: sticky;
|
|
135
|
+
top: 0;
|
|
136
|
+
z-index: 100;
|
|
137
|
+
background: var(--nav-bg);
|
|
138
|
+
border-bottom: var(--border-size-1) solid var(--border);
|
|
139
|
+
backdrop-filter: blur(18px) saturate(150%);
|
|
140
|
+
-webkit-backdrop-filter: blur(18px) saturate(150%);
|
|
141
|
+
transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
|
|
142
|
+
}
|
|
143
|
+
.app-header.scrolled {
|
|
144
|
+
background: color-mix(in srgb, var(--bg-base) 88%, transparent);
|
|
145
|
+
border-bottom-color: var(--border-hover);
|
|
146
|
+
box-shadow: 0 var(--size-2) var(--size-10) color-mix(in srgb, var(--brand) 5%, transparent);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.header-inner {
|
|
150
|
+
max-width: none;
|
|
151
|
+
margin: 0 auto;
|
|
152
|
+
padding: 0 clamp(var(--size-5), 3.5vw, var(--size-9));
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
min-height: var(--nav-height);
|
|
156
|
+
gap: var(--size-6);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.mobile-tab-bar { display: none; }
|
|
160
|
+
|
|
161
|
+
.mobile-menu-btn {
|
|
162
|
+
display: none;
|
|
163
|
+
align-items: center;
|
|
164
|
+
justify-content: center;
|
|
165
|
+
width: var(--size-10);
|
|
166
|
+
height: var(--size-10);
|
|
167
|
+
border: var(--border-size-1) solid var(--border);
|
|
168
|
+
border-radius: var(--radius-round);
|
|
169
|
+
background: color-mix(in srgb, var(--bg-elevated) 74%, transparent);
|
|
170
|
+
color: var(--text-secondary);
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
padding: 0;
|
|
173
|
+
transition: all 0.15s ease;
|
|
174
|
+
}
|
|
175
|
+
.mobile-menu-btn:hover {
|
|
176
|
+
color: var(--text-primary);
|
|
177
|
+
border-color: var(--border-hover);
|
|
178
|
+
background: var(--bg-hover);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.logo {
|
|
182
|
+
display: inline-flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
gap: var(--size-3);
|
|
185
|
+
font-size: var(--font-size-3);
|
|
186
|
+
font-weight: var(--font-weight-8);
|
|
187
|
+
color: var(--text-primary);
|
|
188
|
+
text-decoration: none;
|
|
189
|
+
letter-spacing: 0;
|
|
190
|
+
white-space: nowrap;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.logo:hover open-brand-mark {
|
|
194
|
+
transform: translateY(calc(var(--border-size-1) * -1));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
open-brand-mark {
|
|
198
|
+
transition: transform var(--duration-2) var(--ease-2);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.logo-word {
|
|
202
|
+
display: inline-block;
|
|
203
|
+
transform: translateY(calc(var(--border-size-1) * -1));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.logo-sub {
|
|
207
|
+
font-size: var(--font-size-00);
|
|
208
|
+
color: var(--text-muted);
|
|
209
|
+
margin-left: var(--size-2);
|
|
210
|
+
font-family: var(--font-mono);
|
|
211
|
+
font-weight: var(--font-weight-8);
|
|
212
|
+
text-transform: uppercase;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.header-nav {
|
|
216
|
+
display: flex;
|
|
217
|
+
gap: clamp(var(--size-5), 3vw, var(--size-8));
|
|
218
|
+
flex: 1;
|
|
219
|
+
justify-content: center;
|
|
220
|
+
}
|
|
221
|
+
.header-nav a {
|
|
222
|
+
color: var(--nav-link-color);
|
|
223
|
+
text-decoration: none;
|
|
224
|
+
font-size: var(--font-size-1);
|
|
225
|
+
font-weight: var(--font-weight-5);
|
|
226
|
+
padding: var(--size-2) 0;
|
|
227
|
+
transition: color 0.15s ease, background 0.15s ease;
|
|
228
|
+
}
|
|
229
|
+
.header-nav a:hover {
|
|
230
|
+
color: var(--nav-link-hover);
|
|
231
|
+
}
|
|
232
|
+
.header-nav a[aria-current="page"] {
|
|
233
|
+
color: var(--brand-deep);
|
|
234
|
+
font-weight: var(--font-weight-8);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.header-right {
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
gap: var(--size-1);
|
|
241
|
+
margin-left: auto;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* CTA buttons */
|
|
245
|
+
.btn-secondary {
|
|
246
|
+
display: inline-flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
gap: var(--size-2);
|
|
249
|
+
color: var(--text-primary);
|
|
250
|
+
text-decoration: none;
|
|
251
|
+
font-size: var(--font-size-button);
|
|
252
|
+
font-weight: var(--font-weight-semibold);
|
|
253
|
+
padding: var(--size-2) var(--size-4);
|
|
254
|
+
border: var(--border-size-1) solid color-mix(in srgb, var(--border) 72%, var(--brand));
|
|
255
|
+
border-radius: var(--radius-round);
|
|
256
|
+
background: color-mix(in srgb, var(--bg-elevated) 76%, transparent);
|
|
257
|
+
box-shadow: inset 0 1px 0 color-mix(in srgb, var(--gray-0) 70%, transparent);
|
|
258
|
+
transition: all 0.15s ease;
|
|
259
|
+
}
|
|
260
|
+
.btn-secondary:hover {
|
|
261
|
+
color: var(--brand-deep);
|
|
262
|
+
border-color: var(--brand-light);
|
|
263
|
+
background: color-mix(in srgb, var(--brand-pale) 42%, var(--bg-elevated));
|
|
264
|
+
}
|
|
265
|
+
.btn-secondary svg { flex-shrink: 0; }
|
|
266
|
+
|
|
267
|
+
.btn-primary {
|
|
268
|
+
display: inline-flex;
|
|
269
|
+
align-items: center;
|
|
270
|
+
gap: 4px;
|
|
271
|
+
color: var(--on-brand);
|
|
272
|
+
text-decoration: none;
|
|
273
|
+
font-size: var(--font-size-button);
|
|
274
|
+
font-weight: var(--font-weight-semibold);
|
|
275
|
+
padding: var(--size-2) var(--size-4);
|
|
276
|
+
border: var(--border-size-1) solid transparent;
|
|
277
|
+
border-radius: var(--radius-round);
|
|
278
|
+
background: linear-gradient(135deg, var(--brand), var(--brand-light));
|
|
279
|
+
box-shadow: 0 var(--size-2) var(--size-5) var(--brand-glow);
|
|
280
|
+
white-space: nowrap;
|
|
281
|
+
transition: all 0.15s ease;
|
|
282
|
+
}
|
|
283
|
+
.btn-primary:hover {
|
|
284
|
+
background: linear-gradient(135deg, var(--brand-hover), var(--brand-light));
|
|
285
|
+
transform: translateY(calc(var(--border-size-1) * -1));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.header-right .btn-secondary,
|
|
289
|
+
.header-right .btn-primary {
|
|
290
|
+
display: none;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.lang-switch {
|
|
294
|
+
display: inline-flex;
|
|
295
|
+
align-items: center;
|
|
296
|
+
justify-content: center;
|
|
297
|
+
min-width: var(--size-9);
|
|
298
|
+
width: var(--size-9);
|
|
299
|
+
height: var(--size-9);
|
|
300
|
+
padding: 0;
|
|
301
|
+
font-size: var(--font-size-button);
|
|
302
|
+
font-weight: var(--font-weight-semibold);
|
|
303
|
+
color: var(--text-secondary);
|
|
304
|
+
border: 0;
|
|
305
|
+
border-radius: var(--radius-round);
|
|
306
|
+
background: transparent;
|
|
307
|
+
cursor: pointer;
|
|
308
|
+
text-decoration: none;
|
|
309
|
+
transition: all 0.15s ease;
|
|
310
|
+
}
|
|
311
|
+
.lang-switch:hover {
|
|
312
|
+
color: var(--brand-deep);
|
|
313
|
+
border-color: transparent;
|
|
314
|
+
background: color-mix(in srgb, var(--brand-pale) 34%, transparent);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* Sidebar */
|
|
318
|
+
.docs-sidebar {
|
|
319
|
+
width: clamp(200px, 20vw, 260px);
|
|
320
|
+
flex-shrink: 0;
|
|
321
|
+
border-right: var(--border-size-1) solid var(--border);
|
|
322
|
+
padding: 2rem 0;
|
|
323
|
+
overflow-y: auto;
|
|
324
|
+
height: calc(100vh - var(--nav-height));
|
|
325
|
+
position: sticky;
|
|
326
|
+
top: var(--nav-height);
|
|
327
|
+
scrollbar-width: thin;
|
|
328
|
+
background: color-mix(in srgb, var(--bg-elevated) 42%, transparent);
|
|
329
|
+
}
|
|
330
|
+
:host([home]) .docs-sidebar,
|
|
331
|
+
:host([full-width]) .docs-sidebar {
|
|
332
|
+
width: 0; min-width: 0; padding: 0;
|
|
333
|
+
overflow: hidden; border-right: none;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.nav-section { margin-bottom: 1.5rem; }
|
|
337
|
+
.nav-section summary {
|
|
338
|
+
font-size: 0.625rem;
|
|
339
|
+
font-weight: 800;
|
|
340
|
+
text-transform: uppercase;
|
|
341
|
+
letter-spacing: 0.22em;
|
|
342
|
+
color: var(--text-muted);
|
|
343
|
+
padding: 0 1.5rem;
|
|
344
|
+
margin-bottom: 0.5rem;
|
|
345
|
+
cursor: pointer;
|
|
346
|
+
list-style: none;
|
|
347
|
+
display: flex;
|
|
348
|
+
align-items: center;
|
|
349
|
+
gap: 0.5rem;
|
|
350
|
+
user-select: none;
|
|
351
|
+
}
|
|
352
|
+
.nav-section summary::-webkit-details-marker { display: none; }
|
|
353
|
+
.nav-section summary::marker { content: ""; }
|
|
354
|
+
.nav-section summary:hover { color: var(--text-secondary); }
|
|
355
|
+
|
|
356
|
+
.docs-sidebar a {
|
|
357
|
+
display: block;
|
|
358
|
+
color: var(--text-muted);
|
|
359
|
+
text-decoration: none;
|
|
360
|
+
font-size: 0.85rem;
|
|
361
|
+
padding: 0.35rem 1.5rem;
|
|
362
|
+
border-left: 2px solid transparent;
|
|
363
|
+
transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
|
|
364
|
+
}
|
|
365
|
+
.docs-sidebar a:hover {
|
|
366
|
+
color: var(--text-secondary);
|
|
367
|
+
background: var(--bg-hover);
|
|
368
|
+
}
|
|
369
|
+
.docs-sidebar a.active,
|
|
370
|
+
.docs-sidebar a[aria-current="page"] {
|
|
371
|
+
color: var(--brand);
|
|
372
|
+
border-left-color: var(--brand);
|
|
373
|
+
background: var(--brand-subtle);
|
|
374
|
+
font-weight: 600;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* Footer */
|
|
378
|
+
.app-footer {
|
|
379
|
+
border-top: var(--border-size-1) solid var(--border);
|
|
380
|
+
background: color-mix(in srgb, var(--bg-elevated) 58%, transparent);
|
|
381
|
+
}
|
|
382
|
+
.footer-inner {
|
|
383
|
+
max-width: 1240px;
|
|
384
|
+
margin: 0 auto;
|
|
385
|
+
padding: var(--size-16) var(--size-8);
|
|
386
|
+
display: grid;
|
|
387
|
+
grid-template-columns: repeat(4, 1fr);
|
|
388
|
+
gap: var(--size-8);
|
|
389
|
+
}
|
|
390
|
+
.footer-column h4 {
|
|
391
|
+
font-size: var(--font-size-button);
|
|
392
|
+
font-weight: var(--font-weight-semibold);
|
|
393
|
+
color: var(--text-primary);
|
|
394
|
+
margin: 0 0 var(--size-4);
|
|
395
|
+
}
|
|
396
|
+
.footer-column a {
|
|
397
|
+
display: block;
|
|
398
|
+
color: var(--text-secondary);
|
|
399
|
+
text-decoration: none;
|
|
400
|
+
font-size: var(--font-size-body-sm);
|
|
401
|
+
padding: 4px 0;
|
|
402
|
+
transition: color 0.15s ease;
|
|
403
|
+
}
|
|
404
|
+
.footer-column a:hover {
|
|
405
|
+
color: var(--text-primary);
|
|
406
|
+
}
|
|
407
|
+
.footer-bottom {
|
|
408
|
+
border-top: var(--border-size-1) solid var(--border);
|
|
409
|
+
padding: var(--size-4) var(--size-8);
|
|
410
|
+
max-width: 1240px;
|
|
411
|
+
margin: 0 auto;
|
|
412
|
+
display: flex;
|
|
413
|
+
justify-content: space-between;
|
|
414
|
+
align-items: center;
|
|
415
|
+
color: var(--text-muted);
|
|
416
|
+
font-size: var(--font-size-body-sm);
|
|
417
|
+
}
|
|
418
|
+
.footer-bottom a {
|
|
419
|
+
color: var(--text-secondary);
|
|
420
|
+
text-decoration: none;
|
|
421
|
+
transition: color 0.15s ease;
|
|
422
|
+
}
|
|
423
|
+
.footer-bottom a:hover {
|
|
424
|
+
color: var(--text-primary);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/* Mobile backdrop */
|
|
428
|
+
.mobile-backdrop {
|
|
429
|
+
position: fixed; inset: 0; top: var(--nav-height);
|
|
430
|
+
background: var(--overlay);
|
|
431
|
+
z-index: 80; opacity: 0; pointer-events: none;
|
|
432
|
+
transition: opacity 0.3s ease;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Responsive */
|
|
436
|
+
@media (max-width: 1120px) {
|
|
437
|
+
.header-inner {
|
|
438
|
+
gap: var(--size-3);
|
|
439
|
+
padding-inline: var(--size-4);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.header-nav {
|
|
443
|
+
gap: var(--size-3);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.btn-secondary .btn-text { display: none; }
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@media (max-width: 900px) {
|
|
450
|
+
.mobile-menu-btn { display: flex; }
|
|
451
|
+
.header-inner { padding: 0 var(--size-4); gap: var(--size-2); }
|
|
452
|
+
.header-nav { display: none; }
|
|
453
|
+
.btn-secondary .btn-text { display: none; }
|
|
454
|
+
.header-right { gap: 4px; }
|
|
455
|
+
|
|
456
|
+
.docs-sidebar {
|
|
457
|
+
position: fixed; top: var(--nav-height); left: 0;
|
|
458
|
+
width: min(280px, 80vw);
|
|
459
|
+
height: calc(100vh - var(--nav-height)); z-index: 90;
|
|
460
|
+
background: var(--bg-elevated);
|
|
461
|
+
border-right: var(--border-size-1) solid var(--border);
|
|
462
|
+
padding: 1rem 0; overflow-y: auto;
|
|
463
|
+
transform: translateX(-101%);
|
|
464
|
+
transition: transform 0.25s cubic-bezier(0.4,0,0.2,1);
|
|
465
|
+
will-change: transform;
|
|
466
|
+
}
|
|
467
|
+
:host([menu-open]) .docs-sidebar {
|
|
468
|
+
transform: translateX(0);
|
|
469
|
+
box-shadow: var(--shadow-1);
|
|
470
|
+
}
|
|
471
|
+
:host([menu-open]) .mobile-backdrop { opacity: 1; pointer-events: auto; }
|
|
472
|
+
.nav-section { margin-bottom: 0.5rem; }
|
|
473
|
+
.nav-section summary { padding: var(--size-2) var(--size-4); }
|
|
474
|
+
.docs-sidebar a { padding: 0.5rem 1rem 0.5rem 2rem; }
|
|
475
|
+
.layout-main { width: 100%; }
|
|
476
|
+
.app-footer { padding: 0; }
|
|
477
|
+
.footer-inner {
|
|
478
|
+
grid-template-columns: repeat(2, 1fr);
|
|
479
|
+
padding: var(--size-12) var(--size-4);
|
|
480
|
+
padding-bottom: calc(var(--size-12) + var(--size-16));
|
|
481
|
+
}
|
|
482
|
+
.footer-bottom {
|
|
483
|
+
flex-direction: column;
|
|
484
|
+
gap: var(--size-2);
|
|
485
|
+
padding: var(--size-4);
|
|
486
|
+
padding-bottom: calc(var(--size-4) + var(--size-16));
|
|
487
|
+
text-align: center;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.mobile-tab-bar {
|
|
491
|
+
display: flex; position: fixed; bottom: 0; left: 0; right: 0;
|
|
492
|
+
height: 56px; z-index: 100;
|
|
493
|
+
background: var(--nav-bg);
|
|
494
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
495
|
+
-webkit-backdrop-filter: blur(12px) saturate(180%);
|
|
496
|
+
border-top: var(--border-size-1) solid var(--border);
|
|
497
|
+
padding: 0 env(safe-area-inset-right) 0 env(safe-area-inset-left);
|
|
498
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
499
|
+
}
|
|
500
|
+
.tab-item {
|
|
501
|
+
flex: 1; display: flex; flex-direction: column;
|
|
502
|
+
align-items: center; justify-content: center; gap: 2px;
|
|
503
|
+
color: var(--text-muted);
|
|
504
|
+
text-decoration: none; font-size: 10px; font-weight: 600;
|
|
505
|
+
transition: color 0.15s ease;
|
|
506
|
+
-webkit-tap-highlight-color: transparent; padding: 4px 0;
|
|
507
|
+
}
|
|
508
|
+
.tab-item svg { width: 20px; height: 20px; flex-shrink: 0; }
|
|
509
|
+
.tab-item:hover { color: var(--text-secondary); }
|
|
510
|
+
.tab-item.active { color: var(--brand); }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
@media (max-width: 768px) {
|
|
514
|
+
.header-right { gap: 4px; }
|
|
515
|
+
.lang-switch { display: none; }
|
|
516
|
+
}
|
|
517
|
+
@media (max-width: 480px) {
|
|
518
|
+
.btn-primary { display: none; }
|
|
519
|
+
.btn-secondary { padding: 8px; border: none; }
|
|
520
|
+
.btn-secondary .btn-text { display: none; }
|
|
521
|
+
.header-inner { padding: 0 var(--size-3); gap: var(--size-1); }
|
|
522
|
+
}
|
|
523
|
+
`);
|
|
524
|
+
export class OpenLayout extends OpenElement {
|
|
525
|
+
_cleanupNav;
|
|
526
|
+
_scrollCleanup;
|
|
527
|
+
_navOptions;
|
|
528
|
+
get _locales() {
|
|
529
|
+
try {
|
|
530
|
+
const raw = this.locales || this.getAttribute('locales');
|
|
531
|
+
if (raw) {
|
|
532
|
+
if (Array.isArray(raw)) return raw;
|
|
533
|
+
if (typeof raw === 'string') {
|
|
534
|
+
try {
|
|
535
|
+
return JSON.parse(raw);
|
|
536
|
+
} catch {}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return [
|
|
540
|
+
'en'
|
|
541
|
+
];
|
|
542
|
+
} catch {
|
|
543
|
+
return [
|
|
544
|
+
'en'
|
|
545
|
+
];
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
get _defaultLocale() {
|
|
549
|
+
return this.getAttribute('locale') || this._locales[0] || 'en';
|
|
550
|
+
}
|
|
551
|
+
get _currentLocale() {
|
|
552
|
+
try {
|
|
553
|
+
if (typeof globalThis.location !== 'undefined') {
|
|
554
|
+
return detectLocale(location.pathname, this._locales, this._defaultLocale);
|
|
555
|
+
}
|
|
556
|
+
return this._defaultLocale;
|
|
557
|
+
} catch {
|
|
558
|
+
return this._defaultLocale;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
get _currentPathWithoutLocale() {
|
|
562
|
+
try {
|
|
563
|
+
if (typeof globalThis.location !== 'undefined') {
|
|
564
|
+
return parsePathWithoutLocale(location.pathname, this._locales);
|
|
565
|
+
}
|
|
566
|
+
return this.getAttribute('current-path') || '/';
|
|
567
|
+
} catch {
|
|
568
|
+
return '/';
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
static styles = [
|
|
572
|
+
sheet
|
|
573
|
+
];
|
|
574
|
+
static observedAttributes = [
|
|
575
|
+
'current-path',
|
|
576
|
+
'nav-items',
|
|
577
|
+
'header-nav',
|
|
578
|
+
'logo-text',
|
|
579
|
+
'logo-sub',
|
|
580
|
+
'github-url',
|
|
581
|
+
'edit-url',
|
|
582
|
+
'locale',
|
|
583
|
+
'locales'
|
|
584
|
+
];
|
|
585
|
+
_themeHandler;
|
|
586
|
+
_docClickCleanup;
|
|
587
|
+
render() {
|
|
588
|
+
return this._renderLayout();
|
|
589
|
+
}
|
|
590
|
+
_getStr(attr, def) {
|
|
591
|
+
const camel = attr.replace(/-([a-z])/g, (_, c)=>c.toUpperCase());
|
|
592
|
+
const prop = this[camel];
|
|
593
|
+
if (prop !== undefined && prop !== null) return String(prop);
|
|
594
|
+
return this.getAttribute(attr) || def;
|
|
595
|
+
}
|
|
596
|
+
_getBool(attr) {
|
|
597
|
+
const camel = attr.replace(/-([a-z])/g, (_, c)=>c.toUpperCase());
|
|
598
|
+
const prop = this[camel];
|
|
599
|
+
if (typeof prop === 'boolean') return prop;
|
|
600
|
+
return this.hasAttribute(attr);
|
|
601
|
+
}
|
|
602
|
+
// _currentPathWithoutLocale, _currentLocale, _locales, _switchPath(),
|
|
603
|
+
// _switchLabel(), _updateSwitch(), _localizePath()
|
|
604
|
+
// ?? all inlined (replaces former @openelement/router dependency)
|
|
605
|
+
_currentPath() {
|
|
606
|
+
// SSR-safe: prefer attribute/prop set by renderDsd over URL detection
|
|
607
|
+
// location.pathname is undefined during build.
|
|
608
|
+
const prop = this.currentPath;
|
|
609
|
+
if (typeof prop === 'string' && prop.length > 0) return prop;
|
|
610
|
+
const attr = this.getAttribute('current-path');
|
|
611
|
+
if (attr && attr.length > 0) return attr;
|
|
612
|
+
try {
|
|
613
|
+
if (typeof globalThis.location !== 'undefined') {
|
|
614
|
+
return parsePathWithoutLocale(location.pathname, this._locales);
|
|
615
|
+
}
|
|
616
|
+
return this.getAttribute('current-path') || '/';
|
|
617
|
+
} catch {
|
|
618
|
+
return '/';
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/** Compute GitHub edit URL from current path. */ _computeEditUrl() {
|
|
622
|
+
const path1 = this._currentPath();
|
|
623
|
+
if (!path1 || path1 === '/') return '';
|
|
624
|
+
const EDIT_BASE = 'https://github.com/open-element/openelement/edit/main/www/app/routes';
|
|
625
|
+
const clean = path1.replace(/\/$/, '').split('/').filter(Boolean);
|
|
626
|
+
// Remove locale prefix if present (en/, zh/)
|
|
627
|
+
if ([
|
|
628
|
+
'en',
|
|
629
|
+
'zh'
|
|
630
|
+
].includes(clean[0])) clean.shift();
|
|
631
|
+
const filePath = clean.length === 0 ? 'index/index' : clean.join('/');
|
|
632
|
+
return `${EDIT_BASE}/${filePath}.tsx`;
|
|
633
|
+
}
|
|
634
|
+
_navItems() {
|
|
635
|
+
const items = this._rawNavItems();
|
|
636
|
+
return this._filterByPath(items);
|
|
637
|
+
}
|
|
638
|
+
/** Auto-filter sidebar sections by current path prefix. */ _filterByPath(items) {
|
|
639
|
+
const path1 = this._currentPath();
|
|
640
|
+
const SECTION_MAP = {
|
|
641
|
+
'/guide': [
|
|
642
|
+
'Quick Start',
|
|
643
|
+
'Core',
|
|
644
|
+
'Production'
|
|
645
|
+
],
|
|
646
|
+
'/architecture': [
|
|
647
|
+
'Principles',
|
|
648
|
+
'Compatibility',
|
|
649
|
+
'Reference'
|
|
650
|
+
],
|
|
651
|
+
'/registry': [
|
|
652
|
+
'Registry'
|
|
653
|
+
],
|
|
654
|
+
'/hub': [
|
|
655
|
+
'Registry'
|
|
656
|
+
],
|
|
657
|
+
'/blog': [
|
|
658
|
+
'History'
|
|
659
|
+
]
|
|
660
|
+
};
|
|
661
|
+
for (const [prefix, sections] of Object.entries(SECTION_MAP)){
|
|
662
|
+
if (path1.startsWith(prefix)) {
|
|
663
|
+
return items.filter((s)=>sections.includes(s.section));
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return items;
|
|
667
|
+
}
|
|
668
|
+
_rawNavItems() {
|
|
669
|
+
try {
|
|
670
|
+
const prop = this.navItems;
|
|
671
|
+
if (prop && Array.isArray(prop)) return prop;
|
|
672
|
+
const raw = this.getAttribute('nav-items');
|
|
673
|
+
if (raw) return JSON.parse(raw);
|
|
674
|
+
return [];
|
|
675
|
+
} catch (e) {
|
|
676
|
+
log.warn('Failed to parse nav-items JSON:', e);
|
|
677
|
+
return [];
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
_headerNav() {
|
|
681
|
+
try {
|
|
682
|
+
const prop = this.headerNav;
|
|
683
|
+
if (prop && Array.isArray(prop)) return prop;
|
|
684
|
+
const raw = this.getAttribute('header-nav');
|
|
685
|
+
if (raw) return JSON.parse(raw);
|
|
686
|
+
return [];
|
|
687
|
+
} catch (e) {
|
|
688
|
+
log.warn('Failed to parse header-nav JSON:', e);
|
|
689
|
+
return [];
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
// --- Icons ---
|
|
693
|
+
/** v0.24.1: SVG icon attributes shared across all mobile tab bar icons. */ static _ICON_ATTRS = {
|
|
694
|
+
viewBox: '0 0 20 20',
|
|
695
|
+
fill: 'none',
|
|
696
|
+
stroke: 'currentColor',
|
|
697
|
+
'stroke-width': '1.5',
|
|
698
|
+
'stroke-linecap': 'round',
|
|
699
|
+
'stroke-linejoin': 'round'
|
|
700
|
+
};
|
|
701
|
+
/** v0.24.1: Render mobile tab icon as JSX SVG. Falls back to a generic shape. */ _renderIcon(label) {
|
|
702
|
+
const a1 = OpenLayout._ICON_ATTRS;
|
|
703
|
+
switch(label){
|
|
704
|
+
case 'Home':
|
|
705
|
+
return <svg {...a1}>
|
|
706
|
+
<path d='M3 10l7-7 7 7'/>
|
|
707
|
+
<path d='M5 8v9h3v-5h4v5h3V8'/>
|
|
708
|
+
</svg>;
|
|
709
|
+
case 'Docs':
|
|
710
|
+
case 'Blog':
|
|
711
|
+
return <svg {...a1}>
|
|
712
|
+
<rect x='3' y='2' width='14' height='16' rx='2'/>
|
|
713
|
+
<path d='M7 6h6M7 10h6M7 14h3'/>
|
|
714
|
+
</svg>;
|
|
715
|
+
case 'Examples':
|
|
716
|
+
return <svg {...a1}>
|
|
717
|
+
<rect x='3' y='3' width='14' height='14' rx='2'/>
|
|
718
|
+
<path d='M7 7l6 3-6 3z'/>
|
|
719
|
+
</svg>;
|
|
720
|
+
case 'Components':
|
|
721
|
+
return <svg {...a1}>
|
|
722
|
+
<rect x='2' y='2' width='7' height='7' rx='1'/>
|
|
723
|
+
<rect x='11' y='2' width='7' height='7' rx='1'/>
|
|
724
|
+
<rect x='2' y='11' width='7' height='7' rx='1'/>
|
|
725
|
+
<rect x='11' y='11' width='7' height='7' rx='1'/>
|
|
726
|
+
</svg>;
|
|
727
|
+
case 'Architecture':
|
|
728
|
+
case 'Engine':
|
|
729
|
+
return <svg {...a1}>
|
|
730
|
+
<circle cx='10' cy='10' r='3'/>
|
|
731
|
+
<path d='M10 1v2M10 17v2M3.5 3.5l1.4 1.4M15.1 15.1l1.4 1.4M1 10h2M17 10h2M3.5 16.5l1.4-1.4M15.1 4.9l1.4-1.4'/>
|
|
732
|
+
</svg>;
|
|
733
|
+
case 'Hub':
|
|
734
|
+
case 'RegistryHub':
|
|
735
|
+
return <svg {...a1}>
|
|
736
|
+
<path d='M10 2l7 4v8l-7 4-7-4V6z'/>
|
|
737
|
+
<path d='M10 10l7-4M10 10v8M10 10L3 6'/>
|
|
738
|
+
</svg>;
|
|
739
|
+
case 'Roadmap':
|
|
740
|
+
return <svg {...a1}>
|
|
741
|
+
<circle cx='4' cy='6' r='1.5'/>
|
|
742
|
+
<circle cx='10' cy='10' r='1.5'/>
|
|
743
|
+
<circle cx='16' cy='14' r='1.5'/>
|
|
744
|
+
<path d='M5.5 6h10M11.5 10h5'/>
|
|
745
|
+
</svg>;
|
|
746
|
+
case 'Framework':
|
|
747
|
+
return <svg {...a1}>
|
|
748
|
+
<path d='M5 3h10M5 3v6h7M12 9v3M5 17h7'/>
|
|
749
|
+
</svg>;
|
|
750
|
+
default:
|
|
751
|
+
return <svg {...a1}>
|
|
752
|
+
<circle cx='10' cy='10' r='8'/>
|
|
753
|
+
<path d='M6 6l3 5 5 3-3-5z'/>
|
|
754
|
+
</svg>;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
_safeHref(href, fallback = '#') {
|
|
758
|
+
if (!href) return fallback;
|
|
759
|
+
const trimmed = href.trim();
|
|
760
|
+
return isSafeLayoutUrl(trimmed) ? trimmed : fallback;
|
|
761
|
+
}
|
|
762
|
+
_isExternalHref(href) {
|
|
763
|
+
try {
|
|
764
|
+
const parsed = new URL(href, 'https://openelement.org/');
|
|
765
|
+
return parsed.origin !== 'https://openelement.org' && SAFE_URL_SCHEMES.has(parsed.protocol);
|
|
766
|
+
} catch {
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
_localizedSafeHref(href) {
|
|
771
|
+
const safeHref = this._safeHref(href);
|
|
772
|
+
const isExternal = this._isExternalHref(safeHref);
|
|
773
|
+
return {
|
|
774
|
+
href: isExternal ? safeHref : localizePath(safeHref, this._currentLocale),
|
|
775
|
+
isExternal
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
// --- Main render ---
|
|
779
|
+
_renderLayout() {
|
|
780
|
+
const home = this._getBool('full-width') || this._getBool('home');
|
|
781
|
+
const noSearch = this.hasAttribute('no-search');
|
|
782
|
+
const logoText = this._getStr('logo-text', '');
|
|
783
|
+
const logoSub = this._getStr('logo-sub', '');
|
|
784
|
+
const locales = this._locales;
|
|
785
|
+
const currentLocale = this._currentLocale;
|
|
786
|
+
const currentPath = this._currentPathWithoutLocale;
|
|
787
|
+
const langLabel = locales.length > 1 ? switchLabel(currentLocale) : '';
|
|
788
|
+
const langHref = locales.length > 1 ? switchPath(currentPath, currentLocale, locales) : '';
|
|
789
|
+
return <div className='app-layout' part='container' home={home || undefined}>
|
|
790
|
+
<header className='app-header' part='header'>
|
|
791
|
+
<nav className='header-inner' aria-label='Primary navigation'>
|
|
792
|
+
{(logoText || logoSub) && <a className='logo' href='/'>
|
|
793
|
+
<open-brand-mark size='md'></open-brand-mark>
|
|
794
|
+
{logoText && <span className='logo-word'>{logoText}</span>}
|
|
795
|
+
{logoSub && <span className='logo-sub'>{logoSub}</span>}
|
|
796
|
+
</a>}
|
|
797
|
+
{this._renderHeaderNav()}
|
|
798
|
+
<div className='header-right'>
|
|
799
|
+
{!noSearch && <open-search></open-search>}
|
|
800
|
+
{!home && <button type='button' className='mobile-menu-btn' part='nav-toggle' aria-label='Toggle navigation' onClick={(event)=>this._toggleMenu(event)}>
|
|
801
|
+
<svg width='18' height='18' viewBox='0 0 18 18' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round'>
|
|
802
|
+
<line x1='3' y1='4.5' x2='15' y2='4.5'/>
|
|
803
|
+
<line x1='3' y1='9' x2='15' y2='9'/>
|
|
804
|
+
<line x1='3' y1='13.5' x2='15' y2='13.5'/>
|
|
805
|
+
</svg>
|
|
806
|
+
</button>}
|
|
807
|
+
<open-theme-toggle></open-theme-toggle>
|
|
808
|
+
{locales.length > 1 && <a className='lang-switch' href={langHref} data-nav={langHref}>
|
|
809
|
+
{langLabel}
|
|
810
|
+
</a>}
|
|
811
|
+
</div>
|
|
812
|
+
</nav>
|
|
813
|
+
</header>
|
|
814
|
+
<div className='mobile-backdrop'></div>
|
|
815
|
+
<div className='layout-body'>
|
|
816
|
+
{!home && this._renderSidebarNav()}
|
|
817
|
+
<main className='layout-main' part='main'>
|
|
818
|
+
<slot></slot>
|
|
819
|
+
</main>
|
|
820
|
+
</div>
|
|
821
|
+
<footer className='app-footer' part='footer'>
|
|
822
|
+
<div className='footer-inner'>
|
|
823
|
+
<div className='footer-column'>
|
|
824
|
+
<h4>Product</h4>
|
|
825
|
+
<a href={localizePath('/guide/core-concepts', currentLocale)} data-nav={localizePath('/guide/core-concepts', currentLocale)}>
|
|
826
|
+
Elements
|
|
827
|
+
</a>
|
|
828
|
+
<a href={localizePath('/architecture/design-system', currentLocale)} data-nav={localizePath('/architecture/design-system', currentLocale)}>
|
|
829
|
+
UI
|
|
830
|
+
</a>
|
|
831
|
+
<a href={localizePath('/architecture/architecture', currentLocale)} data-nav={localizePath('/architecture/architecture', currentLocale)}>
|
|
832
|
+
Framework
|
|
833
|
+
</a>
|
|
834
|
+
<a href={localizePath('/architecture/standards-registry', currentLocale)} data-nav={localizePath('/architecture/standards-registry', currentLocale)}>
|
|
835
|
+
Protocols
|
|
836
|
+
</a>
|
|
837
|
+
</div>
|
|
838
|
+
<div className='footer-column'>
|
|
839
|
+
<h4>Resources</h4>
|
|
840
|
+
<a href={localizePath('/guide/getting-started', currentLocale)} data-nav={localizePath('/guide/getting-started', currentLocale)}>
|
|
841
|
+
Guide
|
|
842
|
+
</a>
|
|
843
|
+
<a href={localizePath('/guide/api', currentLocale)} data-nav={localizePath('/guide/api', currentLocale)}>
|
|
844
|
+
API
|
|
845
|
+
</a>
|
|
846
|
+
<a href={localizePath('/architecture/architecture', currentLocale)} data-nav={localizePath('/architecture/architecture', currentLocale)}>
|
|
847
|
+
Architecture
|
|
848
|
+
</a>
|
|
849
|
+
<a href={localizePath('/blog', currentLocale)} data-nav={localizePath('/blog', currentLocale)}>
|
|
850
|
+
Blog
|
|
851
|
+
</a>
|
|
852
|
+
</div>
|
|
853
|
+
<div className='footer-column'>
|
|
854
|
+
<h4>Company</h4>
|
|
855
|
+
<a href='https://github.com/open-element/openelement'>GitHub</a>
|
|
856
|
+
<a href={localizePath('/roadmap', currentLocale)} data-nav={localizePath('/roadmap', currentLocale)}>
|
|
857
|
+
Roadmap
|
|
858
|
+
</a>
|
|
859
|
+
<a href={localizePath('/changelog', currentLocale)} data-nav={localizePath('/changelog', currentLocale)}>
|
|
860
|
+
Changelog
|
|
861
|
+
</a>
|
|
862
|
+
</div>
|
|
863
|
+
<div className='footer-column'>
|
|
864
|
+
<h4>Legal</h4>
|
|
865
|
+
<a href='https://github.com/open-element/openelement/blob/main/LICENSE'>
|
|
866
|
+
MIT License
|
|
867
|
+
</a>
|
|
868
|
+
<a href={localizePath('/contributing', currentLocale)} data-nav={localizePath('/contributing', currentLocale)}>
|
|
869
|
+
Contributing
|
|
870
|
+
</a>
|
|
871
|
+
</div>
|
|
872
|
+
</div>
|
|
873
|
+
<div className='footer-bottom'>
|
|
874
|
+
<span>(c) 2026 openElement. MIT License.</span>
|
|
875
|
+
</div>
|
|
876
|
+
</footer>
|
|
877
|
+
{this._renderMobileTabBar()}
|
|
878
|
+
</div>;
|
|
879
|
+
}
|
|
880
|
+
_renderHeaderNav() {
|
|
881
|
+
const links = this._headerNav();
|
|
882
|
+
if (links.length === 0) return null;
|
|
883
|
+
const cp = this._currentPath();
|
|
884
|
+
return <nav className='header-nav' part='nav'>
|
|
885
|
+
{links.map((link)=>{
|
|
886
|
+
const { href: localized, isExternal } = this._localizedSafeHref(link.href);
|
|
887
|
+
const isCurrent = !isExternal && (cp === link.href || cp === localized || cp.startsWith(localized + '/'));
|
|
888
|
+
return <a href={localized} data-nav={isExternal ? '' : localized} aria-current={isCurrent ? 'page' : undefined}>
|
|
889
|
+
{link.label}
|
|
890
|
+
</a>;
|
|
891
|
+
})}
|
|
892
|
+
</nav>;
|
|
893
|
+
}
|
|
894
|
+
_renderSidebarNav() {
|
|
895
|
+
const nav1 = this._navItems();
|
|
896
|
+
if (nav1.length === 0) return null;
|
|
897
|
+
return <nav className='docs-sidebar' part='sidebar' aria-label='Documentation navigation'>
|
|
898
|
+
{nav1.map((section)=><details className='nav-section' open>
|
|
899
|
+
<summary className='nav-section-title'>
|
|
900
|
+
{section.section}
|
|
901
|
+
</summary>
|
|
902
|
+
{section.items.map((item)=>{
|
|
903
|
+
const href = item.href || item.path || '#';
|
|
904
|
+
const { href: localized, isExternal } = this._localizedSafeHref(href);
|
|
905
|
+
const cp = this._currentPath();
|
|
906
|
+
const isActive = !isExternal && cp === localized;
|
|
907
|
+
return <a href={localized} className={isActive ? 'active' : undefined} aria-current={isActive ? 'page' : undefined} data-nav={isExternal ? '' : localized}>
|
|
908
|
+
{item.label}
|
|
909
|
+
</a>;
|
|
910
|
+
})}
|
|
911
|
+
</details>)}
|
|
912
|
+
</nav>;
|
|
913
|
+
}
|
|
914
|
+
_renderMobileTabBar() {
|
|
915
|
+
const links = this._headerNav();
|
|
916
|
+
if (links.length === 0) return null;
|
|
917
|
+
const MOBILE_TAB_LIMIT = 5;
|
|
918
|
+
const mobileLinks = links.slice(0, MOBILE_TAB_LIMIT);
|
|
919
|
+
const locs = this._locales;
|
|
920
|
+
const sectionRoot = (href)=>{
|
|
921
|
+
const segs = href.split('/').filter(Boolean);
|
|
922
|
+
const start = locs.length > 1 && locs.includes(segs[0]) ? 1 : 0;
|
|
923
|
+
return segs.length > start + 1 ? '/' + segs[start] : href;
|
|
924
|
+
};
|
|
925
|
+
const rawPath = this._currentPathWithoutLocale;
|
|
926
|
+
return <nav className='mobile-tab-bar' aria-label='Quick navigation'>
|
|
927
|
+
{mobileLinks.map((link)=>{
|
|
928
|
+
const { href: localized, isExternal } = this._localizedSafeHref(link.href);
|
|
929
|
+
const root = sectionRoot(link.href);
|
|
930
|
+
const isActive = !isExternal && (rawPath === root || rawPath.startsWith(root + '/'));
|
|
931
|
+
return <a className={`tab-item${isActive ? ' active' : ''}`} href={localized} data-nav={isExternal ? '' : localized} aria-current={isActive ? 'page' : undefined}>
|
|
932
|
+
{this._renderIcon(link.label)}
|
|
933
|
+
<span>{link.label}</span>
|
|
934
|
+
</a>;
|
|
935
|
+
})}
|
|
936
|
+
</nav>;
|
|
937
|
+
}
|
|
938
|
+
// --- Scroll detection ---
|
|
939
|
+
_setupScrollDetection() {
|
|
940
|
+
if (typeof globalThis.window === 'undefined') return;
|
|
941
|
+
let ticking;
|
|
942
|
+
const onScroll = ()=>{
|
|
943
|
+
if (ticking !== undefined) return;
|
|
944
|
+
ticking = globalThis.setTimeout(()=>{
|
|
945
|
+
const header1 = this.shadowRoot?.querySelector('.app-header');
|
|
946
|
+
if (header1) {
|
|
947
|
+
header1.classList.toggle('scrolled', globalThis.scrollY > 0);
|
|
948
|
+
}
|
|
949
|
+
ticking = undefined;
|
|
950
|
+
}, 100);
|
|
951
|
+
};
|
|
952
|
+
globalThis.addEventListener('scroll', onScroll, {
|
|
953
|
+
passive: true
|
|
954
|
+
});
|
|
955
|
+
this._scrollCleanup = ()=>{
|
|
956
|
+
globalThis.removeEventListener('scroll', onScroll);
|
|
957
|
+
if (ticking !== undefined) {
|
|
958
|
+
globalThis.clearTimeout(ticking);
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
_teardownScrollDetection() {
|
|
963
|
+
this._scrollCleanup?.();
|
|
964
|
+
this._scrollCleanup = undefined;
|
|
965
|
+
}
|
|
966
|
+
// --- Lifecycle ---
|
|
967
|
+
connectedCallback() {
|
|
968
|
+
super.connectedCallback();
|
|
969
|
+
const locales = this._locales;
|
|
970
|
+
if (locales.length > 1) {
|
|
971
|
+
const locale = this._currentLocale;
|
|
972
|
+
if (locales.includes(locale)) {
|
|
973
|
+
this.setAttribute('locale', locale);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
// Sync data-theme from document.documentElement on connect
|
|
977
|
+
const docTheme = document.documentElement?.dataset?.theme;
|
|
978
|
+
if (docTheme) {
|
|
979
|
+
this.setAttribute('data-theme', docTheme);
|
|
980
|
+
}
|
|
981
|
+
// SignalContext: provide theme state to all child components
|
|
982
|
+
const initialTheme = docTheme || 'light';
|
|
983
|
+
provideContext(this, THEME_CTX, initialTheme);
|
|
984
|
+
// Listen for theme change events from open-theme-toggle
|
|
985
|
+
this._themeHandler = (e)=>{
|
|
986
|
+
const detail = e.detail;
|
|
987
|
+
if (detail?.theme) {
|
|
988
|
+
this.setAttribute('data-theme', detail.theme);
|
|
989
|
+
provideContext(this, THEME_CTX, detail.theme);
|
|
990
|
+
this._propagateTheme(detail.theme);
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
globalThis.addEventListener?.('open:theme-change', this._themeHandler);
|
|
994
|
+
this._propagateTheme(initialTheme);
|
|
995
|
+
if (this.shadowRoot && this.shadowRoot.childNodes.length > 0) {
|
|
996
|
+
this._setupDetailsToggle();
|
|
997
|
+
}
|
|
998
|
+
this._setupSpaNavigation({
|
|
999
|
+
contentLoader: async (path1, locale)=>{
|
|
1000
|
+
await this._loadContent(path1, locale);
|
|
1001
|
+
},
|
|
1002
|
+
onAfterSwap: (_path)=>{
|
|
1003
|
+
this._updateActiveNav();
|
|
1004
|
+
}
|
|
1005
|
+
});
|
|
1006
|
+
// v0.23.0: Integrated from www/public/mobile-menu.js.
|
|
1007
|
+
// Close mobile menu on backdrop click or sidebar nav link click.
|
|
1008
|
+
this._docClickCleanup = this._setupBackdropClose();
|
|
1009
|
+
// Scroll detection for header backdrop blur
|
|
1010
|
+
this._setupScrollDetection();
|
|
1011
|
+
}
|
|
1012
|
+
disconnectedCallback() {
|
|
1013
|
+
super.disconnectedCallback();
|
|
1014
|
+
this._teardownSpaNavigation();
|
|
1015
|
+
this._docClickCleanup?.();
|
|
1016
|
+
if (this._themeHandler) {
|
|
1017
|
+
globalThis.removeEventListener?.('open:theme-change', this._themeHandler);
|
|
1018
|
+
}
|
|
1019
|
+
this._teardownScrollDetection();
|
|
1020
|
+
}
|
|
1021
|
+
attributeChangedCallback(name, old, val) {
|
|
1022
|
+
if (old === val) return;
|
|
1023
|
+
if (name === 'current-path') {
|
|
1024
|
+
this._updateActiveNav();
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
// --- Mobile menu ---
|
|
1028
|
+
// v0.31 UI-shell debt: replace _replaceShadowRootFromLayout with signal-driven SPA nav.
|
|
1029
|
+
// Currently SPA navigation destroys the entire shadow DOM and rebuilds it from
|
|
1030
|
+
// fetched HTML, then manually re-attaches events in _setupDetailsToggle. This is
|
|
1031
|
+
// incompatible with the signal architecture ?? we should make currentPath/navItems
|
|
1032
|
+
// signals and let data-signal markers handle DOM updates reactively. Then the
|
|
1033
|
+
// _setupDetailsToggle hack (and this entire method) can be deleted.
|
|
1034
|
+
_menuBtnHandler = null;
|
|
1035
|
+
_setupDetailsToggle() {
|
|
1036
|
+
const btn = this.shadowRoot?.querySelector('.mobile-menu-btn');
|
|
1037
|
+
if (!btn) return;
|
|
1038
|
+
// Remove any stale listener from a previous shadow root.
|
|
1039
|
+
if (this._menuBtnHandler) {
|
|
1040
|
+
btn.removeEventListener('click', this._menuBtnHandler);
|
|
1041
|
+
}
|
|
1042
|
+
this._menuBtnHandler = this._toggleMenu.bind(this);
|
|
1043
|
+
btn.addEventListener('click', this._menuBtnHandler);
|
|
1044
|
+
}
|
|
1045
|
+
_toggleMenu(_e) {
|
|
1046
|
+
const isOpen = this.hasAttribute('menu-open');
|
|
1047
|
+
this.toggleAttribute('menu-open', !isOpen);
|
|
1048
|
+
this._syncInert(!isOpen);
|
|
1049
|
+
}
|
|
1050
|
+
_syncInert(menuOpen) {
|
|
1051
|
+
const main1 = this.shadowRoot?.querySelector('.layout-main');
|
|
1052
|
+
if (main1) {
|
|
1053
|
+
if (menuOpen) main1.setAttribute('inert', '');
|
|
1054
|
+
else main1.removeAttribute('inert');
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* v0.23.0: Integrated from www/public/mobile-menu.js.
|
|
1059
|
+
* Closes mobile menu when backdrop or sidebar nav link is clicked.
|
|
1060
|
+
* Uses composedPath() to detect clicks across shadow DOM boundaries.
|
|
1061
|
+
*/ _setupBackdropClose() {
|
|
1062
|
+
const handler = (e)=>{
|
|
1063
|
+
const target = e.target;
|
|
1064
|
+
if (!target || !(target instanceof Element)) return;
|
|
1065
|
+
const path1 = e.composedPath();
|
|
1066
|
+
let isBackdrop = false;
|
|
1067
|
+
let isNavLink = false;
|
|
1068
|
+
for(let i = 0; i < path1.length; i++){
|
|
1069
|
+
const el = path1[i];
|
|
1070
|
+
if (!el?.classList) continue;
|
|
1071
|
+
if (el.classList.contains('mobile-backdrop')) {
|
|
1072
|
+
isBackdrop = true;
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
if (el.tagName === 'A') {
|
|
1076
|
+
isNavLink = true;
|
|
1077
|
+
break;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
if (!isBackdrop && !isNavLink) return;
|
|
1081
|
+
this._closeMenu();
|
|
1082
|
+
};
|
|
1083
|
+
document.addEventListener('click', handler);
|
|
1084
|
+
return ()=>document.removeEventListener('click', handler);
|
|
1085
|
+
}
|
|
1086
|
+
_closeMenu() {
|
|
1087
|
+
this.removeAttribute('menu-open');
|
|
1088
|
+
const details1 = this.shadowRoot?.querySelector('details.mobile-menu');
|
|
1089
|
+
if (details1) details1.removeAttribute('open');
|
|
1090
|
+
this._syncInert(false);
|
|
1091
|
+
}
|
|
1092
|
+
// --- Theme ---
|
|
1093
|
+
_propagateTheme(theme) {
|
|
1094
|
+
const walk = (root)=>{
|
|
1095
|
+
root.querySelectorAll('*').forEach((el)=>{
|
|
1096
|
+
if (el.tagName.includes('-')) {
|
|
1097
|
+
el.setAttribute('data-theme', theme);
|
|
1098
|
+
}
|
|
1099
|
+
if (el.shadowRoot) {
|
|
1100
|
+
walk(el.shadowRoot);
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
};
|
|
1104
|
+
// Walk light DOM children (slotted page components like docs-home, ui-showcase)
|
|
1105
|
+
walk(this);
|
|
1106
|
+
// Walk shadow DOM content (internal layout elements)
|
|
1107
|
+
if (this.shadowRoot) {
|
|
1108
|
+
walk(this.shadowRoot);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Recursively search for open-layout in parsed DOM, including
|
|
1113
|
+
* inside <template shadowrootmode="open"> (DSD content).
|
|
1114
|
+
*
|
|
1115
|
+
* querySelector does not traverse template content, but SSG pages
|
|
1116
|
+
* wrap page output in a page component whose shadow root contains
|
|
1117
|
+
* the <open-layout>.
|
|
1118
|
+
*/ _findOpenLayout(root) {
|
|
1119
|
+
for (const child of Array.from(root.children)){
|
|
1120
|
+
if (child.tagName.toLowerCase() === 'open-layout') return child;
|
|
1121
|
+
if (child.tagName === 'TEMPLATE') {
|
|
1122
|
+
const found = this._findOpenLayout(child.content);
|
|
1123
|
+
if (found) return found;
|
|
1124
|
+
}
|
|
1125
|
+
const found = this._findOpenLayout(child);
|
|
1126
|
+
if (found) return found;
|
|
1127
|
+
}
|
|
1128
|
+
return null;
|
|
1129
|
+
}
|
|
1130
|
+
_activateDeclarativeShadowRoots(root) {
|
|
1131
|
+
const templates = Array.from(root.querySelectorAll('template[shadowrootmode]'));
|
|
1132
|
+
if (root instanceof HTMLElement && root.firstElementChild instanceof HTMLTemplateElement && root.firstElementChild.hasAttribute('shadowrootmode')) {
|
|
1133
|
+
templates.unshift(root.firstElementChild);
|
|
1134
|
+
}
|
|
1135
|
+
for (const template of templates){
|
|
1136
|
+
const host = template.parentElement;
|
|
1137
|
+
if (!host || host.shadowRoot) {
|
|
1138
|
+
template.remove();
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
const mode = template.getAttribute('shadowrootmode') === 'closed' ? 'closed' : 'open';
|
|
1142
|
+
const shadow = host.attachShadow({
|
|
1143
|
+
mode
|
|
1144
|
+
});
|
|
1145
|
+
shadow.appendChild(template.content);
|
|
1146
|
+
template.remove();
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
_isShadowTemplate(el) {
|
|
1150
|
+
return el instanceof HTMLTemplateElement && el.hasAttribute('shadowrootmode');
|
|
1151
|
+
}
|
|
1152
|
+
_syncLayoutAttributes(newLayout, locale) {
|
|
1153
|
+
const incoming = new Set(Array.from(newLayout.attributes).map((attr)=>attr.name));
|
|
1154
|
+
const preserve = new Set([
|
|
1155
|
+
'data-theme',
|
|
1156
|
+
'theme'
|
|
1157
|
+
]);
|
|
1158
|
+
for (const attr of Array.from(this.attributes)){
|
|
1159
|
+
if (!incoming.has(attr.name) && !preserve.has(attr.name)) {
|
|
1160
|
+
this.removeAttribute(attr.name);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
for (const attr of Array.from(newLayout.attributes)){
|
|
1164
|
+
this.setAttribute(attr.name, attr.value);
|
|
1165
|
+
}
|
|
1166
|
+
this.setAttribute('locale', locale);
|
|
1167
|
+
this.setAttribute('current-path', newLayout.getAttribute('current-path') || this._currentPathWithoutLocale);
|
|
1168
|
+
}
|
|
1169
|
+
_replaceShadowRootFromLayout(newLayout) {
|
|
1170
|
+
const shadowTemplate = Array.from(newLayout.children).find((child)=>this._isShadowTemplate(child));
|
|
1171
|
+
if (!shadowTemplate || !this.shadowRoot) return;
|
|
1172
|
+
while(this.shadowRoot.firstChild){
|
|
1173
|
+
this.shadowRoot.removeChild(this.shadowRoot.firstChild);
|
|
1174
|
+
}
|
|
1175
|
+
this.shadowRoot.appendChild(document.adoptNode(shadowTemplate.content));
|
|
1176
|
+
this._activateDeclarativeShadowRoots(this.shadowRoot);
|
|
1177
|
+
this._setupDetailsToggle();
|
|
1178
|
+
this._updateSwitch(this.shadowRoot);
|
|
1179
|
+
}
|
|
1180
|
+
/* --- SPA navigation (inlined from @openelement/router) --- */ _setupSpaNavigation(opts) {
|
|
1181
|
+
this._navOptions = opts;
|
|
1182
|
+
if (this.shadowRoot) {
|
|
1183
|
+
this._setupClickDelegation(this.shadowRoot);
|
|
1184
|
+
}
|
|
1185
|
+
this._setupNavigationApi();
|
|
1186
|
+
this._setupPopState();
|
|
1187
|
+
}
|
|
1188
|
+
_teardownSpaNavigation() {
|
|
1189
|
+
this._cleanupNav?.();
|
|
1190
|
+
this._cleanupNav = undefined;
|
|
1191
|
+
this._navOptions = undefined;
|
|
1192
|
+
}
|
|
1193
|
+
_setupClickDelegation(root) {
|
|
1194
|
+
const handler = (e)=>{
|
|
1195
|
+
const link = e.target.closest('a');
|
|
1196
|
+
if (!link) return;
|
|
1197
|
+
const href = link.getAttribute('href');
|
|
1198
|
+
if (!href) return;
|
|
1199
|
+
if (!isSafeLayoutUrl(href) || /^https?:/i.test(href) || href.startsWith('#')) {
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
e.preventDefault();
|
|
1203
|
+
e.stopImmediatePropagation();
|
|
1204
|
+
const isLangSwitch = link.classList.contains('lang-switch');
|
|
1205
|
+
if (isLangSwitch) {
|
|
1206
|
+
this._replaceTo(href);
|
|
1207
|
+
} else {
|
|
1208
|
+
this._navigateTo(href);
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
root.addEventListener('click', handler);
|
|
1212
|
+
const prev = this._cleanupNav;
|
|
1213
|
+
this._cleanupNav = ()=>{
|
|
1214
|
+
root.removeEventListener('click', handler);
|
|
1215
|
+
prev?.();
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
_setupNavigationApi() {
|
|
1219
|
+
const nav1 = globalThis.navigation;
|
|
1220
|
+
if (!nav1) return;
|
|
1221
|
+
const onNav = (event)=>{
|
|
1222
|
+
const e = event;
|
|
1223
|
+
if (!e.canIntercept || e.hashChange || e.downloadRequest) return;
|
|
1224
|
+
const url = new URL(e.destination.url);
|
|
1225
|
+
if (url.origin !== location.origin) return;
|
|
1226
|
+
e.intercept({
|
|
1227
|
+
handler: ()=>this._navigateNow(url.pathname)
|
|
1228
|
+
});
|
|
1229
|
+
};
|
|
1230
|
+
try {
|
|
1231
|
+
nav1.addEventListener('navigate', onNav);
|
|
1232
|
+
const prev = this._cleanupNav;
|
|
1233
|
+
this._cleanupNav = ()=>{
|
|
1234
|
+
try {
|
|
1235
|
+
nav1.removeEventListener('navigate', onNav);
|
|
1236
|
+
} catch {}
|
|
1237
|
+
prev?.();
|
|
1238
|
+
};
|
|
1239
|
+
} catch {
|
|
1240
|
+
// Navigation API interception is optional; fall back to popstate routing.
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
_setupPopState() {
|
|
1244
|
+
const handler = ()=>{
|
|
1245
|
+
this._navigateNow(location.pathname);
|
|
1246
|
+
};
|
|
1247
|
+
globalThis.addEventListener('popstate', handler);
|
|
1248
|
+
const prev = this._cleanupNav;
|
|
1249
|
+
this._cleanupNav = ()=>{
|
|
1250
|
+
globalThis.removeEventListener('popstate', handler);
|
|
1251
|
+
prev?.();
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
_navigateTo(href) {
|
|
1255
|
+
const url = new URL(href, location.origin);
|
|
1256
|
+
if (url.origin !== location.origin) {
|
|
1257
|
+
location.href = href;
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
history.pushState(null, '', url.pathname + url.search + url.hash);
|
|
1261
|
+
this._navigateNow(url.pathname);
|
|
1262
|
+
}
|
|
1263
|
+
_replaceTo(href) {
|
|
1264
|
+
const url = new URL(href, location.origin);
|
|
1265
|
+
if (url.origin !== location.origin) return;
|
|
1266
|
+
history.replaceState(null, '', url.pathname + url.search + url.hash);
|
|
1267
|
+
this._navigateNow(url.pathname);
|
|
1268
|
+
}
|
|
1269
|
+
_navigateNow(pathname) {
|
|
1270
|
+
const locale = detectLocale(pathname, this._locales, this._defaultLocale);
|
|
1271
|
+
this.setAttribute('current-path', pathname);
|
|
1272
|
+
this.setAttribute('locale', locale);
|
|
1273
|
+
const opts = this._navOptions;
|
|
1274
|
+
if (!opts) return;
|
|
1275
|
+
// Update lang-switch immediately (before async fetch)
|
|
1276
|
+
if (this.shadowRoot) {
|
|
1277
|
+
this._updateSwitch(this.shadowRoot);
|
|
1278
|
+
}
|
|
1279
|
+
opts.contentLoader(pathname, locale).then(()=>{
|
|
1280
|
+
if (this.shadowRoot) {
|
|
1281
|
+
this._updateSwitch(this.shadowRoot);
|
|
1282
|
+
}
|
|
1283
|
+
opts.onAfterSwap?.(pathname, locale);
|
|
1284
|
+
}).catch((err)=>{
|
|
1285
|
+
log.warn('content load failed:', err);
|
|
1286
|
+
location.reload();
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
_updateSwitch(shadowRoot) {
|
|
1290
|
+
const link = shadowRoot.querySelector('.lang-switch');
|
|
1291
|
+
if (!link) return;
|
|
1292
|
+
const pathWithoutLocale = this._currentPathWithoutLocale;
|
|
1293
|
+
const currentLocale = this._currentLocale;
|
|
1294
|
+
link.textContent = switchLabel(currentLocale);
|
|
1295
|
+
link.setAttribute('href', switchPath(pathWithoutLocale, currentLocale, this._locales));
|
|
1296
|
+
}
|
|
1297
|
+
async _loadContent(path1, locale) {
|
|
1298
|
+
try {
|
|
1299
|
+
const resp = await fetch(path1);
|
|
1300
|
+
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
|
1301
|
+
const html = await resp.text();
|
|
1302
|
+
const parsed = new DOMParser().parseFromString(html, 'text/html');
|
|
1303
|
+
const tmp = parsed.body;
|
|
1304
|
+
const newLayout = this._findOpenLayout(tmp);
|
|
1305
|
+
if (!newLayout) throw new Error('No open-layout found');
|
|
1306
|
+
document.documentElement.lang = parsed.documentElement.lang || locale;
|
|
1307
|
+
if (parsed.title) document.title = parsed.title;
|
|
1308
|
+
this._syncHeadElement(parsed, 'meta[name="description"]');
|
|
1309
|
+
this._syncHeadElement(parsed, 'link[rel="canonical"]');
|
|
1310
|
+
this._syncHeadElements(parsed, 'link[rel="alternate"][hreflang]');
|
|
1311
|
+
this._syncLayoutAttributes(newLayout, locale);
|
|
1312
|
+
this._replaceShadowRootFromLayout(newLayout);
|
|
1313
|
+
// DOMParser nodes belong to a different document. adoptNode()
|
|
1314
|
+
// transfers ownership so appendChild works without errors.
|
|
1315
|
+
while(this.firstChild)this.removeChild(this.firstChild);
|
|
1316
|
+
const children = Array.from(newLayout.children).filter((child)=>!this._isShadowTemplate(child));
|
|
1317
|
+
for (const child of children){
|
|
1318
|
+
const adopted = document.adoptNode(child);
|
|
1319
|
+
if (adopted instanceof Element) {
|
|
1320
|
+
this._activateDeclarativeShadowRoots(adopted);
|
|
1321
|
+
}
|
|
1322
|
+
this.appendChild(adopted);
|
|
1323
|
+
}
|
|
1324
|
+
// Propagate theme to newly inserted components.
|
|
1325
|
+
const currentTheme = this.getAttribute('data-theme') || document.documentElement?.dataset?.theme;
|
|
1326
|
+
if (currentTheme) {
|
|
1327
|
+
this._propagateTheme(currentTheme);
|
|
1328
|
+
requestAnimationFrame(()=>this._propagateTheme(currentTheme));
|
|
1329
|
+
}
|
|
1330
|
+
globalThis.scrollTo({
|
|
1331
|
+
top: 0,
|
|
1332
|
+
behavior: 'smooth'
|
|
1333
|
+
});
|
|
1334
|
+
} catch (e) {
|
|
1335
|
+
log.warn('SPA navigation failed, reloading:', e);
|
|
1336
|
+
globalThis.location.reload();
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
_syncHeadElement(parsed, selector) {
|
|
1340
|
+
const incoming = parsed.head.querySelector(selector);
|
|
1341
|
+
const current = document.head.querySelector(selector);
|
|
1342
|
+
if (!incoming) {
|
|
1343
|
+
current?.remove();
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
const cloned = document.adoptNode(incoming.cloneNode(true));
|
|
1347
|
+
if (current) current.replaceWith(cloned);
|
|
1348
|
+
else document.head.appendChild(cloned);
|
|
1349
|
+
}
|
|
1350
|
+
_syncHeadElements(parsed, selector) {
|
|
1351
|
+
document.head.querySelectorAll(selector).forEach((el)=>el.remove());
|
|
1352
|
+
parsed.head.querySelectorAll(selector).forEach((el)=>{
|
|
1353
|
+
document.head.appendChild(document.adoptNode(el.cloneNode(true)));
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
_updateActiveNav() {
|
|
1357
|
+
if (!this.shadowRoot) return;
|
|
1358
|
+
const cp = this._currentPath();
|
|
1359
|
+
const links = this.shadowRoot.querySelectorAll('.docs-sidebar a[data-nav], .header-nav a[data-nav]');
|
|
1360
|
+
links.forEach((a1)=>{
|
|
1361
|
+
const nav1 = a1.getAttribute('data-nav');
|
|
1362
|
+
const isActive = nav1 === cp;
|
|
1363
|
+
a1.classList.toggle('active', isActive);
|
|
1364
|
+
if (isActive) a1.setAttribute('aria-current', 'page');
|
|
1365
|
+
else a1.removeAttribute('aria-current');
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1368
|
+
// --- Utilities ---
|
|
1369
|
+
_esc = escapeHtml;
|
|
1370
|
+
_escAttr = escapeAttr;
|
|
1371
|
+
}
|
|
1372
|
+
export default OpenLayout;
|
|
1373
|
+
// Guard: idempotent across SSR paths
|
|
1374
|
+
if (typeof customElements !== 'undefined' && !customElements.get(tagName)) {
|
|
1375
|
+
customElements.define(tagName, OpenLayout);
|
|
1376
|
+
}
|
|
1377
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy91aS9zcmMvb3Blbi1sYXlvdXQudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAanN4SW1wb3J0U291cmNlIEBvcGVuZWxlbWVudC9jb3JlICovXG4vKipcbiAqIEBvcGVuZWxlbWVudC91aSAtIG9wZW4tbGF5b3V0XG4gKlxuICogQXBwIGxheW91dCBjb21wb25lbnQgd2l0aCBoZWFkZXIsIHNpZGViYXIsIGFuZCBmb290ZXIuXG4gKiBXZWIgU3RhbmRhcmRzIExhYjogbGlnaHQtZmlyc3QsIHJlc3RyYWluZWQsIGRvY3VtZW50YXRpb24tZm9jdXNlZC5cbiAqXG4gKiB2MC4yMC4wOiBNaWdyYXRlZCBmcm9tIERzZExpdEVsZW1lbnQgdG8gRHNkRWxlbWVudCAoT2NlYW4gY29tcG9uZW50KS5cbiAqICAgLSBDU1NTdHlsZVNoZWV0IHJlcGxhY2VzIExpdCBjc3NgYFxuICogICAtIHJlbmRlcigpIHJldHVybnMgc3RyaW5nXG4gKiAgIC0gQGNsaWNrIGJpbmRpbmdzIGZvciBtb2JpbGUgbWVudSB0b2dnbGVcbiAqICAgLSBTUEEgbmF2aWdhdGlvbiB2aWEgTmF2aWdhdGlvbiBBUEkgKG5hdmlnYXRlL2ZldGNoL3N3YXApIHByZXNlcnZlZFxuICogICAtIEV2ZW50IGRlbGVnYXRpb24gYXQgc2hhZG93IHJvb3QgbGV2ZWwgZm9yIG5hdiBjbGlja3NcbiAqIHYwLjI0LjE6IE1pZ3JhdGVkIGZyb20gaHRtbGBgIHRlbXBsYXRlIHRvIEpTWCAoQURSLTAwNTcpLlxuICpcbiAqIEBjc3NwYXJ0IGNvbnRhaW5lciAtIFRoZSBhcHAtbGF5b3V0IHJvb3QgZGl2XG4gKiBAY3NzcGFydCBoZWFkZXIgLSBUaGUgc3RpY2t5IGhlYWRlciBlbGVtZW50XG4gKiBAY3NzcGFydCBzaWRlYmFyIC0gVGhlIGRvY3Mtc2lkZWJhciBuYXZcbiAqIEBjc3NwYXJ0IG1haW4gLSBUaGUgbGF5b3V0LW1haW4gZWxlbWVudFxuICogQGNzc3BhcnQgZm9vdGVyIC0gVGhlIGFwcC1mb290ZXIgZWxlbWVudFxuICogQGNzc3BhcnQgbmF2IC0gVGhlIGhlYWRlci1uYXYgZWxlbWVudFxuICogQGNzc3BhcnQgbmF2LXRvZ2dsZSAtIFRoZSBtb2JpbGUgbWVudSB0b2dnbGUgYnV0dG9uXG4gKlxuICogVXNhZ2U6XG4gKiBgYGBodG1sXG4gKiA8b3Blbi1sYXlvdXQgY3VycmVudC1wYXRoPVwiL2d1aWRlL2dldHRpbmctc3RhcnRlZFwiXG4gKiAgIG5hdi1pdGVtcz0nW3tcInNlY3Rpb25cIjpcIkd1aWRlXCIsXCJpdGVtc1wiOlt7XCJwYXRoXCI6XCIvZ3VpZGUvZ2V0dGluZy1zdGFydGVkXCIsXCJsYWJlbFwiOlwiR2V0dGluZyBTdGFydGVkXCJ9XX1dJz5cbiAqIDwvb3Blbi1sYXlvdXQ+XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgeyBPcGVuRWxlbWVudCB9IGZyb20gJ0BvcGVuZWxlbWVudC9lbGVtZW50JztcbmltcG9ydCB7IFN0eWxlU2hlZXQsIHR5cGUgU3R5bGVTaGVldExpa2UgfSBmcm9tICdAb3BlbmVsZW1lbnQvY29yZS9zdHlsZS1zaGVldCc7XG5pbXBvcnQgeyB0eXBlIENvbnRleHQsIGNyZWF0ZUNvbnRleHQsIHByb3ZpZGVDb250ZXh0IH0gZnJvbSAnQG9wZW5lbGVtZW50L2NvcmUnO1xuaW1wb3J0IHsgZXNjYXBlQXR0ciwgZXNjYXBlSHRtbCB9IGZyb20gJ0BvcGVuZWxlbWVudC9jb3JlJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJ0BvcGVuZWxlbWVudC9jb3JlL2xvZ2dlcic7XG5pbXBvcnQgJy5cXC9vcGVuLXRoZW1lLXRvZ2dsZS5qcyc7XG5pbXBvcnQgJy4vb3Blbi1icmFuZC1tYXJrLmpzJztcblxuZXhwb3J0IGNvbnN0IHRhZ05hbWUgPSAnb3Blbi1sYXlvdXQnO1xuY29uc3QgU0FGRV9VUkxfU0NIRU1FUyA9IG5ldyBTZXQoWydodHRwOicsICdodHRwczonLCAnbWFpbHRvOicsICd0ZWw6JywgJ3NtczonXSk7XG5jb25zdCBsb2cgPSBjcmVhdGVMb2dnZXIoJ3VpJyk7XG5cbmZ1bmN0aW9uIGlzU2FmZUxheW91dFVybCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCB0cmltbWVkID0gdXJsLnRyaW0oKTtcbiAgaWYgKCF0cmltbWVkKSByZXR1cm4gZmFsc2U7XG4gIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoJy8vJykpIHJldHVybiBmYWxzZTtcbiAgaWYgKFxuICAgIHRyaW1tZWQuc3RhcnRzV2l0aCgnLycpIHx8XG4gICAgdHJpbW1lZC5zdGFydHNXaXRoKCcjJykgfHxcbiAgICB0cmltbWVkLnN0YXJ0c1dpdGgoJy4vJykgfHxcbiAgICB0cmltbWVkLnN0YXJ0c1dpdGgoJy4uLycpXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcGFyc2VkID0gbmV3IFVSTCh0cmltbWVkLCAnaHR0cHM6Ly9vcGVuZWxlbWVudC5vcmcvJyk7XG4gICAgcmV0dXJuIFNBRkVfVVJMX1NDSEVNRVMuaGFzKHBhcnNlZC5wcm90b2NvbCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKiAtLS0gTmF2aWdhdGlvbiBBUEkgdHlwZXMgKGZvciBTUEEgcm91dGluZykgLS0tICovXG5pbnRlcmZhY2UgTmF2aWdhdGlvbkxpa2UgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gIGFkZEV2ZW50TGlzdGVuZXIodHlwZTogJ25hdmlnYXRlJywgbGlzdGVuZXI6IEV2ZW50TGlzdGVuZXIpOiB2b2lkO1xuICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGU6ICduYXZpZ2F0ZScsIGxpc3RlbmVyOiBFdmVudExpc3RlbmVyKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIE5hdmlnYXRpb25OYXZpZ2F0ZUV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICBjYW5JbnRlcmNlcHQ6IGJvb2xlYW47XG4gIGhhc2hDaGFuZ2U6IGJvb2xlYW47XG4gIGRvd25sb2FkUmVxdWVzdDogYm9vbGVhbjtcbiAgZGVzdGluYXRpb246IHsgdXJsOiBzdHJpbmcgfTtcbiAgaW50ZXJjZXB0KG9wdHM6IHsgaGFuZGxlcjogKCkgPT4gdm9pZCB9KTogdm9pZDtcbn1cblxuLyogLS0tIExvY2FsZS9wYXRoIGhlbHBlcnMgKGlubGluZWQgZnJvbSBAb3BlbmVsZW1lbnQvcm91dGVyKSAtLS0gKi9cblxuY29uc3QgTE9DQUxFX0xBQkVMUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgZW46ICfkuK3mlocnLCB6aDogJ0VuZ2xpc2gnIH07XG5cbmZ1bmN0aW9uIHBhcnNlUGF0aFdpdGhvdXRMb2NhbGUocGF0aG5hbWU6IHN0cmluZywgbG9jYWxlczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBzZWdzID0gcGF0aG5hbWUuc3BsaXQoJy8nKS5maWx0ZXIoQm9vbGVhbik7XG4gIGlmIChzZWdzLmxlbmd0aCA+IDAgJiYgbG9jYWxlcy5pbmNsdWRlcyhzZWdzWzBdKSkge1xuICAgIHJldHVybiAnLycgKyBzZWdzLnNsaWNlKDEpLmpvaW4oJy8nKSB8fCAnLyc7XG4gIH1cbiAgcmV0dXJuIHBhdGhuYW1lIHx8ICcvJztcbn1cblxuZnVuY3Rpb24gZGV0ZWN0TG9jYWxlKHBhdGhuYW1lOiBzdHJpbmcsIGxvY2FsZXM6IHN0cmluZ1tdLCBkZWZhdWx0TG9jYWxlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBzZWdzID0gcGF0aG5hbWUuc3BsaXQoJy8nKS5maWx0ZXIoQm9vbGVhbik7XG4gIGlmIChzZWdzLmxlbmd0aCA+IDAgJiYgbG9jYWxlcy5pbmNsdWRlcyhzZWdzWzBdKSkgcmV0dXJuIHNlZ3NbMF07XG4gIHJldHVybiBkZWZhdWx0TG9jYWxlO1xufVxuXG5mdW5jdGlvbiBsb2NhbGl6ZVBhdGgocGF0aDogc3RyaW5nLCBsb2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChpc1NhZmVMYXlvdXRVcmwocGF0aCkgJiYgL15odHRwcz86L2kudGVzdChwYXRoKSkgcmV0dXJuIHBhdGg7XG4gIHJldHVybiBgLyR7bG9jYWxlfSR7cGF0aH1gO1xufVxuXG5mdW5jdGlvbiBzd2l0Y2hQYXRoKGN1cnJlbnRQYXRoOiBzdHJpbmcsIGN1cnJlbnRMb2NhbGU6IHN0cmluZywgbG9jYWxlczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCBvdGhlciA9IGxvY2FsZXMuZmluZCgobCkgPT4gbCAhPT0gY3VycmVudExvY2FsZSkgfHwgY3VycmVudExvY2FsZTtcbiAgcmV0dXJuIGAvJHtvdGhlcn0ke2N1cnJlbnRQYXRofWA7XG59XG5cbmZ1bmN0aW9uIHN3aXRjaExhYmVsKGN1cnJlbnRMb2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBMT0NBTEVfTEFCRUxTW2N1cnJlbnRMb2NhbGVdIHx8IGN1cnJlbnRMb2NhbGU7XG59XG5cbi8qKiBTaWduYWxDb250ZXh0IGtleTogdGhlbWUgc3RhdGUgc2hhcmVkIGFjcm9zcyBhbGwgY29tcG9uZW50cyAqL1xuZXhwb3J0IGNvbnN0IFRIRU1FX0NUWDogQ29udGV4dDwnZGFyaycgfCAnbGlnaHQnPiA9IGNyZWF0ZUNvbnRleHQ8J2RhcmsnIHwgJ2xpZ2h0Jz4oXG4gIFN5bWJvbCgndGhlbWUnKSxcbiAgJ2xpZ2h0Jyxcbik7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2SXRlbSB7XG4gIHBhdGg/OiBzdHJpbmc7XG4gIGhyZWY/OiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmF2U2VjdGlvbiB7XG4gIHNlY3Rpb246IHN0cmluZztcbiAgaXRlbXM6IE5hdkl0ZW1bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIZWFkZXJOYXZMaW5rIHtcbiAgaHJlZjogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG5jb25zdCBzaGVldDogU3R5bGVTaGVldExpa2UgPSBuZXcgU3R5bGVTaGVldCgpO1xuc2hlZXQucmVwbGFjZVN5bmMoYFxuICA6aG9zdCB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gIH1cblxuICAqIHsgZm9udC1mYW1pbHk6IHZhcigtLWZvbnQtc2Fucyk7IH1cblxuICAuYXBwLWxheW91dCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIG1pbi1oZWlnaHQ6IDEwMHZoO1xuICAgIGJhY2tncm91bmQ6IHZhcigtLWJnLWJhc2UpO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnkpO1xuICAgIGZvbnQtZmFtaWx5OiB2YXIoLS1mb250LXNhbnMpO1xuICAgIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAgIC1tb3otb3N4LWZvbnQtc21vb3RoaW5nOiBncmF5c2NhbGU7XG4gIH1cblxuICAubGF5b3V0LWJvZHkge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleDogMTtcbiAgICBtYXgtd2lkdGg6IDE0MDBweDtcbiAgICBtYXJnaW46IDAgYXV0bztcbiAgICB3aWR0aDogMTAwJTtcbiAgfVxuXG4gIC5sYXlvdXQtbWFpbiB7XG4gICAgZmxleDogMTtcbiAgICBtaW4td2lkdGg6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gIH1cblxuICAuYXBwLWxheW91dFtob21lXSAubGF5b3V0LWJvZHksXG4gIC5hcHAtbGF5b3V0W2Z1bGwtd2lkdGhdIC5sYXlvdXQtYm9keSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIG1heC13aWR0aDogbm9uZTtcbiAgfVxuXG4gIC5hcHAtbGF5b3V0W2hvbWVdIC5sYXlvdXQtbWFpbixcbiAgLmFwcC1sYXlvdXRbZnVsbC13aWR0aF0gLmxheW91dC1tYWluIHtcbiAgICBmbGV4OiAxO1xuICB9XG5cbiAgLyogSGVhZGVyICovXG4gIC5hcHAtaGVhZGVyIHtcbiAgICBwb3NpdGlvbjogc3RpY2t5O1xuICAgIHRvcDogMDtcbiAgICB6LWluZGV4OiAxMDA7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tbmF2LWJnKTtcbiAgICBib3JkZXItYm90dG9tOiB2YXIoLS1ib3JkZXItc2l6ZS0xKSBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigxOHB4KSBzYXR1cmF0ZSgxNTAlKTtcbiAgICAtd2Via2l0LWJhY2tkcm9wLWZpbHRlcjogYmx1cigxOHB4KSBzYXR1cmF0ZSgxNTAlKTtcbiAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDAuMnMgZWFzZSwgYm9yZGVyLWNvbG9yIDAuMnMgZWFzZSwgYm94LXNoYWRvdyAwLjJzIGVhc2U7XG4gIH1cbiAgLmFwcC1oZWFkZXIuc2Nyb2xsZWQge1xuICAgIGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1iZy1iYXNlKSA4OCUsIHRyYW5zcGFyZW50KTtcbiAgICBib3JkZXItYm90dG9tLWNvbG9yOiB2YXIoLS1ib3JkZXItaG92ZXIpO1xuICAgIGJveC1zaGFkb3c6IDAgdmFyKC0tc2l6ZS0yKSB2YXIoLS1zaXplLTEwKSBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYnJhbmQpIDUlLCB0cmFuc3BhcmVudCk7XG4gIH1cblxuICAuaGVhZGVyLWlubmVyIHtcbiAgICBtYXgtd2lkdGg6IG5vbmU7XG4gICAgbWFyZ2luOiAwIGF1dG87XG4gICAgcGFkZGluZzogMCBjbGFtcCh2YXIoLS1zaXplLTUpLCAzLjV2dywgdmFyKC0tc2l6ZS05KSk7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIG1pbi1oZWlnaHQ6IHZhcigtLW5hdi1oZWlnaHQpO1xuICAgIGdhcDogdmFyKC0tc2l6ZS02KTtcbiAgfVxuXG4gIC5tb2JpbGUtdGFiLWJhciB7IGRpc3BsYXk6IG5vbmU7IH1cblxuICAubW9iaWxlLW1lbnUtYnRuIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgd2lkdGg6IHZhcigtLXNpemUtMTApO1xuICAgIGhlaWdodDogdmFyKC0tc2l6ZS0xMCk7XG4gICAgYm9yZGVyOiB2YXIoLS1ib3JkZXItc2l6ZS0xKSBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1yb3VuZCk7XG4gICAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWJnLWVsZXZhdGVkKSA3NCUsIHRyYW5zcGFyZW50KTtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBwYWRkaW5nOiAwO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjE1cyBlYXNlO1xuICB9XG4gIC5tb2JpbGUtbWVudS1idG46aG92ZXIge1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnkpO1xuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tYm9yZGVyLWhvdmVyKTtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1ob3Zlcik7XG4gIH1cblxuICAubG9nbyB7XG4gICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IHZhcigtLXNpemUtMyk7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtMyk7XG4gICAgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LTgpO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnkpO1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICBsZXR0ZXItc3BhY2luZzogMDtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICB9XG5cbiAgLmxvZ286aG92ZXIgb3Blbi1icmFuZC1tYXJrIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoY2FsYyh2YXIoLS1ib3JkZXItc2l6ZS0xKSAqIC0xKSk7XG4gIH1cblxuICBvcGVuLWJyYW5kLW1hcmsge1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSB2YXIoLS1kdXJhdGlvbi0yKSB2YXIoLS1lYXNlLTIpO1xuICB9XG5cbiAgLmxvZ28td29yZCB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWShjYWxjKHZhcigtLWJvcmRlci1zaXplLTEpICogLTEpKTtcbiAgfVxuXG4gIC5sb2dvLXN1YiB7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtMDApO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICBtYXJnaW4tbGVmdDogdmFyKC0tc2l6ZS0yKTtcbiAgICBmb250LWZhbWlseTogdmFyKC0tZm9udC1tb25vKTtcbiAgICBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtOCk7XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgfVxuXG4gIC5oZWFkZXItbmF2IHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogY2xhbXAodmFyKC0tc2l6ZS01KSwgM3Z3LCB2YXIoLS1zaXplLTgpKTtcbiAgICBmbGV4OiAxO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICB9XG4gIC5oZWFkZXItbmF2IGEge1xuICAgIGNvbG9yOiB2YXIoLS1uYXYtbGluay1jb2xvcik7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgIGZvbnQtc2l6ZTogdmFyKC0tZm9udC1zaXplLTEpO1xuICAgIGZvbnQtd2VpZ2h0OiB2YXIoLS1mb250LXdlaWdodC01KTtcbiAgICBwYWRkaW5nOiB2YXIoLS1zaXplLTIpIDA7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgMC4xNXMgZWFzZSwgYmFja2dyb3VuZCAwLjE1cyBlYXNlO1xuICB9XG4gIC5oZWFkZXItbmF2IGE6aG92ZXIge1xuICAgIGNvbG9yOiB2YXIoLS1uYXYtbGluay1ob3Zlcik7XG4gIH1cbiAgLmhlYWRlci1uYXYgYVthcmlhLWN1cnJlbnQ9XCJwYWdlXCJdIHtcbiAgICBjb2xvcjogdmFyKC0tYnJhbmQtZGVlcCk7XG4gICAgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LTgpO1xuICB9XG5cbiAgLmhlYWRlci1yaWdodCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogdmFyKC0tc2l6ZS0xKTtcbiAgICBtYXJnaW4tbGVmdDogYXV0bztcbiAgfVxuXG4gIC8qIENUQSBidXR0b25zICovXG4gIC5idG4tc2Vjb25kYXJ5IHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogdmFyKC0tc2l6ZS0yKTtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1wcmltYXJ5KTtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtYnV0dG9uKTtcbiAgICBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtc2VtaWJvbGQpO1xuICAgIHBhZGRpbmc6IHZhcigtLXNpemUtMikgdmFyKC0tc2l6ZS00KTtcbiAgICBib3JkZXI6IHZhcigtLWJvcmRlci1zaXplLTEpIHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1ib3JkZXIpIDcyJSwgdmFyKC0tYnJhbmQpKTtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtcm91bmQpO1xuICAgIGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1iZy1lbGV2YXRlZCkgNzYlLCB0cmFuc3BhcmVudCk7XG4gICAgYm94LXNoYWRvdzogaW5zZXQgMCAxcHggMCBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZ3JheS0wKSA3MCUsIHRyYW5zcGFyZW50KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4xNXMgZWFzZTtcbiAgfVxuICAuYnRuLXNlY29uZGFyeTpob3ZlciB7XG4gICAgY29sb3I6IHZhcigtLWJyYW5kLWRlZXApO1xuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tYnJhbmQtbGlnaHQpO1xuICAgIGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1icmFuZC1wYWxlKSA0MiUsIHZhcigtLWJnLWVsZXZhdGVkKSk7XG4gIH1cbiAgLmJ0bi1zZWNvbmRhcnkgc3ZnIHsgZmxleC1zaHJpbms6IDA7IH1cblxuICAuYnRuLXByaW1hcnkge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiA0cHg7XG4gICAgY29sb3I6IHZhcigtLW9uLWJyYW5kKTtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtYnV0dG9uKTtcbiAgICBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtc2VtaWJvbGQpO1xuICAgIHBhZGRpbmc6IHZhcigtLXNpemUtMikgdmFyKC0tc2l6ZS00KTtcbiAgICBib3JkZXI6IHZhcigtLWJvcmRlci1zaXplLTEpIHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1yb3VuZCk7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDEzNWRlZywgdmFyKC0tYnJhbmQpLCB2YXIoLS1icmFuZC1saWdodCkpO1xuICAgIGJveC1zaGFkb3c6IDAgdmFyKC0tc2l6ZS0yKSB2YXIoLS1zaXplLTUpIHZhcigtLWJyYW5kLWdsb3cpO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMTVzIGVhc2U7XG4gIH1cbiAgLmJ0bi1wcmltYXJ5OmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCB2YXIoLS1icmFuZC1ob3ZlciksIHZhcigtLWJyYW5kLWxpZ2h0KSk7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKGNhbGModmFyKC0tYm9yZGVyLXNpemUtMSkgKiAtMSkpO1xuICB9XG5cbiAgLmhlYWRlci1yaWdodCAuYnRuLXNlY29uZGFyeSxcbiAgLmhlYWRlci1yaWdodCAuYnRuLXByaW1hcnkge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAubGFuZy1zd2l0Y2gge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgbWluLXdpZHRoOiB2YXIoLS1zaXplLTkpO1xuICAgIHdpZHRoOiB2YXIoLS1zaXplLTkpO1xuICAgIGhlaWdodDogdmFyKC0tc2l6ZS05KTtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGZvbnQtc2l6ZTogdmFyKC0tZm9udC1zaXplLWJ1dHRvbik7XG4gICAgZm9udC13ZWlnaHQ6IHZhcigtLWZvbnQtd2VpZ2h0LXNlbWlib2xkKTtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xuICAgIGJvcmRlcjogMDtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtcm91bmQpO1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMTVzIGVhc2U7XG4gIH1cbiAgLmxhbmctc3dpdGNoOmhvdmVyIHtcbiAgICBjb2xvcjogdmFyKC0tYnJhbmQtZGVlcCk7XG4gICAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYnJhbmQtcGFsZSkgMzQlLCB0cmFuc3BhcmVudCk7XG4gIH1cblxuICAvKiBTaWRlYmFyICovXG4gIC5kb2NzLXNpZGViYXIge1xuICAgIHdpZHRoOiBjbGFtcCgyMDBweCwgMjB2dywgMjYwcHgpO1xuICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIGJvcmRlci1yaWdodDogdmFyKC0tYm9yZGVyLXNpemUtMSkgc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgICBwYWRkaW5nOiAycmVtIDA7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICBoZWlnaHQ6IGNhbGMoMTAwdmggLSB2YXIoLS1uYXYtaGVpZ2h0KSk7XG4gICAgcG9zaXRpb246IHN0aWNreTtcbiAgICB0b3A6IHZhcigtLW5hdi1oZWlnaHQpO1xuICAgIHNjcm9sbGJhci13aWR0aDogdGhpbjtcbiAgICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYmctZWxldmF0ZWQpIDQyJSwgdHJhbnNwYXJlbnQpO1xuICB9XG4gIDpob3N0KFtob21lXSkgLmRvY3Mtc2lkZWJhcixcbiAgOmhvc3QoW2Z1bGwtd2lkdGhdKSAuZG9jcy1zaWRlYmFyIHtcbiAgICB3aWR0aDogMDsgbWluLXdpZHRoOiAwOyBwYWRkaW5nOiAwO1xuICAgIG92ZXJmbG93OiBoaWRkZW47IGJvcmRlci1yaWdodDogbm9uZTtcbiAgfVxuXG4gIC5uYXYtc2VjdGlvbiB7IG1hcmdpbi1ib3R0b206IDEuNXJlbTsgfVxuICAubmF2LXNlY3Rpb24gc3VtbWFyeSB7XG4gICAgZm9udC1zaXplOiAwLjYyNXJlbTtcbiAgICBmb250LXdlaWdodDogODAwO1xuICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gICAgbGV0dGVyLXNwYWNpbmc6IDAuMjJlbTtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgcGFkZGluZzogMCAxLjVyZW07XG4gICAgbWFyZ2luLWJvdHRvbTogMC41cmVtO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBsaXN0LXN0eWxlOiBub25lO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDAuNXJlbTtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgfVxuICAubmF2LXNlY3Rpb24gc3VtbWFyeTo6LXdlYmtpdC1kZXRhaWxzLW1hcmtlciB7IGRpc3BsYXk6IG5vbmU7IH1cbiAgLm5hdi1zZWN0aW9uIHN1bW1hcnk6Om1hcmtlciB7IGNvbnRlbnQ6IFwiXCI7IH1cbiAgLm5hdi1zZWN0aW9uIHN1bW1hcnk6aG92ZXIgeyBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpOyB9XG5cbiAgLmRvY3Mtc2lkZWJhciBhIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgIGZvbnQtc2l6ZTogMC44NXJlbTtcbiAgICBwYWRkaW5nOiAwLjM1cmVtIDEuNXJlbTtcbiAgICBib3JkZXItbGVmdDogMnB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIHRyYW5zaXRpb246IGNvbG9yIDAuMTVzIGVhc2UsIGJvcmRlci1jb2xvciAwLjE1cyBlYXNlLCBiYWNrZ3JvdW5kIDAuMTVzIGVhc2U7XG4gIH1cbiAgLmRvY3Mtc2lkZWJhciBhOmhvdmVyIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xuICAgIGJhY2tncm91bmQ6IHZhcigtLWJnLWhvdmVyKTtcbiAgfVxuICAuZG9jcy1zaWRlYmFyIGEuYWN0aXZlLFxuICAuZG9jcy1zaWRlYmFyIGFbYXJpYS1jdXJyZW50PVwicGFnZVwiXSB7XG4gICAgY29sb3I6IHZhcigtLWJyYW5kKTtcbiAgICBib3JkZXItbGVmdC1jb2xvcjogdmFyKC0tYnJhbmQpO1xuICAgIGJhY2tncm91bmQ6IHZhcigtLWJyYW5kLXN1YnRsZSk7XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgfVxuXG4gIC8qIEZvb3RlciAqL1xuICAuYXBwLWZvb3RlciB7XG4gICAgYm9yZGVyLXRvcDogdmFyKC0tYm9yZGVyLXNpemUtMSkgc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tYmctZWxldmF0ZWQpIDU4JSwgdHJhbnNwYXJlbnQpO1xuICB9XG4gIC5mb290ZXItaW5uZXIge1xuICAgIG1heC13aWR0aDogMTI0MHB4O1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBhZGRpbmc6IHZhcigtLXNpemUtMTYpIHZhcigtLXNpemUtOCk7XG4gICAgZGlzcGxheTogZ3JpZDtcbiAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdCg0LCAxZnIpO1xuICAgIGdhcDogdmFyKC0tc2l6ZS04KTtcbiAgfVxuICAuZm9vdGVyLWNvbHVtbiBoNCB7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtYnV0dG9uKTtcbiAgICBmb250LXdlaWdodDogdmFyKC0tZm9udC13ZWlnaHQtc2VtaWJvbGQpO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LXByaW1hcnkpO1xuICAgIG1hcmdpbjogMCAwIHZhcigtLXNpemUtNCk7XG4gIH1cbiAgLmZvb3Rlci1jb2x1bW4gYSB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgY29sb3I6IHZhcigtLXRleHQtc2Vjb25kYXJ5KTtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtYm9keS1zbSk7XG4gICAgcGFkZGluZzogNHB4IDA7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgMC4xNXMgZWFzZTtcbiAgfVxuICAuZm9vdGVyLWNvbHVtbiBhOmhvdmVyIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1wcmltYXJ5KTtcbiAgfVxuICAuZm9vdGVyLWJvdHRvbSB7XG4gICAgYm9yZGVyLXRvcDogdmFyKC0tYm9yZGVyLXNpemUtMSkgc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgICBwYWRkaW5nOiB2YXIoLS1zaXplLTQpIHZhcigtLXNpemUtOCk7XG4gICAgbWF4LXdpZHRoOiAxMjQwcHg7XG4gICAgbWFyZ2luOiAwIGF1dG87XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtYm9keS1zbSk7XG4gIH1cbiAgLmZvb3Rlci1ib3R0b20gYSB7XG4gICAgY29sb3I6IHZhcigtLXRleHQtc2Vjb25kYXJ5KTtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgMC4xNXMgZWFzZTtcbiAgfVxuICAuZm9vdGVyLWJvdHRvbSBhOmhvdmVyIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1wcmltYXJ5KTtcbiAgfVxuXG4gIC8qIE1vYmlsZSBiYWNrZHJvcCAqL1xuICAubW9iaWxlLWJhY2tkcm9wIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7IGluc2V0OiAwOyB0b3A6IHZhcigtLW5hdi1oZWlnaHQpO1xuICAgIGJhY2tncm91bmQ6IHZhcigtLW92ZXJsYXkpO1xuICAgIHotaW5kZXg6IDgwOyBvcGFjaXR5OiAwOyBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuM3MgZWFzZTtcbiAgfVxuXG4gIC8qIFJlc3BvbnNpdmUgKi9cbiAgQG1lZGlhIChtYXgtd2lkdGg6IDExMjBweCkge1xuICAgIC5oZWFkZXItaW5uZXIge1xuICAgICAgZ2FwOiB2YXIoLS1zaXplLTMpO1xuICAgICAgcGFkZGluZy1pbmxpbmU6IHZhcigtLXNpemUtNCk7XG4gICAgfVxuXG4gICAgLmhlYWRlci1uYXYge1xuICAgICAgZ2FwOiB2YXIoLS1zaXplLTMpO1xuICAgIH1cblxuICAgIC5idG4tc2Vjb25kYXJ5IC5idG4tdGV4dCB7IGRpc3BsYXk6IG5vbmU7IH1cbiAgfVxuXG4gIEBtZWRpYSAobWF4LXdpZHRoOiA5MDBweCkge1xuICAgIC5tb2JpbGUtbWVudS1idG4geyBkaXNwbGF5OiBmbGV4OyB9XG4gICAgLmhlYWRlci1pbm5lciB7IHBhZGRpbmc6IDAgdmFyKC0tc2l6ZS00KTsgZ2FwOiB2YXIoLS1zaXplLTIpOyB9XG4gICAgLmhlYWRlci1uYXYgeyBkaXNwbGF5OiBub25lOyB9XG4gICAgLmJ0bi1zZWNvbmRhcnkgLmJ0bi10ZXh0IHsgZGlzcGxheTogbm9uZTsgfVxuICAgIC5oZWFkZXItcmlnaHQgeyBnYXA6IDRweDsgfVxuXG4gICAgLmRvY3Mtc2lkZWJhciB7XG4gICAgICBwb3NpdGlvbjogZml4ZWQ7IHRvcDogdmFyKC0tbmF2LWhlaWdodCk7IGxlZnQ6IDA7XG4gICAgICB3aWR0aDogbWluKDI4MHB4LCA4MHZ3KTtcbiAgICAgIGhlaWdodDogY2FsYygxMDB2aCAtIHZhcigtLW5hdi1oZWlnaHQpKTsgei1pbmRleDogOTA7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1iZy1lbGV2YXRlZCk7XG4gICAgICBib3JkZXItcmlnaHQ6IHZhcigtLWJvcmRlci1zaXplLTEpIHNvbGlkIHZhcigtLWJvcmRlcik7XG4gICAgICBwYWRkaW5nOiAxcmVtIDA7IG92ZXJmbG93LXk6IGF1dG87XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMSUpO1xuICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMjVzIGN1YmljLWJlemllcigwLjQsMCwwLjIsMSk7XG4gICAgICB3aWxsLWNoYW5nZTogdHJhbnNmb3JtO1xuICAgIH1cbiAgICA6aG9zdChbbWVudS1vcGVuXSkgLmRvY3Mtc2lkZWJhciB7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XG4gICAgICBib3gtc2hhZG93OiB2YXIoLS1zaGFkb3ctMSk7XG4gICAgfVxuICAgIDpob3N0KFttZW51LW9wZW5dKSAubW9iaWxlLWJhY2tkcm9wIHsgb3BhY2l0eTogMTsgcG9pbnRlci1ldmVudHM6IGF1dG87IH1cbiAgICAubmF2LXNlY3Rpb24geyBtYXJnaW4tYm90dG9tOiAwLjVyZW07IH1cbiAgICAubmF2LXNlY3Rpb24gc3VtbWFyeSB7IHBhZGRpbmc6IHZhcigtLXNpemUtMikgdmFyKC0tc2l6ZS00KTsgfVxuICAgIC5kb2NzLXNpZGViYXIgYSB7IHBhZGRpbmc6IDAuNXJlbSAxcmVtIDAuNXJlbSAycmVtOyB9XG4gICAgLmxheW91dC1tYWluIHsgd2lkdGg6IDEwMCU7IH1cbiAgICAuYXBwLWZvb3RlciB7IHBhZGRpbmc6IDA7IH1cbiAgICAuZm9vdGVyLWlubmVyIHtcbiAgICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KDIsIDFmcik7XG4gICAgICBwYWRkaW5nOiB2YXIoLS1zaXplLTEyKSB2YXIoLS1zaXplLTQpO1xuICAgICAgcGFkZGluZy1ib3R0b206IGNhbGModmFyKC0tc2l6ZS0xMikgKyB2YXIoLS1zaXplLTE2KSk7XG4gICAgfVxuICAgIC5mb290ZXItYm90dG9tIHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBnYXA6IHZhcigtLXNpemUtMik7XG4gICAgICBwYWRkaW5nOiB2YXIoLS1zaXplLTQpO1xuICAgICAgcGFkZGluZy1ib3R0b206IGNhbGModmFyKC0tc2l6ZS00KSArIHZhcigtLXNpemUtMTYpKTtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG5cbiAgICAubW9iaWxlLXRhYi1iYXIge1xuICAgICAgZGlzcGxheTogZmxleDsgcG9zaXRpb246IGZpeGVkOyBib3R0b206IDA7IGxlZnQ6IDA7IHJpZ2h0OiAwO1xuICAgICAgaGVpZ2h0OiA1NnB4OyB6LWluZGV4OiAxMDA7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1uYXYtYmcpO1xuICAgICAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDEycHgpIHNhdHVyYXRlKDE4MCUpO1xuICAgICAgLXdlYmtpdC1iYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTJweCkgc2F0dXJhdGUoMTgwJSk7XG4gICAgICBib3JkZXItdG9wOiB2YXIoLS1ib3JkZXItc2l6ZS0xKSBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgICAgcGFkZGluZzogMCBlbnYoc2FmZS1hcmVhLWluc2V0LXJpZ2h0KSAwIGVudihzYWZlLWFyZWEtaW5zZXQtbGVmdCk7XG4gICAgICBwYWRkaW5nLWJvdHRvbTogZW52KHNhZmUtYXJlYS1pbnNldC1ib3R0b20pO1xuICAgIH1cbiAgICAudGFiLWl0ZW0ge1xuICAgICAgZmxleDogMTsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyOyBnYXA6IDJweDtcbiAgICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTsgZm9udC1zaXplOiAxMHB4OyBmb250LXdlaWdodDogNjAwO1xuICAgICAgdHJhbnNpdGlvbjogY29sb3IgMC4xNXMgZWFzZTtcbiAgICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQ7IHBhZGRpbmc6IDRweCAwO1xuICAgIH1cbiAgICAudGFiLWl0ZW0gc3ZnIHsgd2lkdGg6IDIwcHg7IGhlaWdodDogMjBweDsgZmxleC1zaHJpbms6IDA7IH1cbiAgICAudGFiLWl0ZW06aG92ZXIgeyBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpOyB9XG4gICAgLnRhYi1pdGVtLmFjdGl2ZSB7IGNvbG9yOiB2YXIoLS1icmFuZCk7IH1cbiAgfVxuXG4gIEBtZWRpYSAobWF4LXdpZHRoOiA3NjhweCkge1xuICAgIC5oZWFkZXItcmlnaHQgeyBnYXA6IDRweDsgfVxuICAgIC5sYW5nLXN3aXRjaCB7IGRpc3BsYXk6IG5vbmU7IH1cbiAgfVxuICBAbWVkaWEgKG1heC13aWR0aDogNDgwcHgpIHtcbiAgICAuYnRuLXByaW1hcnkgeyBkaXNwbGF5OiBub25lOyB9XG4gICAgLmJ0bi1zZWNvbmRhcnkgeyBwYWRkaW5nOiA4cHg7IGJvcmRlcjogbm9uZTsgfVxuICAgIC5idG4tc2Vjb25kYXJ5IC5idG4tdGV4dCB7IGRpc3BsYXk6IG5vbmU7IH1cbiAgICAuaGVhZGVyLWlubmVyIHsgcGFkZGluZzogMCB2YXIoLS1zaXplLTMpOyBnYXA6IHZhcigtLXNpemUtMSk7IH1cbiAgfVxuYCk7XG5cbmV4cG9ydCBjbGFzcyBPcGVuTGF5b3V0IGV4dGVuZHMgT3BlbkVsZW1lbnQge1xuICBwcml2YXRlIF9jbGVhbnVwTmF2PzogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBfc2Nyb2xsQ2xlYW51cD86ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgX25hdk9wdGlvbnM/OiB7XG4gICAgY29udGVudExvYWRlcjogKHBhdGg6IHN0cmluZywgbG9jYWxlOiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD47XG4gICAgb25BZnRlclN3YXA/OiAocGF0aDogc3RyaW5nLCBsb2NhbGU6IHN0cmluZykgPT4gdm9pZDtcbiAgfTtcblxuICBwcml2YXRlIGdldCBfbG9jYWxlcygpOiBzdHJpbmdbXSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9ICh0aGlzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5sb2NhbGVzIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdsb2NhbGVzJyk7XG4gICAgICBpZiAocmF3KSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJhdykpIHJldHVybiByYXcgYXMgc3RyaW5nW107XG4gICAgICAgIGlmICh0eXBlb2YgcmF3ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICAgIH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gWydlbiddO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIFsnZW4nXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCBfZGVmYXVsdExvY2FsZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnbG9jYWxlJykgfHwgdGhpcy5fbG9jYWxlc1swXSB8fCAnZW4nO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX2N1cnJlbnRMb2NhbGUoKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzLmxvY2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gZGV0ZWN0TG9jYWxlKGxvY2F0aW9uLnBhdGhuYW1lLCB0aGlzLl9sb2NhbGVzLCB0aGlzLl9kZWZhdWx0TG9jYWxlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0TG9jYWxlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRMb2NhbGU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX2N1cnJlbnRQYXRoV2l0aG91dExvY2FsZSgpOiBzdHJpbmcge1xuICAgIHRyeSB7XG4gICAgICBpZiAodHlwZW9mIGdsb2JhbFRoaXMubG9jYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBwYXJzZVBhdGhXaXRob3V0TG9jYWxlKGxvY2F0aW9uLnBhdGhuYW1lLCB0aGlzLl9sb2NhbGVzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnY3VycmVudC1wYXRoJykgfHwgJy8nO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuICcvJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgb3ZlcnJpZGUgc3R5bGVzID0gW3NoZWV0XTtcbiAgc3RhdGljIG92ZXJyaWRlIG9ic2VydmVkQXR0cmlidXRlcyA9IFtcbiAgICAnY3VycmVudC1wYXRoJyxcbiAgICAnbmF2LWl0ZW1zJyxcbiAgICAnaGVhZGVyLW5hdicsXG4gICAgJ2xvZ28tdGV4dCcsXG4gICAgJ2xvZ28tc3ViJyxcbiAgICAnZ2l0aHViLXVybCcsXG4gICAgJ2VkaXQtdXJsJyxcbiAgICAnbG9jYWxlJyxcbiAgICAnbG9jYWxlcycsXG4gIF07XG5cbiAgcHJpdmF0ZSBfdGhlbWVIYW5kbGVyPzogKGU6IEV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIF9kb2NDbGlja0NsZWFudXA/OiAoKSA9PiB2b2lkO1xuXG4gIG92ZXJyaWRlIHJlbmRlcigpOiBSZXR1cm5UeXBlPHR5cGVvZiBPcGVuRWxlbWVudC5wcm90b3R5cGUucmVuZGVyPiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlbmRlckxheW91dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0U3RyKGF0dHI6IHN0cmluZywgZGVmOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNhbWVsID0gYXR0ci5yZXBsYWNlKC8tKFthLXpdKS9nLCAoXywgYzogc3RyaW5nKSA9PiBjLnRvVXBwZXJDYXNlKCkpO1xuICAgIGNvbnN0IHByb3AgPSAodGhpcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbY2FtZWxdO1xuICAgIGlmIChwcm9wICE9PSB1bmRlZmluZWQgJiYgcHJvcCAhPT0gbnVsbCkgcmV0dXJuIFN0cmluZyhwcm9wKTtcbiAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoYXR0cikgfHwgZGVmO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0Qm9vbChhdHRyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBjYW1lbCA9IGF0dHIucmVwbGFjZSgvLShbYS16XSkvZywgKF8sIGM6IHN0cmluZykgPT4gYy50b1VwcGVyQ2FzZSgpKTtcbiAgICBjb25zdCBwcm9wID0gKHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NhbWVsXTtcbiAgICBpZiAodHlwZW9mIHByb3AgPT09ICdib29sZWFuJykgcmV0dXJuIHByb3A7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKGF0dHIpO1xuICB9XG5cbiAgLy8gX2N1cnJlbnRQYXRoV2l0aG91dExvY2FsZSwgX2N1cnJlbnRMb2NhbGUsIF9sb2NhbGVzLCBfc3dpdGNoUGF0aCgpLFxuICAvLyBfc3dpdGNoTGFiZWwoKSwgX3VwZGF0ZVN3aXRjaCgpLCBfbG9jYWxpemVQYXRoKClcbiAgLy8gPz8gYWxsIGlubGluZWQgKHJlcGxhY2VzIGZvcm1lciBAb3BlbmVsZW1lbnQvcm91dGVyIGRlcGVuZGVuY3kpXG5cbiAgcHJpdmF0ZSBfY3VycmVudFBhdGgoKTogc3RyaW5nIHtcbiAgICAvLyBTU1Itc2FmZTogcHJlZmVyIGF0dHJpYnV0ZS9wcm9wIHNldCBieSByZW5kZXJEc2Qgb3ZlciBVUkwgZGV0ZWN0aW9uXG4gICAgLy8gbG9jYXRpb24ucGF0aG5hbWUgaXMgdW5kZWZpbmVkIGR1cmluZyBidWlsZC5cbiAgICBjb25zdCBwcm9wID0gKHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmN1cnJlbnRQYXRoO1xuICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gJ3N0cmluZycgJiYgcHJvcC5sZW5ndGggPiAwKSByZXR1cm4gcHJvcDtcbiAgICBjb25zdCBhdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2N1cnJlbnQtcGF0aCcpO1xuICAgIGlmIChhdHRyICYmIGF0dHIubGVuZ3RoID4gMCkgcmV0dXJuIGF0dHI7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0eXBlb2YgZ2xvYmFsVGhpcy5sb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlUGF0aFdpdGhvdXRMb2NhbGUobG9jYXRpb24ucGF0aG5hbWUsIHRoaXMuX2xvY2FsZXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCdjdXJyZW50LXBhdGgnKSB8fCAnLyc7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gJy8nO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDb21wdXRlIEdpdEh1YiBlZGl0IFVSTCBmcm9tIGN1cnJlbnQgcGF0aC4gKi9cbiAgcHJpdmF0ZSBfY29tcHV0ZUVkaXRVcmwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXRoID0gdGhpcy5fY3VycmVudFBhdGgoKTtcbiAgICBpZiAoIXBhdGggfHwgcGF0aCA9PT0gJy8nKSByZXR1cm4gJyc7XG4gICAgY29uc3QgRURJVF9CQVNFID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS9vcGVuLWVsZW1lbnQvb3BlbmVsZW1lbnQvZWRpdC9tYWluL3d3dy9hcHAvcm91dGVzJztcbiAgICBjb25zdCBjbGVhbiA9IHBhdGgucmVwbGFjZSgvXFwvJC8sICcnKS5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKTtcbiAgICAvLyBSZW1vdmUgbG9jYWxlIHByZWZpeCBpZiBwcmVzZW50IChlbi8sIHpoLylcbiAgICBpZiAoWydlbicsICd6aCddLmluY2x1ZGVzKGNsZWFuWzBdKSkgY2xlYW4uc2hpZnQoKTtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGNsZWFuLmxlbmd0aCA9PT0gMCA/ICdpbmRleC9pbmRleCcgOiBjbGVhbi5qb2luKCcvJyk7XG4gICAgcmV0dXJuIGAke0VESVRfQkFTRX0vJHtmaWxlUGF0aH0udHN4YDtcbiAgfVxuXG4gIHByaXZhdGUgX25hdkl0ZW1zKCk6IE5hdlNlY3Rpb25bXSB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLl9yYXdOYXZJdGVtcygpO1xuICAgIHJldHVybiB0aGlzLl9maWx0ZXJCeVBhdGgoaXRlbXMpO1xuICB9XG5cbiAgLyoqIEF1dG8tZmlsdGVyIHNpZGViYXIgc2VjdGlvbnMgYnkgY3VycmVudCBwYXRoIHByZWZpeC4gKi9cbiAgcHJpdmF0ZSBfZmlsdGVyQnlQYXRoKGl0ZW1zOiBOYXZTZWN0aW9uW10pOiBOYXZTZWN0aW9uW10ge1xuICAgIGNvbnN0IHBhdGggPSB0aGlzLl9jdXJyZW50UGF0aCgpO1xuICAgIGNvbnN0IFNFQ1RJT05fTUFQOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gPSB7XG4gICAgICAnL2d1aWRlJzogWydRdWljayBTdGFydCcsICdDb3JlJywgJ1Byb2R1Y3Rpb24nXSxcbiAgICAgICcvYXJjaGl0ZWN0dXJlJzogWydQcmluY2lwbGVzJywgJ0NvbXBhdGliaWxpdHknLCAnUmVmZXJlbmNlJ10sXG4gICAgICAnL3JlZ2lzdHJ5JzogWydSZWdpc3RyeSddLFxuICAgICAgJy9odWInOiBbJ1JlZ2lzdHJ5J10sXG4gICAgICAnL2Jsb2cnOiBbJ0hpc3RvcnknXSxcbiAgICB9O1xuICAgIGZvciAoY29uc3QgW3ByZWZpeCwgc2VjdGlvbnNdIG9mIE9iamVjdC5lbnRyaWVzKFNFQ1RJT05fTUFQKSkge1xuICAgICAgaWYgKHBhdGguc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoKHMpID0+IHNlY3Rpb25zLmluY2x1ZGVzKHMuc2VjdGlvbikpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBwcml2YXRlIF9yYXdOYXZJdGVtcygpOiBOYXZTZWN0aW9uW10ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwcm9wID0gKHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLm5hdkl0ZW1zO1xuICAgICAgaWYgKHByb3AgJiYgQXJyYXkuaXNBcnJheShwcm9wKSkgcmV0dXJuIHByb3AgYXMgTmF2U2VjdGlvbltdO1xuICAgICAgY29uc3QgcmF3ID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ25hdi1pdGVtcycpO1xuICAgICAgaWYgKHJhdykgcmV0dXJuIEpTT04ucGFyc2UocmF3KTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cud2FybignRmFpbGVkIHRvIHBhcnNlIG5hdi1pdGVtcyBKU09OOicsIGUpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2hlYWRlck5hdigpOiBIZWFkZXJOYXZMaW5rW10ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwcm9wID0gKHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmhlYWRlck5hdjtcbiAgICAgIGlmIChwcm9wICYmIEFycmF5LmlzQXJyYXkocHJvcCkpIHJldHVybiBwcm9wIGFzIEhlYWRlck5hdkxpbmtbXTtcbiAgICAgIGNvbnN0IHJhdyA9IHRoaXMuZ2V0QXR0cmlidXRlKCdoZWFkZXItbmF2Jyk7XG4gICAgICBpZiAocmF3KSByZXR1cm4gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZy53YXJuKCdGYWlsZWQgdG8gcGFyc2UgaGVhZGVyLW5hdiBKU09OOicsIGUpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLSBJY29ucyAtLS1cblxuICAvKiogdjAuMjQuMTogU1ZHIGljb24gYXR0cmlidXRlcyBzaGFyZWQgYWNyb3NzIGFsbCBtb2JpbGUgdGFiIGJhciBpY29ucy4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX0lDT05fQVRUUlMgPSB7XG4gICAgdmlld0JveDogJzAgMCAyMCAyMCcsXG4gICAgZmlsbDogJ25vbmUnLFxuICAgIHN0cm9rZTogJ2N1cnJlbnRDb2xvcicsXG4gICAgJ3N0cm9rZS13aWR0aCc6ICcxLjUnLFxuICAgICdzdHJva2UtbGluZWNhcCc6ICdyb3VuZCcgYXMgY29uc3QsXG4gICAgJ3N0cm9rZS1saW5lam9pbic6ICdyb3VuZCcgYXMgY29uc3QsXG4gIH07XG5cbiAgLyoqIHYwLjI0LjE6IFJlbmRlciBtb2JpbGUgdGFiIGljb24gYXMgSlNYIFNWRy4gRmFsbHMgYmFjayB0byBhIGdlbmVyaWMgc2hhcGUuICovXG4gIHByaXZhdGUgX3JlbmRlckljb24obGFiZWw6IHN0cmluZykge1xuICAgIGNvbnN0IGEgPSBPcGVuTGF5b3V0Ll9JQ09OX0FUVFJTO1xuICAgIHN3aXRjaCAobGFiZWwpIHtcbiAgICAgIGNhc2UgJ0hvbWUnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPHBhdGggZD0nTTMgMTBsNy03IDcgNycgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J001IDh2OWgzdi01aDR2NWgzVjgnIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgICk7XG4gICAgICBjYXNlICdEb2NzJzpcbiAgICAgIGNhc2UgJ0Jsb2cnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPHJlY3QgeD0nMycgeT0nMicgd2lkdGg9JzE0JyBoZWlnaHQ9JzE2JyByeD0nMicgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J003IDZoNk03IDEwaDZNNyAxNGgzJyAvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICApO1xuICAgICAgY2FzZSAnRXhhbXBsZXMnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPHJlY3QgeD0nMycgeT0nMycgd2lkdGg9JzE0JyBoZWlnaHQ9JzE0JyByeD0nMicgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J003IDdsNiAzLTYgM3onIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgICk7XG4gICAgICBjYXNlICdDb21wb25lbnRzJzpcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8c3ZnIHsuLi5hfT5cbiAgICAgICAgICAgIDxyZWN0IHg9JzInIHk9JzInIHdpZHRoPSc3JyBoZWlnaHQ9JzcnIHJ4PScxJyAvPlxuICAgICAgICAgICAgPHJlY3QgeD0nMTEnIHk9JzInIHdpZHRoPSc3JyBoZWlnaHQ9JzcnIHJ4PScxJyAvPlxuICAgICAgICAgICAgPHJlY3QgeD0nMicgeT0nMTEnIHdpZHRoPSc3JyBoZWlnaHQ9JzcnIHJ4PScxJyAvPlxuICAgICAgICAgICAgPHJlY3QgeD0nMTEnIHk9JzExJyB3aWR0aD0nNycgaGVpZ2h0PSc3JyByeD0nMScgLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJ0FyY2hpdGVjdHVyZSc6XG4gICAgICBjYXNlICdFbmdpbmUnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPGNpcmNsZSBjeD0nMTAnIGN5PScxMCcgcj0nMycgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J00xMCAxdjJNMTAgMTd2Mk0zLjUgMy41bDEuNCAxLjRNMTUuMSAxNS4xbDEuNCAxLjRNMSAxMGgyTTE3IDEwaDJNMy41IDE2LjVsMS40LTEuNE0xNS4xIDQuOWwxLjQtMS40JyAvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICApO1xuICAgICAgY2FzZSAnSHViJzpcbiAgICAgIGNhc2UgJ1JlZ2lzdHJ5SHViJzpcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8c3ZnIHsuLi5hfT5cbiAgICAgICAgICAgIDxwYXRoIGQ9J00xMCAybDcgNHY4bC03IDQtNy00VjZ6JyAvPlxuICAgICAgICAgICAgPHBhdGggZD0nTTEwIDEwbDctNE0xMCAxMHY4TTEwIDEwTDMgNicgLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJ1JvYWRtYXAnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPGNpcmNsZSBjeD0nNCcgY3k9JzYnIHI9JzEuNScgLz5cbiAgICAgICAgICAgIDxjaXJjbGUgY3g9JzEwJyBjeT0nMTAnIHI9JzEuNScgLz5cbiAgICAgICAgICAgIDxjaXJjbGUgY3g9JzE2JyBjeT0nMTQnIHI9JzEuNScgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J001LjUgNmgxME0xMS41IDEwaDUnIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgICk7XG4gICAgICBjYXNlICdGcmFtZXdvcmsnOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPHBhdGggZD0nTTUgM2gxME01IDN2Nmg3TTEyIDl2M001IDE3aDcnIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgICk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxzdmcgey4uLmF9PlxuICAgICAgICAgICAgPGNpcmNsZSBjeD0nMTAnIGN5PScxMCcgcj0nOCcgLz5cbiAgICAgICAgICAgIDxwYXRoIGQ9J002IDZsMyA1IDUgMy0zLTV6JyAvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NhZmVIcmVmKGhyZWY6IHN0cmluZyB8IHVuZGVmaW5lZCwgZmFsbGJhY2sgPSAnIycpOiBzdHJpbmcge1xuICAgIGlmICghaHJlZikgcmV0dXJuIGZhbGxiYWNrO1xuICAgIGNvbnN0IHRyaW1tZWQgPSBocmVmLnRyaW0oKTtcbiAgICByZXR1cm4gaXNTYWZlTGF5b3V0VXJsKHRyaW1tZWQpID8gdHJpbW1lZCA6IGZhbGxiYWNrO1xuICB9XG5cbiAgcHJpdmF0ZSBfaXNFeHRlcm5hbEhyZWYoaHJlZjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBVUkwoaHJlZiwgJ2h0dHBzOi8vb3BlbmVsZW1lbnQub3JnLycpO1xuICAgICAgcmV0dXJuIHBhcnNlZC5vcmlnaW4gIT09ICdodHRwczovL29wZW5lbGVtZW50Lm9yZycgJiYgU0FGRV9VUkxfU0NIRU1FUy5oYXMocGFyc2VkLnByb3RvY29sKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9sb2NhbGl6ZWRTYWZlSHJlZihocmVmOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB7IGhyZWY6IHN0cmluZzsgaXNFeHRlcm5hbDogYm9vbGVhbiB9IHtcbiAgICBjb25zdCBzYWZlSHJlZiA9IHRoaXMuX3NhZmVIcmVmKGhyZWYpO1xuICAgIGNvbnN0IGlzRXh0ZXJuYWwgPSB0aGlzLl9pc0V4dGVybmFsSHJlZihzYWZlSHJlZik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGhyZWY6IGlzRXh0ZXJuYWwgPyBzYWZlSHJlZiA6IGxvY2FsaXplUGF0aChzYWZlSHJlZiwgdGhpcy5fY3VycmVudExvY2FsZSksXG4gICAgICBpc0V4dGVybmFsLFxuICAgIH07XG4gIH1cblxuICAvLyAtLS0gTWFpbiByZW5kZXIgLS0tXG5cbiAgcHJpdmF0ZSBfcmVuZGVyTGF5b3V0KCkge1xuICAgIGNvbnN0IGhvbWUgPSB0aGlzLl9nZXRCb29sKCdmdWxsLXdpZHRoJykgfHwgdGhpcy5fZ2V0Qm9vbCgnaG9tZScpO1xuICAgIGNvbnN0IG5vU2VhcmNoID0gdGhpcy5oYXNBdHRyaWJ1dGUoJ25vLXNlYXJjaCcpO1xuICAgIGNvbnN0IGxvZ29UZXh0ID0gdGhpcy5fZ2V0U3RyKCdsb2dvLXRleHQnLCAnJyk7XG4gICAgY29uc3QgbG9nb1N1YiA9IHRoaXMuX2dldFN0cignbG9nby1zdWInLCAnJyk7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMuX2xvY2FsZXM7XG4gICAgY29uc3QgY3VycmVudExvY2FsZSA9IHRoaXMuX2N1cnJlbnRMb2NhbGU7XG4gICAgY29uc3QgY3VycmVudFBhdGggPSB0aGlzLl9jdXJyZW50UGF0aFdpdGhvdXRMb2NhbGU7XG4gICAgY29uc3QgbGFuZ0xhYmVsID0gbG9jYWxlcy5sZW5ndGggPiAxID8gc3dpdGNoTGFiZWwoY3VycmVudExvY2FsZSkgOiAnJztcbiAgICBjb25zdCBsYW5nSHJlZiA9IGxvY2FsZXMubGVuZ3RoID4gMSA/IHN3aXRjaFBhdGgoY3VycmVudFBhdGgsIGN1cnJlbnRMb2NhbGUsIGxvY2FsZXMpIDogJyc7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J2FwcC1sYXlvdXQnIHBhcnQ9J2NvbnRhaW5lcicgaG9tZT17aG9tZSB8fCB1bmRlZmluZWR9PlxuICAgICAgICA8aGVhZGVyIGNsYXNzTmFtZT0nYXBwLWhlYWRlcicgcGFydD0naGVhZGVyJz5cbiAgICAgICAgICA8bmF2IGNsYXNzTmFtZT0naGVhZGVyLWlubmVyJyBhcmlhLWxhYmVsPSdQcmltYXJ5IG5hdmlnYXRpb24nPlxuICAgICAgICAgICAgeyhsb2dvVGV4dCB8fCBsb2dvU3ViKSAmJiAoXG4gICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbG9nbycgaHJlZj0nLyc+XG4gICAgICAgICAgICAgICAgPG9wZW4tYnJhbmQtbWFyayBzaXplPSdtZCc+PC9vcGVuLWJyYW5kLW1hcms+XG4gICAgICAgICAgICAgICAge2xvZ29UZXh0ICYmIDxzcGFuIGNsYXNzTmFtZT0nbG9nby13b3JkJz57bG9nb1RleHR9PC9zcGFuPn1cbiAgICAgICAgICAgICAgICB7bG9nb1N1YiAmJiA8c3BhbiBjbGFzc05hbWU9J2xvZ28tc3ViJz57bG9nb1N1Yn08L3NwYW4+fVxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3RoaXMuX3JlbmRlckhlYWRlck5hdigpfVxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2hlYWRlci1yaWdodCc+XG4gICAgICAgICAgICAgIHshbm9TZWFyY2ggJiYgPG9wZW4tc2VhcmNoPjwvb3Blbi1zZWFyY2g+fVxuICAgICAgICAgICAgICB7IWhvbWUgJiYgKFxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9J2J1dHRvbidcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nbW9iaWxlLW1lbnUtYnRuJ1xuICAgICAgICAgICAgICAgICAgcGFydD0nbmF2LXRvZ2dsZSdcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9J1RvZ2dsZSBuYXZpZ2F0aW9uJ1xuICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2ZW50OiBFdmVudCkgPT4gdGhpcy5fdG9nZ2xlTWVudShldmVudCl9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPHN2Z1xuICAgICAgICAgICAgICAgICAgICB3aWR0aD0nMTgnXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodD0nMTgnXG4gICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9JzAgMCAxOCAxOCdcbiAgICAgICAgICAgICAgICAgICAgZmlsbD0nbm9uZSdcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPSdjdXJyZW50Q29sb3InXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD0nMS41J1xuICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWNhcD0ncm91bmQnXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxsaW5lIHgxPSczJyB5MT0nNC41JyB4Mj0nMTUnIHkyPSc0LjUnIC8+XG4gICAgICAgICAgICAgICAgICAgIDxsaW5lIHgxPSczJyB5MT0nOScgeDI9JzE1JyB5Mj0nOScgLz5cbiAgICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9JzMnIHkxPScxMy41JyB4Mj0nMTUnIHkyPScxMy41JyAvPlxuICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDxvcGVuLXRoZW1lLXRvZ2dsZT48L29wZW4tdGhlbWUtdG9nZ2xlPlxuICAgICAgICAgICAgICB7bG9jYWxlcy5sZW5ndGggPiAxICYmIChcbiAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdsYW5nLXN3aXRjaCdcbiAgICAgICAgICAgICAgICAgIGhyZWY9e2xhbmdIcmVmfVxuICAgICAgICAgICAgICAgICAgZGF0YS1uYXY9e2xhbmdIcmVmfVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIHtsYW5nTGFiZWx9XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uYXY+XG4gICAgICAgIDwvaGVhZGVyPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbW9iaWxlLWJhY2tkcm9wJz48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J2xheW91dC1ib2R5Jz5cbiAgICAgICAgICB7IWhvbWUgJiYgdGhpcy5fcmVuZGVyU2lkZWJhck5hdigpfVxuICAgICAgICAgIDxtYWluIGNsYXNzTmFtZT0nbGF5b3V0LW1haW4nIHBhcnQ9J21haW4nPlxuICAgICAgICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgICAgIDwvbWFpbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxmb290ZXIgY2xhc3NOYW1lPSdhcHAtZm9vdGVyJyBwYXJ0PSdmb290ZXInPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmb290ZXItaW5uZXInPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2Zvb3Rlci1jb2x1bW4nPlxuICAgICAgICAgICAgICA8aDQ+UHJvZHVjdDwvaDQ+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVQYXRoKCcvZ3VpZGUvY29yZS1jb25jZXB0cycsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICAgIGRhdGEtbmF2PXtsb2NhbGl6ZVBhdGgoJy9ndWlkZS9jb3JlLWNvbmNlcHRzJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBFbGVtZW50c1xuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVQYXRoKCcvYXJjaGl0ZWN0dXJlL2Rlc2lnbi1zeXN0ZW0nLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgICBkYXRhLW5hdj17bG9jYWxpemVQYXRoKCcvYXJjaGl0ZWN0dXJlL2Rlc2lnbi1zeXN0ZW0nLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIFVJXG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBocmVmPXtsb2NhbGl6ZVBhdGgoJy9hcmNoaXRlY3R1cmUvYXJjaGl0ZWN0dXJlJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgICAgZGF0YS1uYXY9e2xvY2FsaXplUGF0aCgnL2FyY2hpdGVjdHVyZS9hcmNoaXRlY3R1cmUnLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEZyYW1ld29ya1xuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVQYXRoKCcvYXJjaGl0ZWN0dXJlL3N0YW5kYXJkcy1yZWdpc3RyeScsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICAgIGRhdGEtbmF2PXtsb2NhbGl6ZVBhdGgoJy9hcmNoaXRlY3R1cmUvc3RhbmRhcmRzLXJlZ2lzdHJ5JywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBQcm90b2NvbHNcbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nZm9vdGVyLWNvbHVtbic+XG4gICAgICAgICAgICAgIDxoND5SZXNvdXJjZXM8L2g0PlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGhyZWY9e2xvY2FsaXplUGF0aCgnL2d1aWRlL2dldHRpbmctc3RhcnRlZCcsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICAgIGRhdGEtbmF2PXtsb2NhbGl6ZVBhdGgoJy9ndWlkZS9nZXR0aW5nLXN0YXJ0ZWQnLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEd1aWRlXG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBocmVmPXtsb2NhbGl6ZVBhdGgoJy9ndWlkZS9hcGknLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgICBkYXRhLW5hdj17bG9jYWxpemVQYXRoKCcvZ3VpZGUvYXBpJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBBUElcbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGhyZWY9e2xvY2FsaXplUGF0aCgnL2FyY2hpdGVjdHVyZS9hcmNoaXRlY3R1cmUnLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgICBkYXRhLW5hdj17bG9jYWxpemVQYXRoKCcvYXJjaGl0ZWN0dXJlL2FyY2hpdGVjdHVyZScsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgQXJjaGl0ZWN0dXJlXG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICBocmVmPXtsb2NhbGl6ZVBhdGgoJy9ibG9nJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgICAgZGF0YS1uYXY9e2xvY2FsaXplUGF0aCgnL2Jsb2cnLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEJsb2dcbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nZm9vdGVyLWNvbHVtbic+XG4gICAgICAgICAgICAgIDxoND5Db21wYW55PC9oND5cbiAgICAgICAgICAgICAgPGEgaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL29wZW4tZWxlbWVudC9vcGVuZWxlbWVudCc+R2l0SHViPC9hPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGhyZWY9e2xvY2FsaXplUGF0aCgnL3JvYWRtYXAnLCBjdXJyZW50TG9jYWxlKX1cbiAgICAgICAgICAgICAgICBkYXRhLW5hdj17bG9jYWxpemVQYXRoKCcvcm9hZG1hcCcsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgUm9hZG1hcFxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVQYXRoKCcvY2hhbmdlbG9nJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgICAgZGF0YS1uYXY9e2xvY2FsaXplUGF0aCgnL2NoYW5nZWxvZycsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgQ2hhbmdlbG9nXG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2Zvb3Rlci1jb2x1bW4nPlxuICAgICAgICAgICAgICA8aDQ+TGVnYWw8L2g0PlxuICAgICAgICAgICAgICA8YSBocmVmPSdodHRwczovL2dpdGh1Yi5jb20vb3Blbi1lbGVtZW50L29wZW5lbGVtZW50L2Jsb2IvbWFpbi9MSUNFTlNFJz5cbiAgICAgICAgICAgICAgICBNSVQgTGljZW5zZVxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVQYXRoKCcvY29udHJpYnV0aW5nJywgY3VycmVudExvY2FsZSl9XG4gICAgICAgICAgICAgICAgZGF0YS1uYXY9e2xvY2FsaXplUGF0aCgnL2NvbnRyaWJ1dGluZycsIGN1cnJlbnRMb2NhbGUpfVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgQ29udHJpYnV0aW5nXG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmb290ZXItYm90dG9tJz5cbiAgICAgICAgICAgIDxzcGFuPihjKSAyMDI2IG9wZW5FbGVtZW50LiBNSVQgTGljZW5zZS48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9vdGVyPlxuICAgICAgICB7dGhpcy5fcmVuZGVyTW9iaWxlVGFiQmFyKCl9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVySGVhZGVyTmF2KCkge1xuICAgIGNvbnN0IGxpbmtzID0gdGhpcy5faGVhZGVyTmF2KCk7XG4gICAgaWYgKGxpbmtzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgY3AgPSB0aGlzLl9jdXJyZW50UGF0aCgpO1xuICAgIHJldHVybiAoXG4gICAgICA8bmF2IGNsYXNzTmFtZT0naGVhZGVyLW5hdicgcGFydD0nbmF2Jz5cbiAgICAgICAge2xpbmtzLm1hcCgobGluaykgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgaHJlZjogbG9jYWxpemVkLCBpc0V4dGVybmFsIH0gPSB0aGlzLl9sb2NhbGl6ZWRTYWZlSHJlZihsaW5rLmhyZWYpO1xuICAgICAgICAgIGNvbnN0IGlzQ3VycmVudCA9ICFpc0V4dGVybmFsICYmXG4gICAgICAgICAgICAoY3AgPT09IGxpbmsuaHJlZiB8fCBjcCA9PT0gbG9jYWxpemVkIHx8IGNwLnN0YXJ0c1dpdGgobG9jYWxpemVkICsgJy8nKSk7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgIGhyZWY9e2xvY2FsaXplZH1cbiAgICAgICAgICAgICAgZGF0YS1uYXY9e2lzRXh0ZXJuYWwgPyAnJyA6IGxvY2FsaXplZH1cbiAgICAgICAgICAgICAgYXJpYS1jdXJyZW50PXtpc0N1cnJlbnQgPyAncGFnZScgOiB1bmRlZmluZWR9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtsaW5rLmxhYmVsfVxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICk7XG4gICAgICAgIH0pfVxuICAgICAgPC9uYXY+XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlclNpZGViYXJOYXYoKSB7XG4gICAgY29uc3QgbmF2ID0gdGhpcy5fbmF2SXRlbXMoKTtcbiAgICBpZiAobmF2Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIChcbiAgICAgIDxuYXZcbiAgICAgICAgY2xhc3NOYW1lPSdkb2NzLXNpZGViYXInXG4gICAgICAgIHBhcnQ9J3NpZGViYXInXG4gICAgICAgIGFyaWEtbGFiZWw9J0RvY3VtZW50YXRpb24gbmF2aWdhdGlvbidcbiAgICAgID5cbiAgICAgICAge25hdi5tYXAoKHNlY3Rpb24pID0+IChcbiAgICAgICAgICA8ZGV0YWlscyBjbGFzc05hbWU9J25hdi1zZWN0aW9uJyBvcGVuPlxuICAgICAgICAgICAgPHN1bW1hcnkgY2xhc3NOYW1lPSduYXYtc2VjdGlvbi10aXRsZSc+XG4gICAgICAgICAgICAgIHtzZWN0aW9uLnNlY3Rpb259XG4gICAgICAgICAgICA8L3N1bW1hcnk+XG4gICAgICAgICAgICB7c2VjdGlvbi5pdGVtcy5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgaHJlZiA9IGl0ZW0uaHJlZiB8fCBpdGVtLnBhdGggfHwgJyMnO1xuICAgICAgICAgICAgICBjb25zdCB7IGhyZWY6IGxvY2FsaXplZCwgaXNFeHRlcm5hbCB9ID0gdGhpcy5fbG9jYWxpemVkU2FmZUhyZWYoaHJlZik7XG4gICAgICAgICAgICAgIGNvbnN0IGNwID0gdGhpcy5fY3VycmVudFBhdGgoKTtcbiAgICAgICAgICAgICAgY29uc3QgaXNBY3RpdmUgPSAhaXNFeHRlcm5hbCAmJiBjcCA9PT0gbG9jYWxpemVkO1xuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICBocmVmPXtsb2NhbGl6ZWR9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2lzQWN0aXZlID8gJ2FjdGl2ZScgOiB1bmRlZmluZWR9XG4gICAgICAgICAgICAgICAgICBhcmlhLWN1cnJlbnQ9e2lzQWN0aXZlID8gJ3BhZ2UnIDogdW5kZWZpbmVkfVxuICAgICAgICAgICAgICAgICAgZGF0YS1uYXY9e2lzRXh0ZXJuYWwgPyAnJyA6IGxvY2FsaXplZH1cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH1cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KX1cbiAgICAgICAgICA8L2RldGFpbHM+XG4gICAgICAgICkpfVxuICAgICAgPC9uYXY+XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlck1vYmlsZVRhYkJhcigpIHtcbiAgICBjb25zdCBsaW5rcyA9IHRoaXMuX2hlYWRlck5hdigpO1xuICAgIGlmIChsaW5rcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgTU9CSUxFX1RBQl9MSU1JVCA9IDU7XG4gICAgY29uc3QgbW9iaWxlTGlua3MgPSBsaW5rcy5zbGljZSgwLCBNT0JJTEVfVEFCX0xJTUlUKTtcblxuICAgIGNvbnN0IGxvY3MgPSB0aGlzLl9sb2NhbGVzO1xuICAgIGNvbnN0IHNlY3Rpb25Sb290ID0gKGhyZWY6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBzZWdzID0gaHJlZi5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKTtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gbG9jcy5sZW5ndGggPiAxICYmIGxvY3MuaW5jbHVkZXMoc2Vnc1swXSkgPyAxIDogMDtcbiAgICAgIHJldHVybiBzZWdzLmxlbmd0aCA+IHN0YXJ0ICsgMSA/ICcvJyArIHNlZ3Nbc3RhcnRdIDogaHJlZjtcbiAgICB9O1xuXG4gICAgY29uc3QgcmF3UGF0aCA9IHRoaXMuX2N1cnJlbnRQYXRoV2l0aG91dExvY2FsZTtcblxuICAgIHJldHVybiAoXG4gICAgICA8bmF2IGNsYXNzTmFtZT0nbW9iaWxlLXRhYi1iYXInIGFyaWEtbGFiZWw9J1F1aWNrIG5hdmlnYXRpb24nPlxuICAgICAgICB7bW9iaWxlTGlua3MubWFwKChsaW5rKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBocmVmOiBsb2NhbGl6ZWQsIGlzRXh0ZXJuYWwgfSA9IHRoaXMuX2xvY2FsaXplZFNhZmVIcmVmKGxpbmsuaHJlZik7XG4gICAgICAgICAgY29uc3Qgcm9vdCA9IHNlY3Rpb25Sb290KGxpbmsuaHJlZik7XG4gICAgICAgICAgY29uc3QgaXNBY3RpdmUgPSAhaXNFeHRlcm5hbCAmJlxuICAgICAgICAgICAgKHJhd1BhdGggPT09IHJvb3QgfHwgcmF3UGF0aC5zdGFydHNXaXRoKHJvb3QgKyAnLycpKTtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgY2xhc3NOYW1lPXtgdGFiLWl0ZW0ke2lzQWN0aXZlID8gJyBhY3RpdmUnIDogJyd9YH1cbiAgICAgICAgICAgICAgaHJlZj17bG9jYWxpemVkfVxuICAgICAgICAgICAgICBkYXRhLW5hdj17aXNFeHRlcm5hbCA/ICcnIDogbG9jYWxpemVkfVxuICAgICAgICAgICAgICBhcmlhLWN1cnJlbnQ9e2lzQWN0aXZlID8gJ3BhZ2UnIDogdW5kZWZpbmVkfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7dGhpcy5fcmVuZGVySWNvbihsaW5rLmxhYmVsKX1cbiAgICAgICAgICAgICAgPHNwYW4+e2xpbmsubGFiZWx9PC9zcGFuPlxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICk7XG4gICAgICAgIH0pfVxuICAgICAgPC9uYXY+XG4gICAgKTtcbiAgfVxuXG4gIC8vIC0tLSBTY3JvbGwgZGV0ZWN0aW9uIC0tLVxuXG4gIHByaXZhdGUgX3NldHVwU2Nyb2xsRGV0ZWN0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgZ2xvYmFsVGhpcy53aW5kb3cgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgbGV0IHRpY2tpbmc6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IG9uU2Nyb2xsID0gKCkgPT4ge1xuICAgICAgaWYgKHRpY2tpbmcgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgICAgdGlja2luZyA9IGdsb2JhbFRoaXMuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGhlYWRlciA9IHRoaXMuc2hhZG93Um9vdD8ucXVlcnlTZWxlY3RvcignLmFwcC1oZWFkZXInKTtcbiAgICAgICAgaWYgKGhlYWRlcikge1xuICAgICAgICAgIGhlYWRlci5jbGFzc0xpc3QudG9nZ2xlKCdzY3JvbGxlZCcsIGdsb2JhbFRoaXMuc2Nyb2xsWSA+IDApO1xuICAgICAgICB9XG4gICAgICAgIHRpY2tpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9LCAxMDApO1xuICAgIH07XG4gICAgZ2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIHRoaXMuX3Njcm9sbENsZWFudXAgPSAoKSA9PiB7XG4gICAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG9uU2Nyb2xsKTtcbiAgICAgIGlmICh0aWNraW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZ2xvYmFsVGhpcy5jbGVhclRpbWVvdXQodGlja2luZyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX3RlYXJkb3duU2Nyb2xsRGV0ZWN0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuX3Njcm9sbENsZWFudXA/LigpO1xuICAgIHRoaXMuX3Njcm9sbENsZWFudXAgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyAtLS0gTGlmZWN5Y2xlIC0tLVxuXG4gIG92ZXJyaWRlIGNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIHN1cGVyLmNvbm5lY3RlZENhbGxiYWNrKCk7XG5cbiAgICBjb25zdCBsb2NhbGVzID0gdGhpcy5fbG9jYWxlcztcbiAgICBpZiAobG9jYWxlcy5sZW5ndGggPiAxKSB7XG4gICAgICBjb25zdCBsb2NhbGUgPSB0aGlzLl9jdXJyZW50TG9jYWxlO1xuICAgICAgaWYgKGxvY2FsZXMuaW5jbHVkZXMobG9jYWxlKSkge1xuICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSgnbG9jYWxlJywgbG9jYWxlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTeW5jIGRhdGEtdGhlbWUgZnJvbSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgb24gY29ubmVjdFxuICAgIGNvbnN0IGRvY1RoZW1lID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Py5kYXRhc2V0Py50aGVtZTtcbiAgICBpZiAoZG9jVGhlbWUpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJywgZG9jVGhlbWUpO1xuICAgIH1cbiAgICAvLyBTaWduYWxDb250ZXh0OiBwcm92aWRlIHRoZW1lIHN0YXRlIHRvIGFsbCBjaGlsZCBjb21wb25lbnRzXG4gICAgY29uc3QgaW5pdGlhbFRoZW1lID0gKGRvY1RoZW1lIGFzICdkYXJrJyB8ICdsaWdodCcpIHx8ICdsaWdodCc7XG4gICAgcHJvdmlkZUNvbnRleHQodGhpcywgVEhFTUVfQ1RYLCBpbml0aWFsVGhlbWUpO1xuXG4gICAgLy8gTGlzdGVuIGZvciB0aGVtZSBjaGFuZ2UgZXZlbnRzIGZyb20gb3Blbi10aGVtZS10b2dnbGVcbiAgICB0aGlzLl90aGVtZUhhbmRsZXIgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRldGFpbCA9IChlIGFzIEN1c3RvbUV2ZW50KS5kZXRhaWw7XG4gICAgICBpZiAoZGV0YWlsPy50aGVtZSkge1xuICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsIGRldGFpbC50aGVtZSk7XG4gICAgICAgIHByb3ZpZGVDb250ZXh0KHRoaXMsIFRIRU1FX0NUWCwgZGV0YWlsLnRoZW1lKTtcbiAgICAgICAgdGhpcy5fcHJvcGFnYXRlVGhlbWUoZGV0YWlsLnRoZW1lKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcj8uKCdvcGVuOnRoZW1lLWNoYW5nZScsIHRoaXMuX3RoZW1lSGFuZGxlcik7XG5cbiAgICB0aGlzLl9wcm9wYWdhdGVUaGVtZShpbml0aWFsVGhlbWUpO1xuXG4gICAgaWYgKHRoaXMuc2hhZG93Um9vdCAmJiB0aGlzLnNoYWRvd1Jvb3QuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9zZXR1cERldGFpbHNUb2dnbGUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZXR1cFNwYU5hdmlnYXRpb24oe1xuICAgICAgY29udGVudExvYWRlcjogYXN5bmMgKHBhdGg6IHN0cmluZywgbG9jYWxlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fbG9hZENvbnRlbnQocGF0aCwgbG9jYWxlKTtcbiAgICAgIH0sXG4gICAgICBvbkFmdGVyU3dhcDogKF9wYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgdGhpcy5fdXBkYXRlQWN0aXZlTmF2KCk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gdjAuMjMuMDogSW50ZWdyYXRlZCBmcm9tIHd3dy9wdWJsaWMvbW9iaWxlLW1lbnUuanMuXG4gICAgLy8gQ2xvc2UgbW9iaWxlIG1lbnUgb24gYmFja2Ryb3AgY2xpY2sgb3Igc2lkZWJhciBuYXYgbGluayBjbGljay5cbiAgICB0aGlzLl9kb2NDbGlja0NsZWFudXAgPSB0aGlzLl9zZXR1cEJhY2tkcm9wQ2xvc2UoKTtcblxuICAgIC8vIFNjcm9sbCBkZXRlY3Rpb24gZm9yIGhlYWRlciBiYWNrZHJvcCBibHVyXG4gICAgdGhpcy5fc2V0dXBTY3JvbGxEZXRlY3Rpb24oKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIHN1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCk7XG4gICAgdGhpcy5fdGVhcmRvd25TcGFOYXZpZ2F0aW9uKCk7XG4gICAgdGhpcy5fZG9jQ2xpY2tDbGVhbnVwPy4oKTtcbiAgICBpZiAodGhpcy5fdGhlbWVIYW5kbGVyKSB7XG4gICAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXI/Lignb3Blbjp0aGVtZS1jaGFuZ2UnLCB0aGlzLl90aGVtZUhhbmRsZXIpO1xuICAgIH1cbiAgICB0aGlzLl90ZWFyZG93blNjcm9sbERldGVjdGlvbigpO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWU6IHN0cmluZywgb2xkOiBzdHJpbmcgfCBudWxsLCB2YWw6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAob2xkID09PSB2YWwpIHJldHVybjtcbiAgICBpZiAobmFtZSA9PT0gJ2N1cnJlbnQtcGF0aCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZUFjdGl2ZU5hdigpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLSBNb2JpbGUgbWVudSAtLS1cblxuICAvLyB2MC4zMSBVSS1zaGVsbCBkZWJ0OiByZXBsYWNlIF9yZXBsYWNlU2hhZG93Um9vdEZyb21MYXlvdXQgd2l0aCBzaWduYWwtZHJpdmVuIFNQQSBuYXYuXG4gIC8vIEN1cnJlbnRseSBTUEEgbmF2aWdhdGlvbiBkZXN0cm95cyB0aGUgZW50aXJlIHNoYWRvdyBET00gYW5kIHJlYnVpbGRzIGl0IGZyb21cbiAgLy8gZmV0Y2hlZCBIVE1MLCB0aGVuIG1hbnVhbGx5IHJlLWF0dGFjaGVzIGV2ZW50cyBpbiBfc2V0dXBEZXRhaWxzVG9nZ2xlLiBUaGlzIGlzXG4gIC8vIGluY29tcGF0aWJsZSB3aXRoIHRoZSBzaWduYWwgYXJjaGl0ZWN0dXJlID8/IHdlIHNob3VsZCBtYWtlIGN1cnJlbnRQYXRoL25hdkl0ZW1zXG4gIC8vIHNpZ25hbHMgYW5kIGxldCBkYXRhLXNpZ25hbCBtYXJrZXJzIGhhbmRsZSBET00gdXBkYXRlcyByZWFjdGl2ZWx5LiBUaGVuIHRoZVxuICAvLyBfc2V0dXBEZXRhaWxzVG9nZ2xlIGhhY2sgKGFuZCB0aGlzIGVudGlyZSBtZXRob2QpIGNhbiBiZSBkZWxldGVkLlxuICBwcml2YXRlIF9tZW51QnRuSGFuZGxlcjogKChlOiBFdmVudCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIF9zZXR1cERldGFpbHNUb2dnbGUoKTogdm9pZCB7XG4gICAgY29uc3QgYnRuID0gdGhpcy5zaGFkb3dSb290Py5xdWVyeVNlbGVjdG9yKCcubW9iaWxlLW1lbnUtYnRuJyk7XG4gICAgaWYgKCFidG4pIHJldHVybjtcbiAgICAvLyBSZW1vdmUgYW55IHN0YWxlIGxpc3RlbmVyIGZyb20gYSBwcmV2aW91cyBzaGFkb3cgcm9vdC5cbiAgICBpZiAodGhpcy5fbWVudUJ0bkhhbmRsZXIpIHtcbiAgICAgIGJ0bi5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX21lbnVCdG5IYW5kbGVyKTtcbiAgICB9XG4gICAgdGhpcy5fbWVudUJ0bkhhbmRsZXIgPSB0aGlzLl90b2dnbGVNZW51LmJpbmQodGhpcyk7XG4gICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fbWVudUJ0bkhhbmRsZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdG9nZ2xlTWVudShfZTogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBpc09wZW4gPSB0aGlzLmhhc0F0dHJpYnV0ZSgnbWVudS1vcGVuJyk7XG4gICAgdGhpcy50b2dnbGVBdHRyaWJ1dGUoJ21lbnUtb3BlbicsICFpc09wZW4pO1xuICAgIHRoaXMuX3N5bmNJbmVydCghaXNPcGVuKTtcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNJbmVydChtZW51T3BlbjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IG1haW4gPSB0aGlzLnNoYWRvd1Jvb3Q/LnF1ZXJ5U2VsZWN0b3IoJy5sYXlvdXQtbWFpbicpO1xuICAgIGlmIChtYWluKSB7XG4gICAgICBpZiAobWVudU9wZW4pIG1haW4uc2V0QXR0cmlidXRlKCdpbmVydCcsICcnKTtcbiAgICAgIGVsc2UgbWFpbi5yZW1vdmVBdHRyaWJ1dGUoJ2luZXJ0Jyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHYwLjIzLjA6IEludGVncmF0ZWQgZnJvbSB3d3cvcHVibGljL21vYmlsZS1tZW51LmpzLlxuICAgKiBDbG9zZXMgbW9iaWxlIG1lbnUgd2hlbiBiYWNrZHJvcCBvciBzaWRlYmFyIG5hdiBsaW5rIGlzIGNsaWNrZWQuXG4gICAqIFVzZXMgY29tcG9zZWRQYXRoKCkgdG8gZGV0ZWN0IGNsaWNrcyBhY3Jvc3Mgc2hhZG93IERPTSBib3VuZGFyaWVzLlxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0dXBCYWNrZHJvcENsb3NlKCk6ICgpID0+IHZvaWQge1xuICAgIGNvbnN0IGhhbmRsZXIgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgaWYgKCF0YXJnZXQgfHwgISh0YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50KSkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwYXRoID0gZS5jb21wb3NlZFBhdGgoKTtcbiAgICAgIGxldCBpc0JhY2tkcm9wID0gZmFsc2U7XG4gICAgICBsZXQgaXNOYXZMaW5rID0gZmFsc2U7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbCA9IHBhdGhbaV0gYXMgRWxlbWVudDtcbiAgICAgICAgaWYgKCFlbD8uY2xhc3NMaXN0KSBjb250aW51ZTtcbiAgICAgICAgaWYgKGVsLmNsYXNzTGlzdC5jb250YWlucygnbW9iaWxlLWJhY2tkcm9wJykpIHtcbiAgICAgICAgICBpc0JhY2tkcm9wID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ0EnKSB7XG4gICAgICAgICAgaXNOYXZMaW5rID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWlzQmFja2Ryb3AgJiYgIWlzTmF2TGluaykgcmV0dXJuO1xuICAgICAgdGhpcy5fY2xvc2VNZW51KCk7XG4gICAgfTtcblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGFuZGxlcik7XG4gICAgcmV0dXJuICgpID0+IGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGFuZGxlcik7XG4gIH1cblxuICBwcml2YXRlIF9jbG9zZU1lbnUoKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUoJ21lbnUtb3BlbicpO1xuICAgIGNvbnN0IGRldGFpbHMgPSB0aGlzLnNoYWRvd1Jvb3Q/LnF1ZXJ5U2VsZWN0b3IoJ2RldGFpbHMubW9iaWxlLW1lbnUnKTtcbiAgICBpZiAoZGV0YWlscykgZGV0YWlscy5yZW1vdmVBdHRyaWJ1dGUoJ29wZW4nKTtcbiAgICB0aGlzLl9zeW5jSW5lcnQoZmFsc2UpO1xuICB9XG5cbiAgLy8gLS0tIFRoZW1lIC0tLVxuICBwcml2YXRlIF9wcm9wYWdhdGVUaGVtZSh0aGVtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgd2FsayA9IChyb290OiBFbGVtZW50IHwgU2hhZG93Um9vdCkgPT4ge1xuICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCcqJykuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgaWYgKGVsLnRhZ05hbWUuaW5jbHVkZXMoJy0nKSkge1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsIHRoZW1lKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWwuc2hhZG93Um9vdCkge1xuICAgICAgICAgIHdhbGsoZWwuc2hhZG93Um9vdCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG4gICAgLy8gV2FsayBsaWdodCBET00gY2hpbGRyZW4gKHNsb3R0ZWQgcGFnZSBjb21wb25lbnRzIGxpa2UgZG9jcy1ob21lLCB1aS1zaG93Y2FzZSlcbiAgICB3YWxrKHRoaXMpO1xuICAgIC8vIFdhbGsgc2hhZG93IERPTSBjb250ZW50IChpbnRlcm5hbCBsYXlvdXQgZWxlbWVudHMpXG4gICAgaWYgKHRoaXMuc2hhZG93Um9vdCkge1xuICAgICAgd2Fsayh0aGlzLnNoYWRvd1Jvb3QpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWN1cnNpdmVseSBzZWFyY2ggZm9yIG9wZW4tbGF5b3V0IGluIHBhcnNlZCBET00sIGluY2x1ZGluZ1xuICAgKiBpbnNpZGUgPHRlbXBsYXRlIHNoYWRvd3Jvb3Rtb2RlPVwib3BlblwiPiAoRFNEIGNvbnRlbnQpLlxuICAgKlxuICAgKiBxdWVyeVNlbGVjdG9yIGRvZXMgbm90IHRyYXZlcnNlIHRlbXBsYXRlIGNvbnRlbnQsIGJ1dCBTU0cgcGFnZXNcbiAgICogd3JhcCBwYWdlIG91dHB1dCBpbiBhIHBhZ2UgY29tcG9uZW50IHdob3NlIHNoYWRvdyByb290IGNvbnRhaW5zXG4gICAqIHRoZSA8b3Blbi1sYXlvdXQ+LlxuICAgKi9cbiAgcHJpdmF0ZSBfZmluZE9wZW5MYXlvdXQocm9vdDogRWxlbWVudCB8IERvY3VtZW50RnJhZ21lbnQpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShyb290LmNoaWxkcmVuKSkge1xuICAgICAgaWYgKGNoaWxkLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29wZW4tbGF5b3V0JykgcmV0dXJuIGNoaWxkIGFzIEhUTUxFbGVtZW50O1xuICAgICAgaWYgKGNoaWxkLnRhZ05hbWUgPT09ICdURU1QTEFURScpIHtcbiAgICAgICAgY29uc3QgZm91bmQgPSB0aGlzLl9maW5kT3BlbkxheW91dCgoY2hpbGQgYXMgSFRNTFRlbXBsYXRlRWxlbWVudCkuY29udGVudCk7XG4gICAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgICAgfVxuICAgICAgY29uc3QgZm91bmQgPSB0aGlzLl9maW5kT3BlbkxheW91dChjaGlsZCk7XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9hY3RpdmF0ZURlY2xhcmF0aXZlU2hhZG93Um9vdHMocm9vdDogRWxlbWVudCB8IFNoYWRvd1Jvb3QgfCBEb2N1bWVudEZyYWdtZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGVtcGxhdGVzID0gQXJyYXkuZnJvbShcbiAgICAgIHJvb3QucXVlcnlTZWxlY3RvckFsbDxIVE1MVGVtcGxhdGVFbGVtZW50PigndGVtcGxhdGVbc2hhZG93cm9vdG1vZGVdJyksXG4gICAgKTtcblxuICAgIGlmIChcbiAgICAgIHJvb3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJlxuICAgICAgcm9vdC5maXJzdEVsZW1lbnRDaGlsZCBpbnN0YW5jZW9mIEhUTUxUZW1wbGF0ZUVsZW1lbnQgJiZcbiAgICAgIHJvb3QuZmlyc3RFbGVtZW50Q2hpbGQuaGFzQXR0cmlidXRlKCdzaGFkb3dyb290bW9kZScpXG4gICAgKSB7XG4gICAgICB0ZW1wbGF0ZXMudW5zaGlmdChyb290LmZpcnN0RWxlbWVudENoaWxkKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRlbXBsYXRlcykge1xuICAgICAgY29uc3QgaG9zdCA9IHRlbXBsYXRlLnBhcmVudEVsZW1lbnQ7XG4gICAgICBpZiAoIWhvc3QgfHwgaG9zdC5zaGFkb3dSb290KSB7XG4gICAgICAgIHRlbXBsYXRlLnJlbW92ZSgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbW9kZSA9IHRlbXBsYXRlLmdldEF0dHJpYnV0ZSgnc2hhZG93cm9vdG1vZGUnKSA9PT0gJ2Nsb3NlZCcgPyAnY2xvc2VkJyA6ICdvcGVuJztcbiAgICAgIGNvbnN0IHNoYWRvdyA9IGhvc3QuYXR0YWNoU2hhZG93KHsgbW9kZSB9KTtcbiAgICAgIHNoYWRvdy5hcHBlbmRDaGlsZCh0ZW1wbGF0ZS5jb250ZW50KTtcbiAgICAgIHRlbXBsYXRlLnJlbW92ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2lzU2hhZG93VGVtcGxhdGUoZWw6IEVsZW1lbnQpOiBlbCBpcyBIVE1MVGVtcGxhdGVFbGVtZW50IHtcbiAgICByZXR1cm4gZWwgaW5zdGFuY2VvZiBIVE1MVGVtcGxhdGVFbGVtZW50ICYmIGVsLmhhc0F0dHJpYnV0ZSgnc2hhZG93cm9vdG1vZGUnKTtcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNMYXlvdXRBdHRyaWJ1dGVzKG5ld0xheW91dDogSFRNTEVsZW1lbnQsIGxvY2FsZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaW5jb21pbmcgPSBuZXcgU2V0KFxuICAgICAgQXJyYXkuZnJvbShuZXdMYXlvdXQuYXR0cmlidXRlcykubWFwKChhdHRyKSA9PiBhdHRyLm5hbWUpLFxuICAgICk7XG4gICAgY29uc3QgcHJlc2VydmUgPSBuZXcgU2V0KFsnZGF0YS10aGVtZScsICd0aGVtZSddKTtcblxuICAgIGZvciAoY29uc3QgYXR0ciBvZiBBcnJheS5mcm9tKHRoaXMuYXR0cmlidXRlcykpIHtcbiAgICAgIGlmICghaW5jb21pbmcuaGFzKGF0dHIubmFtZSkgJiYgIXByZXNlcnZlLmhhcyhhdHRyLm5hbWUpKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgYXR0ciBvZiBBcnJheS5mcm9tKG5ld0xheW91dC5hdHRyaWJ1dGVzKSkge1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoYXR0ci5uYW1lLCBhdHRyLnZhbHVlKTtcbiAgICB9XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ2xvY2FsZScsIGxvY2FsZSk7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoXG4gICAgICAnY3VycmVudC1wYXRoJyxcbiAgICAgIG5ld0xheW91dC5nZXRBdHRyaWJ1dGUoJ2N1cnJlbnQtcGF0aCcpIHx8IHRoaXMuX2N1cnJlbnRQYXRoV2l0aG91dExvY2FsZSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVwbGFjZVNoYWRvd1Jvb3RGcm9tTGF5b3V0KG5ld0xheW91dDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzaGFkb3dUZW1wbGF0ZSA9IEFycmF5LmZyb20obmV3TGF5b3V0LmNoaWxkcmVuKS5maW5kKChjaGlsZCkgPT5cbiAgICAgIHRoaXMuX2lzU2hhZG93VGVtcGxhdGUoY2hpbGQpXG4gICAgKTtcbiAgICBpZiAoIXNoYWRvd1RlbXBsYXRlIHx8ICF0aGlzLnNoYWRvd1Jvb3QpIHJldHVybjtcblxuICAgIHdoaWxlICh0aGlzLnNoYWRvd1Jvb3QuZmlyc3RDaGlsZCkge1xuICAgICAgdGhpcy5zaGFkb3dSb290LnJlbW92ZUNoaWxkKHRoaXMuc2hhZG93Um9vdC5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgdGhpcy5zaGFkb3dSb290LmFwcGVuZENoaWxkKGRvY3VtZW50LmFkb3B0Tm9kZShzaGFkb3dUZW1wbGF0ZS5jb250ZW50KSk7XG4gICAgdGhpcy5fYWN0aXZhdGVEZWNsYXJhdGl2ZVNoYWRvd1Jvb3RzKHRoaXMuc2hhZG93Um9vdCk7XG4gICAgdGhpcy5fc2V0dXBEZXRhaWxzVG9nZ2xlKCk7XG4gICAgdGhpcy5fdXBkYXRlU3dpdGNoKHRoaXMuc2hhZG93Um9vdCk7XG4gIH1cblxuICAvKiAtLS0gU1BBIG5hdmlnYXRpb24gKGlubGluZWQgZnJvbSBAb3BlbmVsZW1lbnQvcm91dGVyKSAtLS0gKi9cblxuICBwcml2YXRlIF9zZXR1cFNwYU5hdmlnYXRpb24ob3B0czoge1xuICAgIGNvbnRlbnRMb2FkZXI6IChwYXRoOiBzdHJpbmcsIGxvY2FsZTogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIG9uQWZ0ZXJTd2FwPzogKHBhdGg6IHN0cmluZywgbG9jYWxlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIH0pOiB2b2lkIHtcbiAgICB0aGlzLl9uYXZPcHRpb25zID0gb3B0cztcblxuICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHtcbiAgICAgIHRoaXMuX3NldHVwQ2xpY2tEZWxlZ2F0aW9uKHRoaXMuc2hhZG93Um9vdCk7XG4gICAgfVxuICAgIHRoaXMuX3NldHVwTmF2aWdhdGlvbkFwaSgpO1xuICAgIHRoaXMuX3NldHVwUG9wU3RhdGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3RlYXJkb3duU3BhTmF2aWdhdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9jbGVhbnVwTmF2Py4oKTtcbiAgICB0aGlzLl9jbGVhbnVwTmF2ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX25hdk9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cENsaWNrRGVsZWdhdGlvbihyb290OiBTaGFkb3dSb290KTogdm9pZCB7XG4gICAgY29uc3QgaGFuZGxlciA9IChlOiBFdmVudCkgPT4ge1xuICAgICAgY29uc3QgbGluayA9IChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdDxIVE1MQW5jaG9yRWxlbWVudD4oJ2EnKTtcbiAgICAgIGlmICghbGluaykgcmV0dXJuO1xuICAgICAgY29uc3QgaHJlZiA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICBpZiAoIWhyZWYpIHJldHVybjtcblxuICAgICAgaWYgKCFpc1NhZmVMYXlvdXRVcmwoaHJlZikgfHwgL15odHRwcz86L2kudGVzdChocmVmKSB8fCBocmVmLnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cbiAgICAgIGNvbnN0IGlzTGFuZ1N3aXRjaCA9IGxpbmsuY2xhc3NMaXN0LmNvbnRhaW5zKCdsYW5nLXN3aXRjaCcpO1xuICAgICAgaWYgKGlzTGFuZ1N3aXRjaCkge1xuICAgICAgICB0aGlzLl9yZXBsYWNlVG8oaHJlZik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9uYXZpZ2F0ZVRvKGhyZWYpO1xuICAgICAgfVxuICAgIH07XG4gICAgcm9vdC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhhbmRsZXIpO1xuICAgIGNvbnN0IHByZXYgPSB0aGlzLl9jbGVhbnVwTmF2O1xuICAgIHRoaXMuX2NsZWFudXBOYXYgPSAoKSA9PiB7XG4gICAgICByb290LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGFuZGxlcik7XG4gICAgICBwcmV2Py4oKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0dXBOYXZpZ2F0aW9uQXBpKCk6IHZvaWQge1xuICAgIGNvbnN0IG5hdiA9IChnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYgeyBuYXZpZ2F0aW9uPzogTmF2aWdhdGlvbkxpa2UgfSkubmF2aWdhdGlvbjtcbiAgICBpZiAoIW5hdikgcmV0dXJuO1xuXG4gICAgY29uc3Qgb25OYXY6IEV2ZW50TGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGUgPSBldmVudCBhcyBOYXZpZ2F0aW9uTmF2aWdhdGVFdmVudDtcbiAgICAgIGlmICghZS5jYW5JbnRlcmNlcHQgfHwgZS5oYXNoQ2hhbmdlIHx8IGUuZG93bmxvYWRSZXF1ZXN0KSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoZS5kZXN0aW5hdGlvbi51cmwpO1xuICAgICAgaWYgKHVybC5vcmlnaW4gIT09IGxvY2F0aW9uLm9yaWdpbikgcmV0dXJuO1xuXG4gICAgICBlLmludGVyY2VwdCh7XG4gICAgICAgIGhhbmRsZXI6ICgpID0+IHRoaXMuX25hdmlnYXRlTm93KHVybC5wYXRobmFtZSksXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIG5hdi5hZGRFdmVudExpc3RlbmVyKCduYXZpZ2F0ZScsIG9uTmF2KTtcbiAgICAgIGNvbnN0IHByZXYgPSB0aGlzLl9jbGVhbnVwTmF2O1xuICAgICAgdGhpcy5fY2xlYW51cE5hdiA9ICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBuYXYucmVtb3ZlRXZlbnRMaXN0ZW5lcignbmF2aWdhdGUnLCBvbk5hdik7XG4gICAgICAgIH0gY2F0Y2ggeyAvKiAqLyB9XG4gICAgICAgIHByZXY/LigpO1xuICAgICAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIE5hdmlnYXRpb24gQVBJIGludGVyY2VwdGlvbiBpcyBvcHRpb25hbDsgZmFsbCBiYWNrIHRvIHBvcHN0YXRlIHJvdXRpbmcuXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfc2V0dXBQb3BTdGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCBoYW5kbGVyID0gKCkgPT4ge1xuICAgICAgdGhpcy5fbmF2aWdhdGVOb3cobG9jYXRpb24ucGF0aG5hbWUpO1xuICAgIH07XG4gICAgZ2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIGhhbmRsZXIpO1xuICAgIGNvbnN0IHByZXYgPSB0aGlzLl9jbGVhbnVwTmF2O1xuICAgIHRoaXMuX2NsZWFudXBOYXYgPSAoKSA9PiB7XG4gICAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgaGFuZGxlcik7XG4gICAgICBwcmV2Py4oKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfbmF2aWdhdGVUbyhocmVmOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGhyZWYsIGxvY2F0aW9uLm9yaWdpbik7XG4gICAgaWYgKHVybC5vcmlnaW4gIT09IGxvY2F0aW9uLm9yaWdpbikge1xuICAgICAgbG9jYXRpb24uaHJlZiA9IGhyZWY7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaGlzdG9yeS5wdXNoU3RhdGUobnVsbCwgJycsIHVybC5wYXRobmFtZSArIHVybC5zZWFyY2ggKyB1cmwuaGFzaCk7XG4gICAgdGhpcy5fbmF2aWdhdGVOb3codXJsLnBhdGhuYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlcGxhY2VUbyhocmVmOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGhyZWYsIGxvY2F0aW9uLm9yaWdpbik7XG4gICAgaWYgKHVybC5vcmlnaW4gIT09IGxvY2F0aW9uLm9yaWdpbikgcmV0dXJuO1xuXG4gICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUobnVsbCwgJycsIHVybC5wYXRobmFtZSArIHVybC5zZWFyY2ggKyB1cmwuaGFzaCk7XG4gICAgdGhpcy5fbmF2aWdhdGVOb3codXJsLnBhdGhuYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgX25hdmlnYXRlTm93KHBhdGhuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBsb2NhbGUgPSBkZXRlY3RMb2NhbGUocGF0aG5hbWUsIHRoaXMuX2xvY2FsZXMsIHRoaXMuX2RlZmF1bHRMb2NhbGUpO1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdjdXJyZW50LXBhdGgnLCBwYXRobmFtZSk7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ2xvY2FsZScsIGxvY2FsZSk7XG5cbiAgICBjb25zdCBvcHRzID0gdGhpcy5fbmF2T3B0aW9ucztcbiAgICBpZiAoIW9wdHMpIHJldHVybjtcblxuICAgIC8vIFVwZGF0ZSBsYW5nLXN3aXRjaCBpbW1lZGlhdGVseSAoYmVmb3JlIGFzeW5jIGZldGNoKVxuICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVN3aXRjaCh0aGlzLnNoYWRvd1Jvb3QpO1xuICAgIH1cblxuICAgIG9wdHMuY29udGVudExvYWRlcihwYXRobmFtZSwgbG9jYWxlKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNoYWRvd1Jvb3QpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlU3dpdGNoKHRoaXMuc2hhZG93Um9vdCk7XG4gICAgICB9XG4gICAgICBvcHRzLm9uQWZ0ZXJTd2FwPy4ocGF0aG5hbWUsIGxvY2FsZSk7XG4gICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgbG9nLndhcm4oJ2NvbnRlbnQgbG9hZCBmYWlsZWQ6JywgZXJyKTtcbiAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlU3dpdGNoKHNoYWRvd1Jvb3Q6IFNoYWRvd1Jvb3QpOiB2b2lkIHtcbiAgICBjb25zdCBsaW5rID0gc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCcubGFuZy1zd2l0Y2gnKSBhcyBIVE1MQW5jaG9yRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKCFsaW5rKSByZXR1cm47XG4gICAgY29uc3QgcGF0aFdpdGhvdXRMb2NhbGUgPSB0aGlzLl9jdXJyZW50UGF0aFdpdGhvdXRMb2NhbGU7XG4gICAgY29uc3QgY3VycmVudExvY2FsZSA9IHRoaXMuX2N1cnJlbnRMb2NhbGU7XG4gICAgbGluay50ZXh0Q29udGVudCA9IHN3aXRjaExhYmVsKGN1cnJlbnRMb2NhbGUpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKCdocmVmJywgc3dpdGNoUGF0aChwYXRoV2l0aG91dExvY2FsZSwgY3VycmVudExvY2FsZSwgdGhpcy5fbG9jYWxlcykpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfbG9hZENvbnRlbnQocGF0aDogc3RyaW5nLCBsb2NhbGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2gocGF0aCk7XG4gICAgICBpZiAoIXJlc3Aub2spIHRocm93IG5ldyBFcnJvcihgSFRUUCAke3Jlc3Auc3RhdHVzfWApO1xuICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlc3AudGV4dCgpO1xuICAgICAgY29uc3QgcGFyc2VkID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhodG1sLCAndGV4dC9odG1sJyk7XG4gICAgICBjb25zdCB0bXAgPSBwYXJzZWQuYm9keTtcbiAgICAgIGNvbnN0IG5ld0xheW91dCA9IHRoaXMuX2ZpbmRPcGVuTGF5b3V0KHRtcCk7XG4gICAgICBpZiAoIW5ld0xheW91dCkgdGhyb3cgbmV3IEVycm9yKCdObyBvcGVuLWxheW91dCBmb3VuZCcpO1xuXG4gICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQubGFuZyA9IHBhcnNlZC5kb2N1bWVudEVsZW1lbnQubGFuZyB8fCBsb2NhbGU7XG4gICAgICBpZiAocGFyc2VkLnRpdGxlKSBkb2N1bWVudC50aXRsZSA9IHBhcnNlZC50aXRsZTtcbiAgICAgIHRoaXMuX3N5bmNIZWFkRWxlbWVudChwYXJzZWQsICdtZXRhW25hbWU9XCJkZXNjcmlwdGlvblwiXScpO1xuICAgICAgdGhpcy5fc3luY0hlYWRFbGVtZW50KHBhcnNlZCwgJ2xpbmtbcmVsPVwiY2Fub25pY2FsXCJdJyk7XG4gICAgICB0aGlzLl9zeW5jSGVhZEVsZW1lbnRzKHBhcnNlZCwgJ2xpbmtbcmVsPVwiYWx0ZXJuYXRlXCJdW2hyZWZsYW5nXScpO1xuXG4gICAgICB0aGlzLl9zeW5jTGF5b3V0QXR0cmlidXRlcyhuZXdMYXlvdXQsIGxvY2FsZSk7XG4gICAgICB0aGlzLl9yZXBsYWNlU2hhZG93Um9vdEZyb21MYXlvdXQobmV3TGF5b3V0KTtcblxuICAgICAgLy8gRE9NUGFyc2VyIG5vZGVzIGJlbG9uZyB0byBhIGRpZmZlcmVudCBkb2N1bWVudC4gYWRvcHROb2RlKClcbiAgICAgIC8vIHRyYW5zZmVycyBvd25lcnNoaXAgc28gYXBwZW5kQ2hpbGQgd29ya3Mgd2l0aG91dCBlcnJvcnMuXG4gICAgICB3aGlsZSAodGhpcy5maXJzdENoaWxkKSB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IEFycmF5LmZyb20obmV3TGF5b3V0LmNoaWxkcmVuKS5maWx0ZXIoKGNoaWxkKSA9PlxuICAgICAgICAhdGhpcy5faXNTaGFkb3dUZW1wbGF0ZShjaGlsZClcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IGFkb3B0ZWQgPSBkb2N1bWVudC5hZG9wdE5vZGUoY2hpbGQpO1xuICAgICAgICBpZiAoYWRvcHRlZCBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICAgICAgICB0aGlzLl9hY3RpdmF0ZURlY2xhcmF0aXZlU2hhZG93Um9vdHMoYWRvcHRlZCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChhZG9wdGVkKTtcbiAgICAgIH1cblxuICAgICAgLy8gUHJvcGFnYXRlIHRoZW1lIHRvIG5ld2x5IGluc2VydGVkIGNvbXBvbmVudHMuXG4gICAgICBjb25zdCBjdXJyZW50VGhlbWUgPSB0aGlzLmdldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScpIHx8XG4gICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudD8uZGF0YXNldD8udGhlbWU7XG4gICAgICBpZiAoY3VycmVudFRoZW1lKSB7XG4gICAgICAgIHRoaXMuX3Byb3BhZ2F0ZVRoZW1lKGN1cnJlbnRUaGVtZSk7XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLl9wcm9wYWdhdGVUaGVtZShjdXJyZW50VGhlbWUpKTtcbiAgICAgIH1cblxuICAgICAgZ2xvYmFsVGhpcy5zY3JvbGxUbyh7IHRvcDogMCwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZy53YXJuKCdTUEEgbmF2aWdhdGlvbiBmYWlsZWQsIHJlbG9hZGluZzonLCBlKTtcbiAgICAgIGdsb2JhbFRoaXMubG9jYXRpb24ucmVsb2FkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfc3luY0hlYWRFbGVtZW50KHBhcnNlZDogRG9jdW1lbnQsIHNlbGVjdG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpbmNvbWluZyA9IHBhcnNlZC5oZWFkLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBkb2N1bWVudC5oZWFkLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgIGlmICghaW5jb21pbmcpIHtcbiAgICAgIGN1cnJlbnQ/LnJlbW92ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbG9uZWQgPSBkb2N1bWVudC5hZG9wdE5vZGUoaW5jb21pbmcuY2xvbmVOb2RlKHRydWUpKTtcbiAgICBpZiAoY3VycmVudCkgY3VycmVudC5yZXBsYWNlV2l0aChjbG9uZWQpO1xuICAgIGVsc2UgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChjbG9uZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY0hlYWRFbGVtZW50cyhwYXJzZWQ6IERvY3VtZW50LCBzZWxlY3Rvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgZG9jdW1lbnQuaGVhZC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKS5mb3JFYWNoKChlbCkgPT4gZWwucmVtb3ZlKCkpO1xuICAgIHBhcnNlZC5oZWFkLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGRvY3VtZW50LmFkb3B0Tm9kZShlbC5jbG9uZU5vZGUodHJ1ZSkpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZUFjdGl2ZU5hdigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2hhZG93Um9vdCkgcmV0dXJuO1xuICAgIGNvbnN0IGNwID0gdGhpcy5fY3VycmVudFBhdGgoKTtcbiAgICBjb25zdCBsaW5rcyA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgJy5kb2NzLXNpZGViYXIgYVtkYXRhLW5hdl0sIC5oZWFkZXItbmF2IGFbZGF0YS1uYXZdJyxcbiAgICApO1xuICAgIGxpbmtzLmZvckVhY2goKGEpID0+IHtcbiAgICAgIGNvbnN0IG5hdiA9IGEuZ2V0QXR0cmlidXRlKCdkYXRhLW5hdicpO1xuICAgICAgY29uc3QgaXNBY3RpdmUgPSBuYXYgPT09IGNwO1xuICAgICAgYS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnLCBpc0FjdGl2ZSk7XG4gICAgICBpZiAoaXNBY3RpdmUpIGEuc2V0QXR0cmlidXRlKCdhcmlhLWN1cnJlbnQnLCAncGFnZScpO1xuICAgICAgZWxzZSBhLnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1jdXJyZW50Jyk7XG4gICAgfSk7XG4gIH1cblxuICAvLyAtLS0gVXRpbGl0aWVzIC0tLVxuXG4gIHByaXZhdGUgX2VzYyA9IGVzY2FwZUh0bWw7XG4gIHByaXZhdGUgX2VzY0F0dHIgPSBlc2NhcGVBdHRyO1xufVxuXG5leHBvcnQgZGVmYXVsdCBPcGVuTGF5b3V0O1xuXG4vLyBHdWFyZDogaWRlbXBvdGVudCBhY3Jvc3MgU1NSIHBhdGhzXG5pZiAodHlwZW9mIGN1c3RvbUVsZW1lbnRzICE9PSAndW5kZWZpbmVkJyAmJiAhY3VzdG9tRWxlbWVudHMuZ2V0KHRhZ05hbWUpKSB7XG4gIGN1c3RvbUVsZW1lbnRzLmRlZmluZSh0YWdOYW1lLCBPcGVuTGF5b3V0KTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1Q0FBdUMsR0FDdkM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0E0QkMsR0FFRCxTQUFTLFdBQVcsUUFBUSx1QkFBdUI7QUFDbkQsU0FBUyxVQUFVLFFBQTZCLGdDQUFnQztBQUNoRixTQUF1QixhQUFhLEVBQUUsY0FBYyxRQUFRLG9CQUFvQjtBQUNoRixTQUFTLFVBQVUsRUFBRSxVQUFVLFFBQVEsb0JBQW9CO0FBQzNELFNBQVMsWUFBWSxRQUFRLDJCQUEyQjtBQUN4RCxPQUFPLDBCQUEwQjtBQUNqQyxPQUFPLHVCQUF1QjtBQUU5QixPQUFPLE1BQU0sVUFBVSxjQUFjO0FBQ3JDLE1BQU0sbUJBQW1CLElBQUksSUFBSTtFQUFDO0VBQVM7RUFBVTtFQUFXO0VBQVE7Q0FBTztBQUMvRSxNQUFNLE1BQU0sYUFBYTtBQUV6QixTQUFTLGdCQUFnQixHQUFXO0VBQ2xDLE1BQU0sVUFBVSxJQUFJLElBQUk7RUFDeEIsSUFBSSxDQUFDLFNBQVMsT0FBTztFQUNyQixJQUFJLFFBQVEsVUFBVSxDQUFDLE9BQU8sT0FBTztFQUNyQyxJQUNFLFFBQVEsVUFBVSxDQUFDLFFBQ25CLFFBQVEsVUFBVSxDQUFDLFFBQ25CLFFBQVEsVUFBVSxDQUFDLFNBQ25CLFFBQVEsVUFBVSxDQUFDLFFBQ25CO0lBQ0EsT0FBTztFQUNUO0VBQ0EsSUFBSTtJQUNGLE1BQU0sU0FBUyxJQUFJ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
|