@serve.zone/appstore 32.27.0 → 33.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.smartconfig.json +4 -1
  2. package/changelog.md +70 -0
  3. package/dist_catalog/catalog.digest +1 -0
  4. package/dist_catalog/catalog.envelope.json +7617 -0
  5. package/{dist_ts_client/data.generated.js → dist_catalog/catalog.json} +6912 -6908
  6. package/dist_ts_client/catalog.d.ts +16 -0
  7. package/dist_ts_client/catalog.js +12 -0
  8. package/dist_ts_client/index.d.ts +3 -1
  9. package/dist_ts_client/index.js +4 -2
  10. package/dist_ts_client/loader.d.ts +69 -0
  11. package/dist_ts_client/loader.js +361 -0
  12. package/dist_ts_client/plugins.d.ts +5 -0
  13. package/dist_ts_client/plugins.js +8 -0
  14. package/dist_ts_client/projection.d.ts +59 -0
  15. package/dist_ts_client/projection.js +83 -0
  16. package/dist_ts_client/storage.d.ts +15 -9
  17. package/dist_ts_client/storage.js +81 -657
  18. package/dist_ts_client/types.d.ts +86 -41
  19. package/dist_ts_client/types.js +1 -1
  20. package/dist_ts_testing/fixtures.d.ts +83 -0
  21. package/dist_ts_testing/fixtures.js +146 -0
  22. package/dist_ts_testing/index.d.ts +1 -0
  23. package/dist_ts_testing/index.js +2 -0
  24. package/dist_ts_testing/plugins.d.ts +7 -0
  25. package/dist_ts_testing/plugins.js +11 -0
  26. package/package.json +16 -11
  27. package/readme.md +162 -93
  28. package/ts_client/catalog.ts +26 -0
  29. package/ts_client/index.ts +3 -1
  30. package/ts_client/loader.ts +414 -0
  31. package/ts_client/plugins.ts +10 -0
  32. package/ts_client/projection.ts +148 -0
  33. package/ts_client/readme.md +17 -27
  34. package/ts_client/storage.ts +93 -882
  35. package/ts_client/types.ts +102 -42
  36. package/ts_testing/fixtures.ts +230 -0
  37. package/ts_testing/index.ts +1 -0
  38. package/ts_testing/plugins.ts +15 -0
  39. package/ts_testing/tspublish.json +3 -0
  40. package/apps/adminer/app.json +0 -10
  41. package/apps/adminer/versions/1.0.0/config.json +0 -6
  42. package/apps/cloudly/app.json +0 -14
  43. package/apps/cloudly/versions/1.0.0/config.json +0 -120
  44. package/apps/cloudly/versions/1.1.0/config.json +0 -120
  45. package/apps/cloudly/versions/1.1.1/config.json +0 -120
  46. package/apps/cloudly/versions/1.1.10/config.json +0 -173
  47. package/apps/cloudly/versions/1.1.2/config.json +0 -130
  48. package/apps/cloudly/versions/1.1.3/config.json +0 -130
  49. package/apps/cloudly/versions/1.1.4/config.json +0 -130
  50. package/apps/cloudly/versions/1.1.5/config.json +0 -149
  51. package/apps/cloudly/versions/1.1.6/config.json +0 -149
  52. package/apps/cloudly/versions/1.1.7/config.json +0 -149
  53. package/apps/cloudly/versions/1.1.8/config.json +0 -173
  54. package/apps/cloudly/versions/1.1.9/config.json +0 -173
  55. package/apps/cloudly/versions/1.10.0/config.json +0 -173
  56. package/apps/cloudly/versions/1.11.0/config.json +0 -173
  57. package/apps/cloudly/versions/1.12.0/config.json +0 -173
  58. package/apps/cloudly/versions/1.13.0/config.json +0 -173
  59. package/apps/cloudly/versions/1.14.0/config.json +0 -173
  60. package/apps/cloudly/versions/1.15.0/config.json +0 -173
  61. package/apps/cloudly/versions/1.16.0/config.json +0 -173
  62. package/apps/cloudly/versions/1.17.0/config.json +0 -173
  63. package/apps/cloudly/versions/1.18.0/config.json +0 -173
  64. package/apps/cloudly/versions/1.19.0/config.json +0 -173
  65. package/apps/cloudly/versions/1.2.0/config.json +0 -173
  66. package/apps/cloudly/versions/1.2.1/config.json +0 -173
  67. package/apps/cloudly/versions/1.20.0/config.json +0 -173
  68. package/apps/cloudly/versions/1.21.0/config.json +0 -173
  69. package/apps/cloudly/versions/1.22.0/config.json +0 -173
  70. package/apps/cloudly/versions/1.23.0/config.json +0 -173
  71. package/apps/cloudly/versions/1.24.0/config.json +0 -173
  72. package/apps/cloudly/versions/1.25.0/config.json +0 -173
  73. package/apps/cloudly/versions/1.26.0/config.json +0 -173
  74. package/apps/cloudly/versions/1.27.0/config.json +0 -173
  75. package/apps/cloudly/versions/1.3.0/config.json +0 -173
  76. package/apps/cloudly/versions/1.4.0/config.json +0 -173
  77. package/apps/cloudly/versions/1.5.0/config.json +0 -173
  78. package/apps/cloudly/versions/1.6.0/config.json +0 -173
  79. package/apps/cloudly/versions/1.7.0/config.json +0 -173
  80. package/apps/cloudly/versions/1.8.0/config.json +0 -173
  81. package/apps/cloudly/versions/1.9.0/config.json +0 -173
  82. package/apps/ghost/app.json +0 -10
  83. package/apps/ghost/versions/1.0.0/config.json +0 -18
  84. package/apps/gitea/app.json +0 -10
  85. package/apps/gitea/versions/1.0.0/config.json +0 -16
  86. package/apps/gitops/app.json +0 -14
  87. package/apps/gitops/versions/1.0.0/config.json +0 -28
  88. package/apps/grafana/app.json +0 -10
  89. package/apps/grafana/versions/1.0.0/config.json +0 -9
  90. package/apps/mariadb/app.json +0 -10
  91. package/apps/mariadb/versions/1.0.0/config.json +0 -9
  92. package/apps/mattermost/app.json +0 -10
  93. package/apps/mattermost/versions/1.0.0/config.json +0 -6
  94. package/apps/n8n/app.json +0 -10
  95. package/apps/n8n/versions/1.0.0/config.json +0 -6
  96. package/apps/nextcloud/app.json +0 -10
  97. package/apps/nextcloud/versions/1.0.0/config.json +0 -16
  98. package/apps/nginx/app.json +0 -10
  99. package/apps/nginx/versions/1.0.0/config.json +0 -6
  100. package/apps/openbao/app.json +0 -16
  101. package/apps/openbao/versions/1.0.0/config.json +0 -52
  102. package/apps/plausible/app.json +0 -10
  103. package/apps/plausible/versions/1.0.0/config.json +0 -9
  104. package/apps/portainer/app.json +0 -10
  105. package/apps/portainer/versions/1.0.0/config.json +0 -6
  106. package/apps/postgres/app.json +0 -10
  107. package/apps/postgres/versions/1.0.0/config.json +0 -11
  108. package/apps/rustdesk-server/app.json +0 -14
  109. package/apps/rustdesk-server/versions/1.0.0/config.json +0 -19
  110. package/apps/siprouter/app.json +0 -14
  111. package/apps/siprouter/versions/1.0.0/config.json +0 -84
  112. package/apps/uptime-kuma/app.json +0 -10
  113. package/apps/uptime-kuma/versions/1.0.0/config.json +0 -6
  114. package/apps/valkey/app.json +0 -10
  115. package/apps/valkey/versions/1.0.0/config.json +0 -6
  116. package/apps/vaultwarden/app.json +0 -10
  117. package/apps/vaultwarden/versions/1.0.0/config.json +0 -6
  118. package/apps/wordpress/app.json +0 -10
  119. package/apps/wordpress/versions/1.0.0/config.json +0 -15
  120. package/appstore.json +0 -194
  121. package/dist_ts_client/classes.appstoreresolver.d.ts +0 -59
  122. package/dist_ts_client/classes.appstoreresolver.js +0 -736
  123. package/dist_ts_client/data.generated.d.ts +0 -2
  124. package/ts_client/classes.appstoreresolver.ts +0 -896
  125. package/ts_client/data.generated.ts +0 -7606
@@ -1,190 +1,96 @@
1
- import * as interfaces from '@serve.zone/interfaces';
2
- const storageFeatureIds = interfaces.appstore.appStoreStorageFeatureIds;
3
- const knownStorageFeatureIds = new Set(Object.values(storageFeatureIds));
4
- const storageClassKeyPattern = /^[A-Za-z][A-Za-z0-9-]{0,62}$/;
5
- const storageRequestIdPattern = /^[a-z][a-z0-9-]{0,62}$/;
6
- const environmentKeyPattern = /^[A-Z_][A-Z0-9_]{0,252}$/;
7
- const capacityPattern = /^([1-9][0-9]*)(KiB|MiB|GiB|TiB)$/;
8
- const capacityMultipliers = {
9
- KiB: 1024n,
10
- MiB: 1024n ** 2n,
11
- GiB: 1024n ** 3n,
12
- TiB: 1024n ** 4n,
13
- };
1
+ import * as plugins from './plugins.js';
2
+ const storageFeatureIds = plugins.servezoneInterfaces.appstore.appStoreStorageFeatureIds;
14
3
  const legacyFilesystemClassKey = 'legacyFilesystem';
15
4
  const legacyObjectStorageClassKey = 'legacyObjectStorage';
16
5
  const legacyObjectStorageRequestId = 'legacy-s3';
