@rededor/site-front-end-lib 0.0.2 → 0.0.3-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.
Files changed (39) hide show
  1. package/esm2022/lib/helpers/getSiteUrl.func.mjs +11 -0
  2. package/esm2022/lib/helpers/index.mjs +4 -1
  3. package/esm2022/lib/helpers/removeHtmlTags.func.mjs +6 -0
  4. package/esm2022/lib/models/breadcrumb/breadcrumb-item.model.mjs +2 -0
  5. package/esm2022/lib/models/breadcrumb/breadcrumb-json-item.model.mjs +2 -0
  6. package/esm2022/lib/models/rdsl-post-category.model.mjs +2 -0
  7. package/esm2022/lib/models/seo/seo-data.model.mjs +2 -0
  8. package/esm2022/lib/models/seo/seo-unidade.model.mjs +2 -0
  9. package/esm2022/lib/models/social-meta-properties.model.mjs +2 -0
  10. package/esm2022/lib/models/wordpress/category/wpCategory.model.mjs +2 -0
  11. package/esm2022/lib/models/wordpress/post/post.model.mjs +2 -0
  12. package/esm2022/lib/services/index.mjs +3 -1
  13. package/esm2022/lib/services/log/log.service.mjs +3 -8
  14. package/esm2022/lib/services/seo/seo.service.mjs +469 -0
  15. package/esm2022/lib/services/server-response/server-response.service.mjs +86 -0
  16. package/esm2022/lib/tokens/LibConfig.mjs +1 -1
  17. package/esm2022/lib/tokens/express.tokens.mjs +4 -0
  18. package/esm2022/public-api.mjs +2 -1
  19. package/fesm2022/rededor-site-front-end-lib.mjs +590 -32
  20. package/fesm2022/rededor-site-front-end-lib.mjs.map +1 -1
  21. package/lib/helpers/getSiteUrl.func.d.ts +2 -0
  22. package/lib/helpers/index.d.ts +3 -0
  23. package/lib/helpers/removeHtmlTags.func.d.ts +2 -0
  24. package/lib/models/breadcrumb/breadcrumb-item.model.d.ts +6 -0
  25. package/lib/models/breadcrumb/breadcrumb-json-item.model.d.ts +8 -0
  26. package/lib/models/rdsl-post-category.model.d.ts +8 -0
  27. package/lib/models/seo/seo-data.model.d.ts +9 -0
  28. package/lib/models/seo/seo-unidade.model.d.ts +6 -0
  29. package/lib/models/social-meta-properties.model.d.ts +9 -0
  30. package/lib/models/wordpress/category/wpCategory.model.d.ts +14 -0
  31. package/lib/models/wordpress/post/post.model.d.ts +33 -0
  32. package/lib/services/index.d.ts +2 -0
  33. package/lib/services/log/log.service.d.ts +0 -1
  34. package/lib/services/seo/seo.service.d.ts +140 -0
  35. package/lib/services/server-response/server-response.service.d.ts +31 -0
  36. package/lib/tokens/LibConfig.d.ts +3 -0
  37. package/lib/tokens/express.tokens.d.ts +4 -0
  38. package/package.json +3 -1
  39. package/public-api.d.ts +1 -0
