@adobe/helix-rum-enhancer 2.44.1 → 2.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ # [2.45.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.44.2...v2.45.0) (2026-01-21)
2
+
3
+
4
+ ### Features
5
+
6
+ * track external redirect estimates ([aff3105](https://github.com/adobe/helix-rum-enhancer/commit/aff3105c3676da3c3a0bb8ab2479fb456147d064))
7
+ * track external redirect estimates ([4015e9d](https://github.com/adobe/helix-rum-enhancer/commit/4015e9d0c626ff5b06f13bf1e62db45813446cf1))
8
+
9
+ ## [2.44.2](https://github.com/adobe/helix-rum-enhancer/compare/v2.44.1...v2.44.2) (2025-11-14)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * focus loss error misfires in forms and SPA navgation ([60217de](https://github.com/adobe/helix-rum-enhancer/commit/60217dea75e714e8e4094dd2a0b48966135c9085))
15
+ * focus loss error misfires in forms and SPA navgation ([5a47d3b](https://github.com/adobe/helix-rum-enhancer/commit/5a47d3b8bccc6229efd2318a0c80b2358907b604))
16
+ * focus loss error misfires in forms and SPA navigation ([4eca02a](https://github.com/adobe/helix-rum-enhancer/commit/4eca02a6fc2be345394972eef2dde5ada44d0e8a))
17
+
1
18
  ## [2.44.1](https://github.com/adobe/helix-rum-enhancer/compare/v2.44.0...v2.44.1) (2025-10-27)
2
19
 
3
20
 
package/modules/index.js CHANGED
@@ -48,6 +48,10 @@ const CONSENT_PROVIDERS = [
48
48
  ];
49
49
 
50
50
  const getConsentProvider = () => CONSENT_PROVIDERS.find(({ detect }) => detect());
51
+ const bodyChildMO = {
52
+ target: document.body,
53
+ options: { attributes: false, childList: true, subtree: false },
54
+ };
51
55
 
52
56
  const PLUGINS = {
53
57
  cwv: `${pluginBasePath}/cwv.js`,
@@ -57,10 +61,13 @@ const PLUGINS = {
57
61
  url: `${pluginBasePath}/form.js`,
58
62
  when: () => document.querySelector('form'),
59
63
  isBlockDependent: true,
60
- mutationObserverParams: {
61
- target: document.body,
62
- options: { attributes: false, childList: true, subtree: false },
63
- },
64
+ mutationObserverParams: bodyChildMO,
65
+ },
66
+ redirect: {
67
+ url: `${pluginBasePath}/redirect.js`,
68
+ when: ({ perfEntry: pe, urlParameters: usp }) => (
69
+ pe && (usp.get('redirect_from') || pe.redirectCount > 0 || pe.fetchStart > 50)
70
+ ),
64
71
  },
65
72
  video: { url: `${pluginBasePath}/video.js`, when: () => document.querySelector('video'), isBlockDependent: true },
66
73
  webcomponent: {
@@ -73,10 +80,7 @@ const PLUGINS = {
73
80
  consent: {
74
81
  when: () => getConsentProvider(),
75
82
  isBlockDependent: true,
76
- mutationObserverParams: {
77
- target: document.body,
78
- options: { attributes: false, childList: true, subtree: false },
79
- },
83
+ mutationObserverParams: bodyChildMO,
80
84
  },
81
85
  // test: broken-plugin
82
86
  };
@@ -119,14 +123,13 @@ const pluginCache = new Map();
119
123
  function loadPlugin(key, params) {
120
124
  const plugin = PLUGINS[key];
121
125
  const usp = new URLSearchParams(window.location.search);
122
- if (!pluginCache.has(key) && plugin.when && !plugin.when({ urlParameters: usp })) {
126
+ if (!pluginCache.has(key) && plugin.when && !plugin.when({ ...params, urlParameters: usp })) {
123
127
  if (plugin.mutationObserverParams && !plugin.isBeingObserved) {
124
128
  // eslint-disable-next-line no-use-before-define
125
129
  createPluginMO(key, params, usp);
126
130
  }
127
131
  return null;
128
132
  }
129
-
130
133
  if (key === 'consent') {
131
134
  plugin.url = `${pluginBasePath}/${getConsentProvider().name}.js`;
132
135
  }
@@ -200,7 +203,7 @@ function processQueue() {
200
203
 
201
204
  function addNavigationTracking() {
202
205
  // enter checkpoint when referrer is not the current page url
203
- const navigate = (source, type, redirectCount) => {
206
+ const navigate = (source, type, perfEntry) => {
204
207
  const payload = { source, target: document.visibilityState };
205
208
  /* c8 ignore next 13 */
206
209
  // prerendering cannot be tested yet with headless browsers
@@ -225,12 +228,8 @@ function addNavigationTracking() {
225
228
  } else {
226
229
  sampleRUM('enter', payload); // enter site
227
230
  }
228
- const from = new URLSearchParams(window.location.search).get('redirect_from');
229
- if (redirectCount || from) {
230
- sampleRUM('redirect', { source: from, target: redirectCount || 1 });
231
- }
231
+ loadPlugin('redirect', { ...PLUGIN_PARAMETERS, perfEntry });
232
232
  };
233
-
234
233
  const processed = new Set(); // avoid processing duplicate types
235
234
  new PerformanceObserver((list) => list
236
235
  .getEntries()
@@ -239,7 +238,7 @@ function addNavigationTracking() {
239
238
  .map(([e]) => navigate(
240
239
  window.hlx.referrer || document.referrer,
241
240
  e.type,
242
- e.redirectCount,
241
+ e,
243
242
  ))).observe({ type: 'navigation', buffered: true });
244
243
  }
245
244
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-rum-enhancer",
3
- "version": "2.44.1",
3
+ "version": "2.45.0",
4
4
  "description": "Helix RUM Enhancer",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -33,16 +33,16 @@
33
33
  "reporter-options": "configFile=.mocha-multi.json"
34
34
  },
35
35
  "devDependencies": {
36
- "@adobe/eslint-config-helix": "3.0.12",
36
+ "@adobe/eslint-config-helix": "3.0.13",
37
37
  "@adobe/helix-rum-js": "2.13.6",
38
38
  "@adobe/rollup-plugin-checksum": "1.2.0",
39
- "@eslint/config-helpers": "0.4.0",
39
+ "@eslint/config-helpers": "0.5.0",
40
40
  "@esm-bundle/chai": "4.3.4-fix.0",
41
- "@rollup/plugin-babel": "6.0.4",
41
+ "@rollup/plugin-babel": "6.1.0",
42
42
  "@semantic-release/changelog": "6.0.3",
43
43
  "@semantic-release/exec": "7.1.0",
44
44
  "@semantic-release/git": "10.0.1",
45
- "@semantic-release/npm": "13.0.0",
45
+ "@semantic-release/npm": "13.1.3",
46
46
  "@web/test-runner": "0.20.2",
47
47
  "@web/test-runner-commands": "0.9.0",
48
48
  "@web/test-runner-junit-reporter": "0.8.0",
@@ -53,16 +53,16 @@
53
53
  "eslint": "9.30.1",
54
54
  "eslint-plugin-header": "3.1.1",
55
55
  "eslint-plugin-import": "2.32.0",
56
- "globals": "16.4.0",
56
+ "globals": "16.5.0",
57
57
  "husky": "9.1.7",
58
58
  "jsdoc-to-markdown": "9.1.3",
59
59
  "junit-report-builder": "5.1.1",
60
- "lint-staged": "16.2.3",
61
- "mocha": "11.7.4",
60
+ "lint-staged": "16.2.7",
61
+ "mocha": "11.7.5",
62
62
  "mocha-multi-reporters": "1.5.1",
63
- "rollup": "4.52.4",
63
+ "rollup": "4.55.1",
64
64
  "rollup-plugin-eslint-bundle": "9.0.0",
65
- "semantic-release": "25.0.0",
65
+ "semantic-release": "25.0.2",
66
66
  "semantic-release-slack-bot": "^4.0.2",
67
67
  "web-vitals": "5.1.0"
68
68
  },
package/plugins/a11y.js CHANGED
@@ -65,6 +65,7 @@ export default function addAccessibilityAudienceTracking({ sampleRUM, sourceSele
65
65
  let totalCount = 0;
66
66
  let lastFocusTime = 0;
67
67
  let hadMeaningfulFocus = false;
68
+ let isKeyboardNav = false;
68
69
 
69
70
  const reportAudience = () => {
70
71
  /* c8 ignore next 3 */
@@ -147,6 +148,7 @@ export default function addAccessibilityAudienceTracking({ sampleRUM, sourceSele
147
148
  };
148
149
 
149
150
  const trackFocusForTrap = (event) => {
151
+ isKeyboardNav = true;
150
152
  setTimeout(() => {
151
153
  const { activeElement } = document;
152
154
  /* c8 ignore next 3 */
@@ -214,6 +216,33 @@ export default function addAccessibilityAudienceTracking({ sampleRUM, sourceSele
214
216
  checkBehavioralScore();
215
217
  });
216
218
 
219
+ // Disarm focus-loss tracking on pointer interactions
220
+ const disarm = () => {
221
+ isKeyboardNav = false;
222
+ };
223
+ document.addEventListener('pointerdown', disarm);
224
+ document.addEventListener('mousedown', disarm);
225
+ document.addEventListener('touchstart', disarm, { passive: true });
226
+
227
+ // Override pushState
228
+ const originalPushState = history.pushState;
229
+ history.pushState = (...args) => {
230
+ originalPushState.apply(history, args);
231
+ hadMeaningfulFocus = false;
232
+ };
233
+
234
+ // Override replaceState
235
+ const originalReplaceState = history.replaceState;
236
+ history.replaceState = (...args) => {
237
+ originalReplaceState.apply(history, args);
238
+ hadMeaningfulFocus = false;
239
+ };
240
+
241
+ // Also catch back/forward browser nav (optional)
242
+ window.addEventListener('popstate', () => {
243
+ hadMeaningfulFocus = false;
244
+ });
245
+
217
246
  document.addEventListener('focusin', (event) => {
218
247
  if (event.target !== document.body) {
219
248
  lastFocusTime = performance.now();
@@ -222,9 +251,10 @@ export default function addAccessibilityAudienceTracking({ sampleRUM, sourceSele
222
251
  });
223
252
 
224
253
  const focusLossObserver = new MutationObserver((mutations) => {
225
- if (hadMeaningfulFocus
226
- && document.activeElement === document.body
227
- && (performance.now() - lastFocusTime > 100)) {
254
+ if (hadMeaningfulFocus // we had a focused element before the focus change
255
+ && isKeyboardNav // the focus change happened via keyboard navigation
256
+ && document.activeElement === document.body // the new focused element is just the page body
257
+ && (performance.now() - lastFocusTime > 100)) { // let async focus events finish
228
258
  /* c8 ignore next 9 */
229
259
  const mutation = mutations.find((m) => (
230
260
  m.type === 'childList' && (m.addedNodes.length > 0 || m.removedNodes.length > 0)
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Copyright 2025 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ /* eslint-env browser */
13
+
14
+ /**
15
+ * Estimate external redirect hops from elapsed ms before fetchStart.
16
+ * Uses a conservative 5-RTT model and subtracts one for the final request.
17
+ * @param {number} ms
18
+ * @return {number}
19
+ */
20
+ function estimateRedirectCount(ms) {
21
+ const rtt = (navigator.connection && navigator.connection.rtt) || 100;
22
+ return Math.max(1, Math.round(ms / (rtt * 5)) - 1);
23
+ }
24
+ export default function addRedirectTracking({ sampleRUM, perfEntry }) {
25
+ try {
26
+ const from = new URLSearchParams(window.location.search).get('redirect_from');
27
+
28
+ let duration;
29
+ let redirectValue;
30
+ if (perfEntry && perfEntry.redirectCount > 0) {
31
+ duration = Math.max(0, Math.round(perfEntry.redirectEnd - perfEntry.redirectStart));
32
+ redirectValue = `${perfEntry.redirectCount}:${duration}`;
33
+ } else if (perfEntry && perfEntry.fetchStart > 50) {
34
+ duration = Math.round(perfEntry.fetchStart);
35
+ redirectValue = `${estimateRedirectCount(duration)}~${duration}`;
36
+ }
37
+
38
+ if (redirectValue || from) {
39
+ const fallback = perfEntry && perfEntry.fetchStart ? Math.round(perfEntry.fetchStart) : 0;
40
+ sampleRUM('redirect', { source: from, target: redirectValue || `1~${fallback}` });
41
+ }
42
+ /* c8 ignore next 3 */
43
+ } catch (e) {
44
+ // silent failure
45
+ }
46
+ }
package/src/index.js CHANGED
@@ -139,6 +139,14 @@
139
139
  const getConsentProvider = () => CONSENT_PROVIDERS.find(({
140
140
  detect
141
141
  }) => detect());
142
+ const bodyChildMO = {
143
+ target: document.body,
144
+ options: {
145
+ attributes: false,
146
+ childList: true,
147
+ subtree: false
148
+ }
149
+ };
142
150
  const PLUGINS = {
143
151
  cwv: `${pluginBasePath}/cwv.js`,
144
152
  a11y: `${pluginBasePath}/a11y.js`,
@@ -146,14 +154,14 @@
146
154
  url: `${pluginBasePath}/form.js`,
147
155
  when: () => document.querySelector('form'),
148
156
  isBlockDependent: true,
149
- mutationObserverParams: {
150
- target: document.body,
151
- options: {
152
- attributes: false,
153
- childList: true,
154
- subtree: false
155
- }
156
- }
157
+ mutationObserverParams: bodyChildMO
158
+ },
159
+ redirect: {
160
+ url: `${pluginBasePath}/redirect.js`,
161
+ when: ({
162
+ perfEntry: pe,
163
+ urlParameters: usp
164
+ }) => pe && (usp.get('redirect_from') || pe.redirectCount > 0 || pe.fetchStart > 50)
157
165
  },
158
166
  video: {
159
167
  url: `${pluginBasePath}/video.js`,
@@ -174,14 +182,7 @@
174
182
  consent: {
175
183
  when: () => getConsentProvider(),
176
184
  isBlockDependent: true,
177
- mutationObserverParams: {
178
- target: document.body,
179
- options: {
180
- attributes: false,
181
- childList: true,
182
- subtree: false
183
- }
184
- }
185
+ mutationObserverParams: bodyChildMO
185
186
  }
186
187
  };
187
188
  function getIntersectionObserver(checkpoint) {
@@ -217,6 +218,7 @@
217
218
  const plugin = PLUGINS[key];
218
219
  const usp = new URLSearchParams(window.location.search);
219
220
  if (!pluginCache.has(key) && plugin.when && !plugin.when({
221
+ ...params,
220
222
  urlParameters: usp
221
223
  })) {
222
224
  if (plugin.mutationObserverParams && !plugin.isBeingObserved) {
@@ -290,7 +292,7 @@
290
292
  }
291
293
  }
292
294
  function addNavigationTracking() {
293
- const navigate = (source, type, redirectCount) => {
295
+ const navigate = (source, type, perfEntry) => {
294
296
  const payload = {
295
297
  source,
296
298
  target: document.visibilityState
@@ -314,18 +316,15 @@
314
316
  } else {
315
317
  sampleRUM('enter', payload);
316
318
  }
317
- const from = new URLSearchParams(window.location.search).get('redirect_from');
318
- if (redirectCount || from) {
319
- sampleRUM('redirect', {
320
- source: from,
321
- target: redirectCount || 1
322
- });
323
- }
319
+ loadPlugin('redirect', {
320
+ ...PLUGIN_PARAMETERS,
321
+ perfEntry
322
+ });
324
323
  };
325
324
  const processed = new Set();
326
325
  new PerformanceObserver(list => list.getEntries().filter(({
327
326
  type
328
- }) => !processed.has(type)).map(e => [e, processed.add(e.type)]).map(([e]) => navigate(window.hlx.referrer || document.referrer, e.type, e.redirectCount))).observe({
327
+ }) => !processed.has(type)).map(e => [e, processed.add(e.type)]).map(([e]) => navigate(window.hlx.referrer || document.referrer, e.type, e))).observe({
329
328
  type: 'navigation',
330
329
  buffered: true
331
330
  });
package/src/index.md5 CHANGED
@@ -1 +1 @@
1
- 55b1128ec28268801a506ca3ba02e344
1
+ a50ddb985eff3e6efe9d073e5f047da4
package/src/index.sri CHANGED
@@ -1 +1 @@
1
- sha384-VosLASRx7DNO3LKUFFVMgcqlBdUzQp8iYtO5V+vKLBOVwf2vWi2qOQYloBWc++NJ
1
+ sha384-/ZrdSEVuJfpAKMwewMHl+Z/eTu+o2Rb7zAXpQO714IjAooUHFAQ/2VugFVhcsnXU
@@ -46,6 +46,7 @@ function addAccessibilityAudienceTracking({
46
46
  let totalCount = 0;
47
47
  let lastFocusTime = 0;
48
48
  let hadMeaningfulFocus = false;
49
+ let isKeyboardNav = false;
49
50
  const reportAudience = () => {
50
51
  if (reported) {
51
52
  return;
@@ -118,6 +119,7 @@ function addAccessibilityAudienceTracking({
118
119
  }
119
120
  };
120
121
  const trackFocusForTrap = event => {
122
+ isKeyboardNav = true;
121
123
  setTimeout(() => {
122
124
  const {
123
125
  activeElement
@@ -175,6 +177,27 @@ function addAccessibilityAudienceTracking({
175
177
  totalCount += 1;
176
178
  checkBehavioralScore();
177
179
  });
180
+ const disarm = () => {
181
+ isKeyboardNav = false;
182
+ };
183
+ document.addEventListener('pointerdown', disarm);
184
+ document.addEventListener('mousedown', disarm);
185
+ document.addEventListener('touchstart', disarm, {
186
+ passive: true
187
+ });
188
+ const originalPushState = history.pushState;
189
+ history.pushState = (...args) => {
190
+ originalPushState.apply(history, args);
191
+ hadMeaningfulFocus = false;
192
+ };
193
+ const originalReplaceState = history.replaceState;
194
+ history.replaceState = (...args) => {
195
+ originalReplaceState.apply(history, args);
196
+ hadMeaningfulFocus = false;
197
+ };
198
+ window.addEventListener('popstate', () => {
199
+ hadMeaningfulFocus = false;
200
+ });
178
201
  document.addEventListener('focusin', event => {
179
202
  if (event.target !== document.body) {
180
203
  lastFocusTime = performance.now();
@@ -182,7 +205,7 @@ function addAccessibilityAudienceTracking({
182
205
  }
183
206
  });
184
207
  const focusLossObserver = new MutationObserver(mutations => {
185
- if (hadMeaningfulFocus && document.activeElement === document.body && performance.now() - lastFocusTime > 100) {
208
+ if (hadMeaningfulFocus && isKeyboardNav && document.activeElement === document.body && performance.now() - lastFocusTime > 100) {
186
209
  const mutation = mutations.find(m => m.type === 'childList' && (m.addedNodes.length > 0 || m.removedNodes.length > 0));
187
210
  sampleRUM('error', {
188
211
  source: 'focus-loss',
@@ -46,6 +46,7 @@ function addAccessibilityAudienceTracking({
46
46
  let totalCount = 0;
47
47
  let lastFocusTime = 0;
48
48
  let hadMeaningfulFocus = false;
49
+ let isKeyboardNav = false;
49
50
  const reportAudience = () => {
50
51
  if (reported) {
51
52
  return;
@@ -118,6 +119,7 @@ function addAccessibilityAudienceTracking({
118
119
  }
119
120
  };
120
121
  const trackFocusForTrap = event => {
122
+ isKeyboardNav = true;
121
123
  setTimeout(() => {
122
124
  const {
123
125
  activeElement
@@ -175,6 +177,27 @@ function addAccessibilityAudienceTracking({
175
177
  totalCount += 1;
176
178
  checkBehavioralScore();
177
179
  });
180
+ const disarm = () => {
181
+ isKeyboardNav = false;
182
+ };
183
+ document.addEventListener('pointerdown', disarm);
184
+ document.addEventListener('mousedown', disarm);
185
+ document.addEventListener('touchstart', disarm, {
186
+ passive: true
187
+ });
188
+ const originalPushState = history.pushState;
189
+ history.pushState = (...args) => {
190
+ originalPushState.apply(history, args);
191
+ hadMeaningfulFocus = false;
192
+ };
193
+ const originalReplaceState = history.replaceState;
194
+ history.replaceState = (...args) => {
195
+ originalReplaceState.apply(history, args);
196
+ hadMeaningfulFocus = false;
197
+ };
198
+ window.addEventListener('popstate', () => {
199
+ hadMeaningfulFocus = false;
200
+ });
178
201
  document.addEventListener('focusin', event => {
179
202
  if (event.target !== document.body) {
180
203
  lastFocusTime = performance.now();
@@ -182,7 +205,7 @@ function addAccessibilityAudienceTracking({
182
205
  }
183
206
  });
184
207
  const focusLossObserver = new MutationObserver(mutations => {
185
- if (hadMeaningfulFocus && document.activeElement === document.body && performance.now() - lastFocusTime > 100) {
208
+ if (hadMeaningfulFocus && isKeyboardNav && document.activeElement === document.body && performance.now() - lastFocusTime > 100) {
186
209
  const mutation = mutations.find(m => m.type === 'childList' && (m.addedNodes.length > 0 || m.removedNodes.length > 0));
187
210
  sampleRUM('error', {
188
211
  source: 'focus-loss',
@@ -203,4 +226,4 @@ function addAccessibilityAudienceTracking({
203
226
  }
204
227
 
205
228
  export { addAccessibilityAudienceTracking as default };
206
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTExeS5tYXAuanMiLCJzb3VyY2VzIjpbIi4uLy4uL3BsdWdpbnMvYTExeS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjQgQWRvYmUuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weVxuICogb2YgdGhlIExpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlclxuICogdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TXG4gKiBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2VcbiAqIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuY29uc3QgQV9XRUlHSFQgPSAxO1xuY29uc3QgQUFfV0VJR0hUID0gMjtcbmNvbnN0IEFBQV9XRUlHSFQgPSA0O1xuXG5jb25zdCBQUkVGRVJFTkNFX1dFSUdIVFMgPSB7XG4gICcocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogcmVkdWNlKSc6IEFfV0VJR0hULFxuICAnKHByZWZlcnMtY29udHJhc3Q6IG1vcmUpJzogQUFfV0VJR0hULFxuICAnKHByZWZlcnMtY29udHJhc3Q6IGhpZ2gpJzogQUFfV0VJR0hULFxuICAnKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSknOiBBQUFfV0VJR0hULFxuICAnKC1tcy1oaWdoLWNvbnRyYXN0OiBhY3RpdmUpJzogQUFBX1dFSUdIVCxcbiAgJyhwcmVmZXJzLXJlZHVjZWQtdHJhbnNwYXJlbmN5OiByZWR1Y2UpJzogQV9XRUlHSFQsXG59O1xuXG5jb25zdCBLRVlCT0FSRF9SRUxFVkFOVF9LRVlTID0gW1xuICAnVGFiJywgJ0Fycm93VXAnLCAnQXJyb3dEb3duJywgJ0Fycm93TGVmdCcsICdBcnJvd1JpZ2h0JywgJ0VudGVyJywgJyAnLCAnRXNjYXBlJyxcbl07XG5cbmNvbnN0IEhJR0hfWk9PTV9MRVZFTCA9IDIwMDtcbmNvbnN0IE1FRElVTV9aT09NX0xFVkVMID0gMTI1O1xuXG5jb25zdCBCRUhBVklPUkFMX01JTl9FVkVOVFMgPSAxMDtcblxuY29uc3QgRk9DVVNUUkFQX01BWF9ISVNUT1JZID0gMjU7XG5jb25zdCBGT0NVU19UUkFQX01JTl9ISVNUT1JZID0gNDtcbmNvbnN0IEZPQ1VTX1RSQVBfUElOR19QT05HX0RVUkFUSU9OID0gMzAwMDtcbmNvbnN0IEZPQ1VTX1RSQVBfTUlOX1JFUEVBVFMgPSAzO1xuXG4vKipcbiAqIERldGVjdHMgYXBwcm94aW1hdGUgem9vbSBsZXZlbCB1c2luZyB0aGUgVmlzdWFsIFZpZXdwb3J0IEFQSS5cbiAqIFRoaXMgaXMgYSBwdXJlIHV0aWxpdHkgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBFc3RpbWF0ZWQgem9vbSBwZXJjZW50YWdlLlxuICovXG5mdW5jdGlvbiBnZXRab29tKCkge1xuICBpZiAod2luZG93LnZpc3VhbFZpZXdwb3J0ICYmIHdpbmRvdy52aXN1YWxWaWV3cG9ydC53aWR0aCA+IDApIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCgod2luZG93LmlubmVyV2lkdGggLyB3aW5kb3cudmlzdWFsVmlld3BvcnQud2lkdGgpICogMTAwKTtcbiAgfVxuICAvKiBjOCBpZ25vcmUgbmV4dCAxICovXG4gIHJldHVybiAxMDA7XG59XG5cbi8qKlxuICogTWluaW1hbCBhY2Nlc3NpYmlsaXR5IGF1ZGllbmNlIGRldGVjdGlvbiBwbHVnaW4gZm9yIGhlbGl4LXJ1bS1lbmhhbmNlci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgUGx1Z2luIHBhcmFtZXRlcnMgZnJvbSBlbmhhbmNlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHBhcmFtcy5zYW1wbGVSVU0gUlVNIHRyYWNraW5nIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcGFyYW1zLnNvdXJjZVNlbGVjdG9yIEZ1bmN0aW9uIHRvIGdlbmVyYXRlIGEgc2VsZWN0b3IgZm9yIGFuIGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGFkZEFjY2Vzc2liaWxpdHlBdWRpZW5jZVRyYWNraW5nKHsgc2FtcGxlUlVNLCBzb3VyY2VTZWxlY3RvciB9KSB7XG4gIGNvbnN0IGZvY3VzSGlzdG9yeSA9IFtdO1xuICBsZXQgc2NvcmUgPSAwO1xuICBsZXQgcmVwb3J0ZWQgPSBmYWxzZTtcbiAgbGV0IGZvY3VzVHJhcERldGVjdGVkID0gZmFsc2U7XG4gIGxldCBrZXlib2FyZENvdW50ID0gMDtcbiAgbGV0IHRvdGFsQ291bnQgPSAwO1xuICBsZXQgbGFzdEZvY3VzVGltZSA9IDA7XG4gIGxldCBoYWRNZWFuaW5nZnVsRm9jdXMgPSBmYWxzZTtcblxuICBjb25zdCByZXBvcnRBdWRpZW5jZSA9ICgpID0+IHtcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAzICovXG4gICAgaWYgKHJlcG9ydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlcG9ydGVkID0gdHJ1ZTtcbiAgICBsZXQgYXVkaWVuY2UgPSAnb2ZmJztcbiAgICBpZiAoc2NvcmUgPiA3KSB7XG4gICAgICBhdWRpZW5jZSA9ICdoaWdoJztcbiAgICB9IGVsc2UgaWYgKHNjb3JlID49IDQpIHtcbiAgICAgIGF1ZGllbmNlID0gJ21lZGl1bSc7XG4gICAgfSBlbHNlIGlmIChzY29yZSA+PSAxKSB7XG4gICAgICBhdWRpZW5jZSA9ICdsb3cnO1xuICAgIH1cbiAgICBzYW1wbGVSVU0oJ2ExMXknLCB7IHNvdXJjZTogYXVkaWVuY2UsIHRhcmdldDogJ29mZjpsb3c6bWVkaXVtOmhpZ2gnIH0pO1xuICB9O1xuXG4gIGNvbnN0IHJlcG9ydEZvY3VzVHJhcCA9ICh0cmFwVHlwZSwgZWxlbWVudHMpID0+IHtcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAzICovXG4gICAgaWYgKGZvY3VzVHJhcERldGVjdGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvY3VzVHJhcERldGVjdGVkID0gdHJ1ZTtcbiAgICBjb25zdCBlbGVtZW50RGVzY3JpcHRpb25zID0gZWxlbWVudHMuc2xpY2UoMCwgMykubWFwKHNvdXJjZVNlbGVjdG9yKTtcbiAgICBzYW1wbGVSVU0oJ2Vycm9yJywge1xuICAgICAgc291cmNlOiBgZm9jdXMtdHJhcDoke3RyYXBUeXBlfWAsXG4gICAgICB0YXJnZXQ6IGVsZW1lbnREZXNjcmlwdGlvbnMuam9pbignLCAnKSxcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBkZXRlY3RSZXBlYXRpbmdTZXF1ZW5jZSA9IChlbGVtZW50cywgc2VxTGVuZ3RoKSA9PiB7XG4gICAgY29uc3QgdG90YWxMZW5ndGggPSBzZXFMZW5ndGggKiBGT0NVU19UUkFQX01JTl9SRVBFQVRTO1xuICAgIC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoIDwgdG90YWxMZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgcmVjZW50ID0gZWxlbWVudHMuc2xpY2UoLXRvdGFsTGVuZ3RoKTtcbiAgICBjb25zdCBiYXNlU2VxdWVuY2UgPSByZWNlbnQuc2xpY2UoMCwgc2VxTGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IEZPQ1VTX1RSQVBfTUlOX1JFUEVBVFM7IGkgKz0gMSkge1xuICAgICAgY29uc3QgbmV4dFNlcXVlbmNlID0gcmVjZW50LnNsaWNlKGkgKiBzZXFMZW5ndGgsIChpICsgMSkgKiBzZXFMZW5ndGgpO1xuICAgICAgaWYgKG5leHRTZXF1ZW5jZS5sZW5ndGggIT09IHNlcUxlbmd0aFxuICAgICAgICB8fCAhbmV4dFNlcXVlbmNlLmV2ZXJ5KChlbCwgaikgPT4gZWwgPT09IGJhc2VTZXF1ZW5jZVtqXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXBvcnRGb2N1c1RyYXAoJ3NlcXVlbmNlJywgYmFzZVNlcXVlbmNlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBjb25zdCBkZXRlY3RGb2N1c1RyYXAgPSAoKSA9PiB7XG4gICAgaWYgKGZvY3VzSGlzdG9yeS5sZW5ndGggPCBGT0NVU19UUkFQX01JTl9ISVNUT1JZIHx8IGZvY3VzVHJhcERldGVjdGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRzID0gZm9jdXNIaXN0b3J5Lm1hcCgoaCkgPT4gaC5lbGVtZW50KTtcbiAgICBjb25zdCB0aW1lc3RhbXBzID0gZm9jdXNIaXN0b3J5Lm1hcCgoaCkgPT4gaC50aW1lc3RhbXApO1xuXG4gICAgaWYgKGVsZW1lbnRzLnNsaWNlKC0zKS5ldmVyeSgoZWwpID0+IGVsID09PSBlbGVtZW50c1tlbGVtZW50cy5sZW5ndGggLSAxXSkpIHtcbiAgICAgIHJlcG9ydEZvY3VzVHJhcCgnc2luZ2xlJywgW2VsZW1lbnRzW2VsZW1lbnRzLmxlbmd0aCAtIDFdXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVjZW50NCA9IGVsZW1lbnRzLnNsaWNlKC00KTtcbiAgICBjb25zdCB1bmlxdWUgPSBbLi4ubmV3IFNldChyZWNlbnQ0KV07XG4gICAgY29uc3QgdGltZURpZmYgPSB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV0gLSB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gNF07XG4gICAgaWYgKHVuaXF1ZS5sZW5ndGggPT09IDIgJiYgdGltZURpZmYgPCBGT0NVU19UUkFQX1BJTkdfUE9OR19EVVJBVElPTikge1xuICAgICAgcmVwb3J0Rm9jdXNUcmFwKCdwaW5nLXBvbmcnLCB1bmlxdWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1pblNlcUxlbmd0aCA9IDIgKiBGT0NVU19UUkFQX01JTl9ISVNUT1JZICsgMTtcbiAgICBpZiAoZm9jdXNIaXN0b3J5Lmxlbmd0aCA+PSBtaW5TZXFMZW5ndGgpIHtcbiAgICAgIGZvciAobGV0IHNlcUxlbmd0aCA9IDI7IHNlcUxlbmd0aCA8PSA0OyBzZXFMZW5ndGggKz0gMSkge1xuICAgICAgICBpZiAoZGV0ZWN0UmVwZWF0aW5nU2VxdWVuY2UoZWxlbWVudHMsIHNlcUxlbmd0aCkpIHtcbiAgICAgICAgICAvKiBjOCBpZ25vcmUgbmV4dCA0ICovXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHRyYWNrRm9jdXNGb3JUcmFwID0gKGV2ZW50KSA9PiB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCB7IGFjdGl2ZUVsZW1lbnQgfSA9IGRvY3VtZW50O1xuICAgICAgLyogYzggaWdub3JlIG5leHQgMyAqL1xuICAgICAgaWYgKCFhY3RpdmVFbGVtZW50IHx8IGFjdGl2ZUVsZW1lbnQgPT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZm9jdXNIaXN0b3J5LnB1c2goe1xuICAgICAgICBlbGVtZW50OiBhY3RpdmVFbGVtZW50LFxuICAgICAgICB0aW1lc3RhbXA6IHBlcmZvcm1hbmNlLm5vdygpLFxuICAgICAgICBzaGlmdEtleTogZXZlbnQuc2hpZnRLZXksXG4gICAgICB9KTtcbiAgICAgIC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbiAgICAgIGlmIChmb2N1c0hpc3RvcnkubGVuZ3RoID4gRk9DVVNUUkFQX01BWF9ISVNUT1JZKSB7XG4gICAgICAgIGZvY3VzSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgfVxuICAgICAgZGV0ZWN0Rm9jdXNUcmFwKCk7XG4gICAgfSwgMCk7XG4gIH07XG5cbiAgY29uc3QgY2hlY2tCZWhhdmlvcmFsU2NvcmUgPSAoKSA9PiB7XG4gICAgaWYgKHRvdGFsQ291bnQgPj0gQkVIQVZJT1JBTF9NSU5fRVZFTlRTICYmICFyZXBvcnRlZCkge1xuICAgICAgaWYgKGtleWJvYXJkQ291bnQgLyB0b3RhbENvdW50ID4gMC43KSB7XG4gICAgICAgIHNjb3JlICs9IEFBQV9XRUlHSFQ7XG4gICAgICB9XG4gICAgICByZXBvcnRBdWRpZW5jZSgpO1xuICAgIH1cbiAgfTtcblxuICAvLyAtLS0gU3RhdGljIFNjb3JpbmcgLS0tXG4gIE9iamVjdC5lbnRyaWVzKFBSRUZFUkVOQ0VfV0VJR0hUUykuZm9yRWFjaCgoW3F1ZXJ5LCBxdWVyeVdlaWdodF0pID0+IHtcbiAgICBpZiAod2luZG93Lm1hdGNoTWVkaWEocXVlcnkpLm1hdGNoZXMpIHtcbiAgICAgIHNjb3JlICs9IHF1ZXJ5V2VpZ2h0O1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgem9vbSA9IGdldFpvb20oKTtcbiAgaWYgKHpvb20gPj0gSElHSF9aT09NX0xFVkVMKSB7XG4gICAgc2NvcmUgKz0gQUFfV0VJR0hUO1xuICB9IGVsc2UgaWYgKHpvb20gPj0gTUVESVVNX1pPT01fTEVWRUwpIHtcbiAgICBzY29yZSArPSBBX1dFSUdIVDtcbiAgfVxuXG4gIGlmIChuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgPT09IDAgJiYgd2luZG93Lm1hdGNoTWVkaWEoJyhwb2ludGVyOiBjb2Fyc2UpJykubWF0Y2hlcykge1xuICAgIHNjb3JlICs9IEFBX1dFSUdIVDtcbiAgfVxuXG4gIGlmICh3aW5kb3cubWF0Y2hNZWRpYSgnKGhvdmVyOiBub25lKScpLm1hdGNoZXMpIHtcbiAgICBzY29yZSArPSBBQV9XRUlHSFQ7XG4gIH1cblxuICAvLyAtLS0gRXZlbnQgTGlzdGVuZXJzICYgT2JzZXJ2ZXJzIC0tLVxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGV2ZW50KSA9PiB7XG4gICAgaWYgKEtFWUJPQVJEX1JFTEVWQU5UX0tFWVMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAga2V5Ym9hcmRDb3VudCArPSAxO1xuICAgICAgdG90YWxDb3VudCArPSAxO1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgdHJhY2tGb2N1c0ZvclRyYXAoZXZlbnQpO1xuICAgICAgfVxuICAgICAgY2hlY2tCZWhhdmlvcmFsU2NvcmUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIHRvdGFsQ291bnQgKz0gMTtcbiAgICBjaGVja0JlaGF2aW9yYWxTY29yZSgpO1xuICB9KTtcblxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdmb2N1c2luJywgKGV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LnRhcmdldCAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgbGFzdEZvY3VzVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgaGFkTWVhbmluZ2Z1bEZvY3VzID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGZvY3VzTG9zc09ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9ucykgPT4ge1xuICAgIGlmIChoYWRNZWFuaW5nZnVsRm9jdXNcbiAgICAgICAgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCA9PT0gZG9jdW1lbnQuYm9keVxuICAgICAgICAmJiAocGVyZm9ybWFuY2Uubm93KCkgLSBsYXN0Rm9jdXNUaW1lID4gMTAwKSkge1xuICAgICAgLyogYzggaWdub3JlIG5leHQgOSAqL1xuICAgICAgY29uc3QgbXV0YXRpb24gPSBtdXRhdGlvbnMuZmluZCgobSkgPT4gKFxuICAgICAgICBtLnR5cGUgPT09ICdjaGlsZExpc3QnICYmIChtLmFkZGVkTm9kZXMubGVuZ3RoID4gMCB8fCBtLnJlbW92ZWROb2Rlcy5sZW5ndGggPiAwKVxuICAgICAgKSk7XG4gICAgICBzYW1wbGVSVU0oJ2Vycm9yJywge1xuICAgICAgICBzb3VyY2U6ICdmb2N1cy1sb3NzJyxcbiAgICAgICAgdGFyZ2V0OiBzb3VyY2VTZWxlY3RvcihtdXRhdGlvbj8udGFyZ2V0KSxcbiAgICAgIH0pO1xuICAgICAgaGFkTWVhbmluZ2Z1bEZvY3VzID0gZmFsc2U7IC8vIFByZXZlbnQgc3BhbVxuICAgIH1cbiAgfSk7XG5cbiAgZm9jdXNMb3NzT2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudCwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSk7XG5cbiAgLy8gLS0tIEZpbmFsIFJlcG9ydGluZyAtLS1cbiAgaWYgKHNjb3JlID49IDcpIHtcbiAgICByZXBvcnRBdWRpZW5jZSgpO1xuICB9IGVsc2Uge1xuICAgIHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiByZXBvcnRBdWRpZW5jZSgpLFxuICAgICAgLyogYzggaWdub3JlIG5leHQgMSAqL1xuICAgICAgd2luZG93LmhseC5BMTFZX1JFUE9SVF9ERUxBWSB8fCAxMF8wMDAsXG4gICAgKTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIkFfV0VJR0hUIiwiQUFfV0VJR0hUIiwiQUFBX1dFSUdIVCIsIlBSRUZFUkVOQ0VfV0VJR0hUUyIsIktFWUJPQVJEX1JFTEVWQU5UX0tFWVMiLCJISUdIX1pPT01fTEVWRUwiLCJNRURJVU1fWk9PTV9MRVZFTCIsIkJFSEFWSU9SQUxfTUlOX0VWRU5UUyIsIkZPQ1VTVFJBUF9NQVhfSElTVE9SWSIsIkZPQ1VTX1RSQVBfTUlOX0hJU1RPUlkiLCJGT0NVU19UUkFQX1BJTkdfUE9OR19EVVJBVElPTiIsIkZPQ1VTX1RSQVBfTUlOX1JFUEVBVFMiLCJnZXRab29tIiwid2luZG93IiwidmlzdWFsVmlld3BvcnQiLCJ3aWR0aCIsIk1hdGgiLCJyb3VuZCIsImlubmVyV2lkdGgiLCJhZGRBY2Nlc3NpYmlsaXR5QXVkaWVuY2VUcmFja2luZyIsInNhbXBsZVJVTSIsInNvdXJjZVNlbGVjdG9yIiwiZm9jdXNIaXN0b3J5Iiwic2NvcmUiLCJyZXBvcnRlZCIsImZvY3VzVHJhcERldGVjdGVkIiwia2V5Ym9hcmRDb3VudCIsInRvdGFsQ291bnQiLCJsYXN0Rm9jdXNUaW1lIiwiaGFkTWVhbmluZ2Z1bEZvY3VzIiwicmVwb3J0QXVkaWVuY2UiLCJhdWRpZW5jZSIsInNvdXJjZSIsInRhcmdldCIsInJlcG9ydEZvY3VzVHJhcCIsInRyYXBUeXBlIiwiZWxlbWVudHMiLCJlbGVtZW50RGVzY3JpcHRpb25zIiwic2xpY2UiLCJtYXAiLCJqb2luIiwiZGV0ZWN0UmVwZWF0aW5nU2VxdWVuY2UiLCJzZXFMZW5ndGgiLCJ0b3RhbExlbmd0aCIsImxlbmd0aCIsInJlY2VudCIsImJhc2VTZXF1ZW5jZSIsImkiLCJuZXh0U2VxdWVuY2UiLCJldmVyeSIsImVsIiwiaiIsImRldGVjdEZvY3VzVHJhcCIsImgiLCJlbGVtZW50IiwidGltZXN0YW1wcyIsInRpbWVzdGFtcCIsInJlY2VudDQiLCJ1bmlxdWUiLCJTZXQiLCJ0aW1lRGlmZiIsIm1pblNlcUxlbmd0aCIsInRyYWNrRm9jdXNGb3JUcmFwIiwiZXZlbnQiLCJzZXRUaW1lb3V0IiwiYWN0aXZlRWxlbWVudCIsImRvY3VtZW50IiwiYm9keSIsInB1c2giLCJwZXJmb3JtYW5jZSIsIm5vdyIsInNoaWZ0S2V5Iiwic2hpZnQiLCJjaGVja0JlaGF2aW9yYWxTY29yZSIsIk9iamVjdCIsImVudHJpZXMiLCJmb3JFYWNoIiwicXVlcnkiLCJxdWVyeVdlaWdodCIsIm1hdGNoTWVkaWEiLCJtYXRjaGVzIiwiem9vbSIsIm5hdmlnYXRvciIsIm1heFRvdWNoUG9pbnRzIiwiYWRkRXZlbnRMaXN0ZW5lciIsImluY2x1ZGVzIiwia2V5IiwiZm9jdXNMb3NzT2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwibXV0YXRpb25zIiwibXV0YXRpb24iLCJmaW5kIiwibSIsInR5cGUiLCJhZGRlZE5vZGVzIiwicmVtb3ZlZE5vZGVzIiwib2JzZXJ2ZSIsImNoaWxkTGlzdCIsInN1YnRyZWUiLCJobHgiLCJBMTFZX1JFUE9SVF9ERUxBWSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFZQSxNQUFNQSxRQUFRLEdBQUcsQ0FBQztBQUNsQixNQUFNQyxTQUFTLEdBQUcsQ0FBQztBQUNuQixNQUFNQyxVQUFVLEdBQUcsQ0FBQztBQUVwQixNQUFNQyxrQkFBa0IsR0FBRztBQUN6QixFQUFBLGtDQUFrQyxFQUFFSCxRQUFRO0FBQzVDLEVBQUEsMEJBQTBCLEVBQUVDLFNBQVM7QUFDckMsRUFBQSwwQkFBMEIsRUFBRUEsU0FBUztBQUNyQyxFQUFBLHlCQUF5QixFQUFFQyxVQUFVO0FBQ3JDLEVBQUEsNkJBQTZCLEVBQUVBLFVBQVU7QUFDekMsRUFBQSx3Q0FBd0MsRUFBRUY7QUFDNUMsQ0FBQztBQUVELE1BQU1JLHNCQUFzQixHQUFHLENBQzdCLEtBQUssRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQ2pGO0FBRUQsTUFBTUMsZUFBZSxHQUFHLEdBQUc7QUFDM0IsTUFBTUMsaUJBQWlCLEdBQUcsR0FBRztBQUU3QixNQUFNQyxxQkFBcUIsR0FBRyxFQUFFO0FBRWhDLE1BQU1DLHFCQUFxQixHQUFHLEVBQUU7QUFDaEMsTUFBTUMsc0JBQXNCLEdBQUcsQ0FBQztBQUNoQyxNQUFNQyw2QkFBNkIsR0FBRyxJQUFJO0FBQzFDLE1BQU1DLHNCQUFzQixHQUFHLENBQUM7QUFPaEMsU0FBU0MsT0FBT0EsR0FBRztFQUNqQixJQUFJQyxNQUFNLENBQUNDLGNBQWMsSUFBSUQsTUFBTSxDQUFDQyxjQUFjLENBQUNDLEtBQUssR0FBRyxDQUFDLEVBQUU7QUFD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
229
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTExeS5tYXAuanMiLCJzb3VyY2VzIjpbIi4uLy4uL3BsdWdpbnMvYTExeS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjQgQWRvYmUuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weVxuICogb2YgdGhlIExpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlclxuICogdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TXG4gKiBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2VcbiAqIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuY29uc3QgQV9XRUlHSFQgPSAxO1xuY29uc3QgQUFfV0VJR0hUID0gMjtcbmNvbnN0IEFBQV9XRUlHSFQgPSA0O1xuXG5jb25zdCBQUkVGRVJFTkNFX1dFSUdIVFMgPSB7XG4gICcocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogcmVkdWNlKSc6IEFfV0VJR0hULFxuICAnKHByZWZlcnMtY29udHJhc3Q6IG1vcmUpJzogQUFfV0VJR0hULFxuICAnKHByZWZlcnMtY29udHJhc3Q6IGhpZ2gpJzogQUFfV0VJR0hULFxuICAnKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSknOiBBQUFfV0VJR0hULFxuICAnKC1tcy1oaWdoLWNvbnRyYXN0OiBhY3RpdmUpJzogQUFBX1dFSUdIVCxcbiAgJyhwcmVmZXJzLXJlZHVjZWQtdHJhbnNwYXJlbmN5OiByZWR1Y2UpJzogQV9XRUlHSFQsXG59O1xuXG5jb25zdCBLRVlCT0FSRF9SRUxFVkFOVF9LRVlTID0gW1xuICAnVGFiJywgJ0Fycm93VXAnLCAnQXJyb3dEb3duJywgJ0Fycm93TGVmdCcsICdBcnJvd1JpZ2h0JywgJ0VudGVyJywgJyAnLCAnRXNjYXBlJyxcbl07XG5cbmNvbnN0IEhJR0hfWk9PTV9MRVZFTCA9IDIwMDtcbmNvbnN0IE1FRElVTV9aT09NX0xFVkVMID0gMTI1O1xuXG5jb25zdCBCRUhBVklPUkFMX01JTl9FVkVOVFMgPSAxMDtcblxuY29uc3QgRk9DVVNUUkFQX01BWF9ISVNUT1JZID0gMjU7XG5jb25zdCBGT0NVU19UUkFQX01JTl9ISVNUT1JZID0gNDtcbmNvbnN0IEZPQ1VTX1RSQVBfUElOR19QT05HX0RVUkFUSU9OID0gMzAwMDtcbmNvbnN0IEZPQ1VTX1RSQVBfTUlOX1JFUEVBVFMgPSAzO1xuXG4vKipcbiAqIERldGVjdHMgYXBwcm94aW1hdGUgem9vbSBsZXZlbCB1c2luZyB0aGUgVmlzdWFsIFZpZXdwb3J0IEFQSS5cbiAqIFRoaXMgaXMgYSBwdXJlIHV0aWxpdHkgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBFc3RpbWF0ZWQgem9vbSBwZXJjZW50YWdlLlxuICovXG5mdW5jdGlvbiBnZXRab29tKCkge1xuICBpZiAod2luZG93LnZpc3VhbFZpZXdwb3J0ICYmIHdpbmRvdy52aXN1YWxWaWV3cG9ydC53aWR0aCA+IDApIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCgod2luZG93LmlubmVyV2lkdGggLyB3aW5kb3cudmlzdWFsVmlld3BvcnQud2lkdGgpICogMTAwKTtcbiAgfVxuICAvKiBjOCBpZ25vcmUgbmV4dCAxICovXG4gIHJldHVybiAxMDA7XG59XG5cbi8qKlxuICogTWluaW1hbCBhY2Nlc3NpYmlsaXR5IGF1ZGllbmNlIGRldGVjdGlvbiBwbHVnaW4gZm9yIGhlbGl4LXJ1bS1lbmhhbmNlci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgUGx1Z2luIHBhcmFtZXRlcnMgZnJvbSBlbmhhbmNlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHBhcmFtcy5zYW1wbGVSVU0gUlVNIHRyYWNraW5nIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcGFyYW1zLnNvdXJjZVNlbGVjdG9yIEZ1bmN0aW9uIHRvIGdlbmVyYXRlIGEgc2VsZWN0b3IgZm9yIGFuIGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGFkZEFjY2Vzc2liaWxpdHlBdWRpZW5jZVRyYWNraW5nKHsgc2FtcGxlUlVNLCBzb3VyY2VTZWxlY3RvciB9KSB7XG4gIGNvbnN0IGZvY3VzSGlzdG9yeSA9IFtdO1xuICBsZXQgc2NvcmUgPSAwO1xuICBsZXQgcmVwb3J0ZWQgPSBmYWxzZTtcbiAgbGV0IGZvY3VzVHJhcERldGVjdGVkID0gZmFsc2U7XG4gIGxldCBrZXlib2FyZENvdW50ID0gMDtcbiAgbGV0IHRvdGFsQ291bnQgPSAwO1xuICBsZXQgbGFzdEZvY3VzVGltZSA9IDA7XG4gIGxldCBoYWRNZWFuaW5nZnVsRm9jdXMgPSBmYWxzZTtcbiAgbGV0IGlzS2V5Ym9hcmROYXYgPSBmYWxzZTtcblxuICBjb25zdCByZXBvcnRBdWRpZW5jZSA9ICgpID0+IHtcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAzICovXG4gICAgaWYgKHJlcG9ydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlcG9ydGVkID0gdHJ1ZTtcbiAgICBsZXQgYXVkaWVuY2UgPSAnb2ZmJztcbiAgICBpZiAoc2NvcmUgPiA3KSB7XG4gICAgICBhdWRpZW5jZSA9ICdoaWdoJztcbiAgICB9IGVsc2UgaWYgKHNjb3JlID49IDQpIHtcbiAgICAgIGF1ZGllbmNlID0gJ21lZGl1bSc7XG4gICAgfSBlbHNlIGlmIChzY29yZSA+PSAxKSB7XG4gICAgICBhdWRpZW5jZSA9ICdsb3cnO1xuICAgIH1cbiAgICBzYW1wbGVSVU0oJ2ExMXknLCB7IHNvdXJjZTogYXVkaWVuY2UsIHRhcmdldDogJ29mZjpsb3c6bWVkaXVtOmhpZ2gnIH0pO1xuICB9O1xuXG4gIGNvbnN0IHJlcG9ydEZvY3VzVHJhcCA9ICh0cmFwVHlwZSwgZWxlbWVudHMpID0+IHtcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAzICovXG4gICAgaWYgKGZvY3VzVHJhcERldGVjdGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvY3VzVHJhcERldGVjdGVkID0gdHJ1ZTtcbiAgICBjb25zdCBlbGVtZW50RGVzY3JpcHRpb25zID0gZWxlbWVudHMuc2xpY2UoMCwgMykubWFwKHNvdXJjZVNlbGVjdG9yKTtcbiAgICBzYW1wbGVSVU0oJ2Vycm9yJywge1xuICAgICAgc291cmNlOiBgZm9jdXMtdHJhcDoke3RyYXBUeXBlfWAsXG4gICAgICB0YXJnZXQ6IGVsZW1lbnREZXNjcmlwdGlvbnMuam9pbignLCAnKSxcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBkZXRlY3RSZXBlYXRpbmdTZXF1ZW5jZSA9IChlbGVtZW50cywgc2VxTGVuZ3RoKSA9PiB7XG4gICAgY29uc3QgdG90YWxMZW5ndGggPSBzZXFMZW5ndGggKiBGT0NVU19UUkFQX01JTl9SRVBFQVRTO1xuICAgIC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoIDwgdG90YWxMZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgcmVjZW50ID0gZWxlbWVudHMuc2xpY2UoLXRvdGFsTGVuZ3RoKTtcbiAgICBjb25zdCBiYXNlU2VxdWVuY2UgPSByZWNlbnQuc2xpY2UoMCwgc2VxTGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IEZPQ1VTX1RSQVBfTUlOX1JFUEVBVFM7IGkgKz0gMSkge1xuICAgICAgY29uc3QgbmV4dFNlcXVlbmNlID0gcmVjZW50LnNsaWNlKGkgKiBzZXFMZW5ndGgsIChpICsgMSkgKiBzZXFMZW5ndGgpO1xuICAgICAgaWYgKG5leHRTZXF1ZW5jZS5sZW5ndGggIT09IHNlcUxlbmd0aFxuICAgICAgICB8fCAhbmV4dFNlcXVlbmNlLmV2ZXJ5KChlbCwgaikgPT4gZWwgPT09IGJhc2VTZXF1ZW5jZVtqXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXBvcnRGb2N1c1RyYXAoJ3NlcXVlbmNlJywgYmFzZVNlcXVlbmNlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBjb25zdCBkZXRlY3RGb2N1c1RyYXAgPSAoKSA9PiB7XG4gICAgaWYgKGZvY3VzSGlzdG9yeS5sZW5ndGggPCBGT0NVU19UUkFQX01JTl9ISVNUT1JZIHx8IGZvY3VzVHJhcERldGVjdGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRzID0gZm9jdXNIaXN0b3J5Lm1hcCgoaCkgPT4gaC5lbGVtZW50KTtcbiAgICBjb25zdCB0aW1lc3RhbXBzID0gZm9jdXNIaXN0b3J5Lm1hcCgoaCkgPT4gaC50aW1lc3RhbXApO1xuXG4gICAgaWYgKGVsZW1lbnRzLnNsaWNlKC0zKS5ldmVyeSgoZWwpID0+IGVsID09PSBlbGVtZW50c1tlbGVtZW50cy5sZW5ndGggLSAxXSkpIHtcbiAgICAgIHJlcG9ydEZvY3VzVHJhcCgnc2luZ2xlJywgW2VsZW1lbnRzW2VsZW1lbnRzLmxlbmd0aCAtIDFdXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVjZW50NCA9IGVsZW1lbnRzLnNsaWNlKC00KTtcbiAgICBjb25zdCB1bmlxdWUgPSBbLi4ubmV3IFNldChyZWNlbnQ0KV07XG4gICAgY29uc3QgdGltZURpZmYgPSB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV0gLSB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gNF07XG4gICAgaWYgKHVuaXF1ZS5sZW5ndGggPT09IDIgJiYgdGltZURpZmYgPCBGT0NVU19UUkFQX1BJTkdfUE9OR19EVVJBVElPTikge1xuICAgICAgcmVwb3J0Rm9jdXNUcmFwKCdwaW5nLXBvbmcnLCB1bmlxdWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1pblNlcUxlbmd0aCA9IDIgKiBGT0NVU19UUkFQX01JTl9ISVNUT1JZICsgMTtcbiAgICBpZiAoZm9jdXNIaXN0b3J5Lmxlbmd0aCA+PSBtaW5TZXFMZW5ndGgpIHtcbiAgICAgIGZvciAobGV0IHNlcUxlbmd0aCA9IDI7IHNlcUxlbmd0aCA8PSA0OyBzZXFMZW5ndGggKz0gMSkge1xuICAgICAgICBpZiAoZGV0ZWN0UmVwZWF0aW5nU2VxdWVuY2UoZWxlbWVudHMsIHNlcUxlbmd0aCkpIHtcbiAgICAgICAgICAvKiBjOCBpZ25vcmUgbmV4dCA0ICovXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHRyYWNrRm9jdXNGb3JUcmFwID0gKGV2ZW50KSA9PiB7XG4gICAgaXNLZXlib2FyZE5hdiA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCB7IGFjdGl2ZUVsZW1lbnQgfSA9IGRvY3VtZW50O1xuICAgICAgLyogYzggaWdub3JlIG5leHQgMyAqL1xuICAgICAgaWYgKCFhY3RpdmVFbGVtZW50IHx8IGFjdGl2ZUVsZW1lbnQgPT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZm9jdXNIaXN0b3J5LnB1c2goe1xuICAgICAgICBlbGVtZW50OiBhY3RpdmVFbGVtZW50LFxuICAgICAgICB0aW1lc3RhbXA6IHBlcmZvcm1hbmNlLm5vdygpLFxuICAgICAgICBzaGlmdEtleTogZXZlbnQuc2hpZnRLZXksXG4gICAgICB9KTtcbiAgICAgIC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbiAgICAgIGlmIChmb2N1c0hpc3RvcnkubGVuZ3RoID4gRk9DVVNUUkFQX01BWF9ISVNUT1JZKSB7XG4gICAgICAgIGZvY3VzSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgfVxuICAgICAgZGV0ZWN0Rm9jdXNUcmFwKCk7XG4gICAgfSwgMCk7XG4gIH07XG5cbiAgY29uc3QgY2hlY2tCZWhhdmlvcmFsU2NvcmUgPSAoKSA9PiB7XG4gICAgaWYgKHRvdGFsQ291bnQgPj0gQkVIQVZJT1JBTF9NSU5fRVZFTlRTICYmICFyZXBvcnRlZCkge1xuICAgICAgaWYgKGtleWJvYXJkQ291bnQgLyB0b3RhbENvdW50ID4gMC43KSB7XG4gICAgICAgIHNjb3JlICs9IEFBQV9XRUlHSFQ7XG4gICAgICB9XG4gICAgICByZXBvcnRBdWRpZW5jZSgpO1xuICAgIH1cbiAgfTtcblxuICAvLyAtLS0gU3RhdGljIFNjb3JpbmcgLS0tXG4gIE9iamVjdC5lbnRyaWVzKFBSRUZFUkVOQ0VfV0VJR0hUUykuZm9yRWFjaCgoW3F1ZXJ5LCBxdWVyeVdlaWdodF0pID0+IHtcbiAgICBpZiAod2luZG93Lm1hdGNoTWVkaWEocXVlcnkpLm1hdGNoZXMpIHtcbiAgICAgIHNjb3JlICs9IHF1ZXJ5V2VpZ2h0O1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgem9vbSA9IGdldFpvb20oKTtcbiAgaWYgKHpvb20gPj0gSElHSF9aT09NX0xFVkVMKSB7XG4gICAgc2NvcmUgKz0gQUFfV0VJR0hUO1xuICB9IGVsc2UgaWYgKHpvb20gPj0gTUVESVVNX1pPT01fTEVWRUwpIHtcbiAgICBzY29yZSArPSBBX1dFSUdIVDtcbiAgfVxuXG4gIGlmIChuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgPT09IDAgJiYgd2luZG93Lm1hdGNoTWVkaWEoJyhwb2ludGVyOiBjb2Fyc2UpJykubWF0Y2hlcykge1xuICAgIHNjb3JlICs9IEFBX1dFSUdIVDtcbiAgfVxuXG4gIGlmICh3aW5kb3cubWF0Y2hNZWRpYSgnKGhvdmVyOiBub25lKScpLm1hdGNoZXMpIHtcbiAgICBzY29yZSArPSBBQV9XRUlHSFQ7XG4gIH1cblxuICAvLyAtLS0gRXZlbnQgTGlzdGVuZXJzICYgT2JzZXJ2ZXJzIC0tLVxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGV2ZW50KSA9PiB7XG4gICAgaWYgKEtFWUJPQVJEX1JFTEVWQU5UX0tFWVMuaW5jbHVkZXMoZXZlbnQua2V5KSkge1xuICAgICAga2V5Ym9hcmRDb3VudCArPSAxO1xuICAgICAgdG90YWxDb3VudCArPSAxO1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgdHJhY2tGb2N1c0ZvclRyYXAoZXZlbnQpO1xuICAgICAgfVxuICAgICAgY2hlY2tCZWhhdmlvcmFsU2NvcmUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgIHRvdGFsQ291bnQgKz0gMTtcbiAgICBjaGVja0JlaGF2aW9yYWxTY29yZSgpO1xuICB9KTtcblxuICAvLyBEaXNhcm0gZm9jdXMtbG9zcyB0cmFja2luZyBvbiBwb2ludGVyIGludGVyYWN0aW9uc1xuICBjb25zdCBkaXNhcm0gPSAoKSA9PiB7XG4gICAgaXNLZXlib2FyZE5hdiA9IGZhbHNlO1xuICB9O1xuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIGRpc2FybSk7XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGRpc2FybSk7XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBkaXNhcm0sIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcblxuICAvLyBPdmVycmlkZSBwdXNoU3RhdGVcbiAgY29uc3Qgb3JpZ2luYWxQdXNoU3RhdGUgPSBoaXN0b3J5LnB1c2hTdGF0ZTtcbiAgaGlzdG9yeS5wdXNoU3RhdGUgPSAoLi4uYXJncykgPT4ge1xuICAgIG9yaWdpbmFsUHVzaFN0YXRlLmFwcGx5KGhpc3RvcnksIGFyZ3MpO1xuICAgIGhhZE1lYW5pbmdmdWxGb2N1cyA9IGZhbHNlO1xuICB9O1xuXG4gIC8vIE92ZXJyaWRlIHJlcGxhY2VTdGF0ZVxuICBjb25zdCBvcmlnaW5hbFJlcGxhY2VTdGF0ZSA9IGhpc3RvcnkucmVwbGFjZVN0YXRlO1xuICBoaXN0b3J5LnJlcGxhY2VTdGF0ZSA9ICguLi5hcmdzKSA9PiB7XG4gICAgb3JpZ2luYWxSZXBsYWNlU3RhdGUuYXBwbHkoaGlzdG9yeSwgYXJncyk7XG4gICAgaGFkTWVhbmluZ2Z1bEZvY3VzID0gZmFsc2U7XG4gIH07XG5cbiAgLy8gQWxzbyBjYXRjaCBiYWNrL2ZvcndhcmQgYnJvd3NlciBuYXYgKG9wdGlvbmFsKVxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCAoKSA9PiB7XG4gICAgaGFkTWVhbmluZ2Z1bEZvY3VzID0gZmFsc2U7XG4gIH0pO1xuXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCAoZXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQudGFyZ2V0ICE9PSBkb2N1bWVudC5ib2R5KSB7XG4gICAgICBsYXN0Rm9jdXNUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICBoYWRNZWFuaW5nZnVsRm9jdXMgPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgZm9jdXNMb3NzT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zKSA9PiB7XG4gICAgaWYgKGhhZE1lYW5pbmdmdWxGb2N1cyAvLyB3ZSBoYWQgYSBmb2N1c2VkIGVsZW1lbnQgYmVmb3JlIHRoZSBmb2N1cyBjaGFuZ2VcbiAgICAgICAgJiYgaXNLZXlib2FyZE5hdiAvLyB0aGUgZm9jdXMgY2hhbmdlIGhhcHBlbmVkIHZpYSBrZXlib2FyZCBuYXZpZ2F0aW9uXG4gICAgICAgICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IGRvY3VtZW50LmJvZHkgLy8gdGhlIG5ldyBmb2N1c2VkIGVsZW1lbnQgaXMganVzdCB0aGUgcGFnZSBib2R5XG4gICAgICAgICYmIChwZXJmb3JtYW5jZS5ub3coKSAtIGxhc3RGb2N1c1RpbWUgPiAxMDApKSB7IC8vIGxldCBhc3luYyBmb2N1cyBldmVudHMgZmluaXNoXG4gICAgICAvKiBjOCBpZ25vcmUgbmV4dCA5ICovXG4gICAgICBjb25zdCBtdXRhdGlvbiA9IG11dGF0aW9ucy5maW5kKChtKSA9PiAoXG4gICAgICAgIG0udHlwZSA9PT0gJ2NoaWxkTGlzdCcgJiYgKG0uYWRkZWROb2Rlcy5sZW5ndGggPiAwIHx8IG0ucmVtb3ZlZE5vZGVzLmxlbmd0aCA+IDApXG4gICAgICApKTtcbiAgICAgIHNhbXBsZVJVTSgnZXJyb3InLCB7XG4gICAgICAgIHNvdXJjZTogJ2ZvY3VzLWxvc3MnLFxuICAgICAgICB0YXJnZXQ6IHNvdXJjZVNlbGVjdG9yKG11dGF0aW9uPy50YXJnZXQpLFxuICAgICAgfSk7XG4gICAgICBoYWRNZWFuaW5nZnVsRm9jdXMgPSBmYWxzZTsgLy8gUHJldmVudCBzcGFtXG4gICAgfVxuICB9KTtcblxuICBmb2N1c0xvc3NPYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LCB7IGNoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZSB9KTtcblxuICAvLyAtLS0gRmluYWwgUmVwb3J0aW5nIC0tLVxuICBpZiAoc2NvcmUgPj0gNykge1xuICAgIHJlcG9ydEF1ZGllbmNlKCk7XG4gIH0gZWxzZSB7XG4gICAgc2V0VGltZW91dChcbiAgICAgICgpID0+IHJlcG9ydEF1ZGllbmNlKCksXG4gICAgICAvKiBjOCBpZ25vcmUgbmV4dCAxICovXG4gICAgICB3aW5kb3cuaGx4LkExMVlfUkVQT1JUX0RFTEFZIHx8IDEwXzAwMCxcbiAgICApO1xuICB9XG59XG4iXSwibmFtZXMiOlsiQV9XRUlHSFQiLCJBQV9XRUlHSFQiLCJBQUFfV0VJR0hUIiwiUFJFRkVSRU5DRV9XRUlHSFRTIiwiS0VZQk9BUkRfUkVMRVZBTlRfS0VZUyIsIkhJR0hfWk9PTV9MRVZFTCIsIk1FRElVTV9aT09NX0xFVkVMIiwiQkVIQVZJT1JBTF9NSU5fRVZFTlRTIiwiRk9DVVNUUkFQX01BWF9ISVNUT1JZIiwiRk9DVVNfVFJBUF9NSU5fSElTVE9SWSIsIkZPQ1VTX1RSQVBfUElOR19QT05HX0RVUkFUSU9OIiwiRk9DVVNfVFJBUF9NSU5fUkVQRUFUUyIsImdldFpvb20iLCJ3aW5kb3ciLCJ2aXN1YWxWaWV3cG9ydCIsIndpZHRoIiwiTWF0aCIsInJvdW5kIiwiaW5uZXJXaWR0aCIsImFkZEFjY2Vzc2liaWxpdHlBdWRpZW5jZVRyYWNraW5nIiwic2FtcGxlUlVNIiwic291cmNlU2VsZWN0b3IiLCJmb2N1c0hpc3RvcnkiLCJzY29yZSIsInJlcG9ydGVkIiwiZm9jdXNUcmFwRGV0ZWN0ZWQiLCJrZXlib2FyZENvdW50IiwidG90YWxDb3VudCIsImxhc3RGb2N1c1RpbWUiLCJoYWRNZWFuaW5nZnVsRm9jdXMiLCJpc0tleWJvYXJkTmF2IiwicmVwb3J0QXVkaWVuY2UiLCJhdWRpZW5jZSIsInNvdXJjZSIsInRhcmdldCIsInJlcG9ydEZvY3VzVHJhcCIsInRyYXBUeXBlIiwiZWxlbWVudHMiLCJlbGVtZW50RGVzY3JpcHRpb25zIiwic2xpY2UiLCJtYXAiLCJqb2luIiwiZGV0ZWN0UmVwZWF0aW5nU2VxdWVuY2UiLCJzZXFMZW5ndGgiLCJ0b3RhbExlbmd0aCIsImxlbmd0aCIsInJlY2VudCIsImJhc2VTZXF1ZW5jZSIsImkiLCJuZXh0U2VxdWVuY2UiLCJldmVyeSIsImVsIiwiaiIsImRldGVjdEZvY3VzVHJhcCIsImgiLCJlbGVtZW50IiwidGltZXN0YW1wcyIsInRpbWVzdGFtcCIsInJlY2VudDQiLCJ1bmlxdWUiLCJTZXQiLCJ0aW1lRGlmZiIsIm1pblNlcUxlbmd0aCIsInRyYWNrRm9jdXNGb3JUcmFwIiwiZXZlbnQiLCJzZXRUaW1lb3V0IiwiYWN0aXZlRWxlbWVudCIsImRvY3VtZW50IiwiYm9keSIsInB1c2giLCJwZXJmb3JtYW5jZSIsIm5vdyIsInNoaWZ0S2V5Iiwic2hpZnQiLCJjaGVja0JlaGF2aW9yYWxTY29yZSIsIk9iamVjdCIsImVudHJpZXMiLCJmb3JFYWNoIiwicXVlcnkiLCJxdWVyeVdlaWdodCIsIm1hdGNoTWVkaWEiLCJtYXRjaGVzIiwiem9vbSIsIm5hdmlnYXRvciIsIm1heFRvdWNoUG9pbnRzIiwiYWRkRXZlbnRMaXN0ZW5lciIsImluY2x1ZGVzIiwia2V5IiwiZGlzYXJtIiwicGFzc2l2ZSIsIm9yaWdpbmFsUHVzaFN0YXRlIiwiaGlzdG9yeSIsInB1c2hTdGF0ZSIsImFyZ3MiLCJhcHBseSIsIm9yaWdpbmFsUmVwbGFjZVN0YXRlIiwicmVwbGFjZVN0YXRlIiwiZm9jdXNMb3NzT2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwibXV0YXRpb25zIiwibXV0YXRpb24iLCJmaW5kIiwibSIsInR5cGUiLCJhZGRlZE5vZGVzIiwicmVtb3ZlZE5vZGVzIiwib2JzZXJ2ZSIsImNoaWxkTGlzdCIsInN1YnRyZWUiLCJobHgiLCJBMTFZX1JFUE9SVF9ERUxBWSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFZQSxNQUFNQSxRQUFRLEdBQUcsQ0FBQztBQUNsQixNQUFNQyxTQUFTLEdBQUcsQ0FBQztBQUNuQixNQUFNQyxVQUFVLEdBQUcsQ0FBQztBQUVwQixNQUFNQyxrQkFBa0IsR0FBRztBQUN6QixFQUFBLGtDQUFrQyxFQUFFSCxRQUFRO0FBQzVDLEVBQUEsMEJBQTBCLEVBQUVDLFNBQVM7QUFDckMsRUFBQSwwQkFBMEIsRUFBRUEsU0FBUztBQUNyQyxFQUFBLHlCQUF5QixFQUFFQyxVQUFVO0FBQ3JDLEVBQUEsNkJBQTZCLEVBQUVBLFVBQVU7QUFDekMsRUFBQSx3Q0FBd0MsRUFBRUY7QUFDNUMsQ0FBQztBQUVELE1BQU1JLHNCQUFzQixHQUFHLENBQzdCLEtBQUssRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFB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
@@ -1 +1 @@
1
- ca3630c51ee48da2595696b4b11cb586
1
+ 83098edb2dc04573f9aac3987a7f1bae
@@ -1 +1 @@
1
- 5a20c1d914d19b130034e4df532b8b4d
1
+ 866b5825b7bdb273170fbab6fa8099bb
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ function estimateRedirectCount(ms) {
13
+ const rtt = navigator.connection && navigator.connection.rtt || 100;
14
+ return Math.max(1, Math.round(ms / (rtt * 5)) - 1);
15
+ }
16
+ function addRedirectTracking({
17
+ sampleRUM,
18
+ perfEntry
19
+ }) {
20
+ try {
21
+ const from = new URLSearchParams(window.location.search).get('redirect_from');
22
+ let duration;
23
+ let redirectValue;
24
+ if (perfEntry && perfEntry.redirectCount > 0) {
25
+ duration = Math.max(0, Math.round(perfEntry.redirectEnd - perfEntry.redirectStart));
26
+ redirectValue = `${perfEntry.redirectCount}:${duration}`;
27
+ } else if (perfEntry && perfEntry.fetchStart > 50) {
28
+ duration = Math.round(perfEntry.fetchStart);
29
+ redirectValue = `${estimateRedirectCount(duration)}~${duration}`;
30
+ }
31
+ if (redirectValue || from) {
32
+ const fallback = perfEntry && perfEntry.fetchStart ? Math.round(perfEntry.fetchStart) : 0;
33
+ sampleRUM('redirect', {
34
+ source: from,
35
+ target: redirectValue || `1~${fallback}`
36
+ });
37
+ }
38
+ } catch (e) {}
39
+ }
40
+
41
+ export { addRedirectTracking as default };
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ function estimateRedirectCount(ms) {
13
+ const rtt = navigator.connection && navigator.connection.rtt || 100;
14
+ return Math.max(1, Math.round(ms / (rtt * 5)) - 1);
15
+ }
16
+ function addRedirectTracking({
17
+ sampleRUM,
18
+ perfEntry
19
+ }) {
20
+ try {
21
+ const from = new URLSearchParams(window.location.search).get('redirect_from');
22
+ let duration;
23
+ let redirectValue;
24
+ if (perfEntry && perfEntry.redirectCount > 0) {
25
+ duration = Math.max(0, Math.round(perfEntry.redirectEnd - perfEntry.redirectStart));
26
+ redirectValue = `${perfEntry.redirectCount}:${duration}`;
27
+ } else if (perfEntry && perfEntry.fetchStart > 50) {
28
+ duration = Math.round(perfEntry.fetchStart);
29
+ redirectValue = `${estimateRedirectCount(duration)}~${duration}`;
30
+ }
31
+ if (redirectValue || from) {
32
+ const fallback = perfEntry && perfEntry.fetchStart ? Math.round(perfEntry.fetchStart) : 0;
33
+ sampleRUM('redirect', {
34
+ source: from,
35
+ target: redirectValue || `1~${fallback}`
36
+ });
37
+ }
38
+ } catch (e) {}
39
+ }
40
+
41
+ export { addRedirectTracking as default };
42
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkaXJlY3QubWFwLmpzIiwic291cmNlcyI6WyIuLi8uLi9wbHVnaW5zL3JlZGlyZWN0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAyNSBBZG9iZS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgZmlsZSBpcyBsaWNlbnNlZCB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5XG4gKiBvZiB0aGUgTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyXG4gKiB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBSRVBSRVNFTlRBVElPTlNcbiAqIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZVxuICogZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyogZXNsaW50LWVudiBicm93c2VyICovXG5cbi8qKlxuICogRXN0aW1hdGUgZXh0ZXJuYWwgcmVkaXJlY3QgaG9wcyBmcm9tIGVsYXBzZWQgbXMgYmVmb3JlIGZldGNoU3RhcnQuXG4gKiBVc2VzIGEgY29uc2VydmF0aXZlIDUtUlRUIG1vZGVsIGFuZCBzdWJ0cmFjdHMgb25lIGZvciB0aGUgZmluYWwgcmVxdWVzdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtc1xuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5mdW5jdGlvbiBlc3RpbWF0ZVJlZGlyZWN0Q291bnQobXMpIHtcbiAgY29uc3QgcnR0ID0gKG5hdmlnYXRvci5jb25uZWN0aW9uICYmIG5hdmlnYXRvci5jb25uZWN0aW9uLnJ0dCkgfHwgMTAwO1xuICByZXR1cm4gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChtcyAvIChydHQgKiA1KSkgLSAxKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGFkZFJlZGlyZWN0VHJhY2tpbmcoeyBzYW1wbGVSVU0sIHBlcmZFbnRyeSB9KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgZnJvbSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KCdyZWRpcmVjdF9mcm9tJyk7XG5cbiAgICBsZXQgZHVyYXRpb247XG4gICAgbGV0IHJlZGlyZWN0VmFsdWU7XG4gICAgaWYgKHBlcmZFbnRyeSAmJiBwZXJmRW50cnkucmVkaXJlY3RDb3VudCA+IDApIHtcbiAgICAgIGR1cmF0aW9uID0gTWF0aC5tYXgoMCwgTWF0aC5yb3VuZChwZXJmRW50cnkucmVkaXJlY3RFbmQgLSBwZXJmRW50cnkucmVkaXJlY3RTdGFydCkpO1xuICAgICAgcmVkaXJlY3RWYWx1ZSA9IGAke3BlcmZFbnRyeS5yZWRpcmVjdENvdW50fToke2R1cmF0aW9ufWA7XG4gICAgfSBlbHNlIGlmIChwZXJmRW50cnkgJiYgcGVyZkVudHJ5LmZldGNoU3RhcnQgPiA1MCkge1xuICAgICAgZHVyYXRpb24gPSBNYXRoLnJvdW5kKHBlcmZFbnRyeS5mZXRjaFN0YXJ0KTtcbiAgICAgIHJlZGlyZWN0VmFsdWUgPSBgJHtlc3RpbWF0ZVJlZGlyZWN0Q291bnQoZHVyYXRpb24pfX4ke2R1cmF0aW9ufWA7XG4gICAgfVxuXG4gICAgaWYgKHJlZGlyZWN0VmFsdWUgfHwgZnJvbSkge1xuICAgICAgY29uc3QgZmFsbGJhY2sgPSBwZXJmRW50cnkgJiYgcGVyZkVudHJ5LmZldGNoU3RhcnQgPyBNYXRoLnJvdW5kKHBlcmZFbnRyeS5mZXRjaFN0YXJ0KSA6IDA7XG4gICAgICBzYW1wbGVSVU0oJ3JlZGlyZWN0JywgeyBzb3VyY2U6IGZyb20sIHRhcmdldDogcmVkaXJlY3RWYWx1ZSB8fCBgMX4ke2ZhbGxiYWNrfWAgfSk7XG4gICAgfVxuICAgIC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIHNpbGVudCBmYWlsdXJlXG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJlc3RpbWF0ZVJlZGlyZWN0Q291bnQiLCJtcyIsInJ0dCIsIm5hdmlnYXRvciIsImNvbm5lY3Rpb24iLCJNYXRoIiwibWF4Iiwicm91bmQiLCJhZGRSZWRpcmVjdFRyYWNraW5nIiwic2FtcGxlUlVNIiwicGVyZkVudHJ5IiwiZnJvbSIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsImxvY2F0aW9uIiwic2VhcmNoIiwiZ2V0IiwiZHVyYXRpb24iLCJyZWRpcmVjdFZhbHVlIiwicmVkaXJlY3RDb3VudCIsInJlZGlyZWN0RW5kIiwicmVkaXJlY3RTdGFydCIsImZldGNoU3RhcnQiLCJmYWxsYmFjayIsInNvdXJjZSIsInRhcmdldCIsImUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBbUJBLFNBQVNBLHFCQUFxQkEsQ0FBQ0MsRUFBRSxFQUFFO0FBQ2pDLEVBQUEsTUFBTUMsR0FBRyxHQUFJQyxTQUFTLENBQUNDLFVBQVUsSUFBSUQsU0FBUyxDQUFDQyxVQUFVLENBQUNGLEdBQUcsSUFBSyxHQUFHO0FBQ3JFLEVBQUEsT0FBT0csSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQyxFQUFFRCxJQUFJLENBQUNFLEtBQUssQ0FBQ04sRUFBRSxJQUFJQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEQ7QUFDZSxTQUFTTSxtQkFBbUJBLENBQUM7RUFBRUMsU0FBUztBQUFFQyxFQUFBQTtBQUFVLENBQUMsRUFBRTtFQUNwRSxJQUFJO0FBQ0YsSUFBQSxNQUFNQyxJQUFJLEdBQUcsSUFBSUMsZUFBZSxDQUFDQyxNQUFNLENBQUNDLFFBQVEsQ0FBQ0MsTUFBTSxDQUFDLENBQUNDLEdBQUcsQ0FBQyxlQUFlLENBQUM7QUFFN0UsSUFBQSxJQUFJQyxRQUFRO0FBQ1osSUFBQSxJQUFJQyxhQUFhO0FBQ2pCLElBQUEsSUFBSVIsU0FBUyxJQUFJQSxTQUFTLENBQUNTLGFBQWEsR0FBRyxDQUFDLEVBQUU7QUFDNUNGLE1BQUFBLFFBQVEsR0FBR1osSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQyxFQUFFRCxJQUFJLENBQUNFLEtBQUssQ0FBQ0csU0FBUyxDQUFDVSxXQUFXLEdBQUdWLFNBQVMsQ0FBQ1csYUFBYSxDQUFDLENBQUM7QUFDbkZILE1BQUFBLGFBQWEsR0FBRyxDQUFBLEVBQUdSLFNBQVMsQ0FBQ1MsYUFBYSxDQUFBLENBQUEsRUFBSUYsUUFBUSxDQUFBLENBQUU7SUFDMUQsQ0FBQyxNQUFNLElBQUlQLFNBQVMsSUFBSUEsU0FBUyxDQUFDWSxVQUFVLEdBQUcsRUFBRSxFQUFFO01BQ2pETCxRQUFRLEdBQUdaLElBQUksQ0FBQ0UsS0FBSyxDQUFDRyxTQUFTLENBQUNZLFVBQVUsQ0FBQztNQUMzQ0osYUFBYSxHQUFHLEdBQUdsQixxQkFBcUIsQ0FBQ2lCLFFBQVEsQ0FBQyxDQUFBLENBQUEsRUFBSUEsUUFBUSxDQUFBLENBQUU7QUFDbEUsSUFBQTtJQUVBLElBQUlDLGFBQWEsSUFBSVAsSUFBSSxFQUFFO0FBQ3pCLE1BQUEsTUFBTVksUUFBUSxHQUFHYixTQUFTLElBQUlBLFNBQVMsQ0FBQ1ksVUFBVSxHQUFHakIsSUFBSSxDQUFDRSxLQUFLLENBQUNHLFNBQVMsQ0FBQ1ksVUFBVSxDQUFDLEdBQUcsQ0FBQztNQUN6RmIsU0FBUyxDQUFDLFVBQVUsRUFBRTtBQUFFZSxRQUFBQSxNQUFNLEVBQUViLElBQUk7QUFBRWMsUUFBQUEsTUFBTSxFQUFFUCxhQUFhLElBQUksQ0FBQSxFQUFBLEVBQUtLLFFBQVEsQ0FBQTtBQUFHLE9BQUMsQ0FBQztBQUNuRixJQUFBO0FBRUYsRUFBQSxDQUFDLENBQUMsT0FBT0csQ0FBQyxFQUFFLENBRVo7QUFDRjs7OzsifQ==
@@ -0,0 +1 @@
1
+ ffe06266f271e876a25169b3b9aeb664
@@ -1 +1 @@
1
- 69d98a5cc1e1f11f6bedc2dbe91d8f8f
1
+ 3476ee246a6b4c1599651d8a7580e2c7