17
- const appStoreVersionConfigKeys = [
18
- 'image',
19
- 'port',
20
- 'containerArgs',
21
- 'targetPorts',
22
- 'domains',
23
- 'publicPortMappings',
24
- 'envVars',
25
- 'volumes',
26
- 'storageClasses',
27
- 'storageRequests',
28
- 'publishedPorts',
29
- 'platformRequirements',
30
- 'platformOidc',
31
- 'minOneboxVersion',
32
- 'minCloudlyVersion',
33
- 'appStoreVersion',
34
- 'upgradeStrategy',
35
- 'source',
36
- 'resolvedSource',
37
- 'resolvedImageDigest',
38
- 'changelog',
39
- 'breaking',
40
- 'requiresManualReview',
41
- 'migrationRequired',
42
- 'backupBeforeUpgrade',
43
- 'requiresFeatures',
44
- 'healthCheck',
45
- ];
46
- export function parseStorageCapacityQuantity(quantityArg, labelArg = 'storage capacity') {
47
- if (typeof quantityArg !== 'string' || quantityArg.length > 64) {
48
- throw new Error(`Invalid ${labelArg}: expected a positive integer followed by KiB, MiB, GiB, or TiB`);
6
+ const storageRequestIdPattern = /^[a-z][a-z0-9-]{0,62}$/;
7
+ const defaultLabel = 'appstore config';
8
+ /**
9
+ * Throws the first storage violation of a version config, judged by the interfaces contract
10
+ * (`appstore.validateAppStoreVersionStorage`), which owns every storage rule.
11
+ */
12
+ const assertValidStorage = (configArg, labelArg) => {
13
+ const errors = plugins.servezoneInterfaces.appstore.validateAppStoreVersionStorage(configArg, labelArg);
14
+ if (errors.length > 0)
15
+ throw new Error(errors.join('; '));
16
+ };
17
+ const normalizeVolumes = (volumesArg) => (volumesArg ?? []).map((volumeArg) => {
18
+ const volume = typeof volumeArg === 'string' ? { mountPath: volumeArg } : volumeArg;
19
+ return {
20
+ ...(volume.name === undefined ? {} : { name: volume.name }),
21
+ mountPath: volume.mountPath,
22
+ ...(volume.readOnly === undefined ? {} : { readOnly: volume.readOnly }),
23
+ ...(volume.backup === undefined ? {} : { backup: volume.backup }),
24
+ };
25
+ });
26
+ /** The stable request id a legacy volume becomes: its name, or its mount path flattened. */
27
+ const createLegacyVolumeRequestId = (volumeArg, indexArg, labelArg) => {
28
+ const stablePart = volumeArg.name || volumeArg.mountPath
29
+ .toLowerCase()
30
+ .split('/')
31
+ .filter(Boolean)
32
+ .join('-')
33
+ .replace(/[^a-z0-9-]+/g, '-')
34
+ .replace(/^-+|-+$/g, '');
35
+ const requestId = `legacy-volume-${stablePart}`;
36
+ if (!stablePart || !storageRequestIdPattern.test(requestId)) {
37
+ throw new Error(`Invalid ${labelArg} volumes[${indexArg}]: cannot derive a stable request id; declare a shorter lowercase name`);
49
38
  }
50
- const match = quantityArg.match(capacityPattern);
51
- if (!match) {
52
- throw new Error(`Invalid ${labelArg} '${quantityArg}': expected a positive integer followed by KiB, MiB, GiB, or TiB`);
39
+ return requestId;
40
+ };
41
+ const deriveRequiredFeatureIds = (explicitRequestsArg) => {
42
+ const required = [];
43
+ if (explicitRequestsArg.length > 0)
44
+ required.push(storageFeatureIds.bindings);
45
+ if (explicitRequestsArg.some((requestArg) => requestArg.kind === 'filesystem')) {
46
+ required.push(storageFeatureIds.filesystem);
53
47
  }
54
- // The storage contract reads a capacity quantity as a safe integer amount of its unit, so a
55
- // larger quantity names a request no adapter can be handed. This parser is the one place the
56
- // App Store reads a quantity, so the same bound is applied here rather than after a request has
57
- // already been assembled from it.
58
- if (!Number.isSafeInteger(Number(match[1]))) {
59
- throw new Error(`Invalid ${labelArg} '${quantityArg}': the quantity exceeds the safe integer range`);
48
+ if (explicitRequestsArg.some((requestArg) => requestArg.kind === 'objectStorage')) {
49
+ required.push(storageFeatureIds.objectStorage);
60
50
  }
61
- return BigInt(match[1]) * capacityMultipliers[match[2]];
62
- }
51
+ if (explicitRequestsArg.some((requestArg) => (requestArg.kind === 'objectStorage' && requestArg.delivery.type === 'file'))) {
52
+ required.push(storageFeatureIds.objectStorageFile);
53
+ }
54
+ return required;
55
+ };
63
56
  /**
64
- * Strict structural validation plus deterministic legacy normalization. This
65
- * does not claim that a runtime can fulfill explicit requests; installers must
66
- * call normalizeAppStoreStorageConfig with an advertised feature set.
57
+ * The legacy `volumes` of a version config in their object form (`{ name?, mountPath, readOnly?,
58
+ * backup? }`), after the config's storage passed the interfaces contract.
67
59
  */
68
- export function validateAppStoreStorageConfig(configArg, labelArg = 'appstore config') {
69
- return validateAndNormalizeStorageConfig(configArg, labelArg);
60
+ export function normalizeAppStoreVolumes(configArg, labelArg = defaultLabel) {
61
+ assertValidStorage(configArg, labelArg);
62
+ return normalizeVolumes(configArg.volumes);
70
63
  }
71
64
  /**
72
- * Canonical pre-fulfillment handoff. Explicit storage contracts fail closed
73
- * unless every derived storage feature is advertised by the target runtime.
65
+ * The canonical pre-fulfillment storage handoff of a version config.
66
+ *
67
+ * The config's storage is judged by the interfaces contract first. Legacy `volumes` become
68
+ * filesystem requests of the reserved `legacyFilesystem` class, `platformRequirements.s3` becomes
69
+ * the `legacy-s3` object-storage request, and explicit requests fail closed unless every storage
70
+ * feature they need is advertised by the target runtime.
74
71
  */
75
- export function normalizeAppStoreStorageConfig(configArg, optionsArg, labelArg = 'appstore config') {
76
- const normalized = validateAndNormalizeStorageConfig(configArg, labelArg);
77
- if (!optionsArg || optionsArg.supportedFeatures === undefined) {
78
- throw new Error(`Invalid ${labelArg}: supportedFeatures is required for storage feature negotiation`);
79
- }
80
- let supportedFeatures;
81
- try {
82
- supportedFeatures = new Set(optionsArg.supportedFeatures);
83
- }
84
- catch {
85
- throw new Error(`Invalid ${labelArg}: supportedFeatures must be iterable`);
86
- }
87
- const unsupportedFeatures = normalized.requiredFeatureIds.filter((featureIdArg) => !supportedFeatures.has(featureIdArg));
88
- if (unsupportedFeatures.length > 0) {
89
- throw new Error(`Unsupported ${labelArg} storage features: ${unsupportedFeatures.join(', ')}`);
90
- }
91
- return normalized;
92
- }
93
- function collectAppInputDestinations(configArg, labelArg) {
94
- const declaredEnvironmentKeys = new Set();
95
- const runtimeEnvironmentOwners = new Map();
96
- const secretFileOwners = new Map();
97
- const addDestination = (ownersArg, destinationArg, ownerArg, kindArg) => {
98
- const existingOwner = ownersArg.get(destinationArg);
99
- if (existingOwner) {
100
- throw new Error(`Invalid ${labelArg}: ${kindArg} destination '${destinationArg}' is used by both ${existingOwner} and ${ownerArg}`);
101
- }
102
- ownersArg.set(destinationArg, ownerArg);
103
- };
104
- for (const declaration of configArg.envVars || []) {
105
- declaredEnvironmentKeys.add(declaration.key);
106
- const owner = `envVars.${declaration.key}`;
107
- if (declaration.secret === true) {
108
- if (declaration.delivery.type === 'launcher-environment') {
109
- addDestination(runtimeEnvironmentOwners, declaration.delivery.variableName, owner, 'environment');
110
- }
111
- else {
112
- addDestination(secretFileOwners, declaration.delivery.targetPath, owner, 'secret file');
113
- }
114
- }
115
- else {
116
- addDestination(runtimeEnvironmentOwners, declaration.key, owner, 'environment');
117
- }
118
- }
119
- const platformOidc = configArg.platformOidc;
120
- if (platformOidc && typeof platformOidc === 'object' && !Array.isArray(platformOidc)) {
121
- const environmentVariables = platformOidc.environmentVariables;
122
- if (environmentVariables && typeof environmentVariables === 'object'
123
- && !Array.isArray(environmentVariables)) {
124
- for (const [field, destination] of Object.entries(environmentVariables)) {
125
- if (typeof destination === 'string') {
126
- addDestination(runtimeEnvironmentOwners, destination, `platformOidc.${field}`, 'environment');
127
- }
128
- }
129
- }
130
- }
131
- return {
132
- declaredEnvironmentKeys,
133
- runtimeEnvironmentKeys: new Set(runtimeEnvironmentOwners.keys()),
134
- declaredSecretPaths: new Set(secretFileOwners.keys()),
135
- };
136
- }
137
- function validateAndNormalizeStorageConfig(configArg, labelArg) {
138
- assertExactKeys(assertPlainRecord(configArg, labelArg), appStoreVersionConfigKeys, labelArg);
139
- const environmentErrors = interfaces.appstore.validateAppStoreEnvironmentDeclarations(configArg.envVars);
140
- if (environmentErrors.length > 0) {
141
- throw new Error(`Invalid ${labelArg}: ${environmentErrors.join('; ')}`);
142
- }
143
- const appInputDestinations = collectAppInputDestinations(configArg, labelArg);
144
- validatePlatformRequirements(configArg.platformRequirements, labelArg);
145
- const explicitClassInput = configArg.storageClasses;
146
- const explicitRequestInput = configArg.storageRequests;
147
- const hasExplicitClasses = explicitClassInput !== undefined;
148
- const hasExplicitRequests = explicitRequestInput !== undefined;
149
- if (hasExplicitClasses !== hasExplicitRequests) {
150
- throw new Error(`Invalid ${labelArg}: storageClasses and storageRequests must be declared together`);
151
- }
152
- const storageClasses = validateStorageClasses(explicitClassInput, labelArg);
153
- const explicitRequests = validateExplicitStorageRequests(explicitRequestInput, storageClasses, appInputDestinations, labelArg);
154
- const requiredFeatureIds = validateFeatureDeclaration(configArg, explicitRequests, labelArg);
155
- if (configArg.platformRequirements?.s3 && explicitRequests.some((requestArg) => requestArg.kind === 'objectStorage')) {
156
- throw new Error(`Invalid ${labelArg}: platformRequirements.s3 cannot coexist with explicit objectStorage requests`);
157
- }
72
+ export function normalizeAppStoreStorageConfig(configArg, optionsArg, labelArg = defaultLabel) {
73
+ assertValidStorage(configArg, labelArg);
74
+ const storageClasses = structuredClone(configArg.storageClasses ?? {});
75
+ const explicitRequests = structuredClone(configArg.storageRequests ?? []);
158
76
  const storageRequests = [...explicitRequests];
159
- const requestOriginEntries = explicitRequests.map((requestArg) => [requestArg.id, 'explicit']);
160
- const requestIds = new Set(explicitRequests.map((requestArg) => requestArg.id));
161
- const mountPaths = explicitRequests
162
- .filter((requestArg) => (requestArg.kind === 'filesystem'))
163
- .map((requestArg) => requestArg.mountPath);
164
- const legacyVolumes = normalizeLegacyVolumes(configArg.volumes, labelArg);
77
+ const requestOrigins = {};
78
+ for (const request of explicitRequests)
79
+ requestOrigins[request.id] = 'explicit';
80
+ const requiredFeatureIds = deriveRequiredFeatureIds(explicitRequests);
81
+ const legacyVolumes = normalizeVolumes(configArg.volumes);
165
82
  if (legacyVolumes.length > 0) {
166
- if (Object.hasOwn(storageClasses, legacyFilesystemClassKey)) {
167
- throw new Error(`Invalid ${labelArg}: storageClasses key '${legacyFilesystemClassKey}' is reserved for legacy volume normalization`);
168
- }
169
83
  storageClasses[legacyFilesystemClassKey] = {
170
84
  kind: 'filesystem',
171
85
  purpose: 'runtime',
172
86
  required: {
173
87
  durability: 'persistent',
174
- ...(legacyVolumes.some((volumeArg) => volumeArg.backup !== false)
175
- ? { backup: true }
176
- : {}),
88
+ ...(legacyVolumes.some((volumeArg) => volumeArg.backup !== false) ? { backup: true } : {}),
177
89
  },
178
90
  };
179
91
  }
180
- for (const [indexArg, volumeArg] of legacyVolumes.entries()) {
92
+ legacyVolumes.forEach((volumeArg, indexArg) => {
181
93
  const requestId = createLegacyVolumeRequestId(volumeArg, indexArg, labelArg);
182
- if (requestIds.has(requestId)) {
183
- throw new Error(`Invalid ${labelArg}: storage request id '${requestId}' is duplicated`);
184
- }
185
- assertNoPathCollision(volumeArg.mountPath, mountPaths, `${labelArg} legacy volume ${indexArg + 1}`);
186
- requestIds.add(requestId);
187
- mountPaths.push(volumeArg.mountPath);
188
94
  storageRequests.push({
189
95
  id: requestId,
190
96
  kind: 'filesystem',
@@ -194,16 +100,10 @@ function validateAndNormalizeStorageConfig(configArg, labelArg) {
194
100
  reclaimPolicy: 'retain',
195
101
  ...(volumeArg.backup === false ? {} : { protection: { backup: 'required' } }),
196
102
  });
197
- requestOriginEntries.push([requestId, 'legacyVolume']);
198
- }
103
+ requestOrigins[requestId] = 'legacyVolume';
104
+ });
199
105
  let legacyCompatibility;
200
106
  if (configArg.platformRequirements?.s3) {
201
- if (Object.hasOwn(storageClasses, legacyObjectStorageClassKey)) {
202
- throw new Error(`Invalid ${labelArg}: storageClasses key '${legacyObjectStorageClassKey}' is reserved for legacy S3 normalization`);
203
- }
204
- if (requestIds.has(legacyObjectStorageRequestId)) {
205
- throw new Error(`Invalid ${labelArg}: storage request id '${legacyObjectStorageRequestId}' is reserved for legacy S3 normalization`);
206
- }
207
107
  storageClasses[legacyObjectStorageClassKey] = {
208
108
  kind: 'objectStorage',
209
109
  purpose: 'runtime',
@@ -226,7 +126,7 @@ function validateAndNormalizeStorageConfig(configArg, labelArg) {
226
126
  },
227
127
  },
228
128
  });
229
- requestOriginEntries.push([legacyObjectStorageRequestId, 'legacyS3']);
129
+ requestOrigins[legacyObjectStorageRequestId] = 'legacyS3';
230
130
  legacyCompatibility = {
231
131
  objectStorage: {
232
132
  requestId: legacyObjectStorageRequestId,
@@ -235,493 +135,17 @@ function validateAndNormalizeStorageConfig(configArg, labelArg) {
235
135
  },
236
136
  };
237
137
  }
238
- validateAllFilesystemMountsAndSecretTargets(storageRequests, appInputDestinations.declaredSecretPaths, labelArg);
138
+ const supportedFeatures = new Set(optionsArg.supportedFeatures);
139
+ const unsupportedFeatures = requiredFeatureIds.filter((featureIdArg) => !supportedFeatures.has(featureIdArg));
140
+ if (unsupportedFeatures.length > 0) {
141
+ throw new Error(`Unsupported ${labelArg} storage features: ${unsupportedFeatures.join(', ')}`);
142
+ }
239
143
  return {
240
144
  storageClasses,
241
145
  storageRequests,
242
- requestOrigins: Object.fromEntries(requestOriginEntries),
146
+ requestOrigins,
243
147
  requiredFeatureIds,
244
148
  ...(legacyCompatibility ? { legacyCompatibility } : {}),
245
149
  };
246
150
  }
247
- function validateStorageClasses(classesArg, labelArg) {
248
- if (classesArg === undefined)
249
- return {};
250
- const classesRecord = assertPlainRecord(classesArg, `${labelArg} storageClasses`);
251
- const entries = Object.entries(classesRecord);
252
- if (entries.length === 0 || entries.length > 64) {
253
- throw new Error(`Invalid ${labelArg}: storageClasses must contain between 1 and 64 entries`);
254
- }
255
- const normalizedEntries = entries.map(([classKeyArg, candidateArg]) => {
256
- if (!storageClassKeyPattern.test(classKeyArg)) {
257
- throw new Error(`Invalid ${labelArg}: storage class key '${classKeyArg}' is not stable`);
258
- }
259
- const classLabel = `${labelArg} storageClasses.${classKeyArg}`;
260
- const candidate = assertPlainRecord(candidateArg, classLabel);
261
- assertExactKeys(candidate, ['kind', 'purpose', 'required', 'preferred'], classLabel);
262
- if (!['filesystem', 'objectStorage'].includes(candidate.kind)) {
263
- throw new Error(`Invalid ${classLabel}: kind must be filesystem or objectStorage`);
264
- }
265
- if (!['runtime', 'database', 'registry', 'backup'].includes(candidate.purpose)) {
266
- throw new Error(`Invalid ${classLabel}: purpose is not supported`);
267
- }
268
- const required = validateClassRequirement(candidate.required, `${classLabel}.required`);
269
- const preferred = validateClassRequirement(candidate.preferred, `${classLabel}.preferred`);
270
- if (required && preferred) {
271
- for (const requirementKey of Object.keys(required)) {
272
- if (preferred[requirementKey] !== undefined
273
- && preferred[requirementKey] !== required[requirementKey]) {
274
- throw new Error(`Invalid ${classLabel}: preferred.${String(requirementKey)} conflicts with required.${String(requirementKey)}`);
275
- }
276
- }
277
- }
278
- const normalized = {
279
- kind: candidate.kind,
280
- purpose: candidate.purpose,
281
- ...(required ? { required } : {}),
282
- ...(preferred ? { preferred } : {}),
283
- };
284
- return [classKeyArg, normalized];
285
- });
286
- return Object.fromEntries(normalizedEntries);
287
- }
288
- function validateClassRequirement(requirementArg, labelArg) {
289
- if (requirementArg === undefined)
290
- return undefined;
291
- const requirement = assertPlainRecord(requirementArg, labelArg);
292
- assertExactKeys(requirement, [
293
- 'performanceTier',
294
- 'durability',
295
- 'topology',
296
- 'hardQuota',
297
- 'snapshots',
298
- 'backup',
299
- 'encryptedInTransit',
300
- ], labelArg);
301
- assertOptionalMember(requirement.performanceTier, ['standard', 'highIops', 'capacity'], `${labelArg}.performanceTier`);
302
- assertOptionalMember(requirement.durability, ['ephemeral', 'persistent'], `${labelArg}.durability`);
303
- assertOptionalMember(requirement.topology, ['singleNode', 'multiNode'], `${labelArg}.topology`);
304
- assertOptionalMember(requirement.snapshots, ['portable', 'native'], `${labelArg}.snapshots`);
305
- for (const booleanKey of ['hardQuota', 'backup', 'encryptedInTransit']) {
306
- if (requirement[booleanKey] !== undefined && requirement[booleanKey] !== true) {
307
- throw new Error(`Invalid ${labelArg}.${booleanKey}: only true may be declared`);
308
- }
309
- }
310
- return { ...requirement };
311
- }
312
- function validateExplicitStorageRequests(requestsArg, classesArg, appInputDestinationsArg, labelArg) {
313
- if (requestsArg === undefined)
314
- return [];
315
- if (!Array.isArray(requestsArg) || requestsArg.length === 0 || requestsArg.length > 64) {
316
- throw new Error(`Invalid ${labelArg}: storageRequests must contain between 1 and 64 entries`);
317
- }
318
- const requestIds = new Set();
319
- const usedClassKeys = new Set();
320
- const deliveryEnvironmentKeys = new Set();
321
- const { declaredEnvironmentKeys, runtimeEnvironmentKeys, declaredSecretPaths, } = appInputDestinationsArg;
322
- const deliverySecretPaths = new Set();
323
- const requests = requestsArg.map((candidateArg, indexArg) => {
324
- const requestLabel = `${labelArg} storageRequests[${indexArg}]`;
325
- const candidate = assertPlainRecord(candidateArg, requestLabel);
326
- if (candidate.kind === 'filesystem') {
327
- assertExactKeys(candidate, [
328
- 'id', 'kind', 'storageClass', 'capacity', 'reclaimPolicy',
329
- 'mountPath', 'accessMode', 'protection',
330
- ], requestLabel);
331
- }
332
- else if (candidate.kind === 'objectStorage') {
333
- assertExactKeys(candidate, [
334
- 'id', 'kind', 'storageClass', 'capacity', 'reclaimPolicy',
335
- 'accessMode', 'delivery', 'protection',
336
- ], requestLabel);
337
- }
338
- else {
339
- throw new Error(`Invalid ${requestLabel}: kind must be filesystem or objectStorage`);
340
- }
341
- if (typeof candidate.id !== 'string' || !storageRequestIdPattern.test(candidate.id)) {
342
- throw new Error(`Invalid ${requestLabel}: id must be a stable lowercase identifier`);
343
- }
344
- if (requestIds.has(candidate.id)) {
345
- throw new Error(`Invalid ${labelArg}: storage request id '${candidate.id}' is duplicated`);
346
- }
347
- requestIds.add(candidate.id);
348
- if (typeof candidate.storageClass !== 'string'
349
- || !Object.hasOwn(classesArg, candidate.storageClass)) {
350
- throw new Error(`Invalid ${requestLabel}: storageClass '${candidate.storageClass}' is not declared`);
351
- }
352
- const storageClass = classesArg[candidate.storageClass];
353
- if (storageClass.kind !== candidate.kind) {
354
- throw new Error(`Invalid ${requestLabel}: storageClass kind does not match request kind`);
355
- }
356
- usedClassKeys.add(candidate.storageClass);
357
- if (!['retain', 'delete'].includes(candidate.reclaimPolicy)) {
358
- throw new Error(`Invalid ${requestLabel}: reclaimPolicy must be retain or delete`);
359
- }
360
- const capacity = validateCapacity(candidate.capacity, `${requestLabel}.capacity`);
361
- if (capacity?.limit && storageClass.required?.hardQuota !== true) {
362
- throw new Error(`Invalid ${requestLabel}: capacity.limit requires storageClass.required.hardQuota`);
363
- }
364
- if (candidate.kind === 'filesystem') {
365
- if (typeof candidate.mountPath !== 'string'
366
- || interfaces.data.normalizeServiceAbsolutePath(candidate.mountPath) !== candidate.mountPath
367
- || candidate.mountPath === '/'
368
- || pathsOverlap(candidate.mountPath, '/run/secrets')) {
369
- throw new Error(`Invalid ${requestLabel}: mountPath must be a canonical non-root path outside /run/secrets`);
370
- }
371
- assertOptionalMember(candidate.accessMode, ['ReadWriteOnce', 'ReadOnlyMany', 'ReadWriteMany'], `${requestLabel}.accessMode`, false);
372
- const protection = validateFilesystemProtection(candidate.protection, `${requestLabel}.protection`);
373
- if (protection?.backup === 'required' && storageClass.required?.backup !== true) {
374
- throw new Error(`Invalid ${requestLabel}: required backup must be declared by the storage class`);
375
- }
376
- if (protection?.snapshots && storageClass.required?.snapshots !== protection.snapshots) {
377
- throw new Error(`Invalid ${requestLabel}: required snapshots must be declared by the storage class`);
378
- }
379
- return {
380
- id: candidate.id,
381
- kind: 'filesystem',
382
- storageClass: candidate.storageClass,
383
- ...(capacity ? { capacity } : {}),
384
- reclaimPolicy: candidate.reclaimPolicy,
385
- mountPath: candidate.mountPath,
386
- accessMode: candidate.accessMode,
387
- ...(protection ? { protection } : {}),
388
- };
389
- }
390
- assertOptionalMember(candidate.accessMode, ['readOnly', 'readWrite'], `${requestLabel}.accessMode`, false);
391
- const delivery = validateObjectStorageDelivery(candidate.delivery, requestLabel, declaredEnvironmentKeys, runtimeEnvironmentKeys, deliveryEnvironmentKeys, declaredSecretPaths, deliverySecretPaths);
392
- const protection = validateObjectStorageProtection(candidate.protection, `${requestLabel}.protection`);
393
- if (protection?.backup === 'required' && storageClass.required?.backup !== true) {
394
- throw new Error(`Invalid ${requestLabel}: required backup must be declared by the storage class`);
395
- }
396
- return {
397
- id: candidate.id,
398
- kind: 'objectStorage',
399
- storageClass: candidate.storageClass,
400
- ...(capacity ? { capacity } : {}),
401
- reclaimPolicy: candidate.reclaimPolicy,
402
- accessMode: candidate.accessMode,
403
- delivery,
404
- ...(protection ? { protection } : {}),
405
- };
406
- });
407
- for (const classKeyArg of Object.keys(classesArg)) {
408
- if (!usedClassKeys.has(classKeyArg)) {
409
- throw new Error(`Invalid ${labelArg}: storage class '${classKeyArg}' is not used by a request`);
410
- }
411
- }
412
- return requests;
413
- }
414
- function validateCapacity(capacityArg, labelArg) {
415
- if (capacityArg === undefined)
416
- return undefined;
417
- const capacity = assertPlainRecord(capacityArg, labelArg);
418
- assertExactKeys(capacity, ['request', 'limit'], labelArg);
419
- const requestedBytes = parseStorageCapacityQuantity(capacity.request, `${labelArg}.request`);
420
- const limitBytes = capacity.limit === undefined
421
- ? undefined
422
- : parseStorageCapacityQuantity(capacity.limit, `${labelArg}.limit`);
423
- if (limitBytes !== undefined && limitBytes < requestedBytes) {
424
- throw new Error(`Invalid ${labelArg}: limit must be greater than or equal to request`);
425
- }
426
- return {
427
- request: capacity.request,
428
- ...(capacity.limit === undefined ? {} : { limit: capacity.limit }),
429
- };
430
- }
431
- /**
432
- * An absent `protection` member already states that the request asks for no protection, so an
433
- * empty one states nothing a fulfillment adapter could act on. The storage contract refuses it by
434
- * name (`protection must not be empty`), and this package is the producer of those requests: the
435
- * manifest author is told here instead of a control plane refusing the request later. Members are
436
- * copied one by one rather than spread, so a member declared as an explicit `undefined` — which
437
- * the member checks treat as absent, and which the contract refuses as a non-JSON data property —
438
- * can never reach the emitted request.
439
- */
440
- function assertProtectionDeclaresRequirement(protectionArg, labelArg) {
441
- if (Object.keys(protectionArg).length === 0) {
442
- throw new Error(`Invalid ${labelArg}: declare at least one protection requirement or omit protection`);
443
- }
444
- return protectionArg;
445
- }
446
- function validateFilesystemProtection(protectionArg, labelArg) {
447
- if (protectionArg === undefined)
448
- return undefined;
449
- const protection = assertPlainRecord(protectionArg, labelArg);
450
- assertExactKeys(protection, ['backup', 'snapshots', 'consistency'], labelArg);
451
- assertOptionalMember(protection.backup, ['required'], `${labelArg}.backup`);
452
- assertOptionalMember(protection.snapshots, ['portable', 'native'], `${labelArg}.snapshots`);
453
- assertOptionalMember(protection.consistency, ['crashConsistent', 'applicationConsistent'], `${labelArg}.consistency`);
454
- return assertProtectionDeclaresRequirement({
455
- ...(protection.backup === undefined
456
- ? {}
457
- : { backup: protection.backup }),
458
- ...(protection.snapshots === undefined
459
- ? {}
460
- : { snapshots: protection.snapshots }),
461
- ...(protection.consistency === undefined
462
- ? {}
463
- : { consistency: protection.consistency }),
464
- }, labelArg);
465
- }
466
- function validateObjectStorageProtection(protectionArg, labelArg) {
467
- if (protectionArg === undefined)
468
- return undefined;
469
- const protection = assertPlainRecord(protectionArg, labelArg);
470
- assertExactKeys(protection, ['backup', 'versioning', 'retentionDays'], labelArg);
471
- assertOptionalMember(protection.backup, ['required'], `${labelArg}.backup`);
472
- assertOptionalMember(protection.versioning, ['required'], `${labelArg}.versioning`);
473
- if (protection.retentionDays !== undefined
474
- && (!Number.isInteger(protection.retentionDays)
475
- || protection.retentionDays < 1
476
- || protection.retentionDays > 36500)) {
477
- throw new Error(`Invalid ${labelArg}.retentionDays: expected an integer between 1 and 36500`);
478
- }
479
- return assertProtectionDeclaresRequirement({
480
- ...(protection.backup === undefined
481
- ? {}
482
- : { backup: protection.backup }),
483
- ...(protection.versioning === undefined
484
- ? {}
485
- : { versioning: protection.versioning }),
486
- ...(protection.retentionDays === undefined
487
- ? {}
488
- : { retentionDays: protection.retentionDays }),
489
- }, labelArg);
490
- }
491
- function validateObjectStorageDelivery(deliveryArg, requestLabelArg, declaredEnvironmentKeysArg, runtimeEnvironmentKeysArg, deliveryEnvironmentKeysArg, declaredSecretPathsArg, deliverySecretPathsArg) {
492
- const deliveryLabel = `${requestLabelArg}.delivery`;
493
- const delivery = assertPlainRecord(deliveryArg, deliveryLabel);
494
- if (delivery.type === 'launcher-environment') {
495
- assertExactKeys(delivery, ['type', 'keys'], deliveryLabel);
496
- const keys = assertPlainRecord(delivery.keys, `${deliveryLabel}.keys`);
497
- assertExactKeys(keys, [
498
- 'endpoint', 'bucket', 'region', 'accessKeyId', 'secretAccessKey', 'sessionToken',
499
- ], `${deliveryLabel}.keys`);
500
- for (const requiredKey of ['endpoint', 'bucket', 'region', 'accessKeyId', 'secretAccessKey']) {
501
- if (typeof keys[requiredKey] !== 'string') {
502
- throw new Error(`Invalid ${deliveryLabel}.keys: '${requiredKey}' is required`);
503
- }
504
- }
505
- const targetKeys = Object.values(keys);
506
- const localKeys = new Set();
507
- for (const targetKeyArg of targetKeys) {
508
- if (typeof targetKeyArg !== 'string' || !environmentKeyPattern.test(targetKeyArg)) {
509
- throw new Error(`Invalid ${deliveryLabel}: environment delivery keys must be canonical`);
510
- }
511
- if (localKeys.has(targetKeyArg)) {
512
- throw new Error(`Invalid ${deliveryLabel}: environment key '${targetKeyArg}' is duplicated`);
513
- }
514
- if (declaredEnvironmentKeysArg.has(targetKeyArg)
515
- || runtimeEnvironmentKeysArg.has(targetKeyArg)) {
516
- throw new Error(`Invalid ${deliveryLabel}: environment key '${targetKeyArg}' collides with an app runtime input`);
517
- }
518
- if (deliveryEnvironmentKeysArg.has(targetKeyArg)) {
519
- throw new Error(`Invalid ${deliveryLabel}: environment key '${targetKeyArg}' is used by another storage request`);
520
- }
521
- localKeys.add(targetKeyArg);
522
- deliveryEnvironmentKeysArg.add(targetKeyArg);
523
- }
524
- return {
525
- type: 'launcher-environment',
526
- keys: { ...keys },
527
- };
528
- }
529
- if (delivery.type === 'file') {
530
- assertExactKeys(delivery, ['type', 'targetPath', 'format', 'uid', 'gid', 'mode'], deliveryLabel);
531
- if (delivery.format !== 'servezone-object-storage') {
532
- throw new Error(`Invalid ${deliveryLabel}: secret file format is not supported`);
533
- }
534
- if (typeof delivery.targetPath !== 'string'
535
- || interfaces.data.normalizeServiceAbsolutePath(delivery.targetPath) !== delivery.targetPath
536
- || !/^\/run\/secrets\/[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(delivery.targetPath)) {
537
- throw new Error(`Invalid ${deliveryLabel}: targetPath must be a unique canonical file below /run/secrets`);
538
- }
539
- if (declaredSecretPathsArg.has(delivery.targetPath)) {
540
- throw new Error(`Invalid ${deliveryLabel}: targetPath collides with an app secret delivery`);
541
- }
542
- if (deliverySecretPathsArg.has(delivery.targetPath)) {
543
- throw new Error(`Invalid ${deliveryLabel}: targetPath is used by another storage request`);
544
- }
545
- // `-0` survives JSON.parse and passes both the safe-integer and the range check, but the
546
- // storage contract refuses it because it is a second spelling of the same identity and would
547
- // give one request two canonical digests.
548
- for (const identityField of ['uid', 'gid']) {
549
- if (!Number.isSafeInteger(delivery[identityField])
550
- || Object.is(delivery[identityField], -0)
551
- || delivery[identityField] < 0
552
- || delivery[identityField] > 2_147_483_647) {
553
- throw new Error(`Invalid ${deliveryLabel}: ${identityField} must be a bounded numeric identity`);
554
- }
555
- }
556
- if (delivery.mode !== 0o400 && delivery.mode !== 0o440) {
557
- throw new Error(`Invalid ${deliveryLabel}: mode must be 0400 or 0440`);
558
- }
559
- deliverySecretPathsArg.add(delivery.targetPath);
560
- return {
561
- type: 'file',
562
- targetPath: delivery.targetPath,
563
- format: 'servezone-object-storage',
564
- uid: delivery.uid,
565
- gid: delivery.gid,
566
- mode: delivery.mode,
567
- };
568
- }
569
- throw new Error(`Invalid ${deliveryLabel}: type must be launcher-environment or file`);
570
- }
571
- function validateFeatureDeclaration(configArg, explicitRequestsArg, labelArg) {
572
- const requiredFeatures = new Set();
573
- if (explicitRequestsArg.length > 0) {
574
- requiredFeatures.add(storageFeatureIds.bindings);
575
- }
576
- if (explicitRequestsArg.some((requestArg) => requestArg.kind === 'filesystem')) {
577
- requiredFeatures.add(storageFeatureIds.filesystem);
578
- }
579
- if (explicitRequestsArg.some((requestArg) => requestArg.kind === 'objectStorage')) {
580
- requiredFeatures.add(storageFeatureIds.objectStorage);
581
- }
582
- if (explicitRequestsArg.some((requestArg) => (requestArg.kind === 'objectStorage' && requestArg.delivery.type === 'file'))) {
583
- requiredFeatures.add(storageFeatureIds.objectStorageFile);
584
- }
585
- const declaredFeatures = configArg.requiresFeatures || [];
586
- if (!Array.isArray(declaredFeatures)
587
- || declaredFeatures.some((entryArg) => typeof entryArg !== 'string')) {
588
- throw new Error(`Invalid ${labelArg}: requiresFeatures must be an array of strings`);
589
- }
590
- if (new Set(declaredFeatures).size !== declaredFeatures.length) {
591
- throw new Error(`Invalid ${labelArg}: requiresFeatures must not contain duplicates`);
592
- }
593
- for (const requiredFeature of requiredFeatures) {
594
- if (!declaredFeatures.includes(requiredFeature)) {
595
- throw new Error(`Invalid ${labelArg}: requiresFeatures is missing '${requiredFeature}'`);
596
- }
597
- }
598
- for (const declaredFeature of declaredFeatures) {
599
- if (declaredFeature.startsWith('storage.') && !knownStorageFeatureIds.has(declaredFeature)) {
600
- throw new Error(`Invalid ${labelArg}: unknown storage feature '${declaredFeature}'`);
601
- }
602
- if (knownStorageFeatureIds.has(declaredFeature)
603
- && !requiredFeatures.has(declaredFeature)) {
604
- throw new Error(`Invalid ${labelArg}: storage feature '${declaredFeature}' is not used`);
605
- }
606
- }
607
- return Array.from(requiredFeatures);
608
- }
609
- function validatePlatformRequirements(requirementsArg, labelArg) {
610
- if (requirementsArg === undefined)
611
- return;
612
- const requirements = assertPlainRecord(requirementsArg, `${labelArg} platformRequirements`);
613
- assertExactKeys(requirements, ['mongodb', 's3', 'clickhouse', 'valkey', 'mariadb', 'mail'], `${labelArg} platformRequirements`);
614
- for (const [keyArg, valueArg] of Object.entries(requirements)) {
615
- if (typeof valueArg !== 'boolean') {
616
- throw new Error(`Invalid ${labelArg} platformRequirements.${keyArg}: expected a boolean`);
617
- }
618
- }
619
- }
620
- function normalizeLegacyVolumes(volumesArg, labelArg) {
621
- if (volumesArg === undefined)
622
- return [];
623
- if (!Array.isArray(volumesArg) || volumesArg.length > 64) {
624
- throw new Error(`Invalid ${labelArg}: volumes must be an array with at most 64 entries`);
625
- }
626
- return volumesArg.map((volumeArg, indexArg) => {
627
- const volumeLabel = `${labelArg} volumes[${indexArg}]`;
628
- const normalized = typeof volumeArg === 'string'
629
- ? { mountPath: volumeArg }
630
- : assertPlainRecord(volumeArg, volumeLabel);
631
- assertExactKeys(normalized, ['name', 'source', 'mountPath', 'driver', 'readOnly', 'backup', 'options'], volumeLabel);
632
- for (const forbiddenKey of ['source', 'driver', 'options']) {
633
- if (normalized[forbiddenKey] !== undefined) {
634
- throw new Error(`Invalid ${volumeLabel}: physical field '${forbiddenKey}' cannot be normalized portably`);
635
- }
636
- }
637
- if (typeof normalized.mountPath !== 'string'
638
- || interfaces.data.normalizeServiceAbsolutePath(normalized.mountPath) !== normalized.mountPath
639
- || normalized.mountPath === '/'
640
- || pathsOverlap(normalized.mountPath, '/run/secrets')) {
641
- throw new Error(`Invalid ${volumeLabel}: mountPath must be a canonical non-root path outside /run/secrets`);
642
- }
643
- if (normalized.name !== undefined
644
- && (typeof normalized.name !== 'string' || !storageRequestIdPattern.test(normalized.name))) {
645
- throw new Error(`Invalid ${volumeLabel}: name must be a stable lowercase identifier`);
646
- }
647
- for (const booleanKey of ['readOnly', 'backup']) {
648
- if (normalized[booleanKey] !== undefined && typeof normalized[booleanKey] !== 'boolean') {
649
- throw new Error(`Invalid ${volumeLabel}.${booleanKey}: expected a boolean`);
650
- }
651
- }
652
- return {
653
- ...(normalized.name === undefined ? {} : { name: normalized.name }),
654
- mountPath: normalized.mountPath,
655
- ...(normalized.readOnly === undefined ? {} : { readOnly: normalized.readOnly }),
656
- ...(normalized.backup === undefined ? {} : { backup: normalized.backup }),
657
- };
658
- });
659
- }
660
- function createLegacyVolumeRequestId(volumeArg, indexArg, labelArg) {
661
- const stablePart = volumeArg.name || volumeArg.mountPath
662
- .toLowerCase()
663
- .split('/')
664
- .filter(Boolean)
665
- .join('-')
666
- .replace(/[^a-z0-9-]+/g, '-')
667
- .replace(/^-+|-+$/g, '');
668
- const requestId = `legacy-volume-${stablePart}`;
669
- if (!stablePart || !storageRequestIdPattern.test(requestId)) {
670
- throw new Error(`Invalid ${labelArg} volumes[${indexArg}]: cannot derive a stable request id; declare a shorter lowercase name`);
671
- }
672
- return requestId;
673
- }
674
- function validateAllFilesystemMountsAndSecretTargets(requestsArg, declaredSecretPathsArg, labelArg) {
675
- const mountPaths = [];
676
- const objectSecretPaths = [];
677
- for (const requestArg of requestsArg) {
678
- if (requestArg.kind === 'filesystem') {
679
- assertNoPathCollision(requestArg.mountPath, mountPaths, `${labelArg} request '${requestArg.id}'`);
680
- mountPaths.push(requestArg.mountPath);
681
- }
682
- else if (requestArg.delivery.type === 'file') {
683
- objectSecretPaths.push(requestArg.delivery.targetPath);
684
- }
685
- }
686
- for (const secretPathArg of [...declaredSecretPathsArg, ...objectSecretPaths]) {
687
- if (mountPaths.some((mountPathArg) => pathsOverlap(secretPathArg, mountPathArg))) {
688
- throw new Error(`Invalid ${labelArg}: secret target '${secretPathArg}' overlaps a filesystem mount`);
689
- }
690
- }
691
- }
692
- function assertNoPathCollision(pathArg, pathsArg, labelArg) {
693
- const collision = pathsArg.find((existingPathArg) => pathsOverlap(pathArg, existingPathArg));
694
- if (collision) {
695
- throw new Error(`Invalid ${labelArg}: path '${pathArg}' overlaps '${collision}'`);
696
- }
697
- }
698
- function pathsOverlap(leftArg, rightArg) {
699
- const left = interfaces.data.normalizeServiceAbsolutePath(leftArg);
700
- const right = interfaces.data.normalizeServiceAbsolutePath(rightArg);
701
- if (!left || !right)
702
- return false;
703
- if (left === '/' || right === '/')
704
- return true;
705
- return left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`);
706
- }
707
- function assertPlainRecord(valueArg, labelArg) {
708
- if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg)) {
709
- throw new Error(`Invalid ${labelArg}: expected an object`);
710
- }
711
- return valueArg;
712
- }
713
- function assertExactKeys(recordArg, allowedKeysArg, labelArg) {
714
- const allowedKeys = new Set(allowedKeysArg);
715
- const unknownKeys = Object.keys(recordArg).filter((keyArg) => !allowedKeys.has(keyArg));
716
- if (unknownKeys.length > 0) {
717
- throw new Error(`Invalid ${labelArg}: unknown field(s) ${unknownKeys.sort().join(', ')}`);
718
- }
719
- }
720
- function assertOptionalMember(valueArg, allowedValuesArg, labelArg, optionalArg = true) {
721
- if (valueArg === undefined && optionalArg)
722
- return;
723
- if (typeof valueArg !== 'string' || !allowedValuesArg.includes(valueArg)) {
724
- throw new Error(`Invalid ${labelArg}: expected one of ${allowedValuesArg.join(', ')}`);
725
- }
726
- }
727
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX2NsaWVudC9zdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFTckQsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDO0FBQ3hFLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxHQUFHLENBQVMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7QUFDakYsTUFBTSxzQkFBc0IsR0FBRyw4QkFBOEIsQ0FBQztBQUM5RCxNQUFNLHVCQUF1QixHQUFHLHdCQUF3QixDQUFDO0FBQ3pELE1BQU0scUJBQXFCLEdBQUcsMEJBQTBCLENBQUM7QUFDekQsTUFBTSxlQUFlLEdBQUcsa0NBQWtDLENBQUM7QUFDM0QsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixHQUFHLEVBQUUsS0FBSztJQUNWLEdBQUcsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNoQixHQUFHLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDaEIsR0FBRyxFQUFFLEtBQUssSUFBSSxFQUFFO0NBQ1IsQ0FBQztBQUNYLE1BQU0sd0JBQXdCLEdBQUcsa0JBQWtCLENBQUM7QUFDcEQsTUFBTSwyQkFBMkIsR0FBRyxxQkFBcUIsQ0FBQztBQUMxRCxNQUFNLDRCQUE0QixHQUFHLFdBQVcsQ0FBQztBQUNqRCxNQUFNLHlCQUF5QixHQUFHO0lBQ2hDLE9BQU87SUFDUCxNQUFNO0lBQ04sZUFBZTtJQUNmLGFBQWE7SUFDYixTQUFTO0lBQ1Qsb0JBQW9CO0lBQ3BCLFNBQVM7SUFDVCxTQUFTO0lBQ1QsZ0JBQWdCO0lBQ2hCLGlCQUFpQjtJQUNqQixnQkFBZ0I7SUFDaEIsc0JBQXNCO0lBQ3RCLGNBQWM7SUFDZCxrQkFBa0I7SUFDbEIsbUJBQW1CO0lBQ25CLGlCQUFpQjtJQUNqQixpQkFBaUI7SUFDakIsUUFBUTtJQUNSLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsV0FBVztJQUNYLFVBQVU7SUFDVixzQkFBc0I7SUFDdEIsbUJBQW1CO0lBQ25CLHFCQUFxQjtJQUNyQixrQkFBa0I7SUFDbEIsYUFBYTtDQUNMLENBQUM7QUFVWCxNQUFNLFVBQVUsNEJBQTRCLENBQzFDLFdBQW9CLEVBQ3BCLFFBQVEsR0FBRyxrQkFBa0I7SUFFN0IsSUFBSSxPQUFPLFdBQVcsS0FBSyxRQUFRLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUMvRCxNQUFNLElBQUksS0FBSyxDQUNiLFdBQVcsUUFBUSxpRUFBaUUsQ0FDckYsQ0FBQztJQUNKLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxRQUFRLEtBQUssV0FBVyxrRUFBa0UsQ0FDdEcsQ0FBQztJQUNKLENBQUM7SUFDRCw0RkFBNEY7SUFDNUYsNkZBQTZGO0lBQzdGLGdHQUFnRztJQUNoRyxrQ0FBa0M7SUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM1QyxNQUFNLElBQUksS0FBSyxDQUNiLFdBQVcsUUFBUSxLQUFLLFdBQVcsZ0RBQWdELENBQ3BGLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBcUMsQ0FBQyxDQUFDO0FBQzlGLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLDZCQUE2QixDQUMzQyxTQUFpQyxFQUNqQyxRQUFRLEdBQUcsaUJBQWlCO0lBRTVCLE9BQU8saUNBQWlDLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsOEJBQThCLENBQzVDLFNBQWlDLEVBQ2pDLFVBQWdELEVBQ2hELFFBQVEsR0FBRyxpQkFBaUI7SUFFNUIsTUFBTSxVQUFVLEdBQUcsaUNBQWlDLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFFLElBQUksQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLGlCQUFpQixLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLGlFQUFpRSxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVELElBQUksaUJBQThCLENBQUM7SUFDbkMsSUFBSSxDQUFDO1FBQ0gsaUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLHNDQUFzQyxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUNELE1BQU0sbUJBQW1CLEdBQUcsVUFBVSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FDOUQsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUN2RCxDQUFDO0lBQ0YsSUFBSSxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDbkMsTUFBTSxJQUFJLEtBQUssQ0FDYixlQUFlLFFBQVEsc0JBQXNCLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUM5RSxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLDJCQUEyQixDQUNsQyxTQUFpQyxFQUNqQyxRQUFnQjtJQUVoQixNQUFNLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDbEQsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUMzRCxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBRW5ELE1BQU0sY0FBYyxHQUFHLENBQ3JCLFNBQThCLEVBQzlCLGNBQXNCLEVBQ3RCLFFBQWdCLEVBQ2hCLE9BQXNDLEVBQ2hDLEVBQUU7UUFDUixNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3BELElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLFFBQVEsS0FBSyxPQUFPLGlCQUFpQixjQUFjLHFCQUFxQixhQUFhLFFBQVEsUUFBUSxFQUFFLENBQ25ILENBQUM7UUFDSixDQUFDO1FBQ0QsU0FBUyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUMsQ0FBQyxDQUFDO0lBRUYsS0FBSyxNQUFNLFdBQVcsSUFBSSxTQUFTLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ2xELHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0MsTUFBTSxLQUFLLEdBQUcsV0FBVyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0MsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2hDLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssc0JBQXNCLEVBQUUsQ0FBQztnQkFDekQsY0FBYyxDQUNaLHdCQUF3QixFQUN4QixXQUFXLENBQUMsUUFBUSxDQUFDLFlBQVksRUFDakMsS0FBSyxFQUNMLGFBQWEsQ0FDZCxDQUFDO1lBQ0osQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGNBQWMsQ0FDWixnQkFBZ0IsRUFDaEIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQy9CLEtBQUssRUFDTCxhQUFhLENBQ2QsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLGNBQWMsQ0FBQyx3QkFBd0IsRUFBRSxXQUFXLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztRQUNsRixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxZQUF1QixDQUFDO0lBQ3ZELElBQUksWUFBWSxJQUFJLE9BQU8sWUFBWSxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUNyRixNQUFNLG9CQUFvQixHQUFJLFlBQTZCLENBQUMsb0JBQW9CLENBQUM7UUFDakYsSUFBSSxvQkFBb0IsSUFBSSxPQUFPLG9CQUFvQixLQUFLLFFBQVE7ZUFDL0QsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQztZQUMxQyxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hFLElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7b0JBQ3BDLGNBQWMsQ0FDWix3QkFBd0IsRUFDeEIsV0FBVyxFQUNYLGdCQUFnQixLQUFLLEVBQUUsRUFDdkIsYUFBYSxDQUNkLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU87UUFDTCx1QkFBdUI7UUFDdkIsc0JBQXNCLEVBQUUsSUFBSSxHQUFHLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEUsbUJBQW1CLEVBQUUsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7S0FDdEQsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGlDQUFpQyxDQUN4QyxTQUFpQyxFQUNqQyxRQUFnQjtJQUVoQixlQUFlLENBQ2IsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxFQUN0Qyx5QkFBeUIsRUFDekIsUUFBUSxDQUNULENBQUM7SUFDRixNQUFNLGlCQUFpQixHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsdUNBQXVDLENBQ25GLFNBQVMsQ0FBQyxPQUFPLENBQ2xCLENBQUM7SUFDRixJQUFJLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxLQUFLLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUNELE1BQU0sb0JBQW9CLEdBQUcsMkJBQTJCLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzlFLDRCQUE0QixDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN2RSxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxjQUFjLENBQUM7SUFDcEQsTUFBTSxvQkFBb0IsR0FBRyxTQUFTLENBQUMsZUFBZSxDQUFDO0lBQ3ZELE1BQU0sa0JBQWtCLEdBQUcsa0JBQWtCLEtBQUssU0FBUyxDQUFDO0lBQzVELE1BQU0sbUJBQW1CLEdBQUcsb0JBQW9CLEtBQUssU0FBUyxDQUFDO0lBQy9ELElBQUksa0JBQWtCLEtBQUssbUJBQW1CLEVBQUUsQ0FBQztRQUMvQyxNQUFNLElBQUksS0FBSyxDQUNiLFdBQVcsUUFBUSxnRUFBZ0UsQ0FDcEYsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLGNBQWMsR0FBRyxzQkFBc0IsQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM1RSxNQUFNLGdCQUFnQixHQUFHLCtCQUErQixDQUN0RCxvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLG9CQUFvQixFQUNwQixRQUFRLENBQ1QsQ0FBQztJQUNGLE1BQU0sa0JBQWtCLEdBQUcsMEJBQTBCLENBQUMsU0FBUyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRTdGLElBQUksU0FBUyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQzdELENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FDcEQsRUFBRSxDQUFDO1FBQ0YsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLFFBQVEsK0VBQStFLENBQ25HLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUM7SUFDOUMsTUFBTSxvQkFBb0IsR0FBbUQsZ0JBQWdCLENBQUMsR0FBRyxDQUMvRixDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUM1QyxDQUFDO0lBQ0YsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRixNQUFNLFVBQVUsR0FBRyxnQkFBZ0I7U0FDaEMsTUFBTSxDQUFDLENBQUMsVUFBVSxFQUF1RSxFQUFFLENBQUMsQ0FDM0YsVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLENBQ2pDLENBQUM7U0FDRCxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU3QyxNQUFNLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFFLElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM3QixJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLHdCQUF3QixDQUFDLEVBQUUsQ0FBQztZQUM1RCxNQUFNLElBQUksS0FBSyxDQUNiLFdBQVcsUUFBUSx5QkFBeUIsd0JBQXdCLCtDQUErQyxDQUNwSCxDQUFDO1FBQ0osQ0FBQztRQUNELGNBQWMsQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHO1lBQ3pDLElBQUksRUFBRSxZQUFZO1lBQ2xCLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLFFBQVEsRUFBRTtnQkFDUixVQUFVLEVBQUUsWUFBWTtnQkFDeEIsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDO29CQUMvRCxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBYSxFQUFFO29CQUMzQixDQUFDLENBQUMsRUFBRSxDQUFDO2FBQ1I7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsSUFBSSxhQUFhLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUM1RCxNQUFNLFNBQVMsR0FBRywyQkFBMkIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdFLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLHlCQUF5QixTQUFTLGlCQUFpQixDQUFDLENBQUM7UUFDMUYsQ0FBQztRQUNELHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEdBQUcsUUFBUSxrQkFBa0IsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQixVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxlQUFlLENBQUMsSUFBSSxDQUFDO1lBQ25CLEVBQUUsRUFBRSxTQUFTO1lBQ2IsSUFBSSxFQUFFLFlBQVk7WUFDbEIsWUFBWSxFQUFFLHdCQUF3QjtZQUN0QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFNBQVM7WUFDOUIsVUFBVSxFQUFFLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsZUFBZTtZQUNqRSxhQUFhLEVBQUUsUUFBUTtZQUN2QixHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBbUIsRUFBRSxFQUFFLENBQUM7U0FDdkYsQ0FBQyxDQUFDO1FBQ0gsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVELElBQUksbUJBQTRFLENBQUM7SUFDakYsSUFBSSxTQUFTLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDdkMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSwyQkFBMkIsQ0FBQyxFQUFFLENBQUM7WUFDL0QsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLFFBQVEseUJBQXlCLDJCQUEyQiwyQ0FBMkMsQ0FDbkgsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsRUFBRSxDQUFDO1lBQ2pELE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxRQUFRLHlCQUF5Qiw0QkFBNEIsMkNBQTJDLENBQ3BILENBQUM7UUFDSixDQUFDO1FBQ0QsY0FBYyxDQUFDLDJCQUEyQixDQUFDLEdBQUc7WUFDNUMsSUFBSSxFQUFFLGVBQWU7WUFDckIsT0FBTyxFQUFFLFNBQVM7WUFDbEIsUUFBUSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRTtTQUN2QyxDQUFDO1FBQ0YsZUFBZSxDQUFDLElBQUksQ0FBQztZQUNuQixFQUFFLEVBQUUsNEJBQTRCO1lBQ2hDLElBQUksRUFBRSxlQUFlO1lBQ3JCLFlBQVksRUFBRSwyQkFBMkI7WUFDekMsVUFBVSxFQUFFLFdBQVc7WUFDdkIsYUFBYSxFQUFFLFFBQVE7WUFDdkIsUUFBUSxFQUFFO2dCQUNSLElBQUksRUFBRSxzQkFBc0I7Z0JBQzVCLElBQUksRUFBRTtvQkFDSixRQUFRLEVBQUUsYUFBYTtvQkFDdkIsTUFBTSxFQUFFLFdBQVc7b0JBQ25CLE1BQU0sRUFBRSxXQUFXO29CQUNuQixXQUFXLEVBQUUsZUFBZTtvQkFDNUIsZUFBZSxFQUFFLGVBQWU7aUJBQ2pDO2FBQ0Y7U0FDRixDQUFDLENBQUM7UUFDSCxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyw0QkFBNEIsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLG1CQUFtQixHQUFHO1lBQ3BCLGFBQWEsRUFBRTtnQkFDYixTQUFTLEVBQUUsNEJBQTRCO2dCQUN2QyxlQUFlLEVBQUUsdUJBQXVCO2dCQUN4QyxvQkFBb0IsRUFBRSwwQkFBMEI7YUFDakQ7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELDJDQUEyQyxDQUN6QyxlQUFlLEVBQ2Ysb0JBQW9CLENBQUMsbUJBQW1CLEVBQ3hDLFFBQVEsQ0FDVCxDQUFDO0lBRUYsT0FBTztRQUNMLGNBQWM7UUFDZCxlQUFlO1FBQ2YsY0FBYyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsb0JBQW9CLENBQUM7UUFDeEQsa0JBQWtCO1FBQ2xCLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDeEQsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUM3QixVQUFvRCxFQUNwRCxRQUFnQjtJQUVoQixJQUFJLFVBQVUsS0FBSyxTQUFTO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDeEMsTUFBTSxhQUFhLEdBQUcsaUJBQWlCLENBQUMsVUFBVSxFQUFFLEdBQUcsUUFBUSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDOUMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLHdEQUF3RCxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUVELE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxFQUFFLEVBQUU7UUFDcEUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQzlDLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLHdCQUF3QixXQUFXLGlCQUFpQixDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLEdBQUcsUUFBUSxtQkFBbUIsV0FBVyxFQUFFLENBQUM7UUFDL0QsTUFBTSxTQUFTLEdBQUcsaUJBQWlCLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzlELGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNyRixJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFjLENBQUMsRUFBRSxDQUFDO1lBQ3hFLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxVQUFVLDRDQUE0QyxDQUFDLENBQUM7UUFDckYsQ0FBQztRQUNELElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsT0FBaUIsQ0FBQyxFQUFFLENBQUM7WUFDekYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFVBQVUsNEJBQTRCLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsd0JBQXdCLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLFVBQVUsV0FBVyxDQUFDLENBQUM7UUFDeEYsTUFBTSxTQUFTLEdBQUcsd0JBQXdCLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxHQUFHLFVBQVUsWUFBWSxDQUFDLENBQUM7UUFDM0YsSUFBSSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDMUIsS0FBSyxNQUFNLGNBQWMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBaUMsRUFBRSxDQUFDO2dCQUNuRixJQUFJLFNBQVMsQ0FBQyxjQUFjLENBQUMsS0FBSyxTQUFTO3VCQUN0QyxTQUFTLENBQUMsY0FBYyxDQUFDLEtBQUssUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7b0JBQzVELE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxVQUFVLGVBQWUsTUFBTSxDQUFDLGNBQWMsQ0FBQyw0QkFBNEIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQy9HLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQThDO1lBQzVELElBQUksRUFBRSxTQUFTLENBQUMsSUFBZ0Q7WUFDaEUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFzRDtZQUN6RSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDakMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3BDLENBQUM7UUFDRixPQUFPLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBVSxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0MsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQy9CLGNBQXVCLEVBQ3ZCLFFBQWdCO0lBRWhCLElBQUksY0FBYyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNuRCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEUsZUFBZSxDQUFDLFdBQVcsRUFBRTtRQUMzQixpQkFBaUI7UUFDakIsWUFBWTtRQUNaLFVBQVU7UUFDVixXQUFXO1FBQ1gsV0FBVztRQUNYLFFBQVE7UUFDUixvQkFBb0I7S0FDckIsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNiLG9CQUFvQixDQUNsQixXQUFXLENBQUMsZUFBZSxFQUMzQixDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLEVBQ3BDLEdBQUcsUUFBUSxrQkFBa0IsQ0FDOUIsQ0FBQztJQUNGLG9CQUFvQixDQUNsQixXQUFXLENBQUMsVUFBVSxFQUN0QixDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsRUFDM0IsR0FBRyxRQUFRLGFBQWEsQ0FDekIsQ0FBQztJQUNGLG9CQUFvQixDQUNsQixXQUFXLENBQUMsUUFBUSxFQUNwQixDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsRUFDM0IsR0FBRyxRQUFRLFdBQVcsQ0FDdkIsQ0FBQztJQUNGLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLEVBQUUsR0FBRyxRQUFRLFlBQVksQ0FBQyxDQUFDO0lBQzdGLEtBQUssTUFBTSxVQUFVLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLG9CQUFvQixDQUFVLEVBQUUsQ0FBQztRQUNoRixJQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxTQUFTLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzlFLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLElBQUksVUFBVSw2QkFBNkIsQ0FBQyxDQUFDO1FBQ2xGLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLEdBQUcsV0FBVyxFQUFrRCxDQUFDO0FBQzVFLENBQUM7QUFFRCxTQUFTLCtCQUErQixDQUN0QyxXQUFzRCxFQUN0RCxVQUFxRSxFQUNyRSx1QkFBOEMsRUFDOUMsUUFBZ0I7SUFFaEIsSUFBSSxXQUFXLEtBQUssU0FBUztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3pDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDdkYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEseURBQXlELENBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUNyQyxNQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ3hDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUNsRCxNQUFNLEVBQ0osdUJBQXVCLEVBQ3ZCLHNCQUFzQixFQUN0QixtQkFBbUIsR0FDcEIsR0FBRyx1QkFBdUIsQ0FBQztJQUM1QixNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFFOUMsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsRUFBRTtRQUMxRCxNQUFNLFlBQVksR0FBRyxHQUFHLFFBQVEsb0JBQW9CLFFBQVEsR0FBRyxDQUFDO1FBQ2hFLE1BQU0sU0FBUyxHQUFHLGlCQUFpQixDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNoRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDcEMsZUFBZSxDQUFDLFNBQVMsRUFBRTtnQkFDekIsSUFBSSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLGVBQWU7Z0JBQ3pELFdBQVcsRUFBRSxZQUFZLEVBQUUsWUFBWTthQUN4QyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25CLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssZUFBZSxFQUFFLENBQUM7WUFDOUMsZUFBZSxDQUFDLFNBQVMsRUFBRTtnQkFDekIsSUFBSSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLGVBQWU7Z0JBQ3pELFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWTthQUN2QyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25CLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFlBQVksNENBQTRDLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQ0QsSUFBSSxPQUFPLFNBQVMsQ0FBQyxFQUFFLEtBQUssUUFBUSxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3BGLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxZQUFZLDRDQUE0QyxDQUFDLENBQUM7UUFDdkYsQ0FBQztRQUNELElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSx5QkFBeUIsU0FBUyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUM3RixDQUFDO1FBQ0QsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0IsSUFBSSxPQUFPLFNBQVMsQ0FBQyxZQUFZLEtBQUssUUFBUTtlQUN6QyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxZQUFZLG1CQUFtQixTQUFTLENBQUMsWUFBWSxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3ZHLENBQUM7UUFDRCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3hELElBQUksWUFBWSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFlBQVksaURBQWlELENBQUMsQ0FBQztRQUM1RixDQUFDO1FBQ0QsYUFBYSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsYUFBdUIsQ0FBQyxFQUFFLENBQUM7WUFDdEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFlBQVksMENBQTBDLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLFlBQVksV0FBVyxDQUFDLENBQUM7UUFDbEYsSUFBSSxRQUFRLEVBQUUsS0FBSyxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUUsU0FBUyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2pFLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxZQUFZLDJEQUEyRCxDQUFDLENBQUM7UUFDdEcsQ0FBQztRQUVELElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUNwQyxJQUFJLE9BQU8sU0FBUyxDQUFDLFNBQVMsS0FBSyxRQUFRO21CQUN0QyxVQUFVLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLENBQUMsU0FBUzttQkFDekYsU0FBUyxDQUFDLFNBQVMsS0FBSyxHQUFHO21CQUMzQixZQUFZLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsWUFBWSxvRUFBb0UsQ0FBQyxDQUFDO1lBQy9HLENBQUM7WUFDRCxvQkFBb0IsQ0FDbEIsU0FBUyxDQUFDLFVBQVUsRUFDcEIsQ0FBQyxlQUFlLEVBQUUsY0FBYyxFQUFFLGVBQWUsQ0FBQyxFQUNsRCxHQUFHLFlBQVksYUFBYSxFQUM1QixLQUFLLENBQ04sQ0FBQztZQUNGLE1BQU0sVUFBVSxHQUFHLDRCQUE0QixDQUM3QyxTQUFTLENBQUMsVUFBVSxFQUNwQixHQUFHLFlBQVksYUFBYSxDQUM3QixDQUFDO1lBQ0YsSUFBSSxVQUFVLEVBQUUsTUFBTSxLQUFLLFVBQVUsSUFBSSxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDaEYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFlBQVkseURBQXlELENBQUMsQ0FBQztZQUNwRyxDQUFDO1lBQ0QsSUFBSSxVQUFVLEVBQUUsU0FBUyxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUUsU0FBUyxLQUFLLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDdkYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFlBQVksNERBQTRELENBQUMsQ0FBQztZQUN2RyxDQUFDO1lBQ0QsT0FBTztnQkFDTCxFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUU7Z0JBQ2hCLElBQUksRUFBRSxZQUFZO2dCQUNsQixZQUFZLEVBQUUsU0FBUyxDQUFDLFlBQVk7Z0JBQ3BDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDakMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUEwRDtnQkFDbkYsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTO2dCQUM5QixVQUFVLEVBQUUsU0FBUyxDQUFDLFVBQThEO2dCQUNwRixHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDMEIsQ0FBQztRQUNwRSxDQUFDO1FBRUQsb0JBQW9CLENBQ2xCLFNBQVMsQ0FBQyxVQUFVLEVBQ3BCLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxFQUN6QixHQUFHLFlBQVksYUFBYSxFQUM1QixLQUFLLENBQ04sQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHLDZCQUE2QixDQUM1QyxTQUFTLENBQUMsUUFBUSxFQUNsQixZQUFZLEVBQ1osdUJBQXVCLEVBQ3ZCLHNCQUFzQixFQUN0Qix1QkFBdUIsRUFDdkIsbUJBQW1CLEVBQ25CLG1CQUFtQixDQUNwQixDQUFDO1FBQ0YsTUFBTSxVQUFVLEdBQUcsK0JBQStCLENBQ2hELFNBQVMsQ0FBQyxVQUFVLEVBQ3BCLEdBQUcsWUFBWSxhQUFhLENBQzdCLENBQUM7UUFDRixJQUFJLFVBQVUsRUFBRSxNQUFNLEtBQUssVUFBVSxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUUsTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2hGLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxZQUFZLHlEQUF5RCxDQUFDLENBQUM7UUFDcEcsQ0FBQztRQUNELE9BQU87WUFDTCxFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUU7WUFDaEIsSUFBSSxFQUFFLGVBQWU7WUFDckIsWUFBWSxFQUFFLFNBQVMsQ0FBQyxZQUFZO1lBQ3BDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQTBEO1lBQ25GLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBMEQ7WUFDaEYsUUFBUTtZQUNSLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUNzQixDQUFDO0lBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBRUgsS0FBSyxNQUFNLFdBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDbEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxvQkFBb0IsV0FBVyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2xHLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQ3ZCLFdBQW9CLEVBQ3BCLFFBQWdCO0lBRWhCLElBQUksV0FBVyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoRCxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUQsZUFBZSxDQUFDLFFBQVEsRUFBRSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxRCxNQUFNLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsUUFBUSxVQUFVLENBQUMsQ0FBQztJQUM3RixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsS0FBSyxLQUFLLFNBQVM7UUFDN0MsQ0FBQyxDQUFDLFNBQVM7UUFDWCxDQUFDLENBQUMsNEJBQTRCLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFHLFFBQVEsUUFBUSxDQUFDLENBQUM7SUFDdEUsSUFBSSxVQUFVLEtBQUssU0FBUyxJQUFJLFVBQVUsR0FBRyxjQUFjLEVBQUUsQ0FBQztRQUM1RCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxrREFBa0QsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFDRCxPQUFPO1FBQ0wsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFpQjtRQUNuQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQWUsRUFBRSxDQUFDO0tBQzdFLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLG1DQUFtQyxDQUMxQyxhQUEwQixFQUMxQixRQUFnQjtJQUVoQixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzVDLE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxRQUFRLGtFQUFrRSxDQUN0RixDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUM7QUFFRCxTQUFTLDRCQUE0QixDQUNuQyxhQUFzQixFQUN0QixRQUFnQjtJQUVoQixJQUFJLGFBQWEsS0FBSyxTQUFTO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDbEQsTUFBTSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzlELGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLGFBQWEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzlFLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLFFBQVEsU0FBUyxDQUFDLENBQUM7SUFDNUUsb0JBQW9CLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxHQUFHLFFBQVEsWUFBWSxDQUFDLENBQUM7SUFDNUYsb0JBQW9CLENBQ2xCLFVBQVUsQ0FBQyxXQUFXLEVBQ3RCLENBQUMsaUJBQWlCLEVBQUUsdUJBQXVCLENBQUMsRUFDNUMsR0FBRyxRQUFRLGNBQWMsQ0FDMUIsQ0FBQztJQUNGLE9BQU8sbUNBQW1DLENBQUM7UUFDekMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEtBQUssU0FBUztZQUNqQyxDQUFDLENBQUMsRUFBRTtZQUNKLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBb0IsRUFBRSxDQUFDO1FBQ2hELEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxLQUFLLFNBQVM7WUFDcEMsQ0FBQyxDQUFDLEVBQUU7WUFDSixDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQXNFLEVBQUUsQ0FBQztRQUNyRyxHQUFHLENBQUMsVUFBVSxDQUFDLFdBQVcsS0FBSyxTQUFTO1lBQ3RDLENBQUMsQ0FBQyxFQUFFO1lBQ0osQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxXQUEwRCxFQUFFLENBQUM7S0FDNUYsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLCtCQUErQixDQUN0QyxhQUFzQixFQUN0QixRQUFnQjtJQUVoQixJQUFJLGFBQWEsS0FBSyxTQUFTO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDbEQsTUFBTSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzlELGVBQWUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pGLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLFFBQVEsU0FBUyxDQUFDLENBQUM7SUFDNUUsb0JBQW9CLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEdBQUcsUUFBUSxhQUFhLENBQUMsQ0FBQztJQUNwRixJQUFJLFVBQVUsQ0FBQyxhQUFhLEtBQUssU0FBUztXQUNyQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO2VBQ3pDLFVBQVUsQ0FBQyxhQUF3QixHQUFHLENBQUM7ZUFDdkMsVUFBVSxDQUFDLGFBQXdCLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSx5REFBeUQsQ0FBQyxDQUFDO0lBQ2hHLENBQUM7SUFDRCxPQUFPLG1DQUFtQyxDQUFDO1FBQ3pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLFNBQVM7WUFDakMsQ0FBQyxDQUFDLEVBQUU7WUFDSixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQW9CLEVBQUUsQ0FBQztRQUNoRCxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsS0FBSyxTQUFTO1lBQ3JDLENBQUMsQ0FBQyxFQUFFO1lBQ0osQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUF3QixFQUFFLENBQUM7UUFDeEQsR0FBRyxDQUFDLFVBQVUsQ0FBQyxhQUFhLEtBQUssU0FBUztZQUN4QyxDQUFDLENBQUMsRUFBRTtZQUNKLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxVQUFVLENBQUMsYUFBdUIsRUFBRSxDQUFDO0tBQzNELEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBUyw2QkFBNkIsQ0FDcEMsV0FBb0IsRUFDcEIsZUFBdUIsRUFDdkIsMEJBQXVDLEVBQ3ZDLHlCQUFzQyxFQUN0QywwQkFBdUMsRUFDdkMsc0JBQW1DLEVBQ25DLHNCQUFtQztJQUVuQyxNQUFNLGFBQWEsR0FBRyxHQUFHLGVBQWUsV0FBVyxDQUFDO0lBQ3BELE1BQU0sUUFBUSxHQUFHLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUMvRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssc0JBQXNCLEVBQUUsQ0FBQztRQUM3QyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxhQUFhLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZFLGVBQWUsQ0FBQyxJQUFJLEVBQUU7WUFDcEIsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLGNBQWM7U0FDakYsRUFBRSxHQUFHLGFBQWEsT0FBTyxDQUFDLENBQUM7UUFDNUIsS0FBSyxNQUFNLFdBQVcsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDN0YsSUFBSSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLGFBQWEsV0FBVyxXQUFXLGVBQWUsQ0FBQyxDQUFDO1lBQ2pGLENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQ3BDLEtBQUssTUFBTSxZQUFZLElBQUksVUFBVSxFQUFFLENBQUM7WUFDdEMsSUFBSSxPQUFPLFlBQVksS0FBSyxRQUFRLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDbEYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLGFBQWEsK0NBQStDLENBQUMsQ0FBQztZQUMzRixDQUFDO1lBQ0QsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxhQUFhLHNCQUFzQixZQUFZLGlCQUFpQixDQUFDLENBQUM7WUFDL0YsQ0FBQztZQUNELElBQUksMEJBQTBCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQzttQkFDM0MseUJBQXlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ2pELE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxhQUFhLHNCQUFzQixZQUFZLHNDQUFzQyxDQUNqRyxDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksMEJBQTBCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxhQUFhLHNCQUFzQixZQUFZLHNDQUFzQyxDQUFDLENBQUM7WUFDcEgsQ0FBQztZQUNELFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDNUIsMEJBQTBCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLHNCQUFzQjtZQUM1QixJQUFJLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRTtTQUMrQyxDQUFDO0lBQ3JFLENBQUM7SUFFRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDN0IsZUFBZSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDakcsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLDBCQUEwQixFQUFFLENBQUM7WUFDbkQsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLGFBQWEsdUNBQXVDLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsSUFBSSxPQUFPLFFBQVEsQ0FBQyxVQUFVLEtBQUssUUFBUTtlQUN0QyxVQUFVLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxRQUFRLENBQUMsVUFBVTtlQUN6RixDQUFDLG9EQUFvRCxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNyRixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsYUFBYSxpRUFBaUUsQ0FBQyxDQUFDO1FBQzdHLENBQUM7UUFDRCxJQUFJLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNwRCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsYUFBYSxtREFBbUQsQ0FBQyxDQUFDO1FBQy9GLENBQUM7UUFDRCxJQUFJLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNwRCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsYUFBYSxpREFBaUQsQ0FBQyxDQUFDO1FBQzdGLENBQUM7UUFDRCx5RkFBeUY7UUFDekYsNkZBQTZGO1FBQzdGLDBDQUEwQztRQUMxQyxLQUFLLE1BQU0sYUFBYSxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBVSxFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO21CQUM3QyxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzttQkFDckMsUUFBUSxDQUFDLGFBQWEsQ0FBWSxHQUFHLENBQUM7bUJBQ3RDLFFBQVEsQ0FBQyxhQUFhLENBQVksR0FBRyxhQUFhLEVBQUUsQ0FBQztnQkFDekQsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLGFBQWEsS0FBSyxhQUFhLHFDQUFxQyxDQUFDLENBQUM7WUFDbkcsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssS0FBSyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDdkQsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLGFBQWEsNkJBQTZCLENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQ0Qsc0JBQXNCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU07WUFDWixVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVU7WUFDL0IsTUFBTSxFQUFFLDBCQUEwQjtZQUNsQyxHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQWE7WUFDM0IsR0FBRyxFQUFFLFFBQVEsQ0FBQyxHQUFhO1lBQzNCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBcUI7U0FDckMsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsYUFBYSw2Q0FBNkMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRCxTQUFTLDBCQUEwQixDQUNqQyxTQUFpQyxFQUNqQyxtQkFBa0UsRUFDbEUsUUFBZ0I7SUFFaEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztJQUM5RCxJQUFJLG1CQUFtQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNuQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUNELElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDL0UsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFDRCxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxlQUFlLENBQUMsRUFBRSxDQUFDO1FBQ2xGLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBQ0QsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQzNDLFVBQVUsQ0FBQyxJQUFJLEtBQUssZUFBZSxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FDM0UsQ0FBQyxFQUFFLENBQUM7UUFDSCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDO0lBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1dBQy9CLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsT0FBTyxRQUFRLEtBQUssUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUN2RSxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxnREFBZ0QsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFDRCxJQUFJLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQy9ELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLGdEQUFnRCxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUNELEtBQUssTUFBTSxlQUFlLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEsa0NBQWtDLGVBQWUsR0FBRyxDQUFDLENBQUM7UUFDM0YsQ0FBQztJQUNILENBQUM7SUFDRCxLQUFLLE1BQU0sZUFBZSxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDL0MsSUFBSSxlQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDM0YsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEsOEJBQThCLGVBQWUsR0FBRyxDQUFDLENBQUM7UUFDdkYsQ0FBQztRQUNELElBQUksc0JBQXNCLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztlQUMxQyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxlQUE0QyxDQUFDLEVBQUUsQ0FBQztZQUN6RSxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxzQkFBc0IsZUFBZSxlQUFlLENBQUMsQ0FBQztRQUMzRixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFTLDRCQUE0QixDQUNuQyxlQUErRCxFQUMvRCxRQUFnQjtJQUVoQixJQUFJLGVBQWUsS0FBSyxTQUFTO1FBQUUsT0FBTztJQUMxQyxNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQyxlQUFlLEVBQUUsR0FBRyxRQUFRLHVCQUF1QixDQUFDLENBQUM7SUFDNUYsZUFBZSxDQUNiLFlBQVksRUFDWixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQzVELEdBQUcsUUFBUSx1QkFBdUIsQ0FDbkMsQ0FBQztJQUNGLEtBQUssTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDOUQsSUFBSSxPQUFPLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSx5QkFBeUIsTUFBTSxzQkFBc0IsQ0FBQyxDQUFDO1FBQzVGLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQzdCLFVBQTZDLEVBQzdDLFFBQWdCO0lBRWhCLElBQUksVUFBVSxLQUFLLFNBQVM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxRQUFRLG9EQUFvRCxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBRTtRQUM1QyxNQUFNLFdBQVcsR0FBRyxHQUFHLFFBQVEsWUFBWSxRQUFRLEdBQUcsQ0FBQztRQUN2RCxNQUFNLFVBQVUsR0FBRyxPQUFPLFNBQVMsS0FBSyxRQUFRO1lBQzlDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUU7WUFDMUIsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM5QyxlQUFlLENBQ2IsVUFBVSxFQUNWLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsU0FBUyxDQUFDLEVBQzFFLFdBQVcsQ0FDWixDQUFDO1FBQ0YsS0FBSyxNQUFNLFlBQVksSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUMzRCxJQUFJLFVBQVUsQ0FBQyxZQUFZLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFdBQVcscUJBQXFCLFlBQVksaUNBQWlDLENBQUMsQ0FBQztZQUM1RyxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksT0FBTyxVQUFVLENBQUMsU0FBUyxLQUFLLFFBQVE7ZUFDdkMsVUFBVSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssVUFBVSxDQUFDLFNBQVM7ZUFDM0YsVUFBVSxDQUFDLFNBQVMsS0FBSyxHQUFHO2VBQzVCLFlBQVksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDeEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFdBQVcsb0VBQW9FLENBQUMsQ0FBQztRQUM5RyxDQUFDO1FBQ0QsSUFBSSxVQUFVLENBQUMsSUFBSSxLQUFLLFNBQVM7ZUFDNUIsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0YsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFdBQVcsOENBQThDLENBQUMsQ0FBQztRQUN4RixDQUFDO1FBQ0QsS0FBSyxNQUFNLFVBQVUsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ2hELElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLFNBQVMsSUFBSSxPQUFPLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDeEYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFdBQVcsSUFBSSxVQUFVLHNCQUFzQixDQUFDLENBQUM7WUFDOUUsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPO1lBQ0wsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFjLEVBQUUsQ0FBQztZQUM3RSxTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVM7WUFDL0IsR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFtQixFQUFFLENBQUM7WUFDMUYsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFpQixFQUFFLENBQUM7U0FDckYsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsMkJBQTJCLENBQ2xDLFNBQThDLEVBQzlDLFFBQWdCLEVBQ2hCLFFBQWdCO0lBRWhCLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLFNBQVM7U0FDckQsV0FBVyxFQUFFO1NBQ2IsS0FBSyxDQUFDLEdBQUcsQ0FBQztTQUNWLE1BQU0sQ0FBQyxPQUFPLENBQUM7U0FDZixJQUFJLENBQUMsR0FBRyxDQUFDO1NBQ1QsT0FBTyxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUM7U0FDNUIsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMzQixNQUFNLFNBQVMsR0FBRyxpQkFBaUIsVUFBVSxFQUFFLENBQUM7SUFDaEQsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQzVELE1BQU0sSUFBSSxLQUFLLENBQ2IsV0FBVyxRQUFRLFlBQVksUUFBUSx3RUFBd0UsQ0FDaEgsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQsU0FBUywyQ0FBMkMsQ0FDbEQsV0FBMEQsRUFDMUQsc0JBQW1DLEVBQ25DLFFBQWdCO0lBRWhCLE1BQU0sVUFBVSxHQUFhLEVBQUUsQ0FBQztJQUNoQyxNQUFNLGlCQUFpQixHQUFhLEVBQUUsQ0FBQztJQUN2QyxLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUNyQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxHQUFHLFFBQVEsYUFBYSxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNsRyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QyxDQUFDO2FBQU0sSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMvQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6RCxDQUFDO0lBQ0gsQ0FBQztJQUNELEtBQUssTUFBTSxhQUFhLElBQUksQ0FBQyxHQUFHLHNCQUFzQixFQUFFLEdBQUcsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1FBQzlFLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDakYsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEsb0JBQW9CLGFBQWEsK0JBQStCLENBQUMsQ0FBQztRQUN2RyxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLE9BQWUsRUFBRSxRQUFrQixFQUFFLFFBQWdCO0lBQ2xGLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUM3RixJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEsV0FBVyxPQUFPLGVBQWUsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNwRixDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE9BQWUsRUFBRSxRQUFnQjtJQUNyRCxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25FLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDckUsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNsQyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksS0FBSyxLQUFLLEdBQUc7UUFBRSxPQUFPLElBQUksQ0FBQztJQUMvQyxPQUFPLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFDeEYsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsUUFBaUIsRUFBRSxRQUFnQjtJQUM1RCxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDekUsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEsc0JBQXNCLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBQ0QsT0FBTyxRQUF3QixDQUFDO0FBQ2xDLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FDdEIsU0FBdUIsRUFDdkIsY0FBaUMsRUFDakMsUUFBZ0I7SUFFaEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDNUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsUUFBUSxzQkFBc0IsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUYsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUMzQixRQUFpQixFQUNqQixnQkFBbUMsRUFDbkMsUUFBZ0IsRUFDaEIsV0FBVyxHQUFHLElBQUk7SUFFbEIsSUFBSSxRQUFRLEtBQUssU0FBUyxJQUFJLFdBQVc7UUFBRSxPQUFPO0lBQ2xELElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDekUsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLFFBQVEscUJBQXFCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekYsQ0FBQztBQUNILENBQUMifQ==
151
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NsaWVudC9zdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBWXhDLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQztBQUN6RixNQUFNLHdCQUF3QixHQUFHLGtCQUFrQixDQUFDO0FBQ3BELE1BQU0sMkJBQTJCLEdBQUcscUJBQXFCLENBQUM7QUFDMUQsTUFBTSw0QkFBNEIsR0FBRyxXQUFXLENBQUM7QUFDakQsTUFBTSx1QkFBdUIsR0FBRyx3QkFBd0IsQ0FBQztBQUN6RCxNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQztBQUV2Qzs7O0dBR0c7QUFDSCxNQUFNLGtCQUFrQixHQUFHLENBQUMsU0FBZ0MsRUFBRSxRQUFnQixFQUFRLEVBQUU7SUFDdEYsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyw4QkFBOEIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDeEcsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM1RCxDQUFDLENBQUM7QUFFRixNQUFNLGdCQUFnQixHQUFHLENBQUMsVUFBNEMsRUFBYSxFQUFFLENBQ25GLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBVyxFQUFFO0lBQzVDLE1BQU0sTUFBTSxHQUFHLE9BQU8sU0FBUyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNwRixPQUFPO1FBQ0wsR0FBRyxDQUFDLE1B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