@playpilot/tpi 8.10.1 → 8.10.3
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/dist/editorial.mount.js +2 -2
- package/dist/link-injections.js +2 -2
- package/dist/mount.js +2 -2
- package/package.json +1 -1
- package/src/lib/api/youtubeAvailability.ts +3 -4
- package/src/lib/injection.ts +0 -8
- package/src/lib/meta.ts +2 -1
- package/src/routes/+layout.svelte +6 -1
- package/src/tests/lib/api/youtubeAvailability.test.js +3 -3
- package/src/tests/lib/meta.test.js +11 -2
- package/vite._mount.config.js.timestamp-1781001671448-4d03f5733979f.mjs +105 -0
package/package.json
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { PUBLIC_YOUTUBE_AVAILABILITY_URL } from '$env/static/public'
|
|
2
|
-
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
3
|
-
import { track } from '$lib/tracking'
|
|
4
2
|
|
|
5
3
|
export async function isYouTubeVideoAvailableInRegion(videoId: string): Promise<boolean> {
|
|
6
4
|
const region = window.PlayPilotLinkInjections?.region?.toUpperCase()
|
|
@@ -18,8 +16,9 @@ export async function isYouTubeVideoAvailableInRegion(videoId: string): Promise<
|
|
|
18
16
|
if (!data.blocked && !!data.allowed && !data.allowed?.includes(region)) return false
|
|
19
17
|
|
|
20
18
|
return true
|
|
21
|
-
} catch
|
|
22
|
-
|
|
19
|
+
} catch {
|
|
20
|
+
// Silently fail for now
|
|
21
|
+
// track(TrackingEvent.YouTubeAvailabilityRequestFailed, null, { message: error.message })
|
|
23
22
|
|
|
24
23
|
return false
|
|
25
24
|
}
|
package/src/lib/injection.ts
CHANGED
|
@@ -169,7 +169,6 @@ export function injectLinksInDocument(elements: HTMLElement[], injections: LinkI
|
|
|
169
169
|
if (document.querySelector(keySelector)) insertInTextDisclaimer(elements)
|
|
170
170
|
|
|
171
171
|
return mergedInjections.filter(i => i.title_details).map((injection, index) => {
|
|
172
|
-
// Favour manual injections over AI injections
|
|
173
172
|
const hasManualEquivalent = !injection.manual && isAvailableAsManualInjection(injection, index, mergedInjections)
|
|
174
173
|
const duplicate = injection.duplicate ?? hasManualEquivalent
|
|
175
174
|
|
|
@@ -307,9 +306,6 @@ function addCSSVariablesToLinks(): void {
|
|
|
307
306
|
}
|
|
308
307
|
}
|
|
309
308
|
|
|
310
|
-
/**
|
|
311
|
-
* Add event listeners to all injected links. These events are for both the popover and the modal.
|
|
312
|
-
*/
|
|
313
309
|
function addLinkInjectionEventListeners(injections: LinkInjection[]): void {
|
|
314
310
|
window.addEventListener('mousemove', destroyLinkPopoverOnMouseleave)
|
|
315
311
|
window.addEventListener('click', (event) => openModalForInjectedLink(event, injections))
|
|
@@ -341,10 +337,6 @@ export function clearLinkInjections(): void {
|
|
|
341
337
|
destroyLinkPopover(false)
|
|
342
338
|
}
|
|
343
339
|
|
|
344
|
-
/**
|
|
345
|
-
* Clear specific link injection from the page
|
|
346
|
-
* @param key Given of the injection to be removed from the page
|
|
347
|
-
*/
|
|
348
340
|
export function clearLinkInjection(key: string): void {
|
|
349
341
|
const element: HTMLAnchorElement | null = document.querySelector(`[${keyDataAttribute}="${key}"]`)
|
|
350
342
|
if (!element) return
|
package/src/lib/meta.ts
CHANGED
|
@@ -68,7 +68,8 @@ export function getDatetime(datetime: string): string | null {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export function getSchemaJson(): Record<string, any> {
|
|
71
|
-
const
|
|
71
|
+
const schemaElements = Array.from(document.querySelectorAll('[type="application/ld+json"]'))
|
|
72
|
+
const schemaElement = schemaElements.find(element => element.textContent.includes('dateModified') || element.textContent.includes('datePublished'))
|
|
72
73
|
|
|
73
74
|
if (!schemaElement) return {}
|
|
74
75
|
|
|
@@ -128,9 +128,14 @@
|
|
|
128
128
|
line-height: 1.8;
|
|
129
129
|
|
|
130
130
|
nav {
|
|
131
|
-
display:
|
|
131
|
+
display: grid;
|
|
132
|
+
grid-template-columns: 1fr 1fr;
|
|
132
133
|
gap: margin(1);
|
|
133
134
|
|
|
135
|
+
@include desktop {
|
|
136
|
+
display: flex;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
a {
|
|
135
140
|
padding: margin(0.25) margin(0.75);
|
|
136
141
|
border: 1px solid currentColor;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
import { isYouTubeVideoAvailableInRegion } from '$lib/api/youtubeAvailability'
|
|
3
3
|
import { fakeFetch } from '../../helpers'
|
|
4
|
-
import { track } from '$lib/tracking'
|
|
5
|
-
import { TrackingEvent } from '$lib/enums/TrackingEvent'
|
|
6
4
|
|
|
7
5
|
vi.mock('$lib/tracking', () => ({
|
|
8
6
|
track: vi.fn(),
|
|
@@ -64,7 +62,9 @@ describe('youtubeAvailability', () => {
|
|
|
64
62
|
fakeFetch({ ok: false, status: 500 })
|
|
65
63
|
|
|
66
64
|
expect(await isYouTubeVideoAvailableInRegion('video-id')).toBe(false)
|
|
67
|
-
|
|
65
|
+
|
|
66
|
+
// For now it's silently failing on purpose
|
|
67
|
+
// expect(track).toHaveBeenCalledWith(TrackingEvent.YouTubeAvailabilityRequestFailed, null, { message: expect.any(String) })
|
|
68
68
|
})
|
|
69
69
|
})
|
|
70
70
|
})
|
|
@@ -240,9 +240,9 @@ describe('meta.js', () => {
|
|
|
240
240
|
})
|
|
241
241
|
|
|
242
242
|
it('Should return schema relevant object', () => {
|
|
243
|
-
document.body.innerHTML = '<script type="application/ld+json">{ "key": "value" }</script>'
|
|
243
|
+
document.body.innerHTML = '<script type="application/ld+json">{ "key": "value", "dateModified": "a" }</script>'
|
|
244
244
|
|
|
245
|
-
expect(getSchemaJson()).toEqual({ key: 'value' })
|
|
245
|
+
expect(getSchemaJson()).toEqual({ key: 'value', dateModified: 'a' })
|
|
246
246
|
})
|
|
247
247
|
|
|
248
248
|
it('Should return empty object when json object is invalid', () => {
|
|
@@ -261,5 +261,14 @@ describe('meta.js', () => {
|
|
|
261
261
|
document.body.innerHTML = '<script type="application/ld+json">{ "key": "Some "unescaped" value" }</script>'
|
|
262
262
|
expect(getSchemaJson()).toEqual({})
|
|
263
263
|
})
|
|
264
|
+
|
|
265
|
+
it('Should return script with dateModified if multiple scripts are present', () => {
|
|
266
|
+
document.body.innerHTML = `
|
|
267
|
+
<script type="application/ld+json"></script>
|
|
268
|
+
<script type="application/ld+json">{ "dateModified": "a" }</script>
|
|
269
|
+
`
|
|
270
|
+
|
|
271
|
+
expect(getSchemaJson()).toEqual({ dateModified: 'a' })
|
|
272
|
+
})
|
|
264
273
|
})
|
|
265
274
|
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// vite._mount.config.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import * as dotenv from "file:///C:/Sites/playpilot-link-injection/node_modules/dotenv/lib/main.js";
|
|
4
|
+
import { defineConfig } from "file:///C:/Sites/playpilot-link-injection/node_modules/vitest/dist/config.js";
|
|
5
|
+
import { svelte } from "file:///C:/Sites/playpilot-link-injection/node_modules/@sveltejs/vite-plugin-svelte/src/index.js";
|
|
6
|
+
import cssInjectedByJsPlugin from "file:///C:/Sites/playpilot-link-injection/node_modules/vite-plugin-css-injected-by-js/dist/esm/index.js";
|
|
7
|
+
|
|
8
|
+
// package.json
|
|
9
|
+
var package_default = {
|
|
10
|
+
name: "@playpilot/tpi",
|
|
11
|
+
version: "8.10.3",
|
|
12
|
+
type: "module",
|
|
13
|
+
scripts: {
|
|
14
|
+
dev: "vite dev",
|
|
15
|
+
"dev-build": "npx http-server . /build.html -p 3000",
|
|
16
|
+
build: "vite build --config vite._main.config.js && vite build --config vite._mount.config.js && vite build --config vite._mount.config.js --mode editorial",
|
|
17
|
+
preview: "vite preview",
|
|
18
|
+
check: "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
|
19
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
|
20
|
+
format: "prettier --write .",
|
|
21
|
+
lint: "prettier --check . && eslint .",
|
|
22
|
+
"test:unit": "vitest",
|
|
23
|
+
test: "npm run test:unit -- --run",
|
|
24
|
+
release: "node release.js"
|
|
25
|
+
},
|
|
26
|
+
devDependencies: {
|
|
27
|
+
"@playpilot/retargeting-tracking": "^0.1.0",
|
|
28
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
29
|
+
"@sveltejs/kit": "^2.56.1",
|
|
30
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
31
|
+
"@testing-library/svelte": "^5.2.6",
|
|
32
|
+
"@types/node": "^25.5.2",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.32.1",
|
|
34
|
+
"@typescript-eslint/parser": "^8.32.1",
|
|
35
|
+
dotenv: "^17.4.1",
|
|
36
|
+
eslint: "^9.27.0",
|
|
37
|
+
"eslint-config-prettier": "^9.1.0",
|
|
38
|
+
"eslint-plugin-svelte": "^3.15.0",
|
|
39
|
+
globals: "^15.0.0",
|
|
40
|
+
"happy-dom": "^16.8.1",
|
|
41
|
+
prettier: "^3.8.3",
|
|
42
|
+
"prettier-plugin-svelte": "^3.2.6",
|
|
43
|
+
sass: "^1.99.0",
|
|
44
|
+
svelte: "5.44.1",
|
|
45
|
+
"svelte-check": "^4.0.0",
|
|
46
|
+
"svelte-preprocess": "^6.0.3",
|
|
47
|
+
"svelte-tiny-slider": "^2.7.1",
|
|
48
|
+
typescript: "^5.9.3",
|
|
49
|
+
"typescript-eslint": "^8.59.2",
|
|
50
|
+
vite: "^5.4.21",
|
|
51
|
+
"vite-plugin-css-injected-by-js": "^4.0.1",
|
|
52
|
+
vitest: "^2.1.9"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// vite._mount.config.js
|
|
57
|
+
var __vite_injected_original_dirname = "C:\\Sites\\playpilot-link-injection";
|
|
58
|
+
dotenv.config({ path: ".env" });
|
|
59
|
+
var vite_mount_config_default = defineConfig(({ mode }) => {
|
|
60
|
+
const isEditiorial = mode === "editorial";
|
|
61
|
+
return {
|
|
62
|
+
plugins: [
|
|
63
|
+
svelte(),
|
|
64
|
+
cssInjectedByJsPlugin(),
|
|
65
|
+
injectEnvVariables
|
|
66
|
+
],
|
|
67
|
+
build: {
|
|
68
|
+
emptyOutDir: false,
|
|
69
|
+
rollupOptions: {
|
|
70
|
+
input: "./src/mount.ts",
|
|
71
|
+
output: {
|
|
72
|
+
format: "iife",
|
|
73
|
+
name: "PlayPilotMount",
|
|
74
|
+
entryFileNames: isEditiorial ? "editorial.mount.js" : "mount.js"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
resolve: {
|
|
79
|
+
alias: {
|
|
80
|
+
"$lib": path.resolve(__vite_injected_original_dirname, "./src/lib")
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
define: {
|
|
84
|
+
__SCRIPT_VERSION__: JSON.stringify(package_default.version),
|
|
85
|
+
__IS_EDITORIAL_SCRIPT__: JSON.stringify(isEditiorial)
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
var injectEnvVariables = {
|
|
90
|
+
name: "resolve-env-variables",
|
|
91
|
+
/** @param {string} id */
|
|
92
|
+
resolveId(id) {
|
|
93
|
+
if (id === "$env/static/public") return "\0$env/static/public";
|
|
94
|
+
},
|
|
95
|
+
/** @param {string} id */
|
|
96
|
+
load(id) {
|
|
97
|
+
if (id === "\0$env/static/public") {
|
|
98
|
+
return Object.entries(process.env).filter(([key]) => key.startsWith("PUBLIC_")).map(([key, value]) => `export const ${key} = ${JSON.stringify(value)};`).join("\n");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export {
|
|
103
|
+
vite_mount_config_default as default
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5fbW91bnQuY29uZmlnLmpzIiwgInBhY2thZ2UuanNvbiJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2Rpcm5hbWUgPSBcIkM6XFxcXFNpdGVzXFxcXHBsYXlwaWxvdC1saW5rLWluamVjdGlvblwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQzpcXFxcU2l0ZXNcXFxccGxheXBpbG90LWxpbmstaW5qZWN0aW9uXFxcXHZpdGUuX21vdW50LmNvbmZpZy5qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vQzovU2l0ZXMvcGxheXBpbG90LWxpbmstaW5qZWN0aW9uL3ZpdGUuX21vdW50LmNvbmZpZy5qc1wiO2ltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCAqIGFzIGRvdGVudiBmcm9tICdkb3RlbnYnXHJcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gJ3ZpdGVzdC9jb25maWcnXHJcbmltcG9ydCB7IHN2ZWx0ZSB9IGZyb20gJ0BzdmVsdGVqcy92aXRlLXBsdWdpbi1zdmVsdGUnXHJcbmltcG9ydCBjc3NJbmplY3RlZEJ5SnNQbHVnaW4gZnJvbSAndml0ZS1wbHVnaW4tY3NzLWluamVjdGVkLWJ5LWpzJ1xyXG5pbXBvcnQgcGFja2FnZUpzb24gZnJvbSAnLi9wYWNrYWdlLmpzb24nXHJcblxyXG5kb3RlbnYuY29uZmlnKHsgcGF0aDogJy5lbnYnIH0pXHJcblxyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoKHsgbW9kZSB9KSA9PiB7XHJcbiAgY29uc3QgaXNFZGl0aW9yaWFsID0gbW9kZSA9PT0gJ2VkaXRvcmlhbCdcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHBsdWdpbnM6IFtcclxuICAgICAgc3ZlbHRlKCksXHJcbiAgICAgIGNzc0luamVjdGVkQnlKc1BsdWdpbigpLFxyXG4gICAgICBpbmplY3RFbnZWYXJpYWJsZXMsXHJcbiAgICBdLFxyXG5cclxuICAgIGJ1aWxkOiB7XHJcbiAgICAgIGVtcHR5T3V0RGlyOiBmYWxzZSxcclxuICAgICAgcm9sbHVwT3B0aW9uczoge1xyXG4gICAgICAgIGlucHV0OiAnLi9zcmMvbW91bnQudHMnLFxyXG4gICAgICAgIG91dHB1dDoge1xyXG4gICAgICAgICAgZm9ybWF0OiAnaWlmZScsXHJcbiAgICAgICAgICBuYW1lOiAnUGxheVBpbG90TW91bnQnLFxyXG4gICAgICAgICAgZW50cnlGaWxlTmFtZXM6IGlzRWRpdGlvcmlhbCA/ICdlZGl0b3JpYWwubW91bnQuanMnIDogJ21vdW50LmpzJyxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSxcclxuXHJcbiAgICByZXNvbHZlOiB7XHJcbiAgICAgIGFsaWFzOiB7XHJcbiAgICAgICAgJyRsaWInOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9zcmMvbGliJyksXHJcbiAgICAgIH0sXHJcbiAgICB9LFxyXG5cclxuICAgIGRlZmluZToge1xyXG4gICAgICBfX1NDUklQVF9WRVJTSU9OX186IEpTT04uc3RyaW5naWZ5KHBhY2thZ2VKc29uLnZlcnNpb24pLFxyXG4gICAgICBfX0lTX0VESVRPUklBTF9TQ1JJUFRfXzogSlNPTi5zdHJpbmdpZnkoaXNFZGl0aW9yaWFsKSxcclxuICAgIH0sXHJcbiAgfVxyXG59KVxyXG5cclxuY29uc3QgaW5qZWN0RW52VmFyaWFibGVzID0ge1xyXG4gIG5hbWU6ICdyZXNvbHZlLWVudi12YXJpYWJsZXMnLFxyXG4gIC8qKiBAcGFyYW0ge3N0cmluZ30gaWQgKi9cclxuICByZXNvbHZlSWQoaWQpIHtcclxuICAgIGlmIChpZCA9PT0gJyRlbnYvc3RhdGljL3B1YmxpYycpIHJldHVybiAnXFwwJGVudi9zdGF0aWMvcHVibGljJ1xyXG4gIH0sXHJcbiAgLyoqIEBwYXJhbSB7c3RyaW5nfSBpZCAqL1xyXG4gIGxvYWQoaWQpIHtcclxuICAgIGlmIChpZCA9PT0gJ1xcMCRlbnYvc3RhdGljL3B1YmxpYycpIHtcclxuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHByb2Nlc3MuZW52KVxyXG4gICAgICAgIC5maWx0ZXIoKFtrZXldKSA9PiBrZXkuc3RhcnRzV2l0aCgnUFVCTElDXycpKVxyXG4gICAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYGV4cG9ydCBjb25zdCAke2tleX0gPSAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX07YClcclxuICAgICAgICAuam9pbignXFxuJylcclxuICAgIH1cclxuICB9LFxyXG59XHJcbiIsICJ7XHJcblx0XCJuYW1lXCI6IFwiQHBsYXlwaWxvdC90cGlcIixcclxuXHRcInZlcnNpb25cIjogXCI4LjEwLjNcIixcclxuXHRcInR5cGVcIjogXCJtb2R1bGVcIixcclxuXHRcInNjcmlwdHNcIjoge1xyXG5cdFx0XCJkZXZcIjogXCJ2aXRlIGRldlwiLFxyXG5cdFx0XCJkZXYtYnVpbGRcIjogXCJucHggaHR0cC1zZXJ2ZXIgLiAvYnVpbGQuaHRtbCAtcCAzMDAwXCIsXHJcblx0XHRcImJ1aWxkXCI6IFwidml0ZSBidWlsZCAtLWNvbmZpZyB2aXRlLl9tYWluLmNvbmZpZy5qcyAmJiB2aXRlIGJ1aWxkIC0tY29uZmlnIHZpdGUuX21vdW50LmNvbmZpZy5qcyAmJiB2aXRlIGJ1aWxkIC0tY29uZmlnIHZpdGUuX21vdW50LmNvbmZpZy5qcyAtLW1vZGUgZWRpdG9yaWFsXCIsXHJcblx0XHRcInByZXZpZXdcIjogXCJ2aXRlIHByZXZpZXdcIixcclxuXHRcdFwiY2hlY2tcIjogXCJzdmVsdGUta2l0IHN5bmMgJiYgc3ZlbHRlLWNoZWNrIC0tdHNjb25maWcgLi9qc2NvbmZpZy5qc29uXCIsXHJcblx0XHRcImNoZWNrOndhdGNoXCI6IFwic3ZlbHRlLWtpdCBzeW5jICYmIHN2ZWx0ZS1jaGVjayAtLXRzY29uZmlnIC4vanNjb25maWcuanNvbiAtLXdhdGNoXCIsXHJcblx0XHRcImZvcm1hdFwiOiBcInByZXR0aWVyIC0td3JpdGUgLlwiLFxyXG5cdFx0XCJsaW50XCI6IFwicHJldHRpZXIgLS1jaGVjayAuICYmIGVzbGludCAuXCIsXHJcblx0XHRcInRlc3Q6dW5pdFwiOiBcInZpdGVzdFwiLFxyXG5cdFx0XCJ0ZXN0XCI6IFwibnBtIHJ1biB0ZXN0OnVuaXQgLS0gLS1ydW5cIixcclxuXHRcdFwicmVsZWFzZVwiOiBcIm5vZGUgcmVsZWFzZS5qc1wiXHJcblx0fSxcclxuXHRcImRldkRlcGVuZGVuY2llc1wiOiB7XHJcblx0XHRcIkBwbGF5cGlsb3QvcmV0YXJnZXRpbmctdHJhY2tpbmdcIjogXCJeMC4xLjBcIixcclxuXHRcdFwiQHN2ZWx0ZWpzL2FkYXB0ZXItYXV0b1wiOiBcIl43LjAuMVwiLFxyXG5cdFx0XCJAc3ZlbHRlanMva2l0XCI6IFwiXjIuNTYuMVwiLFxyXG5cdFx0XCJAc3ZlbHRlanMvdml0ZS1wbHVnaW4tc3ZlbHRlXCI6IFwiXjQuMC4wXCIsXHJcblx0XHRcIkB0ZXN0aW5nLWxpYnJhcnkvc3ZlbHRlXCI6IFwiXjUuMi42XCIsXHJcblx0XHRcIkB0eXBlcy9ub2RlXCI6IFwiXjI1LjUuMlwiLFxyXG5cdFx0XCJAdHlwZXNjcmlwdC1lc2xpbnQvZXNsaW50LXBsdWdpblwiOiBcIl44LjMyLjFcIixcclxuXHRcdFwiQHR5cGVzY3JpcHQtZXNsaW50L3BhcnNlclwiOiBcIl44LjMyLjFcIixcclxuXHRcdFwiZG90ZW52XCI6IFwiXjE3LjQuMVwiLFxyXG5cdFx0XCJlc2xpbnRcIjogXCJeOS4yNy4wXCIsXHJcblx0XHRcImVzbGludC1jb25maWctcHJldHRpZXJcIjogXCJeOS4xLjBcIixcclxuXHRcdFwiZXNsaW50LXBsdWdpbi1zdmVsdGVcIjogXCJeMy4xNS4wXCIsXHJcblx0XHRcImdsb2JhbHNcIjogXCJeMTUuMC4wXCIsXHJcblx0XHRcImhhcHB5LWRvbVwiOiBcIl4xNi44LjFcIixcclxuXHRcdFwicHJldHRpZXJcIjogXCJeMy44LjNcIixcclxuXHRcdFwicHJldHRpZXItcGx1Z2luLXN2ZWx0ZVwiOiBcIl4zLjIuNlwiLFxyXG5cdFx0XCJzYXNzXCI6IFwiXjEuOTkuMFwiLFxyXG5cdFx0XCJzdmVsdGVcIjogXCI1LjQ0LjFcIixcclxuXHRcdFwic3ZlbHRlLWNoZWNrXCI6IFwiXjQuMC4wXCIsXHJcblx0XHRcInN2ZWx0ZS1wcmVwcm9jZXNzXCI6IFwiXjYuMC4zXCIsXHJcblx0XHRcInN2ZWx0ZS10aW55LXNsaWRlclwiOiBcIl4yLjcuMVwiLFxyXG5cdFx0XCJ0eXBlc2NyaXB0XCI6IFwiXjUuOS4zXCIsXHJcblx0XHRcInR5cGVzY3JpcHQtZXNsaW50XCI6IFwiXjguNTkuMlwiLFxyXG5cdFx0XCJ2aXRlXCI6IFwiXjUuNC4yMVwiLFxyXG5cdFx0XCJ2aXRlLXBsdWdpbi1jc3MtaW5qZWN0ZWQtYnktanNcIjogXCJeNC4wLjFcIixcclxuXHRcdFwidml0ZXN0XCI6IFwiXjIuMS45XCJcclxuXHR9XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUF5UyxPQUFPLFVBQVU7QUFDMVQsWUFBWSxZQUFZO0FBQ3hCLFNBQVMsb0JBQW9CO0FBQzdCLFNBQVMsY0FBYztBQUN2QixPQUFPLDJCQUEyQjs7O0FDSmxDO0FBQUEsRUFDQyxNQUFRO0FBQUEsRUFDUixTQUFXO0FBQUEsRUFDWCxNQUFRO0FBQUEsRUFDUixTQUFXO0FBQUEsSUFDVixLQUFPO0FBQUEsSUFDUCxhQUFhO0FBQUEsSUFDYixPQUFTO0FBQUEsSUFDVCxTQUFXO0FBQUEsSUFDWCxPQUFTO0FBQUEsSUFDVCxlQUFlO0FBQUEsSUFDZixRQUFVO0FBQUEsSUFDVixNQUFRO0FBQUEsSUFDUixhQUFhO0FBQUEsSUFDYixNQUFRO0FBQUEsSUFDUixTQUFXO0FBQUEsRUFDWjtBQUFBLEVBQ0EsaUJBQW1CO0FBQUEsSUFDbEIsbUNBQW1DO0FBQUEsSUFDbkMsMEJBQTBCO0FBQUEsSUFDMUIsaUJBQWlCO0FBQUEsSUFDakIsZ0NBQWdDO0FBQUEsSUFDaEMsMkJBQTJCO0FBQUEsSUFDM0IsZUFBZTtBQUFBLElBQ2Ysb0NBQW9DO0FBQUEsSUFDcEMsNkJBQTZCO0FBQUEsSUFDN0IsUUFBVTtBQUFBLElBQ1YsUUFBVTtBQUFBLElBQ1YsMEJBQTBCO0FBQUEsSUFDMUIsd0JBQXdCO0FBQUEsSUFDeEIsU0FBVztBQUFBLElBQ1gsYUFBYTtBQUFBLElBQ2IsVUFBWTtBQUFBLElBQ1osMEJBQTBCO0FBQUEsSUFDMUIsTUFBUTtBQUFBLElBQ1IsUUFBVTtBQUFBLElBQ1YsZ0JBQWdCO0FBQUEsSUFDaEIscUJBQXFCO0FBQUEsSUFDckIsc0JBQXNCO0FBQUEsSUFDdEIsWUFBYztBQUFBLElBQ2QscUJBQXFCO0FBQUEsSUFDckIsTUFBUTtBQUFBLElBQ1Isa0NBQWtDO0FBQUEsSUFDbEMsUUFBVTtBQUFBLEVBQ1g7QUFDRDs7O0FEN0NBLElBQU0sbUNBQW1DO0FBT2xDLGNBQU8sRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUU5QixJQUFPLDRCQUFRLGFBQWEsQ0FBQyxFQUFFLEtBQUssTUFBTTtBQUN4QyxRQUFNLGVBQWUsU0FBUztBQUU5QixTQUFPO0FBQUEsSUFDTCxTQUFTO0FBQUEsTUFDUCxPQUFPO0FBQUEsTUFDUCxzQkFBc0I7QUFBQSxNQUN0QjtBQUFBLElBQ0Y7QUFBQSxJQUVBLE9BQU87QUFBQSxNQUNMLGFBQWE7QUFBQSxNQUNiLGVBQWU7QUFBQSxRQUNiLE9BQU87QUFBQSxRQUNQLFFBQVE7QUFBQSxVQUNOLFFBQVE7QUFBQSxVQUNSLE1BQU07QUFBQSxVQUNOLGdCQUFnQixlQUFlLHVCQUF1QjtBQUFBLFFBQ3hEO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxJQUVBLFNBQVM7QUFBQSxNQUNQLE9BQU87QUFBQSxRQUNMLFFBQVEsS0FBSyxRQUFRLGtDQUFXLFdBQVc7QUFBQSxNQUM3QztBQUFBLElBQ0Y7QUFBQSxJQUVBLFFBQVE7QUFBQSxNQUNOLG9CQUFvQixLQUFLLFVBQVUsZ0JBQVksT0FBTztBQUFBLE1BQ3RELHlCQUF5QixLQUFLLFVBQVUsWUFBWTtBQUFBLElBQ3REO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFRCxJQUFNLHFCQUFxQjtBQUFBLEVBQ3pCLE1BQU07QUFBQTtBQUFBLEVBRU4sVUFBVSxJQUFJO0FBQ1osUUFBSSxPQUFPLHFCQUFzQixRQUFPO0FBQUEsRUFDMUM7QUFBQTtBQUFBLEVBRUEsS0FBSyxJQUFJO0FBQ1AsUUFBSSxPQUFPLHdCQUF3QjtBQUNqQyxhQUFPLE9BQU8sUUFBUSxRQUFRLEdBQUcsRUFDOUIsT0FBTyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksV0FBVyxTQUFTLENBQUMsRUFDM0MsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxLQUFLLFVBQVUsS0FBSyxDQUFDLEdBQUcsRUFDdkUsS0FBSyxJQUFJO0FBQUEsSUFDZDtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
|