@@ -0,0 +1,469 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { DOCUMENT } from '@angular/common';
3
+ import * as he from 'he';
4
+ import { getSiteUrl, removeHtmlTags } from '../../helpers';
5
+ import { LIB_CONFIG } from '../../tokens/LibConfig';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/platform-browser";
8
+ import * as i2 from "@angular/common";
9
+ export class SeoService {
10
+ constructor(title, meta, location, libConfig, document) {
11
+ this.title = title;
12
+ this.meta = meta;
13
+ this.location = location;
14
+ this.libConfig = libConfig;
15
+ this.document = document;
16
+ this.separator = ' - ';
17
+ this.defaultTitle = 'Rede D’Or';
18
+ this.sameAs = [
19
+ 'https://www.facebook.com/rededor/',
20
+ 'https://www.instagram.com/rededor_oficial/',
21
+ 'https://www.linkedin.com/company/rededor-saoluiz',
22
+ 'https://twitter.com/rededor',
23
+ ];
24
+ this.twitterUser = '@rededor';
25
+ this.jsonTagId = 'seoJSON';
26
+ this.breadcrumbsJsonTagId = 'breadcrumbsJSON';
27
+ this.unidade = null;
28
+ this.unidadeName = "";
29
+ this.unidadePath = "";
30
+ this.unidadeSlug = "";
31
+ }
32
+ setFullSeo(data) {
33
+ this.setTitle(data.title.text, !!data.title.sub);
34
+ this.setDescription(data.description);
35
+ this.setCanonicalHref(data.canonical);
36
+ this.setPageJson();
37
+ this.setSocialTags(data.socialTags);
38
+ }
39
+ /**
40
+ * Define tag description da página
41
+ * @param content conteúdo da descrição <string>
42
+ */
43
+ setDescription(content) {
44
+ const descTag = this.meta.getTag("name='description'");
45
+ if (content) {
46
+ content = he.decode(content);
47
+ content = removeHtmlTags(content);
48
+ }
49
+ else {
50
+ content = '';
51
+ }
52
+ this.activeDescription = content;
53
+ const tagContent = { name: 'description', content };
54
+ if (descTag) {
55
+ this.meta.updateTag(tagContent);
56
+ }
57
+ else {
58
+ this.meta.addTag(tagContent);
59
+ }
60
+ return this;
61
+ }
62
+ /**
63
+ * Define meta tags para a página
64
+ * @param tag nome da tag meta
65
+ * @param content conteúdo da tag meta
66
+ * @param type tipo de tag meta
67
+ */
68
+ setMetaTag(tag, content, type = 'name') {
69
+ const metatag = this.meta.getTag(`${type}='${tag}'`);
70
+ content = he.decode(content);
71
+ content = removeHtmlTags(content);
72
+ const tagContent = {
73
+ [type]: tag,
74
+ content,
75
+ };
76
+ if (!metatag) {
77
+ this.meta.addTag(tagContent);
78
+ }
79
+ else {
80
+ this.meta.updateTag(tagContent);
81
+ }
82
+ return this;
83
+ }
84
+ /**
85
+ * Remove meta tags da página
86
+ * @param tag nome da tag meta
87
+ * @param content conteúdo da tag meta
88
+ * @param attr atributo da tag meta
89
+ * @param type tipo de tag meta
90
+ */
91
+ removeTag(tag, content, attr, type = 'name') {
92
+ const metatag = this.meta.getTag(`${type}='${tag}'`);
93
+ if (metatag) {
94
+ this.meta.removeTag(`${attr}=${content}`);
95
+ }
96
+ return this;
97
+ }
98
+ /**
99
+ * Define meta tags para Facebook
100
+ * @param title título para o facebook
101
+ * @param description descrição para o facebook
102
+ * @param url url para definição do facebook
103
+ * @param img imagem para definição no facebook
104
+ */
105
+ setMetaFacebook(title, description, url, img = null) {
106
+ this.setMetaTag('og:url', url, 'property');
107
+ this.setMetaTag('og:title', title, 'property');
108
+ this.setMetaTag('og:description', description, 'property');
109
+ this.setMetaTag('og:type', 'website', 'property');
110
+ this.setMetaTag('og:image', img ?? '', 'property');
111
+ }
112
+ /**
113
+ * Define meta tags para Twitter
114
+ * @param title título para o twitter
115
+ * @param description descrição para o twitter
116
+ * @param url url para o twitter
117
+ * @param img imagem para definição no twitter
118
+ */
119
+ setMetaTwitter(title, description, url, img = null) {
120
+ this.setMetaTag('twitter:site', url, 'name');
121
+ this.setMetaTag('twitter:title', title, 'name');
122
+ this.setMetaTag('twitter:description', description, 'name');
123
+ this.setMetaTag("twitter:image", img ?? '', "name");
124
+ }
125
+ /**
126
+ * Define tags de redes sociais (Twitter e Open Graph)
127
+ * @param properties
128
+ */
129
+ setSocialTags(properties) {
130
+ const pagePath = this.location.path();
131
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
132
+ let defaultProperties = {
133
+ twitterCard: 'summary',
134
+ twitterSite: this.twitterUser,
135
+ type: 'website',
136
+ title: this.getTitle(),
137
+ description: this.activeDescription || '',
138
+ url: `${siteurl}${pagePath}`,
139
+ image: `${siteurl}/assets/imgs/logo-novo-rededor-saoluiz-blue.png`,
140
+ };
141
+ if (properties) {
142
+ defaultProperties = { ...defaultProperties, ...properties };
143
+ }
144
+ this.setMetaTag('twitter:card', defaultProperties.twitterCard || '', 'name')
145
+ .setMetaTag('twitter:site', defaultProperties.twitterSite || '', 'name')
146
+ .setMetaTag('og:type', defaultProperties.type || '', 'property')
147
+ .setMetaTag('og:title', defaultProperties.title || '', 'property')
148
+ .setMetaTag('og:description', defaultProperties.description || '', 'property')
149
+ .setMetaTag('og:url', defaultProperties.url || '', 'property')
150
+ .setMetaTag('og:image', defaultProperties.image || '', 'property');
151
+ return this;
152
+ }
153
+ /**
154
+ * Define título da página
155
+ * @param title título da página <string>
156
+ * @param sub Se é subsite acrescenta unidade <boolean>
157
+ */
158
+ setTitle(title, sub = false) {
159
+ if (title && title !== '') {
160
+ title = he.decode(title);
161
+ title = removeHtmlTags(title);
162
+ if (sub) {
163
+ title = he.decode(`${title}${this.separator}${this.unidadeName}`);
164
+ }
165
+ this.title.setTitle(title);
166
+ }
167
+ return this;
168
+ }
169
+ /** Obtem título atual da página */
170
+ getTitle() {
171
+ return this.title.getTitle();
172
+ }
173
+ set404Title(component = 'Default Component') {
174
+ if (component && component !== '') {
175
+ component = he.decode(component);
176
+ component = removeHtmlTags(component);
177
+ if (this.unidadeName) {
178
+ component = he.decode(`${component}${this.separator}${this.unidadeName}`);
179
+ }
180
+ }
181
+ const title = `Erro 404 - ${component} - ${this.libConfig?.siteName} - ${this.location.path()}`;
182
+ this.title.setTitle(title);
183
+ console.log("set404Title", title);
184
+ return this;
185
+ }
186
+ /** Cria tag script para JSON de breadcrumbs */
187
+ createBreadcrumbsJSONTag() {
188
+ const tag = this.document.createElement('script');
189
+ tag.id = this.breadcrumbsJsonTagId;
190
+ tag.type = 'application/ld+json';
191
+ this.document.head.appendChild(tag);
192
+ this.breadcrumbsJsonTag = tag;
193
+ return tag;
194
+ }
195
+ /** Retorna tag para script json de breadcrumbs ou cria se não houver. */
196
+ getBreadcrumbsJSONTag() {
197
+ const elements = this.document.head.children;
198
+ let i;
199
+ for (i = 0; i < elements.length; i++) {
200
+ const elem = elements[i];
201
+ if (elem && elem.id === this.breadcrumbsJsonTagId) {
202
+ return elem;
203
+ }
204
+ }
205
+ return this.createBreadcrumbsJSONTag();
206
+ }
207
+ /** Define o JSON de breadcrumbs da página */
208
+ setBreadcrumbsJson(items) {
209
+ this.breadcrumbsJsonTag = this.getBreadcrumbsJSONTag();
210
+ const json = {
211
+ '@context': 'http://schema.org',
212
+ '@type': 'BreadcrumbList',
213
+ itemListElement: this.getJsonBreadcrumbItems(items),
214
+ };
215
+ this.breadcrumbsJsonTag.innerHTML = JSON.stringify(json);
216
+ return this;
217
+ }
218
+ /** Converte itens do breadcrumb em itens do JSON */
219
+ getJsonBreadcrumbItems(items) {
220
+ const jsonItems = [
221
+ {
222
+ '@type': 'ListItem',
223
+ position: 1,
224
+ item: { '@id': this.getBreadcrumbItemUrl(['/']), name: he.encode('Página Inicial') },
225
+ },
226
+ ];
227
+ items.forEach((item, i) => {
228
+ const jsonItem = {
229
+ '@type': 'ListItem',
230
+ position: i + 2,
231
+ item: { '@id': this.getBreadcrumbItemUrl(item?.url || []), name: he.encode(item.label) },
232
+ };
233
+ jsonItems.push(jsonItem);
234
+ });
235
+ return jsonItems;
236
+ }
237
+ /**
238
+ * Monta a url do item de breadcrumb proveniente do array de urls
239
+ * ou do caminho da própria página, conforme caso do último item.
240
+ */
241
+ getBreadcrumbItemUrl(url) {
242
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
243
+ if (!url || url.length <= 0) {
244
+ const pagePath = this.location.path();
245
+ return `${siteurl}${pagePath}`;
246
+ }
247
+ url = url.filter(u => u !== this.unidadePath);
248
+ const unidadePath = this.getUnidadePath();
249
+ const fullPath = `${unidadePath}/${url.join("/").replace(/^\/?/, "")}`;
250
+ return `${siteurl}/${fullPath}`.replace(/\/$/, '');
251
+ }
252
+ /** Cria tag script para o JSON de SEO */
253
+ createJSONTag() {
254
+ const tag = this.document.createElement('script');
255
+ tag.id = this.jsonTagId;
256
+ tag.type = 'application/ld+json';
257
+ this.document.head.appendChild(tag);
258
+ this.jsonTag = tag;
259
+ return tag;
260
+ }
261
+ /** Retorna tag para script json de breadcrumbs ou cria se não houver. */
262
+ getJSONTag() {
263
+ const elements = this.document.head.children;
264
+ let i;
265
+ for (i = 0; i < elements.length; i++) {
266
+ const elem = elements[i];
267
+ if (elem && elem.id === this.jsonTagId) {
268
+ return elem;
269
+ }
270
+ }
271
+ return this.createJSONTag();
272
+ }
273
+ /** Define JSON para SEO somente quando no servidor */
274
+ setPageJson() {
275
+ this.jsonTag = this.getJSONTag();
276
+ const graph = [this.getOrgJson(), this.getWebsiteJson(), this.getWebpageJson()];
277
+ const json = { '@context': 'http://schema.org', '@graph': graph };
278
+ this.jsonTag.innerHTML = JSON.stringify(json);
279
+ return this;
280
+ }
281
+ /** Obtem JSON da Organização */
282
+ getOrgJson() {
283
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
284
+ return {
285
+ '@type': 'Organization',
286
+ '@id': `${siteurl}#organization`,
287
+ name: this.defaultTitle,
288
+ keywords: this.libConfig?.keywords,
289
+ url: `${siteurl}`,
290
+ sameAs: this.sameAs,
291
+ };
292
+ }
293
+ /** Obtem JSON do Website (portal, unidades, etc) */
294
+ getWebsiteJson() {
295
+ const unidadePath = this.getUnidadePath();
296
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
297
+ return {
298
+ '@type': 'WebSite',
299
+ '@id': `${siteurl}${unidadePath}#website`,
300
+ url: `${siteurl}${unidadePath}`,
301
+ name: this.unidadeName,
302
+ keywords: this.libConfig?.keywords,
303
+ };
304
+ }
305
+ /** Obtem Json da página */
306
+ getWebpageJson() {
307
+ const unidadePath = this.getUnidadePath();
308
+ const siteURL = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
309
+ const pagePath = `${siteURL}${this.location.path()}`;
310
+ const desc = this.activeDescription ? this.activeDescription : '';
311
+ return {
312
+ '@type': 'WebPage',
313
+ '@id': `${pagePath}#webpage`,
314
+ url: pagePath,
315
+ inLanguage: 'pt-BR',
316
+ name: this.getTitle(),
317
+ isPartOf: { '@id': `${siteURL}${unidadePath}#website` },
318
+ about: { '@id': `${siteURL}#organization` },
319
+ description: desc,
320
+ };
321
+ }
322
+ getUnidadePath() {
323
+ let unidadePath = "";
324
+ if (this.unidade && this.unidadePath) {
325
+ unidadePath = this.unidade?.path === "/" ? "" : this.unidadePath?.substring(0, this.unidadePath?.length - 1);
326
+ }
327
+ return unidadePath;
328
+ }
329
+ /**
330
+ * Obtém a URL canônica da página.
331
+ * @returns A URL canônica da página.
332
+ */
333
+ getCanonicalHref() {
334
+ if (!this.canonicalTag) {
335
+ this.canonicalTag = this.getCanonicalTag();
336
+ }
337
+ return this.canonicalTag.href;
338
+ }
339
+ /** Cria tag para links canonicals no head */
340
+ createCanonicalTag() {
341
+ const tag = this.document.createElement('link');
342
+ tag.setAttribute('rel', 'canonical');
343
+ this.document.head.appendChild(tag);
344
+ tag.setAttribute('href', this.document.URL);
345
+ this.canonicalTag = tag;
346
+ return tag;
347
+ }
348
+ /** Retorna tag para link canonical existe ou cria se não houver. */
349
+ getCanonicalTag() {
350
+ const elements = this.document.head.children;
351
+ let i;
352
+ for (i = 0; i < elements.length; i++) {
353
+ const elem = elements[i];
354
+ if (elem && elem.tagName === 'LINK' && elem.rel === 'canonical') {
355
+ return elem;
356
+ }
357
+ }
358
+ return this.createCanonicalTag();
359
+ }
360
+ /**
361
+ * Define link canonical da página
362
+ * @param url url canonical
363
+ */
364
+ setCanonicalHref(url) {
365
+ if (!this.canonicalTag) {
366
+ this.canonicalTag = this.getCanonicalTag();
367
+ }
368
+ let path = this.location.path();
369
+ if (!path.startsWith('/')) {
370
+ path = `/${path}`;
371
+ }
372
+ const canonicalUrl = url && this.isCustomCanonical(url) ? url : `${getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix)}${path}`;
373
+ this.canonicalTag.setAttribute('href', canonicalUrl);
374
+ return this;
375
+ }
376
+ /**
377
+ * Verifica se a URL fornecida é um link canonical personalizado
378
+ * @param url URL fornecida
379
+ */
380
+ isCustomCanonical(url) {
381
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
382
+ return url.startsWith(siteurl);
383
+ }
384
+ /**
385
+ * Obtém uma url válida na aplicação proveniente de uma URL gerada
386
+ * pelo plugin Yoast para canonical automático.
387
+ * Ex.: https://wp.rededorsaoluiz.com.br/brasil/especialidades/cardiologia/
388
+ * @param urlFromWpApi URL canonica gerada pelo Yoast Plugin.
389
+ */
390
+ toLocalCanonical(urlFromWpApi) {
391
+ const apiUrl = this.libConfig?.wpUrl ?? '';
392
+ const siteurl = getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix);
393
+ const unidadeSlug = this.unidadeSlug;
394
+ let converted = urlFromWpApi.replace(apiUrl, siteurl);
395
+ if (unidadeSlug !== "/" && converted.includes(`/${unidadeSlug}/`)) {
396
+ converted = converted.replace(`/${unidadeSlug}/`, `${this.unidadePath}`);
397
+ }
398
+ return converted;
399
+ }
400
+ getPostContent(post) {
401
+ const content = post.acf.rdsl_post_content.find((content) => content.acf_fc_layout === "text_html");
402
+ return content.content || post.content.rendered || "";
403
+ }
404
+ addArticleScript(post, scriptName) {
405
+ const postContent = this.getPostContent(post);
406
+ const postHeaderImage = post.acf["rdsl_post_header_img"]
407
+ ? {
408
+ url: post.acf["rdsl_post_header_img"].url,
409
+ width: post.acf["rdsl_post_header_img"].width,
410
+ height: post.acf["rdsl_post_header_img"].height
411
+ }
412
+ : null;
413
+ const structuredData = {
414
+ "@context": "https://schema.org",
415
+ "@type": "Article",
416
+ mainEntityOfPage: `${getSiteUrl(this.libConfig?.siteUrl, this.libConfig?.siteSufix)}${this.location.path()}`,
417
+ headline: post.title?.rendered,
418
+ datePublished: post.date_gmt,
419
+ publisher: {
420
+ "@type": "Organization",
421
+ name: "Rede D’Or"
422
+ },
423
+ description: post.title?.rendered,
424
+ articleBody: removeHtmlTags(he.decode(postContent)),
425
+ dateModified: post.modified_gmt,
426
+ image: {
427
+ "@type": "ImageObject",
428
+ url: postHeaderImage?.url || post.featured_media_path || "",
429
+ height: postHeaderImage?.height || "",
430
+ width: postHeaderImage?.width || ""
431
+ },
432
+ author: {
433
+ "@type": "Organization",
434
+ name: "Rede D’Or"
435
+ },
436
+ wordcount: postContent.split(" ").length
437
+ };
438
+ const script = this.document.createElement("script");
439
+ script.type = "application/ld+json";
440
+ script.id = scriptName;
441
+ script.innerHTML = JSON.stringify(structuredData);
442
+ this.document.head.appendChild(script);
443
+ }
444
+ removeArticleScript(scriptName) {
445
+ const script = this.document.getElementById(scriptName);
446
+ script?.remove();
447
+ }
448
+ setUnidade({ unidade = null, unidadeName = "", unidadePath = "", unidadeSlug = "", }) {
449
+ this.unidade = unidade;
450
+ this.unidadeName = unidadeName;
451
+ this.unidadePath = unidadePath;
452
+ this.unidadeSlug = unidadeSlug;
453
+ }
454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, deps: [{ token: i1.Title }, { token: i1.Meta }, { token: i2.Location }, { token: LIB_CONFIG }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
455
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, providedIn: 'root' }); }
456
+ }
457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SeoService, decorators: [{
458
+ type: Injectable,
459
+ args: [{
460
+ providedIn: 'root',
461
+ }]
462
+ }], ctorParameters: () => [{ type: i1.Title }, { type: i1.Meta }, { type: i2.Location }, { type: undefined, decorators: [{
463
+ type: Inject,
464
+ args: [LIB_CONFIG]
465
+ }] }, { type: Document, decorators: [{
466
+ type: Inject,
467
+ args: [DOCUMENT]
468
+ }] }] });
469
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VvLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaXRlLWZyb250LWVuZC1saWIvc3JjL2xpYi9zZXJ2aWNlcy9zZW8vc2VvLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFFLFFBQVEsRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBRXJELE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBUXpCLE9BQU8sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSx3QkFBd0IsQ0FBQzs7OztBQUsvRCxNQUFNLE9BQU8sVUFBVTtJQXVCckIsWUFDVSxLQUFZLEVBQ1osSUFBVSxFQUNWLFFBQWtCLEVBQ0UsU0FBb0IsRUFDdEIsUUFBa0I7UUFKcEMsVUFBSyxHQUFMLEtBQUssQ0FBTztRQUNaLFNBQUksR0FBSixJQUFJLENBQU07UUFDVixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ0UsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUN0QixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBM0J2QyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGlCQUFZLEdBQUcsV0FBVyxDQUFDO1FBRTNCLFdBQU0sR0FBRztZQUNkLG1DQUFtQztZQUNuQyw0Q0FBNEM7WUFDNUMsa0RBQWtEO1lBQ2xELDZCQUE2QjtTQUM5QixDQUFDO1FBQ0ssZ0JBQVcsR0FBRyxVQUFVLENBQUM7UUFJeEIsY0FBUyxHQUFHLFNBQVMsQ0FBQztRQUV0Qix5QkFBb0IsR0FBRyxpQkFBaUIsQ0FBQztRQUUxQyxZQUFPLEdBQVEsSUFBSSxDQUFDO1FBQ3BCLGdCQUFXLEdBQVcsRUFBRSxDQUFDO1FBQ3pCLGdCQUFXLEdBQVcsRUFBRSxDQUFD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eEQsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFTSxVQUFVLENBQUMsRUFDaEIsT0FBTyxHQUFHLElBQUksRUFDZCxXQUFXLEdBQUcsRUFBRSxFQUNoQixXQUFXLEdBQUcsRUFBRSxFQUNoQixXQUFXLEdBQUcsRUFBRSxHQUNMO1FBQ1gsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDakMsQ0FBQzsrR0E5ZVUsVUFBVSxtRkEyQlgsVUFBVSxhQUNWLFFBQVE7bUhBNUJQLFVBQVUsY0FGVCxNQUFNOzs0RkFFUCxVQUFVO2tCQUh0QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBNEJJLE1BQU07MkJBQUMsVUFBVTs7MEJBQ2pCLE1BQU07MkJBQUMsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBNZXRhLCBUaXRsZSB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQgeyBET0NVTUVOVCwgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuaW1wb3J0ICogYXMgaGUgZnJvbSAnaGUnO1xyXG5cclxuaW1wb3J0IHsgU29jaWFsTWV0YVByb3BlcnRpZXMgfSBmcm9tICcuLi8uLi9tb2RlbHMvc29jaWFsLW1ldGEtcHJvcGVydGllcy5tb2RlbCc7XHJcbmltcG9ydCB7IEJyZWFkY3J1bWJJdGVtIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi1pdGVtLm1vZGVsJztcclxuaW1wb3J0IHsgQnJlYWRjcnVtYkpzb25JdGVtIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi1qc29uLWl0ZW0ubW9kZWwnO1xyXG5pbXBvcnQgeyBTZW9EYXRhIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Nlby9zZW8tZGF0YS5tb2RlbCc7XHJcbmltcG9ydCB7IFNlb1VuaWRhZGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvc2VvL3Nlby11bmlkYWRlLm1vZGVsJztcclxuaW1wb3J0IHsgV3BQb3N0IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3dvcmRwcmVzcy9wb3N0L3Bvc3QubW9kZWwnO1xyXG5pbXBvcnQgeyBnZXRTaXRlVXJsLCByZW1vdmVIdG1sVGFncyB9IGZyb20gJy4uLy4uL2hlbHBlcnMnO1xyXG5pbXBvcnQgeyBMSUJfQ09ORklHLCBMaWJDb25maWcgfSBmcm9tICcuLi8uLi90b2tlbnMvTGliQ29uZmlnJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTZW9TZXJ2aWNlIHtcclxuICBwdWJsaWMgc2VwYXJhdG9yID0gJyAtICc7XHJcbiAgcHVibGljIGRlZmF1bHRUaXRsZSA9ICdSZWRlIETigJlPcic7XHJcbiAgcHVibGljIGFjdGl2ZURlc2NyaXB0aW9uITogc3RyaW5nO1xyXG4gIHB1YmxpYyBzYW1lQXMgPSBbXHJcbiAgICAnaHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL3JlZGVkb3IvJyxcclxuICAgICdodHRwczovL3d3dy5pbnN0YWdyYW0uY29tL3JlZGVkb3Jfb2ZpY2lhbC8nLFxyXG4gICAgJ2h0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9jb21wYW55L3JlZGVkb3Itc2FvbHVpeicsXHJcbiAgICAnaHR0cHM6Ly90d2l0dGVyLmNvbS9yZWRlZG9yJyxcclxuICBdO1xyXG4gIHB1YmxpYyB0d2l0dGVyVXNlciA9ICdAcmVkZWRvcic7XHJcblxyXG4gIHByaXZhdGUgY2Fub25pY2FsVGFnITogSFRNTExpbmtFbGVtZW50O1xyXG4gIHByaXZhdGUganNvblRhZyE6IEhUTUxTY3JpcHRFbGVtZW50O1xyXG4gIHByaXZhdGUganNvblRhZ0lkID0gJ3Nlb0pTT04nO1xyXG4gIHByaXZhdGUgYnJlYWRjcnVtYnNKc29uVGFnITogSFRNTFNjcmlwdEVsZW1lbnQ7XHJcbiAgcHJpdmF0ZSBicmVhZGNydW1ic0pzb25UYWdJZCA9ICdicmVhZGNydW1ic0pTT04nO1xyXG5cclxuICBwdWJsaWMgdW5pZGFkZTogYW55ID0gbnVsbDtcclxuICBwdWJsaWMgdW5pZGFkZU5hbWU6IHN0cmluZyA9IFwiXCI7XHJcbiAgcHVibGljIHVuaWRhZGVQYXRoOiBzdHJpbmcgPSBcIlwiO1xyXG4gIHB1YmxpYyB1bmlkYWRlU2x1Zzogc3RyaW5nID0gXCJcIjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHRpdGxlOiBUaXRsZSxcclxuICAgIHByaXZhdGUgbWV0YTogTWV0YSxcclxuICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLFxyXG4gICAgQEluamVjdChMSUJfQ09ORklHKSBwcml2YXRlIGxpYkNvbmZpZzogTGliQ29uZmlnLFxyXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogRG9jdW1lbnQsXHJcbiAgKSB7fVxyXG5cclxuICBwdWJsaWMgc2V0RnVsbFNlbyhkYXRhOiBTZW9EYXRhKSB7XHJcbiAgICB0aGlzLnNldFRpdGxlKGRhdGEudGl0bGUudGV4dCwgISFkYXRhLnRpdGxlLnN1Yik7XHJcbiAgICB0aGlzLnNldERlc2NyaXB0aW9uKGRhdGEuZGVzY3JpcHRpb24pO1xyXG4gICAgdGhpcy5zZXRDYW5vbmljYWxIcmVmKGRhdGEuY2Fub25pY2FsKTtcclxuICAgIHRoaXMuc2V0UGFnZUpzb24oKTtcclxuICAgIHRoaXMuc2V0U29jaWFsVGFncyhkYXRhLnNvY2lhbFRhZ3MpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lIHRhZyBkZXNjcmlwdGlvbiBkYSBww6FnaW5hXHJcbiAgICogQHBhcmFtIGNvbnRlbnQgY29udGXDumRvIGRhIGRlc2NyacOnw6NvIDxzdHJpbmc+XHJcbiAgICovXHJcbiAgcHVibGljIHNldERlc2NyaXB0aW9uKGNvbnRlbnQ6IHN0cmluZyk6IFNlb1NlcnZpY2Uge1xyXG4gICAgY29uc3QgZGVzY1RhZyA9IHRoaXMubWV0YS5nZXRUYWcoXCJuYW1lPSdkZXNjcmlwdGlvbidcIik7XHJcbiAgICBpZiAoY29udGVudCkge1xyXG4gICAgICBjb250ZW50ID0gaGUuZGVjb2RlKGNvbnRlbnQpO1xyXG4gICAgICBjb250ZW50ID0gcmVtb3ZlSHRtbFRhZ3MoY29udGVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZW50ID0gJyc7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFjdGl2ZURlc2NyaXB0aW9uID0gY29udGVudDtcclxuICAgIGNvbnN0IHRhZ0NvbnRlbnQgPSB7IG5hbWU6ICdkZXNjcmlwdGlvbicsIGNvbnRlbnQgfTtcclxuICAgIGlmIChkZXNjVGFnKSB7XHJcbiAgICAgIHRoaXMubWV0YS51cGRhdGVUYWcodGFnQ29udGVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm1ldGEuYWRkVGFnKHRhZ0NvbnRlbnQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZWZpbmUgbWV0YSB0YWdzIHBhcmEgYSBww6FnaW5hXHJcbiAgICogQHBhcmFtIHRhZyBub21lIGRhIHRhZyBtZXRhXHJcbiAgICogQHBhcmFtIGNvbnRlbnQgY29udGXDumRvIGRhIHRhZyBtZXRhXHJcbiAgICogQHBhcmFtIHR5cGUgdGlwbyBkZSB0YWcgbWV0YVxyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXRNZXRhVGFnKHRhZzogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIHR5cGUgPSAnbmFtZScpIHtcclxuICAgIGNvbnN0IG1ldGF0YWcgPSB0aGlzLm1ldGEuZ2V0VGFnKGAke3R5cGV9PScke3RhZ30nYCk7XHJcbiAgICBjb250ZW50ID0gaGUuZGVjb2RlKGNvbnRlbnQpO1xyXG4gICAgY29udGVudCA9IHJlbW92ZUh0bWxUYWdzKGNvbnRlbnQpO1xyXG4gICAgY29uc3QgdGFnQ29udGVudCA9IHtcclxuICAgICAgW3R5cGVdOiB0YWcsXHJcbiAgICAgIGNvbnRlbnQsXHJcbiAgICB9O1xyXG4gICAgaWYgKCFtZXRhdGFnKSB7XHJcbiAgICAgIHRoaXMubWV0YS5hZGRUYWcodGFnQ29udGVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm1ldGEudXBkYXRlVGFnKHRhZ0NvbnRlbnQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmUgbWV0YSB0YWdzIGRhIHDDoWdpbmFcclxuICAgKiBAcGFyYW0gdGFnIG5vbWUgZGEgdGFnIG1ldGFcclxuICAgKiBAcGFyYW0gY29udGVudCBjb250ZcO6ZG8gZGEgdGFnIG1ldGFcclxuICAgKiBAcGFyYW0gYXR0ciBhdHJpYnV0byBkYSB0YWcgbWV0YVxyXG4gICAqIEBwYXJhbSB0eXBlIHRpcG8gZGUgdGFnIG1ldGFcclxuICAgKi9cclxuICBwdWJsaWMgcmVtb3ZlVGFnKHRhZzogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIGF0dHI6IHN0cmluZywgdHlwZSA9ICduYW1lJyl7XHJcbiAgICBjb25zdCBtZXRhdGFnID0gdGhpcy5tZXRhLmdldFRhZyhgJHt0eXBlfT0nJHt0YWd9J2ApO1xyXG4gICAgaWYgKG1ldGF0YWcpIHtcclxuICAgICAgdGhpcy5tZXRhLnJlbW92ZVRhZyhgJHthdHRyfT0ke2NvbnRlbnR9YCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluZSBtZXRhIHRhZ3MgcGFyYSBGYWNlYm9va1xyXG4gICAqIEBwYXJhbSB0aXRsZSB0w610dWxvIHBhcmEgbyBmYWNlYm9va1xyXG4gICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmnDp8OjbyBwYXJhIG8gZmFjZWJvb2tcclxuICAgKiBAcGFyYW0gdXJsIHVybCBwYXJhIGRlZmluacOnw6NvIGRvIGZhY2Vib29rXHJcbiAgICogQHBhcmFtIGltZyBpbWFnZW0gcGFyYSBkZWZpbmnDp8OjbyBubyBmYWNlYm9va1xyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXRNZXRhRmFjZWJvb2sodGl0bGU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgdXJsOiBzdHJpbmcsIGltZzogc3RyaW5nIHwgbnVsbCA9IG51bGwpIHtcclxuICAgIHRoaXMuc2V0TWV0YVRhZygnb2c6dXJsJywgdXJsLCAncHJvcGVydHknKTtcclxuICAgIHRoaXMuc2V0TWV0YVRhZygnb2c6dGl0bGUnLCB0aXRsZSwgJ3Byb3BlcnR5Jyk7XHJcbiAgICB0aGlzLnNldE1ldGFUYWcoJ29nOmRlc2NyaXB0aW9uJywgZGVzY3JpcHRpb24sICdwcm9wZXJ0eScpO1xyXG4gICAgdGhpcy5zZXRNZXRhVGFnKCdvZzp0eXBlJywgJ3dlYnNpdGUnLCAncHJvcGVydHknKTtcclxuICAgIHRoaXMuc2V0TWV0YVRhZygnb2c6aW1hZ2UnLCBpbWcgPz8gJycsICdwcm9wZXJ0eScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lIG1ldGEgdGFncyBwYXJhIFR3aXR0ZXJcclxuICAgKiBAcGFyYW0gdGl0bGUgdMOtdHVsbyBwYXJhIG8gdHdpdHRlclxyXG4gICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmnDp8OjbyBwYXJhIG8gdHdpdHRlclxyXG4gICAqIEBwYXJhbSB1cmwgdXJsIHBhcmEgbyB0d2l0dGVyXHJcbiAgICogQHBhcmFtIGltZyBpbWFnZW0gcGFyYSBkZWZpbmnDp8OjbyBubyB0d2l0dGVyXHJcbiAgICovXHJcbiAgcHVibGljIHNldE1ldGFUd2l0dGVyKHRpdGxlOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcsIHVybDogc3RyaW5nLCBpbWc6IHN0cmluZyB8IG51bGwgPSBudWxsKSB7XHJcbiAgICB0aGlzLnNldE1ldGFUYWcoJ3R3aXR0ZXI6c2l0ZScsIHVybCwgJ25hbWUnKTtcclxuICAgIHRoaXMuc2V0TWV0YVRhZygndHdpdHRlcjp0aXRsZScsIHRpdGxlLCAnbmFtZScpO1xyXG4gICAgdGhpcy5zZXRNZXRhVGFnKCd0d2l0dGVyOmRlc2NyaXB0aW9uJywgZGVzY3JpcHRpb24sICduYW1lJyk7XHJcbiAgICB0aGlzLnNldE1ldGFUYWcoXCJ0d2l0dGVyOmltYWdlXCIsIGltZyA/PyAnJywgXCJuYW1lXCIpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lIHRhZ3MgZGUgcmVkZXMgc29jaWFpcyAoVHdpdHRlciBlIE9wZW4gR3JhcGgpXHJcbiAgICogQHBhcmFtIHByb3BlcnRpZXNcclxuICAgKi9cclxuICBzZXRTb2NpYWxUYWdzKHByb3BlcnRpZXM/OiBTb2NpYWxNZXRhUHJvcGVydGllcykge1xyXG4gICAgY29uc3QgcGFnZVBhdGggPSB0aGlzLmxvY2F0aW9uLnBhdGgoKTtcclxuICAgIGNvbnN0IHNpdGV1cmwgPSBnZXRTaXRlVXJsKHRoaXMubGliQ29uZmlnPy5zaXRlVXJsLCB0aGlzLmxpYkNvbmZpZz8uc2l0ZVN1Zml4KTtcclxuICAgIGxldCBkZWZhdWx0UHJvcGVydGllczogU29jaWFsTWV0YVByb3BlcnRpZXMgPSB7XHJcbiAgICAgIHR3aXR0ZXJDYXJkOiAnc3VtbWFyeScsXHJcbiAgICAgIHR3aXR0ZXJTaXRlOiB0aGlzLnR3aXR0ZXJVc2VyLFxyXG4gICAgICB0eXBlOiAnd2Vic2l0ZScsXHJcbiAgICAgIHRpdGxlOiB0aGlzLmdldFRpdGxlKCksXHJcbiAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmFjdGl2ZURlc2NyaXB0aW9uIHx8ICcnLFxyXG4gICAgICB1cmw6IGAke3NpdGV1cmx9JHtwYWdlUGF0aH1gLFxyXG4gICAgICBpbWFnZTogYCR7c2l0ZXVybH0vYXNzZXRzL2ltZ3MvbG9nby1ub3ZvLXJlZGVkb3Itc2FvbHVpei1ibHVlLnBuZ2AsXHJcbiAgICB9O1xyXG4gICAgaWYgKHByb3BlcnRpZXMpIHtcclxuICAgICAgZGVmYXVsdFByb3BlcnRpZXMgPSB7IC4uLmRlZmF1bHRQcm9wZXJ0aWVzLCAuLi5wcm9wZXJ0aWVzIH07XHJcbiAgICB9XHJcbiAgICB0aGlzLnNldE1ldGFUYWcoJ3R3aXR0ZXI6Y2FyZCcsIGRlZmF1bHRQcm9wZXJ0aWVzLnR3aXR0ZXJDYXJkIHx8ICcnLCAnbmFtZScpXHJcbiAgICAgIC5zZXRNZXRhVGFnKCd0d2l0dGVyOnNpdGUnLCBkZWZhdWx0UHJvcGVydGllcy50d2l0dGVyU2l0ZSB8fCAnJywgJ25hbWUnKVxyXG4gICAgICAuc2V0TWV0YVRhZygnb2c6dHlwZScsIGRlZmF1bHRQcm9wZXJ0aWVzLnR5cGUgfHwgJycsICdwcm9wZXJ0eScpXHJcbiAgICAgIC5zZXRNZXRhVGFnKCdvZzp0aXRsZScsIGRlZmF1bHRQcm9wZXJ0aWVzLnRpdGxlIHx8ICcnLCAncHJvcGVydHknKVxyXG4gICAgICAuc2V0TWV0YVRhZygnb2c6ZGVzY3JpcHRpb24nLCBkZWZhdWx0UHJvcGVydGllcy5kZXNjcmlwdGlvbiB8fCAnJywgJ3Byb3BlcnR5JylcclxuICAgICAgLnNldE1ldGFUYWcoJ29nOnVybCcsIGRlZmF1bHRQcm9wZXJ0aWVzLnVybCB8fCAnJywgJ3Byb3BlcnR5JylcclxuICAgICAgLnNldE1ldGFUYWcoJ29nOmltYWdlJywgZGVmYXVsdFByb3BlcnRpZXMuaW1hZ2UgfHwgJycsICdwcm9wZXJ0eScpO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lIHTDrXR1bG8gZGEgcMOhZ2luYVxyXG4gICAqIEBwYXJhbSB0aXRsZSB0w610dWxvIGRhIHDDoWdpbmEgPHN0cmluZz5cclxuICAgKiBAcGFyYW0gc3ViIFNlIMOpIHN1YnNpdGUgYWNyZXNjZW50YSB1bmlkYWRlIDxib29sZWFuPlxyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXRUaXRsZSh0aXRsZTogc3RyaW5nLCBzdWIgPSBmYWxzZSkge1xyXG4gICAgaWYgKHRpdGxlICYmIHRpdGxlICE9PSAnJykge1xyXG4gICAgICB0aXRsZSA9IGhlLmRlY29kZSh0aXRsZSk7XHJcbiAgICAgIHRpdGxlID0gcmVtb3ZlSHRtbFRhZ3ModGl0bGUpO1xyXG4gICAgICBpZiAoc3ViKSB7XHJcbiAgICAgICAgdGl0bGUgPSBoZS5kZWNvZGUoYCR7dGl0bGV9JHt0aGlzLnNlcGFyYXRvcn0ke3RoaXMudW5pZGFkZU5hbWV9YCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy50aXRsZS5zZXRUaXRsZSh0aXRsZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBPYnRlbSB0w610dWxvIGF0dWFsIGRhIHDDoWdpbmEgKi9cclxuICBwdWJsaWMgZ2V0VGl0bGUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLnRpdGxlLmdldFRpdGxlKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0NDA0VGl0bGUoY29tcG9uZW50OiBzdHJpbmcgPSAnRGVmYXVsdCBDb21wb25lbnQnKSB7XHJcbiAgICBpZiAoY29tcG9uZW50ICYmIGNvbXBvbmVudCAhPT0gJycpIHtcclxuICAgICAgY29tcG9uZW50ID0gaGUuZGVjb2RlKGNvbXBvbmVudCk7XHJcbiAgICAgIGNvbXBvbmVudCA9IHJlbW92ZUh0bWxUYWdzKGNvbXBvbmVudCk7XHJcbiAgICAgIGlmICh0aGlzLnVuaWRhZGVOYW1lKSB7XHJcbiAgICAgICAgY29tcG9uZW50ID0gaGUuZGVjb2RlKGAke2NvbXBvbmVudH0ke3RoaXMuc2VwYXJhdG9yfSR7dGhpcy51bmlkYWRlTmFtZX1gKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgdGl0bGUgPSBgRXJybyA0MDQgLSAke2NvbXBvbmVudH0gLSAke3RoaXMubGliQ29uZmlnPy5zaXRlTmFtZX0gLSAke3RoaXMubG9jYXRpb24ucGF0aCgpfWA7XHJcbiAgICB0aGlzLnRpdGxlLnNldFRpdGxlKHRpdGxlKTtcclxuICAgIGNvbnNvbGUubG9nKFwic2V0NDA0VGl0bGVcIiwgdGl0bGUpXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBDcmlhIHRhZyBzY3JpcHQgcGFyYSBKU09OIGRlIGJyZWFkY3J1bWJzICovXHJcbiAgcHJpdmF0ZSBjcmVhdGVCcmVhZGNydW1ic0pTT05UYWcoKTogSFRNTFNjcmlwdEVsZW1lbnQge1xyXG4gICAgY29uc3QgdGFnOiBIVE1MU2NyaXB0RWxlbWVudCA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XHJcbiAgICB0YWcuaWQgPSB0aGlzLmJyZWFkY3J1bWJzSnNvblRhZ0lkO1xyXG4gICAgdGFnLnR5cGUgPSAnYXBwbGljYXRpb24vbGQranNvbic7XHJcbiAgICB0aGlzLmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQodGFnKTtcclxuICAgIHRoaXMuYnJlYWRjcnVtYnNKc29uVGFnID0gdGFnO1xyXG4gICAgcmV0dXJuIHRhZztcclxuICB9XHJcblxyXG4gIC8qKiBSZXRvcm5hIHRhZyBwYXJhIHNjcmlwdCBqc29uIGRlIGJyZWFkY3J1bWJzIG91IGNyaWEgc2UgbsOjbyBob3V2ZXIuICovXHJcbiAgcHJpdmF0ZSBnZXRCcmVhZGNydW1ic0pTT05UYWcoKTogSFRNTFNjcmlwdEVsZW1lbnQge1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmRvY3VtZW50LmhlYWQuY2hpbGRyZW47XHJcbiAgICBsZXQgaTogbnVtYmVyO1xyXG4gICAgZm9yIChpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGVsZW0gPSBlbGVtZW50c1tpXSBhcyBIVE1MU2NyaXB0RWxlbWVudDtcclxuICAgICAgaWYgKGVsZW0gJiYgZWxlbS5pZCA9PT0gdGhpcy5icmVhZGNydW1ic0pzb25UYWdJZCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVCcmVhZGNydW1ic0pTT05UYWcoKTtcclxuICB9XHJcblxyXG4gIC8qKiBEZWZpbmUgbyBKU09OIGRlIGJyZWFkY3J1bWJzIGRhIHDDoWdpbmEgKi9cclxuICBwdWJsaWMgc2V0QnJlYWRjcnVtYnNKc29uKGl0ZW1zOiBCcmVhZGNydW1iSXRlbVtdKSB7XHJcbiAgICB0aGlzLmJyZWFkY3J1bWJzSnNvblRhZyA9IHRoaXMuZ2V0QnJlYWRjcnVtYnNKU09OVGFnKCk7XHJcbiAgICBjb25zdCBqc29uID0ge1xyXG4gICAgICAnQGNvbnRleHQnOiAnaHR0cDovL3NjaGVtYS5vcmcnLFxyXG4gICAgICAnQHR5cGUnOiAnQnJlYWRjcnVtYkxpc3QnLFxyXG4gICAgICBpdGVtTGlzdEVsZW1lbnQ6IHRoaXMuZ2V0SnNvbkJyZWFkY3J1bWJJdGVtcyhpdGVtcyksXHJcbiAgICB9O1xyXG4gICAgdGhpcy5icmVhZGNydW1ic0pzb25UYWcuaW5uZXJIVE1MID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBDb252ZXJ0ZSBpdGVucyBkbyBicmVhZGNydW1iIGVtIGl0ZW5zIGRvIEpTT04gKi9cclxuICBwcml2YXRlIGdldEpzb25CcmVhZGNydW1iSXRlbXMoaXRlbXM6IEJyZWFkY3J1bWJJdGVtW10pOiBCcmVhZGNydW1iSnNvbkl0ZW1bXSB7XHJcbiAgICBjb25zdCBqc29uSXRlbXMgPSBbXHJcbiAgICAgIHtcclxuICAgICAgICAnQHR5cGUnOiAnTGlzdEl0ZW0nLFxyXG4gICAgICAgIHBvc2l0aW9uOiAxLFxyXG4gICAgICAgIGl0ZW06IHsgJ0BpZCc6IHRoaXMuZ2V0QnJlYWRjcnVtYkl0ZW1VcmwoWycvJ10pLCBuYW1lOiBoZS5lbmNvZGUoJ1DDoWdpbmEgSW5pY2lhbCcpIH0sXHJcbiAgICAgIH0gYXMgQnJlYWRjcnVtYkpzb25JdGVtLFxyXG4gICAgXTtcclxuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcclxuICAgICAgY29uc3QganNvbkl0ZW06IEJyZWFkY3J1bWJKc29uSXRlbSA9IHtcclxuICAgICAgICAnQHR5cGUnOiAnTGlzdEl0ZW0nLFxyXG4gICAgICAgIHBvc2l0aW9uOiBpICsgMixcclxuICAgICAgICBpdGVtOiB7ICdAaWQnOiB0aGlzLmdldEJyZWFkY3J1bWJJdGVtVXJsKGl0ZW0/LnVybCB8fCBbXSksIG5hbWU6IGhlLmVuY29kZShpdGVtLmxhYmVsKSB9LFxyXG4gICAgICB9O1xyXG4gICAgICBqc29uSXRlbXMucHVzaChqc29uSXRlbSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBqc29uSXRlbXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNb250YSBhIHVybCBkbyBpdGVtIGRlIGJyZWFkY3J1bWIgcHJvdmVuaWVudGUgZG8gYXJyYXkgZGUgdXJsc1xyXG4gICAqIG91IGRvIGNhbWluaG8gZGEgcHLDs3ByaWEgcMOhZ2luYSwgY29uZm9ybWUgY2FzbyBkbyDDumx0aW1vIGl0ZW0uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRCcmVhZGNydW1iSXRlbVVybCh1cmw6IHN0cmluZ1tdKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHNpdGV1cmwgPSBnZXRTaXRlVXJsKHRoaXMubGliQ29uZmlnPy5zaXRlVXJsLCB0aGlzLmxpYkNvbmZpZz8uc2l0ZVN1Zml4KTtcclxuICAgIGlmICghdXJsIHx8IHVybC5sZW5ndGggPD0gMCkge1xyXG4gICAgICBjb25zdCBwYWdlUGF0aCA9IHRoaXMubG9jYXRpb24ucGF0aCgpO1xyXG4gICAgICByZXR1cm4gYCR7c2l0ZXVybH0ke3BhZ2VQYXRofWA7XHJcbiAgICB9XHJcbiAgICB1cmwgPSB1cmwuZmlsdGVyKCB1ID0+IHUgIT09IHRoaXMudW5pZGFkZVBhdGgpO1xyXG4gICAgY29uc3QgdW5pZGFkZVBhdGggPSB0aGlzLmdldFVuaWRhZGVQYXRoKCk7XHJcbiAgICBjb25zdCBmdWxsUGF0aCA9IGAke3VuaWRhZGVQYXRofS8ke3VybC5qb2luKFwiL1wiKS5yZXBsYWNlKC9eXFwvPy8sIFwiXCIpfWA7XHJcbiAgICByZXR1cm4gYCR7c2l0ZXVybH0vJHtmdWxsUGF0aH1gLnJlcGxhY2UoL1xcLyQvLCAnJyk7XHJcbiAgfVxyXG5cclxuICAvKiogQ3JpYSB0YWcgc2NyaXB0IHBhcmEgbyBKU09OIGRlIFNFTyAqL1xyXG4gIHByaXZhdGUgY3JlYXRlSlNPTlRhZygpOiBIVE1MU2NyaXB0RWxlbWVudCB7XHJcbiAgICBjb25zdCB0YWc6IEhUTUxTY3JpcHRFbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcclxuICAgIHRhZy5pZCA9IHRoaXMuanNvblRhZ0lkO1xyXG4gICAgdGFnLnR5cGUgPSAnYXBwbGljYXRpb24vbGQranNvbic7XHJcbiAgICB0aGlzLmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQodGFnKTtcclxuICAgIHRoaXMuanNvblRhZyA9IHRhZztcclxuICAgIHJldHVybiB0YWc7XHJcbiAgfVxyXG5cclxuICAvKiogUmV0b3JuYSB0YWcgcGFyYSBzY3JpcHQganNvbiBkZSBicmVhZGNydW1icyBvdSBjcmlhIHNlIG7Do28gaG91dmVyLiAqL1xyXG4gIHByaXZhdGUgZ2V0SlNPTlRhZygpOiBIVE1MU2NyaXB0RWxlbWVudCB7XHJcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZG9jdW1lbnQuaGVhZC5jaGlsZHJlbjtcclxuICAgIGxldCBpOiBudW1iZXI7XHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgZWxlbSA9IGVsZW1lbnRzW2ldIGFzIEhUTUxTY3JpcHRFbGVtZW50O1xyXG4gICAgICBpZiAoZWxlbSAmJiBlbGVtLmlkID09PSB0aGlzLmpzb25UYWdJZCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVKU09OVGFnKCk7XHJcbiAgfVxyXG5cclxuICAvKiogRGVmaW5lIEpTT04gcGFyYSBTRU8gc29tZW50ZSBxdWFuZG8gbm8gc2Vydmlkb3IgKi9cclxuICBwdWJsaWMgc2V0UGFnZUpzb24oKSB7XHJcbiAgICB0aGlzLmpzb25UYWcgPSB0aGlzLmdldEpTT05UYWcoKTtcclxuICAgIGNvbnN0IGdyYXBoID0gW3RoaXMuZ2V0T3JnSnNvbigpLCB0aGlzLmdldFdlYnNpdGVKc29uKCksIHRoaXMuZ2V0V2VicGFnZUpzb24oKV07XHJcbiAgICBjb25zdCBqc29uID0geyAnQGNvbnRleHQnOiAnaHR0cDovL3NjaGVtYS5vcmcnLCAnQGdyYXBoJzogZ3JhcGggfTtcclxuICAgIHRoaXMuanNvblRhZy5pbm5lckhUTUwgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIE9idGVtIEpTT04gZGEgT3JnYW5pemHDp8OjbyAqL1xyXG4gIHByaXZhdGUgZ2V0T3JnSnNvbigpIHtcclxuICAgIGNvbnN0IHNpdGV1cmwgPSBnZXRTaXRlVXJsKHRoaXMubGliQ29uZmlnPy5zaXRlVXJsLCB0aGlzLmxpYkNvbmZpZz8uc2l0ZVN1Zml4KTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICdAdHlwZSc6ICdPcmdhbml6YXRpb24nLFxyXG4gICAgICAnQGlkJzogYCR7c2l0ZXVybH0jb3JnYW5pemF0aW9uYCxcclxuICAgICAgbmFtZTogdGhpcy5kZWZhdWx0VGl0bGUsXHJcbiAgICAgIGtleXdvcmRzOiB0aGlzLmxpYkNvbmZpZz8ua2V5d29yZHMsXHJcbiAgICAgIHVybDogYCR7c2l0ZXVybH1gLFxyXG4gICAgICBzYW1lQXM6IHRoaXMuc2FtZUFzLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKiBPYnRlbSBKU09OIGRvIFdlYnNpdGUgKHBvcnRhbCwgdW5pZGFkZXMsIGV0YykgKi9cclxuICBwcml2YXRlIGdldFdlYnNpdGVKc29uKCkge1xyXG4gICAgY29uc3QgdW5pZGFkZVBhdGggPSB0aGlzLmdldFVuaWRhZGVQYXRoKCk7XHJcbiAgICBjb25zdCBzaXRldXJsID0gZ2V0U2l0ZVVybCh0aGlzLmxpYkNvbmZpZz8uc2l0ZVVybCwgdGhpcy5saWJDb25maWc/LnNpdGVTdWZpeCk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAnQHR5cGUnOiAnV2ViU2l0ZScsXHJcbiAgICAgICdAaWQnOiBgJHtzaXRldXJsfSR7dW5pZGFkZVBhdGh9I3dlYnNpdGVgLFxyXG4gICAgICB1cmw6IGAke3NpdGV1cmx9JHt1bmlkYWRlUGF0aH1gLFxyXG4gICAgICBuYW1lOiB0aGlzLnVuaWRhZGVOYW1lLFxyXG4gICAgICBrZXl3b3JkczogdGhpcy5saWJDb25maWc/LmtleXdvcmRzLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKiBPYnRlbSBKc29uIGRhIHDDoWdpbmEgKi9cclxuICBwcml2YXRlIGdldFdlYnBhZ2VKc29uKCkge1xyXG4gICAgY29uc3QgdW5pZGFkZVBhdGggPSB0aGlzLmdldFVuaWRhZGVQYXRoKCk7XHJcbiAgICBjb25zdCBzaXRlVVJMID0gZ2V0U2l0ZVVybCh0aGlzLmxpYkNvbmZpZz8uc2l0ZVVybCwgdGhpcy5saWJDb25maWc/LnNpdGVTdWZpeCk7XHJcbiAgICBjb25zdCBwYWdlUGF0aCA9IGAke3NpdGVVUkx9JHt0aGlzLmxvY2F0aW9uLnBhdGgoKX1gO1xyXG4gICAgY29uc3QgZGVzYyA9IHRoaXMuYWN0aXZlRGVzY3JpcHRpb24gPyB0aGlzLmFjdGl2ZURlc2NyaXB0aW9uIDogJyc7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAnQHR5cGUnOiAnV2ViUGFnZScsXHJcbiAgICAgICdAaWQnOiBgJHtwYWdlUGF0aH0jd2VicGFnZWAsXHJcbiAgICAgIHVybDogcGFnZVBhdGgsXHJcbiAgICAgIGluTGFuZ3VhZ2U6ICdwdC1CUicsXHJcbiAgICAgIG5hbWU6IHRoaXMuZ2V0VGl0bGUoKSxcclxuICAgICAgaXNQYXJ0T2Y6IHsgJ0BpZCc6IGAke3NpdGVVUkx9JHt1bmlkYWRlUGF0aH0jd2Vic2l0ZWAgfSxcclxuICAgICAgYWJvdXQ6IHsgJ0BpZCc6IGAke3NpdGVVUkx9I29yZ2FuaXphdGlvbmAgfSxcclxuICAgICAgZGVzY3JpcHRpb246IGRlc2MsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRVbmlkYWRlUGF0aCgpIHtcclxuICAgIGxldCB1bmlkYWRlUGF0aCA9IFwiXCI7XHJcbiAgICBpZiAodGhpcy51bmlkYWRlICYmIHRoaXMudW5pZGFkZVBhdGgpIHtcclxuICAgICAgdW5pZGFkZVBhdGggPSB0aGlzLnVuaWRhZGU/LnBhdGggPT09IFwiL1wiID8gXCJcIiA6IHRoaXMudW5pZGFkZVBhdGg/LnN1YnN0cmluZygwLCB0aGlzLnVuaWRhZGVQYXRoPy5sZW5ndGggLSAxKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1bmlkYWRlUGF0aDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9idMOpbSBhIFVSTCBjYW7DtG5pY2EgZGEgcMOhZ2luYS5cclxuICAgKiBAcmV0dXJucyBBIFVSTCBjYW7DtG5pY2EgZGEgcMOhZ2luYS5cclxuICAgKi9cclxuICBwdWJsaWMgZ2V0Q2Fub25pY2FsSHJlZigpOiBzdHJpbmcge1xyXG4gICAgaWYgKCF0aGlzLmNhbm9uaWNhbFRhZykge1xyXG4gICAgICB0aGlzLmNhbm9uaWNhbFRhZyA9IHRoaXMuZ2V0Q2Fub25pY2FsVGFnKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jYW5vbmljYWxUYWcuaHJlZjtcclxuICB9XHJcblxyXG4gIC8qKiBDcmlhIHRhZyBwYXJhIGxpbmtzIGNhbm9uaWNhbHMgbm8gaGVhZCAqL1xyXG4gIHByaXZhdGUgY3JlYXRlQ2Fub25pY2FsVGFnKCk6IEhUTUxMaW5rRWxlbWVudCB7XHJcbiAgICBjb25zdCB0YWcgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcclxuICAgIHRhZy5zZXRBdHRyaWJ1dGUoJ3JlbCcsICdjYW5vbmljYWwnKTtcclxuICAgIHRoaXMuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCh0YWcpO1xyXG4gICAgdGFnLnNldEF0dHJpYnV0ZSgnaHJlZicsIHRoaXMuZG9jdW1lbnQuVVJMKTtcclxuICAgIHRoaXMuY2Fub25pY2FsVGFnID0gdGFnO1xyXG4gICAgcmV0dXJuIHRhZztcclxuICB9XHJcblxyXG4gIC8qKiBSZXRvcm5hIHRhZyBwYXJhIGxpbmsgY2Fub25pY2FsIGV4aXN0ZSBvdSBjcmlhIHNlIG7Do28gaG91dmVyLiAqL1xyXG4gIHByaXZhdGUgZ2V0Q2Fub25pY2FsVGFnKCk6IEhUTUxMaW5rRWxlbWVudCB7XHJcbiAgICBjb25zdCBlbGVtZW50cyA9IHRoaXMuZG9jdW1lbnQuaGVhZC5jaGlsZHJlbjtcclxuICAgIGxldCBpOiBudW1iZXI7XHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgZWxlbSA9IGVsZW1lbnRzW2ldIGFzIEhUTUxMaW5rRWxlbWVudDtcclxuICAgICAgaWYgKGVsZW0gJiYgZWxlbS50YWdOYW1lID09PSAnTElOSycgJiYgZWxlbS5yZWwgPT09ICdjYW5vbmljYWwnKSB7XHJcbiAgICAgICAgcmV0dXJuIGVsZW07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUNhbm9uaWNhbFRhZygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lIGxpbmsgY2Fub25pY2FsIGRhIHDDoWdpbmFcclxuICAgKiBAcGFyYW0gdXJsIHVybCBjYW5vbmljYWxcclxuICAgKi9cclxuICBwdWJsaWMgc2V0Q2Fub25pY2FsSHJlZih1cmw/OiBzdHJpbmcpIHtcclxuICAgIGlmICghdGhpcy5jYW5vbmljYWxUYWcpIHtcclxuICAgICAgdGhpcy5jYW5vbmljYWxUYWcgPSB0aGlzLmdldENhbm9uaWNhbFRhZygpO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCBwYXRoID0gdGhpcy5sb2NhdGlvbi5wYXRoKCk7XHJcbiAgICBpZiAoIXBhdGguc3RhcnRzV2l0aCgnLycpKSB7XHJcbiAgICAgIHBhdGggPSBgLyR7cGF0aH1gO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNhbm9uaWNhbFVybCA9IHVybCAmJiB0aGlzLmlzQ3VzdG9tQ2Fub25pY2FsKHVybCkgPyB1cmwgOiBgJHtnZXRTaXRlVXJsKHRoaXMubGliQ29uZmlnPy5zaXRlVXJsLCB0aGlzLmxpYkNvbmZpZz8uc2l0ZVN1Zml4KX0ke3BhdGh9YDtcclxuXHJcbiAgICB0aGlzLmNhbm9uaWNhbFRhZy5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBjYW5vbmljYWxVcmwpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWZXJpZmljYSBzZSBhIFVSTCBmb3JuZWNpZGEgw6kgdW0gbGluayBjYW5vbmljYWwgcGVyc29uYWxpemFkb1xyXG4gICAqIEBwYXJhbSB1cmwgVVJMIGZvcm5lY2lkYVxyXG4gICAqL1xyXG4gIHB1YmxpYyBpc0N1c3RvbUNhbm9uaWNhbCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3Qgc2l0ZXVybCA9IGdldFNpdGVVcmwodGhpcy5saWJDb25maWc/LnNpdGVVcmwsIHRoaXMubGliQ29uZmlnPy5zaXRlU3VmaXgpO1xyXG4gICAgcmV0dXJuIHVybC5zdGFydHNXaXRoKHNpdGV1cmwpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT2J0w6ltIHVtYSB1cmwgdsOhbGlkYSBuYSBhcGxpY2HDp8OjbyBwcm92ZW5pZW50ZSBkZSB1bWEgVVJMIGdlcmFkYVxyXG4gICAqIHBlbG8gcGx1Z2luIFlvYXN0IHBhcmEgY2Fub25pY2FsIGF1dG9tw6F0aWNvLlxyXG4gICAqIEV4LjogaHR0cHM6Ly93cC5yZWRlZG9yc2FvbHVpei5jb20uYnIvYnJhc2lsL2VzcGVjaWFsaWRhZGVzL2NhcmRpb2xvZ2lhL1xyXG4gICAqIEBwYXJhbSB1cmxGcm9tV3BBcGkgVVJMIGNhbm9uaWNhIGdlcmFkYSBwZWxvIFlvYXN0IFBsdWdpbi5cclxuICAgKi9cclxuICB0b0xvY2FsQ2Fub25pY2FsKHVybEZyb21XcEFwaTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGFwaVVybCA9IHRoaXMubGliQ29uZmlnPy53cFVybCA/PyAnJztcclxuICAgIGNvbnN0IHNpdGV1cmwgPSBnZXRTaXRlVXJsKHRoaXMubGliQ29uZmlnPy5zaXRlVXJsLCB0aGlzLmxpYkNvbmZpZz8uc2l0ZVN1Zml4KTtcclxuICAgIGNvbnN0IHVuaWRhZGVTbHVnID0gdGhpcy51bmlkYWRlU2x1ZztcclxuICAgIGxldCBjb252ZXJ0ZWQgPSB1cmxGcm9tV3BBcGkucmVwbGFjZShhcGlVcmwsIHNpdGV1cmwpO1xyXG4gICAgaWYgKCB1bmlkYWRlU2x1ZyAhPT0gXCIvXCIgJiYgY29udmVydGVkLmluY2x1ZGVzKGAvJHt1bmlkYWRlU2x1Z30vYCkpIHtcclxuICAgICAgY29udmVydGVkID0gY29udmVydGVkLnJlcGxhY2UoYC8ke3VuaWRhZGVTbHVnfS9gLCBgJHt0aGlzLnVuaWRhZGVQYXRofWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvbnZlcnRlZDtcclxuICB9XHJcblxyXG4gIGdldFBvc3RDb250ZW50KHBvc3Q6IFdwUG9zdCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBjb250ZW50ID0gcG9zdC5hY2YucmRzbF9wb3N0X2NvbnRlbnQuZmluZCgoY29udGVudDogYW55KSA9PiBjb250ZW50LmFjZl9mY19sYXlvdXQgPT09IFwidGV4dF9odG1sXCIpO1xyXG4gICAgcmV0dXJuIGNvbnRlbnQuY29udGVudCB8fCBwb3N0LmNvbnRlbnQucmVuZGVyZWQgfHwgXCJcIjtcclxuICB9XHJcblxyXG4gIGFkZEFydGljbGVTY3JpcHQocG9zdDogV3BQb3N0LCBzY3JpcHROYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBvc3RDb250ZW50ID0gdGhpcy5nZXRQb3N0Q29udGVudChwb3N0KTtcclxuICAgIGNvbnN0IHBvc3RIZWFkZXJJbWFnZSA9XHJcbiAgICAgIHBvc3QuYWNmW1wicmRzbF9wb3N0X2hlYWRlcl9pbWdcIl1cclxuICAgICAgICA/IHtcclxuICAgICAgICAgICAgdXJsOiBwb3N0LmFjZltcInJkc2xfcG9zdF9oZWFkZXJfaW1nXCJdLnVybCxcclxuICAgICAgICAgICAgd2lkdGg6IHBvc3QuYWNmW1wicmRzbF9wb3N0X2hlYWRlcl9pbWdcIl0ud2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogcG9zdC5hY2ZbXCJyZHNsX3Bvc3RfaGVhZGVyX2ltZ1wiXS5oZWlnaHRcclxuICAgICAgICAgIH1cclxuICAgICAgICA6IG51bGw7XHJcblxyXG4gICAgY29uc3Qgc3RydWN0dXJlZERhdGEgPSB7XHJcbiAgICAgIFwiQGNvbnRleHRcIjogXCJodHRwczovL3NjaGVtYS5vcmdcIixcclxuICAgICAgXCJAdHlwZVwiOiBcIkFydGljbGVcIixcclxuICAgICAgbWFpbkVudGl0eU9mUGFnZTogYCR7Z2V0U2l0ZVVybCh0aGlzLmxpYkNvbmZpZz8uc2l0ZVVybCwgdGhpcy5saWJDb25maWc/LnNpdGVTdWZpeCl9JHt0aGlzLmxvY2F0aW9uLnBhdGgoKX1gLFxyXG4gICAgICBoZWFkbGluZTogcG9zdC50aXRsZT8ucmVuZGVyZWQsXHJcbiAgICAgIGRhdGVQdWJsaXNoZWQ6IHBvc3QuZGF0ZV9nbXQsXHJcbiAgICAgIHB1Ymxpc2hlcjoge1xyXG4gICAgICAgIFwiQHR5cGVcIjogXCJPcmdhbml6YXRpb25cIixcclxuICAgICAgICBuYW1lOiBcIlJlZGUgROKAmU9yXCJcclxuICAgICAgfSxcclxuICAgICAgZGVzY3JpcHRpb246IHBvc3QudGl0bGU/LnJlbmRlcmVkLFxyXG4gICAgICBhcnRpY2xlQm9keTogcmVtb3ZlSHRtbFRhZ3MoaGUuZGVjb2RlKHBvc3RDb250ZW50KSksXHJcbiAgICAgIGRhdGVNb2RpZmllZDogcG9zdC5tb2RpZmllZF9nbXQsXHJcbiAgICAgIGltYWdlOiB7XHJcbiAgICAgICAgXCJAdHlwZVwiOiBcIkltYWdlT2JqZWN0XCIsXHJcbiAgICAgICAgdXJsOiBwb3N0SGVhZGVySW1hZ2U/LnVybCB8fCBwb3N0LmZlYXR1cmVkX21lZGlhX3BhdGggfHwgXCJcIixcclxuICAgICAgICBoZWlnaHQ6IHBvc3RIZWFkZXJJbWFnZT8uaGVpZ2h0IHx8IFwiXCIsXHJcbiAgICAgICAgd2lkdGg6IHBvc3RIZWFkZXJJbWFnZT8ud2lkdGggfHwgXCJcIlxyXG4gICAgICB9LFxyXG4gICAgICBhdXRob3I6IHtcclxuICAgICAgICBcIkB0eXBlXCI6IFwiT3JnYW5pemF0aW9uXCIsXHJcbiAgICAgICAgbmFtZTogXCJSZWRlIETigJlPclwiXHJcbiAgICAgIH0sXHJcbiAgICAgIHdvcmRjb3VudDogcG9zdENvbnRlbnQuc3BsaXQoXCIgXCIpLmxlbmd0aFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBzY3JpcHQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XHJcblxyXG4gICAgc2NyaXB0LnR5cGUgPSBcImFwcGxpY2F0aW9uL2xkK2pzb25cIjtcclxuICAgIHNjcmlwdC5pZCA9IHNjcmlwdE5hbWU7XHJcbiAgICBzY3JpcHQuaW5uZXJIVE1MID0gSlNPTi5zdHJpbmdpZnkoc3RydWN0dXJlZERhdGEpO1xyXG5cclxuICAgIHRoaXMuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlQXJ0aWNsZVNjcmlwdChzY3JpcHROYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNjcmlwdCA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc2NyaXB0TmFtZSk7XHJcbiAgICBzY3JpcHQ/LnJlbW92ZSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldFVuaWRhZGUoe1xyXG4gICAgdW5pZGFkZSA9IG51bGwsXHJcbiAgICB1bmlkYWRlTmFtZSA9IFwiXCIsXHJcbiAgICB1bmlkYWRlUGF0aCA9IFwiXCIsXHJcbiAgICB1bmlkYWRlU2x1ZyA9IFwiXCIsXHJcbiAgfTogU2VvVW5pZGFkZSkge1xyXG4gICAgdGhpcy51bmlkYWRlID0gdW5pZGFkZTtcclxuICAgIHRoaXMudW5pZGFkZU5hbWUgPSB1bmlkYWRlTmFtZTtcclxuICAgIHRoaXMudW5pZGFkZVBhdGggPSB1bmlkYWRlUGF0aDtcclxuICAgIHRoaXMudW5pZGFkZVNsdWcgPSB1bmlkYWRlU2x1ZztcclxuICB9XHJcbn1cclxuIl19
@@ -0,0 +1,86 @@
1
+ import { Inject, Injectable, Optional } from '@angular/core';
2
+ import { RESPONSE } from '../../tokens/express.tokens';
3
+ import * as i0 from "@angular/core";
4
+ export class ServerResponseService {
5
+ constructor(response) {
6
+ this.response = response;
7
+ }
8
+ getHeader(key) {
9
+ return this.response.getHeader(key);
10
+ }
11
+ setHeader(key, value) {
12
+ if (this.response) {
13
+ this.response.header(key, value);
14
+ }
15
+ return this;
16
+ }
17
+ appendHeader(key, value, delimiter = ',') {
18
+ if (this.response) {
19
+ const current = this.getHeader(key);
20
+ if (!current) {
21
+ return this.setHeader(key, value);
22
+ }
23
+ const newValue = [...current.split(delimiter), value].filter((el, i, a) => i === a.indexOf(el)).join(delimiter);
24
+ this.response.header(key, newValue);
25
+ }
26
+ return this;
27
+ }
28
+ setHeaders(dictionary) {
29
+ if (this.response) {
30
+ Object.keys(dictionary).forEach((key) => this.setHeader(key, dictionary[key]));
31
+ }
32
+ return this;
33
+ }
34
+ setStatus(code, message) {
35
+ if (this.response) {
36
+ this.response.statusCode = code;
37
+ if (message) {
38
+ this.response.statusMessage = message;
39
+ }
40
+ }
41
+ return this;
42
+ }
43
+ setNotFound(message = 'Não encontrado') {
44
+ if (this.response) {
45
+ this.response.statusCode = 404;
46
+ this.response.statusMessage = message;
47
+ }
48
+ console.log(">>> setNotFound", this.response.statusCode, this.response.statusMessage);
49
+ return this;
50
+ }
51
+ setUnauthorized(message = 'Não autorizado') {
52
+ if (this.response) {
53
+ this.response.statusCode = 401;
54
+ this.response.statusMessage = message;
55
+ }
56
+ return this;
57
+ }
58
+ setError(message = 'Erro interno de servidor') {
59
+ if (this.response) {
60
+ this.response.statusCode = 500;
61
+ this.response.statusMessage = message;
62
+ }
63
+ return this;
64
+ }
65
+ setRedirect(message = 'Redirecionado permanentemente') {
66
+ if (this.response) {
67
+ this.response.statusCode = 301;
68
+ this.response.statusMessage = message;
69
+ }
70
+ return this;
71
+ }
72
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, deps: [{ token: RESPONSE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
73
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, providedIn: 'root' }); }
74
+ }
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: ServerResponseService, decorators: [{
76
+ type: Injectable,
77
+ args: [{
78
+ providedIn: 'root',
79
+ }]
80
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
81
+ type: Optional
82
+ }, {
83
+ type: Inject,
84
+ args: [RESPONSE]
85
+ }] }] });
86
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLXJlc3BvbnNlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaXRlLWZyb250LWVuZC1saWIvc3JjL2xpYi9zZXJ2aWNlcy9zZXJ2ZXItcmVzcG9uc2Uvc2VydmVyLXJlc3BvbnNlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFnQnZELE1BQU0sT0FBTyxxQkFBcUI7SUFHaEMsWUFBMEMsUUFBYTtRQUNyRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQVc7UUFDbkIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQVcsQ0FBQztJQUNoRCxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQVcsRUFBRSxLQUFhO1FBQ2xDLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsWUFBWSxDQUFDLEdBQVcsRUFBRSxLQUFhLEVBQUUsU0FBUyxHQUFHLEdBQUc7UUFDdEQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNwQyxDQUFDO1lBQ0Qs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MEJBSWMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xyXG5pbXBvcnQgeyBSRVNQT05TRSB9IGZyb20gJy4uLy4uL3Rva2Vucy9leHByZXNzLnRva2Vucyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElTZXJ2ZXJSZXNwb25zZVNlcnZpY2Uge1xyXG4gIGdldEhlYWRlcihrZXk6IHN0cmluZyk6IHN0cmluZztcclxuICBzZXRIZWFkZXIoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB0aGlzO1xyXG4gIHNldEhlYWRlcnMoZGljdGlvbmFyeTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSk6IHRoaXM7XHJcbiAgYXBwZW5kSGVhZGVyKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBkZWxpbWl0ZXI/OiBzdHJpbmcpOiB0aGlzO1xyXG4gIHNldFN0YXR1cyhjb2RlOiBudW1iZXIsIG1lc3NhZ2U/OiBzdHJpbmcpOiB0aGlzO1xyXG4gIHNldE5vdEZvdW5kKG1lc3NhZ2U/OiBzdHJpbmcpOiB0aGlzO1xyXG4gIHNldEVycm9yKG1lc3NhZ2U/OiBzdHJpbmcpOiB0aGlzO1xyXG4gIHNldFJlZGlyZWN0KG1lc3NhZ2U/OiBzdHJpbmcpOiB0aGlzO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2VydmVyUmVzcG9uc2VTZXJ2aWNlIGltcGxlbWVudHMgSVNlcnZlclJlc3BvbnNlU2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZXNwb25zZTogUmVzcG9uc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBJbmplY3QoUkVTUE9OU0UpIHJlc3BvbnNlOiBhbnkpIHtcclxuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZTtcclxuICB9XHJcblxyXG4gIGdldEhlYWRlcihrZXk6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXNwb25zZS5nZXRIZWFkZXIoa2V5KSBhcyBzdHJpbmc7XHJcbiAgfVxyXG5cclxuICBzZXRIZWFkZXIoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB0aGlzIHtcclxuICAgIGlmICh0aGlzLnJlc3BvbnNlKSB7XHJcbiAgICAgIHRoaXMucmVzcG9uc2UuaGVhZGVyKGtleSwgdmFsdWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBhcHBlbmRIZWFkZXIoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIGRlbGltaXRlciA9ICcsJyk6IHRoaXMge1xyXG4gICAgaWYgKHRoaXMucmVzcG9uc2UpIHtcclxuICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0SGVhZGVyKGtleSk7XHJcbiAgICAgIGlmICghY3VycmVudCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldEhlYWRlcihrZXksIHZhbHVlKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBuZXdWYWx1ZSA9IFsuLi5jdXJyZW50LnNwbGl0KGRlbGltaXRlciksIHZhbHVlXS5maWx0ZXIoKGVsLCBpLCBhKSA9PiBpID09PSBhLmluZGV4T2YoZWwpKS5qb2luKGRlbGltaXRlcik7XHJcbiAgICAgIHRoaXMucmVzcG9uc2UuaGVhZGVyKGtleSwgbmV3VmFsdWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBzZXRIZWFkZXJzKGRpY3Rpb25hcnk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pOiB0aGlzIHtcclxuICAgIGlmICh0aGlzLnJlc3BvbnNlKSB7XHJcbiAgICAgIE9iamVjdC5rZXlzKGRpY3Rpb25hcnkpLmZvckVhY2goKGtleSkgPT4gdGhpcy5zZXRIZWFkZXIoa2V5LCBkaWN0aW9uYXJ5W2tleV0pKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgc2V0U3RhdHVzKGNvZGU6IG51bWJlciwgbWVzc2FnZT86IHN0cmluZyk6IHRoaXMge1xyXG4gICAgaWYgKHRoaXMucmVzcG9uc2UpIHtcclxuICAgICAgdGhpcy5yZXNwb25zZS5zdGF0dXNDb2RlID0gY29kZTtcclxuICAgICAgaWYgKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLnJlc3BvbnNlLnN0YXR1c01lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldE5vdEZvdW5kKG1lc3NhZ2UgPSAnTsOjbyBlbmNvbnRyYWRvJyk6IHRoaXMge1xyXG4gICAgaWYgKHRoaXMucmVzcG9uc2UpIHtcclxuICAgICAgdGhpcy5yZXNwb25zZS5zdGF0dXNDb2RlID0gNDA0O1xyXG4gICAgICB0aGlzLnJlc3BvbnNlLnN0YXR1c01lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgfVxyXG4gICAgY29uc29sZS5sb2coXCI+Pj4gc2V0Tm90Rm91bmRcIiwgdGhpcy5yZXNwb25zZS5zdGF0dXNDb2RlLCB0aGlzLnJlc3BvbnNlLnN0YXR1c01lc3NhZ2UpXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldFVuYXV0aG9yaXplZChtZXNzYWdlID0gJ07Do28gYXV0b3JpemFkbycpOiB0aGlzIHtcclxuICAgIGlmICh0aGlzLnJlc3BvbnNlKSB7XHJcbiAgICAgIHRoaXMucmVzcG9uc2Uuc3RhdHVzQ29kZSA9IDQwMTtcclxuICAgICAgdGhpcy5yZXNwb25zZS5zdGF0dXNNZXNzYWdlID0gbWVzc2FnZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgc2V0RXJyb3IobWVzc2FnZSA9ICdFcnJvIGludGVybm8gZGUgc2Vydmlkb3InKTogdGhpcyB7XHJcbiAgICBpZiAodGhpcy5yZXNwb25zZSkge1xyXG4gICAgICB0aGlzLnJlc3BvbnNlLnN0YXR1c0NvZGUgPSA1MDA7XHJcbiAgICAgIHRoaXMucmVzcG9uc2Uuc3RhdHVzTWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldFJlZGlyZWN0KG1lc3NhZ2UgPSAnUmVkaXJlY2lvbmFkbyBwZXJtYW5lbnRlbWVudGUnKTogdGhpcyB7XHJcbiAgICBpZiAodGhpcy5yZXNwb25zZSkge1xyXG4gICAgICB0aGlzLnJlc3BvbnNlLnN0YXR1c0NvZGUgPSAzMDE7XHJcbiAgICAgIHRoaXMucmVzcG9uc2Uuc3RhdHVzTWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEh0dHBDYWNoZURpcmVjdGl2ZSA9XHJcbiAgfCAncHVibGljJ1xyXG4gIHwgJ3ByaXZhdGUnXHJcbiAgfCAnbm8tc3RvcmUnXHJcbiAgfCAnbm8tY2FjaGUnXHJcbiAgfCAnbXVzdC1yZXZhbGlkYXRlJ1xyXG4gIHwgJ25vLXRyYW5zZm9ybSdcclxuICB8ICdwcm94eS1yZXZhbGlkYXRlJztcclxuIl19