__vite_ssr_exportName__("RemoteEnvironmentAuthorization", () => { try { return RemoteEnvironmentAuthorization } catch {} });
__vite_ssr_exportName__("make", () => { try { return make } catch {} });
__vite_ssr_exportName__("layer", () => { try { return layer } catch {} });
const __vite_ssr_import_0__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/contracts/src/index.ts", {"importedNames":["EnvironmentId"]});
const __vite_ssr_import_1__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/contracts/src/relay.ts", {"importedNames":["RelayEnvironmentConnectScope"]});
const __vite_ssr_import_2__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/shared/src/relayTracing.ts", {"importedNames":["withRelayClientTracing"]});
const __vite_ssr_import_3__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/authorization/remote.ts", {"importedNames":["exchangeRemoteDpopAccessToken","resolveRemoteDpopWebSocketConnectionUrl","resolveRemoteWebSocketConnectionUrl"]});
const __vite_ssr_import_4__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/errors.ts", {"importedNames":["environmentMismatchError","mapManagedRelayError","mapRemoteDpopEnvironmentError","mapRemoteEnvironmentError"]});
const __vite_ssr_import_5__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/model.ts", {"importedNames":["ConnectionBlockedError","ConnectionTransientError"]});
const __vite_ssr_import_6__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/environment/descriptor.ts", {"importedNames":["fetchRemoteEnvironmentDescriptor"]});
const __vite_ssr_import_7__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/environment/endpoint.ts", {"importedNames":["environmentEndpointUrl"]});
const __vite_ssr_import_8__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/platform/capabilities.ts");
const __vite_ssr_import_9__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/relay/managedRelay.ts");
const __vite_ssr_import_10__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/authorization/tokenStore.ts");
const __vite_ssr_import_11__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Clock.js");
const __vite_ssr_import_12__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Context.js");
const __vite_ssr_import_13__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Effect.js");
const __vite_ssr_import_14__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Fiber.js");
const __vite_ssr_import_15__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Layer.js");
const __vite_ssr_import_16__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Option.js");
const __vite_ssr_import_17__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Ref.js");
const __vite_ssr_import_18__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Result.js");
const __vite_ssr_import_19__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Scope.js");
const __vite_ssr_import_20__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Semaphore.js");
const __vite_ssr_import_21__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/http/HttpClient.js");
const __vite_ssr_import_22__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/model.ts", {"importedNames":["DPOP_ACCESS_TOKEN_REFRESH_SKEW_MS"]});























class RemoteEnvironmentAuthorization extends __vite_ssr_import_12__.Service()("@t3tools/client-runtime/authorization/service/RemoteEnvironmentAuthorization") {};
const CACHED_ENDPOINT_SOCKET_TIMEOUT_MS = 3e3;
const BEARER_DESCRIPTOR_CACHE_TTL_MS = 1e4;
const DPOP_AUTHORIZATION_TIMEOUT_MS = 3e4;
function mapDpopSocketError(error) {
	return error._tag === "ConnectionTransientError" || error._tag === "ConnectionBlockedError" ? error : (0,__vite_ssr_import_4__.mapRemoteDpopEnvironmentError)(error);
}
const fetchDescriptor = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.fetchDescriptor")(function* (httpBaseUrl, connectionMethod) {
	return yield* (0,__vite_ssr_import_6__.fetchRemoteEnvironmentDescriptor)({ httpBaseUrl }).pipe(__vite_ssr_import_13__.mapError((error) => (0,__vite_ssr_import_4__.mapRemoteEnvironmentError)(error, connectionMethod)));
});
const make = __vite_ssr_import_13__.gen(function* () {
	const serviceScope = yield* __vite_ssr_import_19__.Scope;
	const signer = yield* __vite_ssr_import_9__.ManagedRelayDpopSigner;
	const relay = yield* __vite_ssr_import_9__.ManagedRelayClient;
	const cloudSession = yield* __vite_ssr_import_8__.CloudSession;
	const deviceIdentity = yield* __vite_ssr_import_8__.RelayDeviceIdentity;
	const presentation = yield* __vite_ssr_import_8__.ClientPresentation;
	const tokenStore = yield* __vite_ssr_import_10__.RemoteDpopAccessTokenStore;
	const httpClient = yield* __vite_ssr_import_21__.HttpClient;
	const tokenLock = yield* __vite_ssr_import_20__.make(1);
	const tokenOwners = new Map();
	const pendingTokens = new Map();
	const bearerDescriptors = yield* __vite_ssr_import_17__.make(new Map());
	/**
	* A saved LAN address can belong to another machine on a different network.
	*/
	const verifyDirectEndpoint = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.verifyDirectEndpoint")(function* (input) {
		const now = yield* __vite_ssr_import_11__.currentTimeMillis;
		const cachedDescriptor = (yield* __vite_ssr_import_17__.get(bearerDescriptors)).get(input.expectedEnvironmentId);
		const canReuseDescriptor = cachedDescriptor?.httpBaseUrl === input.httpBaseUrl && cachedDescriptor.validatedAtEpochMs + BEARER_DESCRIPTOR_CACHE_TTL_MS > now;
		const descriptor = canReuseDescriptor ? cachedDescriptor.descriptor : yield* fetchDescriptor(input.httpBaseUrl, input.connectionMethod).pipe(__vite_ssr_import_13__.provideService(__vite_ssr_import_21__.HttpClient, httpClient));
		if (descriptor.environmentId !== input.expectedEnvironmentId) {
			return yield* (0,__vite_ssr_import_4__.environmentMismatchError)({
				expected: input.expectedEnvironmentId,
				actual: descriptor.environmentId
			});
		};
		if (!canReuseDescriptor) {
			yield* __vite_ssr_import_17__.update(bearerDescriptors, (current) => {
				const next = new Map(current);
				next.set(input.expectedEnvironmentId, {
					httpBaseUrl: input.httpBaseUrl,
					descriptor,
					validatedAtEpochMs: now
				});
				return next;
			});
		};
		return descriptor;
	});
	const authorizeBearer = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.authorizeBearer")(function* (input) {
		const descriptor = yield* verifyDirectEndpoint(input);
		const socketUrl = yield* (0,__vite_ssr_import_3__.resolveRemoteWebSocketConnectionUrl)({
			wsBaseUrl: input.wsBaseUrl,
			httpBaseUrl: input.httpBaseUrl,
			bearerToken: input.bearerToken,
			clientMetadata: presentation.metadata,
			connectionMethod: input.connectionMethod
		}).pipe(__vite_ssr_import_13__.mapError((0,__vite_ssr_import_4__.mapRemoteEnvironmentError)), __vite_ssr_import_13__.provideService(__vite_ssr_import_21__.HttpClient, httpClient));
		return {
			environmentId: descriptor.environmentId,
			label: descriptor.label,
			httpBaseUrl: input.httpBaseUrl,
			socketUrl,
			httpAuthorization: {
				_tag: "Bearer",
				token: input.bearerToken
			}
		};
	});
	const createDpopSocketUrl = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.createDpopSocketUrl")(function* (token, timeoutMs, endpoint = token.endpoint) {
		return yield* (0,__vite_ssr_import_3__.resolveRemoteDpopWebSocketConnectionUrl)({
			wsBaseUrl: endpoint.wsBaseUrl,
			httpBaseUrl: endpoint.httpBaseUrl,
			accessToken: token.accessToken,
			createProof: (proof) => signer.createProof(proof).pipe(__vite_ssr_import_13__.mapError(() => new __vite_ssr_import_5__.ConnectionBlockedError({
				reason: "configuration",
				detail: "Could not create the websocket authorization proof."
			}))),
			clientMetadata: presentation.metadata,
			connectionMethod: "relay",
			...timeoutMs === undefined ? {} : { timeoutMs }
		}).pipe(__vite_ssr_import_13__.provideService(__vite_ssr_import_21__.HttpClient, httpClient));
	});
	const sessionChanged = () => new __vite_ssr_import_5__.ConnectionBlockedError({
		reason: "authentication",
		detail: "Your cloud sign-in changed. Sign in again to authorize the environment."
	});
	// A missing identity before the attempt captures one means the cloud session
	// is still loading, not a sign-out. Only a captured identity that goes away
	// or changes is evidence of one.
	const sessionPending = () => new __vite_ssr_import_5__.ConnectionTransientError({
		reason: "session-pending",
		detail: "Waiting for the T3 Connect sign-in to load."
	});
	const assertSession = __vite_ssr_import_13__.fnUntraced(function* (identity) {
		const current = yield* cloudSession.identity;
		if (__vite_ssr_import_16__.isNone(current) || current.value !== identity) {
			return yield* sessionChanged();
		}
	});
	// Called under tokenLock so a late rejection cannot remove a newer credential.
	const removeRejectedToken = __vite_ssr_import_13__.fnUntraced(function* (environmentId, accessToken) {
		const cached = yield* tokenStore.get(environmentId);
		if (__vite_ssr_import_16__.isSome(cached) && cached.value.accessToken === accessToken) {
			yield* tokenStore.remove(environmentId);
			tokenOwners.delete(environmentId);
		}
	});
	const obtainBootstrap = __vite_ssr_import_13__.fn("relay.connection.bootstrap.obtain")(function* (environmentId, identity) {
		yield* assertSession(identity);
		const clerkToken = yield* cloudSession.clerkToken.pipe(__vite_ssr_import_13__.withSpan("relay.connection.cloudSessionToken.resolve"));
		const deviceId = yield* deviceIdentity.deviceId.pipe(__vite_ssr_import_13__.withSpan("relay.connection.deviceIdentity.resolve"));
		yield* assertSession(identity);
		const connected = yield* relay.connectEnvironment({
			clerkToken,
			scopes: [__vite_ssr_import_1__.RelayEnvironmentConnectScope],
			environmentId,
			...__vite_ssr_import_16__.isSome(deviceId) ? { deviceId: deviceId.value } : {}
		}).pipe(__vite_ssr_import_13__.mapError((0,__vite_ssr_import_4__.mapManagedRelayError)));
		if (connected.environmentId !== environmentId) {
			return yield* (0,__vite_ssr_import_4__.environmentMismatchError)({
				expected: environmentId,
				actual: connected.environmentId
			});
		};
		yield* assertSession(identity);
		return connected;
	});
	const exchangeDpopToken = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.exchangeDpopToken")(function* (environmentId, thumbprint, identity) {
		const bootstrap = yield* obtainBootstrap(environmentId, identity);
		const descriptor = yield* fetchDescriptor(bootstrap.endpoint.httpBaseUrl, "relay").pipe(__vite_ssr_import_13__.provideService(__vite_ssr_import_21__.HttpClient, httpClient), __vite_ssr_import_13__.withSpan("environment.authorization.descriptor"));
		if (descriptor.environmentId !== environmentId) {
			return yield* (0,__vite_ssr_import_4__.environmentMismatchError)({
				expected: environmentId,
				actual: descriptor.environmentId
			});
		};
		const bootstrapProof = yield* signer.createProof({
			method: "POST",
			url: (0,__vite_ssr_import_7__.environmentEndpointUrl)(bootstrap.endpoint.httpBaseUrl, "/oauth/token")
		}).pipe(__vite_ssr_import_13__.mapError(() => new __vite_ssr_import_5__.ConnectionBlockedError({
			reason: "configuration",
			detail: "Could not create the environment authorization proof."
		})));
		yield* assertSession(identity);
		const access = yield* (0,__vite_ssr_import_3__.exchangeRemoteDpopAccessToken)({
			httpBaseUrl: bootstrap.endpoint.httpBaseUrl,
			credential: bootstrap.credential,
			dpopProof: bootstrapProof,
			clientMetadata: presentation.metadata
		}).pipe(__vite_ssr_import_13__.mapError((0,__vite_ssr_import_4__.mapRemoteDpopEnvironmentError)), __vite_ssr_import_13__.provideService(__vite_ssr_import_21__.HttpClient, httpClient), __vite_ssr_import_13__.withSpan("environment.authorization.accessToken.exchange"));
		const issuedAt = yield* __vite_ssr_import_11__.currentTimeMillis;
		return new __vite_ssr_import_10__.RemoteDpopAccessToken({
			environmentId: descriptor.environmentId,
			accountId: identity.accountId,
			label: descriptor.label,
			endpoint: bootstrap.endpoint,
			accessToken: access.access_token,
			expiresAtEpochMs: issuedAt + access.expires_in * 1e3,
			dpopThumbprint: thumbprint
		});
	});
	const getDpopToken = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.getDpopToken")(function* (input) {
		const session = yield* cloudSession.identity;
		if (__vite_ssr_import_16__.isNone(session)) {
			return yield* sessionPending();
		};
		const identity = session.value;
		const thumbprint = yield* signer.thumbprint.pipe(__vite_ssr_import_13__.mapError(() => new __vite_ssr_import_5__.ConnectionBlockedError({
			reason: "configuration",
			detail: "Could not load the environment authorization key."
		})), __vite_ssr_import_13__.withSpan("environment.authorization.dpopKey.resolve"));
		const selected = yield* tokenLock.withPermits(1)(__vite_ssr_import_13__.gen(function* () {
			yield* assertSession(identity);
			const now = yield* __vite_ssr_import_11__.currentTimeMillis;
			const cached = yield* tokenStore.get(input.expectedEnvironmentId).pipe(__vite_ssr_import_13__.withSpan("environment.authorization.accessToken.cache"));
			const owner = tokenOwners.get(input.expectedEnvironmentId);
			if (__vite_ssr_import_16__.isSome(cached) && cached.value.environmentId === input.expectedEnvironmentId && cached.value.accountId === identity.accountId && cached.value.dpopThumbprint === thumbprint && cached.value.expiresAtEpochMs > now + __vite_ssr_import_22__.DPOP_ACCESS_TOKEN_REFRESH_SKEW_MS && cached.value.accessToken !== input.rejectedAccessToken && (owner?.accessToken !== cached.value.accessToken || owner.identity === identity)) {
				tokenOwners.set(input.expectedEnvironmentId, {
					accessToken: cached.value.accessToken,
					identity
				});
				return {
					token: __vite_ssr_import_13__.succeed(cached.value),
					fromCache: true
				};
			};
			if (input.rejectedAccessToken !== undefined) {
				yield* removeRejectedToken(input.expectedEnvironmentId, input.rejectedAccessToken);
			};
			const pending = pendingTokens.get(input.expectedEnvironmentId);
			if (pending?.identity === identity && pending.thumbprint === thumbprint) {
				return {
					token: pending.token,
					fromCache: false
				};
			};
			const id = {};
			const fiber = yield* exchangeDpopToken(input.expectedEnvironmentId, thumbprint, identity).pipe(
				__vite_ssr_import_13__.flatMap((token) => tokenLock.withPermits(1)(__vite_ssr_import_13__.gen(function* () {
					yield* assertSession(identity);
					yield* tokenStore.put(token).pipe(__vite_ssr_import_13__.withSpan("environment.authorization.accessToken.persist"));
					const current = yield* cloudSession.identity;
					if (__vite_ssr_import_16__.isNone(current) || current.value !== identity) {
						yield* removeRejectedToken(input.expectedEnvironmentId, token.accessToken);
						return yield* sessionChanged();
					};
					tokenOwners.set(input.expectedEnvironmentId, {
						accessToken: token.accessToken,
						identity
					});
					if (pendingTokens.get(input.expectedEnvironmentId)?.id === id) {
						pendingTokens.delete(input.expectedEnvironmentId);
					};
					return token;
				}))),
				__vite_ssr_import_13__.timeoutOrElse({
					duration: DPOP_AUTHORIZATION_TIMEOUT_MS,
					orElse: () => __vite_ssr_import_13__.fail(new __vite_ssr_import_5__.ConnectionTransientError({
						reason: "timeout",
						detail: "Timed out renewing the environment credential."
					}))
				}),
				__vite_ssr_import_13__.ensuring(tokenLock.withPermits(1)(__vite_ssr_import_13__.sync(() => {
					if (pendingTokens.get(input.expectedEnvironmentId)?.id === id) {
						pendingTokens.delete(input.expectedEnvironmentId);
					}
				}))),
				// One caller's timeout must not cancel renewal for other HTTP requests.
				__vite_ssr_import_13__.forkIn(serviceScope)
			);
			const token = __vite_ssr_import_14__.join(fiber);
			pendingTokens.set(input.expectedEnvironmentId, {
				id,
				identity,
				thumbprint,
				token
			});
			return {
				token,
				fromCache: false
			};
		}));
		yield* __vite_ssr_import_13__.annotateCurrentSpan({ "connection.remote_token_cache": selected.fromCache ? "hit" : "miss" });
		const token = yield* selected.token;
		yield* assertSession(identity);
		return {
			token,
			fromCache: selected.fromCache,
			identity
		};
	});
	const httpAuthorization = (token, httpBaseUrl = token.endpoint.httpBaseUrl) => ({
		environmentId: token.environmentId,
		label: token.label,
		httpBaseUrl,
		httpAuthorization: {
			_tag: "Dpop",
			accessToken: token.accessToken,
			expiresAtEpochMs: token.expiresAtEpochMs
		}
	});
	const authorizeDpop = __vite_ssr_import_13__.fn("clientRuntime.connection.remote.authorizeDpop")(function* (input) {
		const endpoint = input.directEndpoint;
		if (endpoint !== undefined) {
			yield* verifyDirectEndpoint({
				expectedEnvironmentId: input.expectedEnvironmentId,
				httpBaseUrl: endpoint.httpBaseUrl,
				connectionMethod: "direct"
			});
		};
		const authorized = (token, socketUrl) => ({
			...httpAuthorization(token, endpoint?.httpBaseUrl),
			socketUrl
		});
		let selected = yield* getDpopToken(input);
		if (selected.fromCache) {
			const cachedSocket = yield* createDpopSocketUrl(selected.token, CACHED_ENDPOINT_SOCKET_TIMEOUT_MS, endpoint).pipe(__vite_ssr_import_13__.result);
			if (__vite_ssr_import_18__.isSuccess(cachedSocket)) {
				yield* assertSession(selected.identity);
				return authorized(selected.token, cachedSocket.success);
			};
			if (cachedSocket.failure._tag === "ConnectionBlockedError") {
				return yield* mapDpopSocketError(cachedSocket.failure);
			};
			// An unreachable direct address says nothing about the token, so keep
			// it for the T3 Connect route rather than forcing a relay round trip.
			if (endpoint !== undefined && cachedSocket.failure._tag !== "EnvironmentAuthInvalidError") {
				return yield* mapDpopSocketError(cachedSocket.failure);
			};
			yield* assertSession(selected.identity);
			selected = yield* getDpopToken({
				...input,
				rejectedAccessToken: selected.token.accessToken
			});
		};
		const socket = yield* createDpopSocketUrl(selected.token, undefined, endpoint).pipe(__vite_ssr_import_13__.result);
		if (__vite_ssr_import_18__.isFailure(socket)) {
			if (endpoint === undefined || socket.failure._tag === "ConnectionBlockedError") {
				yield* tokenLock.withPermits(1)(removeRejectedToken(input.expectedEnvironmentId, selected.token.accessToken));
			};
			return yield* mapDpopSocketError(socket.failure);
		};
		yield* assertSession(selected.identity);
		return authorized(selected.token, socket.success);
	});
	return RemoteEnvironmentAuthorization.of({
		authorizeBearer,
		authorizeDpop: (input) => authorizeDpop(input).pipe(__vite_ssr_import_13__.withSpan("environment.authorization")),
		authorizeDpopHttp: (input) => getDpopToken(input).pipe(__vite_ssr_import_13__.map(({ token }) => httpAuthorization(token)), __vite_ssr_import_13__.withSpan("environment.authorization.http"), (0,__vite_ssr_import_2__.withRelayClientTracing))
	});
});
const layer = __vite_ssr_import_15__.effect(RemoteEnvironmentAuthorization, make);
//# sourceMappingSource=vite-generated
//# sourceMappingURL=data:application/json;base64,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UUFBUSxTQUFTLCtCQUErQjtJQUN6RixPQUFPLE9BQU8sbUJBQW1CLGFBQWEsT0FBTztHQUN2RDtHQUNBLE9BQU8sY0FBYyxTQUFTLFFBQVE7R0FDdEMsV0FBVyxPQUFPLGFBQWE7SUFDN0IsR0FBRztJQUNILHFCQUFxQixTQUFTLE1BQU07R0FDdEMsQ0FBQztFQUNIO0VBQ0EsTUFBTSxTQUFTLE9BQU8sb0JBQW9CLFNBQVMsT0FBTyxXQUFXLFFBQVEsQ0FBQyxDQUFDLEtBQzdFLHVCQUFPLE1BQ1Q7RUFDQSxJQUFJLHVCQUFPLFVBQVUsTUFBTSxHQUFHO0dBQzVCLElBQUksYUFBYSxhQUFhLE9BQU8sUUFBUSxTQUFTLDBCQUEwQjtJQUM5RSxPQUFPLFVBQVUsWUFBWSxDQUFDLENBQUMsQ0FDN0Isb0JBQW9CLE1BQU0sdUJBQXVCLFNBQVMsTUFBTSxXQUFXLENBQzdFO0dBQ0Y7R0FDQSxPQUFPLE9BQU8sbUJBQW1CLE9BQU8sT0FBTztFQUNqRDtFQUNBLE9BQU8sY0FBYyxTQUFTLFFBQVE7RUFDdEMsT0FBTyxXQUFXLFNBQVMsT0FBTyxPQUFPLE9BQU87Q0FDbEQsQ0FBQztDQUVELE9BQU8sK0JBQStCLEdBQUc7RUFDdkM7RUFDQSxnQkFBZ0IsVUFDZCxjQUFjLEtBQUssQ0FBQyxDQUFDLEtBQUssdUJBQU8sU0FBUywyQkFBMkIsQ0FBQztFQUN4RSxvQkFBb0IsVUFDbEIsYUFBYSxLQUFLLENBQUMsQ0FBQyxLQUNsQix1QkFBTyxLQUFLLEVBQUUsWUFBWSxrQkFBa0IsS0FBSyxDQUFDLEdBQ2xELHVCQUFPLFNBQVMsZ0NBQWdDLE1BQ2hELDZDQUNGO0NBQ0osQ0FBQztBQUNILENBQUM7QUFFTSxNQUFNLFFBQVEsdUJBQU0sT0FBTyxnQ0FBZ0MsSUFBSSIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsic2VydmljZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICB0eXBlIENsaWVudENvbm5lY3Rpb25NZXRob2QsXG4gIEVudmlyb25tZW50SWQsXG4gIHR5cGUgRXhlY3V0aW9uRW52aXJvbm1lbnREZXNjcmlwdG9yLFxufSBmcm9tIFwiQHQzdG9vbHMvY29udHJhY3RzXCI7XG5pbXBvcnQgeyBSZWxheUVudmlyb25tZW50Q29ubmVjdFNjb3BlIH0gZnJvbSBcIkB0M3Rvb2xzL2NvbnRyYWN0cy9yZWxheVwiO1xuaW1wb3J0IHsgd2l0aFJlbGF5Q2xpZW50VHJhY2luZyB9IGZyb20gXCJAdDN0b29scy9zaGFyZWQvcmVsYXlUcmFjaW5nXCI7XG5pbXBvcnQge1xuICBleGNoYW5nZVJlbW90ZURwb3BBY2Nlc3NUb2tlbixcbiAgdHlwZSBSZW1vdGVFbnZpcm9ubWVudEF1dGhFcnJvcixcbiAgcmVzb2x2ZVJlbW90ZURwb3BXZWJTb2NrZXRDb25uZWN0aW9uVXJsLFxuICByZXNvbHZlUmVtb3RlV2ViU29ja2V0Q29ubmVjdGlvblVybCxcbn0gZnJvbSBcIi4vcmVtb3RlLnRzXCI7XG5pbXBvcnQge1xuICBlbnZpcm9ubWVudE1pc21hdGNoRXJyb3IsXG4gIG1hcE1hbmFnZWRSZWxheUVycm9yLFxuICBtYXBSZW1vdGVEcG9wRW52aXJvbm1lbnRFcnJvcixcbiAgbWFwUmVtb3RlRW52aXJvbm1lbnRFcnJvcixcbn0gZnJvbSBcIi4uL2Nvbm5lY3Rpb24vZXJyb3JzLnRzXCI7XG5pbXBvcnQge1xuICBDb25uZWN0aW9uQmxvY2tlZEVycm9yLFxuICBDb25uZWN0aW9uVHJhbnNpZW50RXJyb3IsXG4gIHR5cGUgQ29ubmVjdGlvbkF0dGVtcHRFcnJvcixcbn0gZnJvbSBcIi4uL2Nvbm5lY3Rpb24vbW9kZWwudHNcIjtcbmltcG9ydCB7IGZldGNoUmVtb3RlRW52aXJvbm1lbnREZXNjcmlwdG9yIH0gZnJvbSBcIi4uL2Vudmlyb25tZW50L2Rlc2NyaXB0b3IudHNcIjtcbmltcG9ydCB7IGVudmlyb25tZW50RW5kcG9pbnRVcmwgfSBmcm9tIFwiLi4vZW52aXJvbm1lbnQvZW5kcG9pbnQudHNcIjtcbmltcG9ydCAqIGFzIENsaWVudENhcGFiaWxpdGllcyBmcm9tIFwiLi4vcGxhdGZvcm0vY2FwYWJpbGl0aWVzLnRzXCI7XG5pbXBvcnQgKiBhcyBNYW5hZ2VkUmVsYXkgZnJvbSBcIi4uL3JlbGF5L21hbmFnZWRSZWxheS50c1wiO1xuaW1wb3J0ICogYXMgVG9rZW5TdG9yZSBmcm9tIFwiLi90b2tlblN0b3JlLnRzXCI7XG5pbXBvcnQgKiBhcyBDbG9jayBmcm9tIFwiZWZmZWN0L0Nsb2NrXCI7XG5pbXBvcnQgKiBhcyBDb250ZXh0IGZyb20gXCJlZmZlY3QvQ29udGV4dFwiO1xuaW1wb3J0ICogYXMgRWZmZWN0IGZyb20gXCJlZmZlY3QvRWZmZWN0XCI7XG5pbXBvcnQgKiBhcyBGaWJlciBmcm9tIFwiZWZmZWN0L0ZpYmVyXCI7XG5pbXBvcnQgKiBhcyBMYXllciBmcm9tIFwiZWZmZWN0L0xheWVyXCI7XG5pbXBvcnQgKiBhcyBPcHRpb24gZnJvbSBcImVmZmVjdC9PcHRpb25cIjtcbmltcG9ydCAqIGFzIFJlZiBmcm9tIFwiZWZmZWN0L1JlZlwiO1xuaW1wb3J0ICogYXMgUmVzdWx0IGZyb20gXCJlZmZlY3QvUmVzdWx0XCI7XG5pbXBvcnQgKiBhcyBTY29wZSBmcm9tIFwiZWZmZWN0L1Njb3BlXCI7XG5pbXBvcnQgKiBhcyBTZW1hcGhvcmUgZnJvbSBcImVmZmVjdC9TZW1hcGhvcmVcIjtcbmltcG9ydCAqIGFzIEh0dHBDbGllbnQgZnJvbSBcImVmZmVjdC9odHRwL0h0dHBDbGllbnRcIjtcblxuaW1wb3J0IHtcbiAgRFBPUF9BQ0NFU1NfVE9LRU5fUkVGUkVTSF9TS0VXX01TLFxuICB0eXBlIFByZXBhcmVkSHR0cEF1dGhvcml6YXRpb24sXG59IGZyb20gXCIuLi9jb25uZWN0aW9uL21vZGVsLnRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aG9yaXplZFJlbW90ZUVudmlyb25tZW50IHtcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnRJZDogRW52aXJvbm1lbnRJZDtcbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcbiAgcmVhZG9ubHkgaHR0cEJhc2VVcmw6IHN0cmluZztcbiAgcmVhZG9ubHkgc29ja2V0VXJsOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGh0dHBBdXRob3JpemF0aW9uOiBQcmVwYXJlZEh0dHBBdXRob3JpemF0aW9uO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhvcml6ZWRSZW1vdGVIdHRwRW52aXJvbm1lbnQge1xuICByZWFkb25seSBlbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkO1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuICByZWFkb25seSBodHRwQmFzZVVybDogc3RyaW5nO1xuICByZWFkb25seSBodHRwQXV0aG9yaXphdGlvbjogRXh0cmFjdDxQcmVwYXJlZEh0dHBBdXRob3JpemF0aW9uLCB7IHJlYWRvbmx5IF90YWc6IFwiRHBvcFwiIH0+O1xufVxuXG5leHBvcnQgY2xhc3MgUmVtb3RlRW52aXJvbm1lbnRBdXRob3JpemF0aW9uIGV4dGVuZHMgQ29udGV4dC5TZXJ2aWNlPFxuICBSZW1vdGVFbnZpcm9ubWVudEF1dGhvcml6YXRpb24sXG4gIHtcbiAgICByZWFkb25seSBhdXRob3JpemVCZWFyZXI6IChpbnB1dDoge1xuICAgICAgcmVhZG9ubHkgZXhwZWN0ZWRFbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkO1xuICAgICAgcmVhZG9ubHkgaHR0cEJhc2VVcmw6IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IHdzQmFzZVVybDogc3RyaW5nO1xuICAgICAgcmVhZG9ubHkgYmVhcmVyVG9rZW46IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IGNvbm5lY3Rpb25NZXRob2Q6IENsaWVudENvbm5lY3Rpb25NZXRob2Q7XG4gICAgfSkgPT4gRWZmZWN0LkVmZmVjdDxBdXRob3JpemVkUmVtb3RlRW52aXJvbm1lbnQsIENvbm5lY3Rpb25BdHRlbXB0RXJyb3I+O1xuICAgIHJlYWRvbmx5IGF1dGhvcml6ZURwb3A6IChpbnB1dDoge1xuICAgICAgcmVhZG9ubHkgZXhwZWN0ZWRFbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkO1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgYWNjZXNzIHRva2VuIGlzIG5vdCBib3VuZCB0byBhbiBvcmlnaW4sIGFuZCBlYWNoIHByb29mIGlzIG1pbnRlZFxuICAgICAgICogZm9yIHRoZSBVUkwgaXQgc2lnbnMsIHNvIGEgdG9rZW4gZnJvbSB0aGUgcmVsYXkgYWxzbyB3b3JrcyBvbiB0aGVcbiAgICAgICAqIGVudmlyb25tZW50J3MgTEFOIG9yIHRhaWxuZXQgYWRkcmVzcy5cbiAgICAgICAqL1xuICAgICAgcmVhZG9ubHkgZGlyZWN0RW5kcG9pbnQ/OiB7IHJlYWRvbmx5IGh0dHBCYXNlVXJsOiBzdHJpbmc7IHJlYWRvbmx5IHdzQmFzZVVybDogc3RyaW5nIH07XG4gICAgfSkgPT4gRWZmZWN0LkVmZmVjdDxBdXRob3JpemVkUmVtb3RlRW52aXJvbm1lbnQsIENvbm5lY3Rpb25BdHRlbXB0RXJyb3I+O1xuICAgIHJlYWRvbmx5IGF1dGhvcml6ZURwb3BIdHRwOiAoaW5wdXQ6IHtcbiAgICAgIHJlYWRvbmx5IGV4cGVjdGVkRW52aXJvbm1lbnRJZDogRW52aXJvbm1lbnRJZDtcbiAgICAgIHJlYWRvbmx5IHJlamVjdGVkQWNjZXNzVG9rZW4/OiBzdHJpbmc7XG4gICAgfSkgPT4gRWZmZWN0LkVmZmVjdDxBdXRob3JpemVkUmVtb3RlSHR0cEVudmlyb25tZW50LCBDb25uZWN0aW9uQXR0ZW1wdEVycm9yPjtcbiAgfVxuPigpKFwiQHQzdG9vbHMvY2xpZW50LXJ1bnRpbWUvYXV0aG9yaXphdGlvbi9zZXJ2aWNlL1JlbW90ZUVudmlyb25tZW50QXV0aG9yaXphdGlvblwiKSB7fVxuXG5jb25zdCBDQUNIRURfRU5EUE9JTlRfU09DS0VUX1RJTUVPVVRfTVMgPSAzXzAwMDtcbmNvbnN0IEJFQVJFUl9ERVNDUklQVE9SX0NBQ0hFX1RUTF9NUyA9IDEwXzAwMDtcbmNvbnN0IERQT1BfQVVUSE9SSVpBVElPTl9USU1FT1VUX01TID0gMzBfMDAwO1xuXG5mdW5jdGlvbiBtYXBEcG9wU29ja2V0RXJyb3IoZXJyb3I6IFJlbW90ZUVudmlyb25tZW50QXV0aEVycm9yIHwgQ29ubmVjdGlvbkF0dGVtcHRFcnJvcikge1xuICByZXR1cm4gZXJyb3IuX3RhZyA9PT0gXCJDb25uZWN0aW9uVHJhbnNpZW50RXJyb3JcIiB8fCBlcnJvci5fdGFnID09PSBcIkNvbm5lY3Rpb25CbG9ja2VkRXJyb3JcIlxuICAgID8gZXJyb3JcbiAgICA6IG1hcFJlbW90ZURwb3BFbnZpcm9ubWVudEVycm9yKGVycm9yKTtcbn1cblxuY29uc3QgZmV0Y2hEZXNjcmlwdG9yID0gRWZmZWN0LmZuKFwiY2xpZW50UnVudGltZS5jb25uZWN0aW9uLnJlbW90ZS5mZXRjaERlc2NyaXB0b3JcIikoZnVuY3Rpb24qIChcbiAgaHR0cEJhc2VVcmw6IHN0cmluZyxcbiAgY29ubmVjdGlvbk1ldGhvZDogQ2xpZW50Q29ubmVjdGlvbk1ldGhvZCxcbikge1xuICByZXR1cm4geWllbGQqIGZldGNoUmVtb3RlRW52aXJvbm1lbnREZXNjcmlwdG9yKHsgaHR0cEJhc2VVcmwgfSkucGlwZShcbiAgICBFZmZlY3QubWFwRXJyb3IoKGVycm9yKSA9PiBtYXBSZW1vdGVFbnZpcm9ubWVudEVycm9yKGVycm9yLCBjb25uZWN0aW9uTWV0aG9kKSksXG4gICk7XG59KTtcblxuZXhwb3J0IGNvbnN0IG1ha2UgPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gIGNvbnN0IHNlcnZpY2VTY29wZSA9IHlpZWxkKiBTY29wZS5TY29wZTtcbiAgY29uc3Qgc2lnbmVyID0geWllbGQqIE1hbmFnZWRSZWxheS5NYW5hZ2VkUmVsYXlEcG9wU2lnbmVyO1xuICBjb25zdCByZWxheSA9IHlpZWxkKiBNYW5hZ2VkUmVsYXkuTWFuYWdlZFJlbGF5Q2xpZW50O1xuICBjb25zdCBjbG91ZFNlc3Npb24gPSB5aWVsZCogQ2xpZW50Q2FwYWJpbGl0aWVzLkNsb3VkU2Vzc2lvbjtcbiAgY29uc3QgZGV2aWNlSWRlbnRpdHkgPSB5aWVsZCogQ2xpZW50Q2FwYWJpbGl0aWVzLlJlbGF5RGV2aWNlSWRlbnRpdHk7XG4gIGNvbnN0IHByZXNlbnRhdGlvbiA9IHlpZWxkKiBDbGllbnRDYXBhYmlsaXRpZXMuQ2xpZW50UHJlc2VudGF0aW9uO1xuICBjb25zdCB0b2tlblN0b3JlID0geWllbGQqIFRva2VuU3RvcmUuUmVtb3RlRHBvcEFjY2Vzc1Rva2VuU3RvcmU7XG4gIGNvbnN0IGh0dHBDbGllbnQgPSB5aWVsZCogSHR0cENsaWVudC5IdHRwQ2xpZW50O1xuICBjb25zdCB0b2tlbkxvY2sgPSB5aWVsZCogU2VtYXBob3JlLm1ha2UoMSk7XG4gIGNvbnN0IHRva2VuT3duZXJzID0gbmV3IE1hcDxcbiAgICBFbnZpcm9ubWVudElkLFxuICAgIHsgcmVhZG9ubHkgYWNjZXNzVG9rZW46IHN0cmluZzsgcmVhZG9ubHkgaWRlbnRpdHk6IENsaWVudENhcGFiaWxpdGllcy5DbG91ZFNlc3Npb25JZGVudGl0eSB9XG4gID4oKTtcbiAgY29uc3QgcGVuZGluZ1Rva2VucyA9IG5ldyBNYXA8XG4gICAgRW52aXJvbm1lbnRJZCxcbiAgICB7XG4gICAgICByZWFkb25seSBpZDogb2JqZWN0O1xuICAgICAgcmVhZG9ubHkgaWRlbnRpdHk6IENsaWVudENhcGFiaWxpdGllcy5DbG91ZFNlc3Npb25JZGVudGl0eTtcbiAgICAgIHJlYWRvbmx5IHRodW1icHJpbnQ6IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IHRva2VuOiBFZmZlY3QuRWZmZWN0PFRva2VuU3RvcmUuUmVtb3RlRHBvcEFjY2Vzc1Rva2VuLCBDb25uZWN0aW9uQXR0ZW1wdEVycm9yPjtcbiAgICB9XG4gID4oKTtcbiAgY29uc3QgYmVhcmVyRGVzY3JpcHRvcnMgPSB5aWVsZCogUmVmLm1ha2U8XG4gICAgUmVhZG9ubHlNYXA8XG4gICAgICBFbnZpcm9ubWVudElkLFxuICAgICAge1xuICAgICAgICByZWFkb25seSBodHRwQmFzZVVybDogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBkZXNjcmlwdG9yOiBFeGVjdXRpb25FbnZpcm9ubWVudERlc2NyaXB0b3I7XG4gICAgICAgIHJlYWRvbmx5IHZhbGlkYXRlZEF0RXBvY2hNczogbnVtYmVyO1xuICAgICAgfVxuICAgID5cbiAgPihuZXcgTWFwKCkpO1xuXG4gIC8qKlxuICAgKiBBIHNhdmVkIExBTiBhZGRyZXNzIGNhbiBiZWxvbmcgdG8gYW5vdGhlciBtYWNoaW5lIG9uIGEgZGlmZmVyZW50IG5ldHdvcmsuXG4gICAqL1xuICBjb25zdCB2ZXJpZnlEaXJlY3RFbmRwb2ludCA9IEVmZmVjdC5mbihcImNsaWVudFJ1bnRpbWUuY29ubmVjdGlvbi5yZW1vdGUudmVyaWZ5RGlyZWN0RW5kcG9pbnRcIikoXG4gICAgZnVuY3Rpb24qIChpbnB1dDoge1xuICAgICAgcmVhZG9ubHkgZXhwZWN0ZWRFbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkO1xuICAgICAgcmVhZG9ubHkgaHR0cEJhc2VVcmw6IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IGNvbm5lY3Rpb25NZXRob2Q6IENsaWVudENvbm5lY3Rpb25NZXRob2Q7XG4gICAgfSkge1xuICAgICAgY29uc3Qgbm93ID0geWllbGQqIENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzO1xuICAgICAgY29uc3QgY2FjaGVkRGVzY3JpcHRvciA9ICh5aWVsZCogUmVmLmdldChiZWFyZXJEZXNjcmlwdG9ycykpLmdldChpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQpO1xuICAgICAgY29uc3QgY2FuUmV1c2VEZXNjcmlwdG9yID1cbiAgICAgICAgY2FjaGVkRGVzY3JpcHRvcj8uaHR0cEJhc2VVcmwgPT09IGlucHV0Lmh0dHBCYXNlVXJsICYmXG4gICAgICAgIGNhY2hlZERlc2NyaXB0b3IudmFsaWRhdGVkQXRFcG9jaE1zICsgQkVBUkVSX0RFU0NSSVBUT1JfQ0FDSEVfVFRMX01TID4gbm93O1xuICAgICAgY29uc3QgZGVzY3JpcHRvciA9IGNhblJldXNlRGVzY3JpcHRvclxuICAgICAgICA/IGNhY2hlZERlc2NyaXB0b3IuZGVzY3JpcHRvclxuICAgICAgICA6IHlpZWxkKiBmZXRjaERlc2NyaXB0b3IoaW5wdXQuaHR0cEJhc2VVcmwsIGlucHV0LmNvbm5lY3Rpb25NZXRob2QpLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QucHJvdmlkZVNlcnZpY2UoSHR0cENsaWVudC5IdHRwQ2xpZW50LCBodHRwQ2xpZW50KSxcbiAgICAgICAgICApO1xuICAgICAgaWYgKGRlc2NyaXB0b3IuZW52aXJvbm1lbnRJZCAhPT0gaW5wdXQuZXhwZWN0ZWRFbnZpcm9ubWVudElkKSB7XG4gICAgICAgIHJldHVybiB5aWVsZCogZW52aXJvbm1lbnRNaXNtYXRjaEVycm9yKHtcbiAgICAgICAgICBleHBlY3RlZDogaW5wdXQuZXhwZWN0ZWRFbnZpcm9ubWVudElkLFxuICAgICAgICAgIGFjdHVhbDogZGVzY3JpcHRvci5lbnZpcm9ubWVudElkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghY2FuUmV1c2VEZXNjcmlwdG9yKSB7XG4gICAgICAgIHlpZWxkKiBSZWYudXBkYXRlKGJlYXJlckRlc2NyaXB0b3JzLCAoY3VycmVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXcgTWFwKGN1cnJlbnQpO1xuICAgICAgICAgIG5leHQuc2V0KGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCwge1xuICAgICAgICAgICAgaHR0cEJhc2VVcmw6IGlucHV0Lmh0dHBCYXNlVXJsLFxuICAgICAgICAgICAgZGVzY3JpcHRvcixcbiAgICAgICAgICAgIHZhbGlkYXRlZEF0RXBvY2hNczogbm93LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgIH0sXG4gICk7XG5cbiAgY29uc3QgYXV0aG9yaXplQmVhcmVyID0gRWZmZWN0LmZuKFwiY2xpZW50UnVudGltZS5jb25uZWN0aW9uLnJlbW90ZS5hdXRob3JpemVCZWFyZXJcIikoXG4gICAgZnVuY3Rpb24qIChpbnB1dDoge1xuICAgICAgcmVhZG9ubHkgZXhwZWN0ZWRFbnZpcm9ubWVudElkOiBQYXJhbWV0ZXJzPFxuICAgICAgICBSZW1vdGVFbnZpcm9ubWVudEF1dGhvcml6YXRpb25bXCJTZXJ2aWNlXCJdW1wiYXV0aG9yaXplQmVhcmVyXCJdXG4gICAgICA+WzBdW1wiZXhwZWN0ZWRFbnZpcm9ubWVudElkXCJdO1xuICAgICAgcmVhZG9ubHkgaHR0cEJhc2VVcmw6IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IHdzQmFzZVVybDogc3RyaW5nO1xuICAgICAgcmVhZG9ubHkgYmVhcmVyVG9rZW46IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IGNvbm5lY3Rpb25NZXRob2Q6IENsaWVudENvbm5lY3Rpb25NZXRob2Q7XG4gICAgfSkge1xuICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHlpZWxkKiB2ZXJpZnlEaXJlY3RFbmRwb2ludChpbnB1dCk7XG4gICAgICBjb25zdCBzb2NrZXRVcmwgPSB5aWVsZCogcmVzb2x2ZVJlbW90ZVdlYlNvY2tldENvbm5lY3Rpb25Vcmwoe1xuICAgICAgICB3c0Jhc2VVcmw6IGlucHV0LndzQmFzZVVybCxcbiAgICAgICAgaHR0cEJhc2VVcmw6IGlucHV0Lmh0dHBCYXNlVXJsLFxuICAgICAgICBiZWFyZXJUb2tlbjogaW5wdXQuYmVhcmVyVG9rZW4sXG4gICAgICAgIGNsaWVudE1ldGFkYXRhOiBwcmVzZW50YXRpb24ubWV0YWRhdGEsXG4gICAgICAgIGNvbm5lY3Rpb25NZXRob2Q6IGlucHV0LmNvbm5lY3Rpb25NZXRob2QsXG4gICAgICB9KS5waXBlKFxuICAgICAgICBFZmZlY3QubWFwRXJyb3IobWFwUmVtb3RlRW52aXJvbm1lbnRFcnJvciksXG4gICAgICAgIEVmZmVjdC5wcm92aWRlU2VydmljZShIdHRwQ2xpZW50Lkh0dHBDbGllbnQsIGh0dHBDbGllbnQpLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVudmlyb25tZW50SWQ6IGRlc2NyaXB0b3IuZW52aXJvbm1lbnRJZCxcbiAgICAgICAgbGFiZWw6IGRlc2NyaXB0b3IubGFiZWwsXG4gICAgICAgIGh0dHBCYXNlVXJsOiBpbnB1dC5odHRwQmFzZVVybCxcbiAgICAgICAgc29ja2V0VXJsLFxuICAgICAgICBodHRwQXV0aG9yaXphdGlvbjoge1xuICAgICAgICAgIF90YWc6IFwiQmVhcmVyXCIgYXMgY29uc3QsXG4gICAgICAgICAgdG9rZW46IGlucHV0LmJlYXJlclRva2VuLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICApO1xuXG4gIGNvbnN0IGNyZWF0ZURwb3BTb2NrZXRVcmwgPSBFZmZlY3QuZm4oXCJjbGllbnRSdW50aW1lLmNvbm5lY3Rpb24ucmVtb3RlLmNyZWF0ZURwb3BTb2NrZXRVcmxcIikoXG4gICAgZnVuY3Rpb24qIChcbiAgICAgIHRva2VuOiBUb2tlblN0b3JlLlJlbW90ZURwb3BBY2Nlc3NUb2tlbixcbiAgICAgIHRpbWVvdXRNcz86IG51bWJlcixcbiAgICAgIGVuZHBvaW50OiB7IHJlYWRvbmx5IGh0dHBCYXNlVXJsOiBzdHJpbmc7IHJlYWRvbmx5IHdzQmFzZVVybDogc3RyaW5nIH0gPSB0b2tlbi5lbmRwb2ludCxcbiAgICApIHtcbiAgICAgIHJldHVybiB5aWVsZCogcmVzb2x2ZVJlbW90ZURwb3BXZWJTb2NrZXRDb25uZWN0aW9uVXJsKHtcbiAgICAgICAgd3NCYXNlVXJsOiBlbmRwb2ludC53c0Jhc2VVcmwsXG4gICAgICAgIGh0dHBCYXNlVXJsOiBlbmRwb2ludC5odHRwQmFzZVVybCxcbiAgICAgICAgYWNjZXNzVG9rZW46IHRva2VuLmFjY2Vzc1Rva2VuLFxuICAgICAgICBjcmVhdGVQcm9vZjogKHByb29mKSA9PlxuICAgICAgICAgIHNpZ25lci5jcmVhdGVQcm9vZihwcm9vZikucGlwZShcbiAgICAgICAgICAgIEVmZmVjdC5tYXBFcnJvcihcbiAgICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvbkJsb2NrZWRFcnJvcih7XG4gICAgICAgICAgICAgICAgICByZWFzb246IFwiY29uZmlndXJhdGlvblwiLFxuICAgICAgICAgICAgICAgICAgZGV0YWlsOiBcIkNvdWxkIG5vdCBjcmVhdGUgdGhlIHdlYnNvY2tldCBhdXRob3JpemF0aW9uIHByb29mLlwiLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICBjbGllbnRNZXRhZGF0YTogcHJlc2VudGF0aW9uLm1ldGFkYXRhLFxuICAgICAgICBjb25uZWN0aW9uTWV0aG9kOiBcInJlbGF5XCIsXG4gICAgICAgIC4uLih0aW1lb3V0TXMgPT09IHVuZGVmaW5lZCA/IHt9IDogeyB0aW1lb3V0TXMgfSksXG4gICAgICB9KS5waXBlKEVmZmVjdC5wcm92aWRlU2VydmljZShIdHRwQ2xpZW50Lkh0dHBDbGllbnQsIGh0dHBDbGllbnQpKTtcbiAgICB9LFxuICApO1xuXG4gIGNvbnN0IHNlc3Npb25DaGFuZ2VkID0gKCkgPT5cbiAgICBuZXcgQ29ubmVjdGlvbkJsb2NrZWRFcnJvcih7XG4gICAgICByZWFzb246IFwiYXV0aGVudGljYXRpb25cIixcbiAgICAgIGRldGFpbDogXCJZb3VyIGNsb3VkIHNpZ24taW4gY2hhbmdlZC4gU2lnbiBpbiBhZ2FpbiB0byBhdXRob3JpemUgdGhlIGVudmlyb25tZW50LlwiLFxuICAgIH0pO1xuXG4gIC8vIEEgbWlzc2luZyBpZGVudGl0eSBiZWZvcmUgdGhlIGF0dGVtcHQgY2FwdHVyZXMgb25lIG1lYW5zIHRoZSBjbG91ZCBzZXNzaW9uXG4gIC8vIGlzIHN0aWxsIGxvYWRpbmcsIG5vdCBhIHNpZ24tb3V0LiBPbmx5IGEgY2FwdHVyZWQgaWRlbnRpdHkgdGhhdCBnb2VzIGF3YXlcbiAgLy8gb3IgY2hhbmdlcyBpcyBldmlkZW5jZSBvZiBvbmUuXG4gIGNvbnN0IHNlc3Npb25QZW5kaW5nID0gKCkgPT5cbiAgICBuZXcgQ29ubmVjdGlvblRyYW5zaWVudEVycm9yKHtcbiAgICAgIHJlYXNvbjogXCJzZXNzaW9uLXBlbmRpbmdcIixcbiAgICAgIGRldGFpbDogXCJXYWl0aW5nIGZvciB0aGUgVDMgQ29ubmVjdCBzaWduLWluIHRvIGxvYWQuXCIsXG4gICAgfSk7XG5cbiAgY29uc3QgYXNzZXJ0U2Vzc2lvbiA9IEVmZmVjdC5mblVudHJhY2VkKGZ1bmN0aW9uKiAoXG4gICAgaWRlbnRpdHk6IENsaWVudENhcGFiaWxpdGllcy5DbG91ZFNlc3Npb25JZGVudGl0eSxcbiAgKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHlpZWxkKiBjbG91ZFNlc3Npb24uaWRlbnRpdHk7XG4gICAgaWYgKE9wdGlvbi5pc05vbmUoY3VycmVudCkgfHwgY3VycmVudC52YWx1ZSAhPT0gaWRlbnRpdHkpIHtcbiAgICAgIHJldHVybiB5aWVsZCogc2Vzc2lvbkNoYW5nZWQoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIENhbGxlZCB1bmRlciB0b2tlbkxvY2sgc28gYSBsYXRlIHJlamVjdGlvbiBjYW5ub3QgcmVtb3ZlIGEgbmV3ZXIgY3JlZGVudGlhbC5cbiAgY29uc3QgcmVtb3ZlUmVqZWN0ZWRUb2tlbiA9IEVmZmVjdC5mblVudHJhY2VkKGZ1bmN0aW9uKiAoXG4gICAgZW52aXJvbm1lbnRJZDogRW52aXJvbm1lbnRJZCxcbiAgICBhY2Nlc3NUb2tlbjogc3RyaW5nLFxuICApIHtcbiAgICBjb25zdCBjYWNoZWQgPSB5aWVsZCogdG9rZW5TdG9yZS5nZXQoZW52aXJvbm1lbnRJZCk7XG4gICAgaWYgKE9wdGlvbi5pc1NvbWUoY2FjaGVkKSAmJiBjYWNoZWQudmFsdWUuYWNjZXNzVG9rZW4gPT09IGFjY2Vzc1Rva2VuKSB7XG4gICAgICB5aWVsZCogdG9rZW5TdG9yZS5yZW1vdmUoZW52aXJvbm1lbnRJZCk7XG4gICAgICB0b2tlbk93bmVycy5kZWxldGUoZW52aXJvbm1lbnRJZCk7XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBvYnRhaW5Cb290c3RyYXAgPSBFZmZlY3QuZm4oXCJyZWxheS5jb25uZWN0aW9uLmJvb3RzdHJhcC5vYnRhaW5cIikoZnVuY3Rpb24qIChcbiAgICBlbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkLFxuICAgIGlkZW50aXR5OiBDbGllbnRDYXBhYmlsaXRpZXMuQ2xvdWRTZXNzaW9uSWRlbnRpdHksXG4gICkge1xuICAgIHlpZWxkKiBhc3NlcnRTZXNzaW9uKGlkZW50aXR5KTtcbiAgICBjb25zdCBjbGVya1Rva2VuID0geWllbGQqIGNsb3VkU2Vzc2lvbi5jbGVya1Rva2VuLnBpcGUoXG4gICAgICBFZmZlY3Qud2l0aFNwYW4oXCJyZWxheS5jb25uZWN0aW9uLmNsb3VkU2Vzc2lvblRva2VuLnJlc29sdmVcIiksXG4gICAgKTtcbiAgICBjb25zdCBkZXZpY2VJZCA9IHlpZWxkKiBkZXZpY2VJZGVudGl0eS5kZXZpY2VJZC5waXBlKFxuICAgICAgRWZmZWN0LndpdGhTcGFuKFwicmVsYXkuY29ubmVjdGlvbi5kZXZpY2VJZGVudGl0eS5yZXNvbHZlXCIpLFxuICAgICk7XG4gICAgeWllbGQqIGFzc2VydFNlc3Npb24oaWRlbnRpdHkpO1xuICAgIGNvbnN0IGNvbm5lY3RlZCA9IHlpZWxkKiByZWxheVxuICAgICAgLmNvbm5lY3RFbnZpcm9ubWVudCh7XG4gICAgICAgIGNsZXJrVG9rZW4sXG4gICAgICAgIHNjb3BlczogW1JlbGF5RW52aXJvbm1lbnRDb25uZWN0U2NvcGVdLFxuICAgICAgICBlbnZpcm9ubWVudElkLFxuICAgICAgICAuLi4oT3B0aW9uLmlzU29tZShkZXZpY2VJZCkgPyB7IGRldmljZUlkOiBkZXZpY2VJZC52YWx1ZSB9IDoge30pLFxuICAgICAgfSlcbiAgICAgIC5waXBlKEVmZmVjdC5tYXBFcnJvcihtYXBNYW5hZ2VkUmVsYXlFcnJvcikpO1xuICAgIGlmIChjb25uZWN0ZWQuZW52aXJvbm1lbnRJZCAhPT0gZW52aXJvbm1lbnRJZCkge1xuICAgICAgcmV0dXJuIHlpZWxkKiBlbnZpcm9ubWVudE1pc21hdGNoRXJyb3Ioe1xuICAgICAgICBleHBlY3RlZDogZW52aXJvbm1lbnRJZCxcbiAgICAgICAgYWN0dWFsOiBjb25uZWN0ZWQuZW52aXJvbm1lbnRJZCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihpZGVudGl0eSk7XG4gICAgcmV0dXJuIGNvbm5lY3RlZDtcbiAgfSk7XG5cbiAgY29uc3QgZXhjaGFuZ2VEcG9wVG9rZW4gPSBFZmZlY3QuZm4oXCJjbGllbnRSdW50aW1lLmNvbm5lY3Rpb24ucmVtb3RlLmV4Y2hhbmdlRHBvcFRva2VuXCIpKFxuICAgIGZ1bmN0aW9uKiAoXG4gICAgICBlbnZpcm9ubWVudElkOiBFbnZpcm9ubWVudElkLFxuICAgICAgdGh1bWJwcmludDogc3RyaW5nLFxuICAgICAgaWRlbnRpdHk6IENsaWVudENhcGFiaWxpdGllcy5DbG91ZFNlc3Npb25JZGVudGl0eSxcbiAgICApIHtcbiAgICAgIGNvbnN0IGJvb3RzdHJhcCA9IHlpZWxkKiBvYnRhaW5Cb290c3RyYXAoZW52aXJvbm1lbnRJZCwgaWRlbnRpdHkpO1xuICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHlpZWxkKiBmZXRjaERlc2NyaXB0b3IoYm9vdHN0cmFwLmVuZHBvaW50Lmh0dHBCYXNlVXJsLCBcInJlbGF5XCIpLnBpcGUoXG4gICAgICAgIEVmZmVjdC5wcm92aWRlU2VydmljZShIdHRwQ2xpZW50Lkh0dHBDbGllbnQsIGh0dHBDbGllbnQpLFxuICAgICAgICBFZmZlY3Qud2l0aFNwYW4oXCJlbnZpcm9ubWVudC5hdXRob3JpemF0aW9uLmRlc2NyaXB0b3JcIiksXG4gICAgICApO1xuICAgICAgaWYgKGRlc2NyaXB0b3IuZW52aXJvbm1lbnRJZCAhPT0gZW52aXJvbm1lbnRJZCkge1xuICAgICAgICByZXR1cm4geWllbGQqIGVudmlyb25tZW50TWlzbWF0Y2hFcnJvcih7XG4gICAgICAgICAgZXhwZWN0ZWQ6IGVudmlyb25tZW50SWQsXG4gICAgICAgICAgYWN0dWFsOiBkZXNjcmlwdG9yLmVudmlyb25tZW50SWQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9vdHN0cmFwUHJvb2YgPSB5aWVsZCogc2lnbmVyXG4gICAgICAgIC5jcmVhdGVQcm9vZih7XG4gICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICB1cmw6IGVudmlyb25tZW50RW5kcG9pbnRVcmwoYm9vdHN0cmFwLmVuZHBvaW50Lmh0dHBCYXNlVXJsLCBcIi9vYXV0aC90b2tlblwiKSxcbiAgICAgICAgfSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgRWZmZWN0Lm1hcEVycm9yKFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgbmV3IENvbm5lY3Rpb25CbG9ja2VkRXJyb3Ioe1xuICAgICAgICAgICAgICAgIHJlYXNvbjogXCJjb25maWd1cmF0aW9uXCIsXG4gICAgICAgICAgICAgICAgZGV0YWlsOiBcIkNvdWxkIG5vdCBjcmVhdGUgdGhlIGVudmlyb25tZW50IGF1dGhvcml6YXRpb24gcHJvb2YuXCIsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihpZGVudGl0eSk7XG4gICAgICBjb25zdCBhY2Nlc3MgPSB5aWVsZCogZXhjaGFuZ2VSZW1vdGVEcG9wQWNjZXNzVG9rZW4oe1xuICAgICAgICBodHRwQmFzZVVybDogYm9vdHN0cmFwLmVuZHBvaW50Lmh0dHBCYXNlVXJsLFxuICAgICAgICBjcmVkZW50aWFsOiBib290c3RyYXAuY3JlZGVudGlhbCxcbiAgICAgICAgZHBvcFByb29mOiBib290c3RyYXBQcm9vZixcbiAgICAgICAgY2xpZW50TWV0YWRhdGE6IHByZXNlbnRhdGlvbi5tZXRhZGF0YSxcbiAgICAgIH0pLnBpcGUoXG4gICAgICAgIEVmZmVjdC5tYXBFcnJvcihtYXBSZW1vdGVEcG9wRW52aXJvbm1lbnRFcnJvciksXG4gICAgICAgIEVmZmVjdC5wcm92aWRlU2VydmljZShIdHRwQ2xpZW50Lkh0dHBDbGllbnQsIGh0dHBDbGllbnQpLFxuICAgICAgICBFZmZlY3Qud2l0aFNwYW4oXCJlbnZpcm9ubWVudC5hdXRob3JpemF0aW9uLmFjY2Vzc1Rva2VuLmV4Y2hhbmdlXCIpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzc3VlZEF0ID0geWllbGQqIENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzO1xuICAgICAgcmV0dXJuIG5ldyBUb2tlblN0b3JlLlJlbW90ZURwb3BBY2Nlc3NUb2tlbih7XG4gICAgICAgIGVudmlyb25tZW50SWQ6IGRlc2NyaXB0b3IuZW52aXJvbm1lbnRJZCxcbiAgICAgICAgYWNjb3VudElkOiBpZGVudGl0eS5hY2NvdW50SWQsXG4gICAgICAgIGxhYmVsOiBkZXNjcmlwdG9yLmxhYmVsLFxuICAgICAgICBlbmRwb2ludDogYm9vdHN0cmFwLmVuZHBvaW50LFxuICAgICAgICBhY2Nlc3NUb2tlbjogYWNjZXNzLmFjY2Vzc190b2tlbixcbiAgICAgICAgZXhwaXJlc0F0RXBvY2hNczogaXNzdWVkQXQgKyBhY2Nlc3MuZXhwaXJlc19pbiAqIDFfMDAwLFxuICAgICAgICBkcG9wVGh1bWJwcmludDogdGh1bWJwcmludCxcbiAgICAgIH0pO1xuICAgIH0sXG4gICk7XG5cbiAgY29uc3QgZ2V0RHBvcFRva2VuID0gRWZmZWN0LmZuKFwiY2xpZW50UnVudGltZS5jb25uZWN0aW9uLnJlbW90ZS5nZXREcG9wVG9rZW5cIikoZnVuY3Rpb24qIChcbiAgICBpbnB1dDogUGFyYW1ldGVyczxSZW1vdGVFbnZpcm9ubWVudEF1dGhvcml6YXRpb25bXCJTZXJ2aWNlXCJdW1wiYXV0aG9yaXplRHBvcEh0dHBcIl0+WzBdLFxuICApIHtcbiAgICBjb25zdCBzZXNzaW9uID0geWllbGQqIGNsb3VkU2Vzc2lvbi5pZGVudGl0eTtcbiAgICBpZiAoT3B0aW9uLmlzTm9uZShzZXNzaW9uKSkge1xuICAgICAgcmV0dXJuIHlpZWxkKiBzZXNzaW9uUGVuZGluZygpO1xuICAgIH1cbiAgICBjb25zdCBpZGVudGl0eSA9IHNlc3Npb24udmFsdWU7XG4gICAgY29uc3QgdGh1bWJwcmludCA9IHlpZWxkKiBzaWduZXIudGh1bWJwcmludC5waXBlKFxuICAgICAgRWZmZWN0Lm1hcEVycm9yKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyBDb25uZWN0aW9uQmxvY2tlZEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJjb25maWd1cmF0aW9uXCIsXG4gICAgICAgICAgICBkZXRhaWw6IFwiQ291bGQgbm90IGxvYWQgdGhlIGVudmlyb25tZW50IGF1dGhvcml6YXRpb24ga2V5LlwiLFxuICAgICAgICAgIH0pLFxuICAgICAgKSxcbiAgICAgIEVmZmVjdC53aXRoU3BhbihcImVudmlyb25tZW50LmF1dGhvcml6YXRpb24uZHBvcEtleS5yZXNvbHZlXCIpLFxuICAgICk7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB5aWVsZCogdG9rZW5Mb2NrLndpdGhQZXJtaXRzKDEpKFxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihpZGVudGl0eSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IHlpZWxkKiBDbG9jay5jdXJyZW50VGltZU1pbGxpcztcbiAgICAgICAgY29uc3QgY2FjaGVkID0geWllbGQqIHRva2VuU3RvcmVcbiAgICAgICAgICAuZ2V0KGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZClcbiAgICAgICAgICAucGlwZShFZmZlY3Qud2l0aFNwYW4oXCJlbnZpcm9ubWVudC5hdXRob3JpemF0aW9uLmFjY2Vzc1Rva2VuLmNhY2hlXCIpKTtcbiAgICAgICAgY29uc3Qgb3duZXIgPSB0b2tlbk93bmVycy5nZXQoaW5wdXQuZXhwZWN0ZWRFbnZpcm9ubWVudElkKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIE9wdGlvbi5pc1NvbWUoY2FjaGVkKSAmJlxuICAgICAgICAgIGNhY2hlZC52YWx1ZS5lbnZpcm9ubWVudElkID09PSBpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQgJiZcbiAgICAgICAgICBjYWNoZWQudmFsdWUuYWNjb3VudElkID09PSBpZGVudGl0eS5hY2NvdW50SWQgJiZcbiAgICAgICAgICBjYWNoZWQudmFsdWUuZHBvcFRodW1icHJpbnQgPT09IHRodW1icHJpbnQgJiZcbiAgICAgICAgICBjYWNoZWQudmFsdWUuZXhwaXJlc0F0RXBvY2hNcyA+IG5vdyArIERQT1BfQUNDRVNTX1RPS0VOX1JFRlJFU0hfU0tFV19NUyAmJlxuICAgICAgICAgIGNhY2hlZC52YWx1ZS5hY2Nlc3NUb2tlbiAhPT0gaW5wdXQucmVqZWN0ZWRBY2Nlc3NUb2tlbiAmJlxuICAgICAgICAgIChvd25lcj8uYWNjZXNzVG9rZW4gIT09IGNhY2hlZC52YWx1ZS5hY2Nlc3NUb2tlbiB8fCBvd25lci5pZGVudGl0eSA9PT0gaWRlbnRpdHkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRva2VuT3duZXJzLnNldChpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQsIHtcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiBjYWNoZWQudmFsdWUuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4geyB0b2tlbjogRWZmZWN0LnN1Y2NlZWQoY2FjaGVkLnZhbHVlKSwgZnJvbUNhY2hlOiB0cnVlIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0LnJlamVjdGVkQWNjZXNzVG9rZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHlpZWxkKiByZW1vdmVSZWplY3RlZFRva2VuKGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCwgaW5wdXQucmVqZWN0ZWRBY2Nlc3NUb2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHBlbmRpbmdUb2tlbnMuZ2V0KGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCk7XG4gICAgICAgIGlmIChwZW5kaW5nPy5pZGVudGl0eSA9PT0gaWRlbnRpdHkgJiYgcGVuZGluZy50aHVtYnByaW50ID09PSB0aHVtYnByaW50KSB7XG4gICAgICAgICAgcmV0dXJuIHsgdG9rZW46IHBlbmRpbmcudG9rZW4sIGZyb21DYWNoZTogZmFsc2UgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlkID0ge307XG4gICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIGV4Y2hhbmdlRHBvcFRva2VuKFxuICAgICAgICAgIGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCxcbiAgICAgICAgICB0aHVtYnByaW50LFxuICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICApLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKHRva2VuKSA9PlxuICAgICAgICAgICAgdG9rZW5Mb2NrLndpdGhQZXJtaXRzKDEpKFxuICAgICAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgeWllbGQqIGFzc2VydFNlc3Npb24oaWRlbnRpdHkpO1xuICAgICAgICAgICAgICAgIHlpZWxkKiB0b2tlblN0b3JlXG4gICAgICAgICAgICAgICAgICAucHV0KHRva2VuKVxuICAgICAgICAgICAgICAgICAgLnBpcGUoRWZmZWN0LndpdGhTcGFuKFwiZW52aXJvbm1lbnQuYXV0aG9yaXphdGlvbi5hY2Nlc3NUb2tlbi5wZXJzaXN0XCIpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50ID0geWllbGQqIGNsb3VkU2Vzc2lvbi5pZGVudGl0eTtcbiAgICAgICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShjdXJyZW50KSB8fCBjdXJyZW50LnZhbHVlICE9PSBpZGVudGl0eSkge1xuICAgICAgICAgICAgICAgICAgeWllbGQqIHJlbW92ZVJlamVjdGVkVG9rZW4oaW5wdXQuZXhwZWN0ZWRFbnZpcm9ubWVudElkLCB0b2tlbi5hY2Nlc3NUb2tlbik7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geWllbGQqIHNlc3Npb25DaGFuZ2VkKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRva2VuT3duZXJzLnNldChpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQsIHtcbiAgICAgICAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiB0b2tlbi5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nVG9rZW5zLmdldChpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQpPy5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICAgIHBlbmRpbmdUb2tlbnMuZGVsZXRlKGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbjtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICksXG4gICAgICAgICAgRWZmZWN0LnRpbWVvdXRPckVsc2Uoe1xuICAgICAgICAgICAgZHVyYXRpb246IERQT1BfQVVUSE9SSVpBVElPTl9USU1FT1VUX01TLFxuICAgICAgICAgICAgb3JFbHNlOiAoKSA9PlxuICAgICAgICAgICAgICBFZmZlY3QuZmFpbChcbiAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvblRyYW5zaWVudEVycm9yKHtcbiAgICAgICAgICAgICAgICAgIHJlYXNvbjogXCJ0aW1lb3V0XCIsXG4gICAgICAgICAgICAgICAgICBkZXRhaWw6IFwiVGltZWQgb3V0IHJlbmV3aW5nIHRoZSBlbnZpcm9ubWVudCBjcmVkZW50aWFsLlwiLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgICAgIHRva2VuTG9jay53aXRoUGVybWl0cygxKShcbiAgICAgICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nVG9rZW5zLmdldChpbnB1dC5leHBlY3RlZEVudmlyb25tZW50SWQpPy5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICAgIHBlbmRpbmdUb2tlbnMuZGVsZXRlKGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSxcbiAgICAgICAgICAvLyBPbmUgY2FsbGVyJ3MgdGltZW91dCBtdXN0IG5vdCBjYW5jZWwgcmVuZXdhbCBmb3Igb3RoZXIgSFRUUCByZXF1ZXN0cy5cbiAgICAgICAgICBFZmZlY3QuZm9ya0luKHNlcnZpY2VTY29wZSksXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHRva2VuID0gRmliZXIuam9pbihmaWJlcik7XG4gICAgICAgIHBlbmRpbmdUb2tlbnMuc2V0KGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCwgeyBpZCwgaWRlbnRpdHksIHRodW1icHJpbnQsIHRva2VuIH0pO1xuICAgICAgICByZXR1cm4geyB0b2tlbiwgZnJvbUNhY2hlOiBmYWxzZSB9O1xuICAgICAgfSksXG4gICAgKTtcbiAgICB5aWVsZCogRWZmZWN0LmFubm90YXRlQ3VycmVudFNwYW4oe1xuICAgICAgXCJjb25uZWN0aW9uLnJlbW90ZV90b2tlbl9jYWNoZVwiOiBzZWxlY3RlZC5mcm9tQ2FjaGUgPyBcImhpdFwiIDogXCJtaXNzXCIsXG4gICAgfSk7XG4gICAgY29uc3QgdG9rZW4gPSB5aWVsZCogc2VsZWN0ZWQudG9rZW47XG4gICAgeWllbGQqIGFzc2VydFNlc3Npb24oaWRlbnRpdHkpO1xuICAgIHJldHVybiB7IHRva2VuLCBmcm9tQ2FjaGU6IHNlbGVjdGVkLmZyb21DYWNoZSwgaWRlbnRpdHkgfTtcbiAgfSk7XG5cbiAgY29uc3QgaHR0cEF1dGhvcml6YXRpb24gPSAoXG4gICAgdG9rZW46IFRva2VuU3RvcmUuUmVtb3RlRHBvcEFjY2Vzc1Rva2VuLFxuICAgIGh0dHBCYXNlVXJsID0gdG9rZW4uZW5kcG9pbnQuaHR0cEJhc2VVcmwsXG4gICk6IEF1dGhvcml6ZWRSZW1vdGVIdHRwRW52aXJvbm1lbnQgPT4gKHtcbiAgICBlbnZpcm9ubWVudElkOiB0b2tlbi5lbnZpcm9ubWVudElkLFxuICAgIGxhYmVsOiB0b2tlbi5sYWJlbCxcbiAgICBodHRwQmFzZVVybCxcbiAgICBodHRwQXV0aG9yaXphdGlvbjoge1xuICAgICAgX3RhZzogXCJEcG9wXCIsXG4gICAgICBhY2Nlc3NUb2tlbjogdG9rZW4uYWNjZXNzVG9rZW4sXG4gICAgICBleHBpcmVzQXRFcG9jaE1zOiB0b2tlbi5leHBpcmVzQXRFcG9jaE1zLFxuICAgIH0sXG4gIH0pO1xuXG4gIGNvbnN0IGF1dGhvcml6ZURwb3AgPSBFZmZlY3QuZm4oXCJjbGllbnRSdW50aW1lLmNvbm5lY3Rpb24ucmVtb3RlLmF1dGhvcml6ZURwb3BcIikoZnVuY3Rpb24qIChcbiAgICBpbnB1dDogUGFyYW1ldGVyczxSZW1vdGVFbnZpcm9ubWVudEF1dGhvcml6YXRpb25bXCJTZXJ2aWNlXCJdW1wiYXV0aG9yaXplRHBvcFwiXT5bMF0sXG4gICkge1xuICAgIGNvbnN0IGVuZHBvaW50ID0gaW5wdXQuZGlyZWN0RW5kcG9pbnQ7XG4gICAgaWYgKGVuZHBvaW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHlpZWxkKiB2ZXJpZnlEaXJlY3RFbmRwb2ludCh7XG4gICAgICAgIGV4cGVjdGVkRW52aXJvbm1lbnRJZDogaW5wdXQuZXhwZWN0ZWRFbnZpcm9ubWVudElkLFxuICAgICAgICBodHRwQmFzZVVybDogZW5kcG9pbnQuaHR0cEJhc2VVcmwsXG4gICAgICAgIGNvbm5lY3Rpb25NZXRob2Q6IFwiZGlyZWN0XCIsXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgYXV0aG9yaXplZCA9ICh0b2tlbjogVG9rZW5TdG9yZS5SZW1vdGVEcG9wQWNjZXNzVG9rZW4sIHNvY2tldFVybDogc3RyaW5nKSA9PiAoe1xuICAgICAgLi4uaHR0cEF1dGhvcml6YXRpb24odG9rZW4sIGVuZHBvaW50Py5odHRwQmFzZVVybCksXG4gICAgICBzb2NrZXRVcmwsXG4gICAgfSk7XG4gICAgbGV0IHNlbGVjdGVkID0geWllbGQqIGdldERwb3BUb2tlbihpbnB1dCk7XG4gICAgaWYgKHNlbGVjdGVkLmZyb21DYWNoZSkge1xuICAgICAgY29uc3QgY2FjaGVkU29ja2V0ID0geWllbGQqIGNyZWF0ZURwb3BTb2NrZXRVcmwoXG4gICAgICAgIHNlbGVjdGVkLnRva2VuLFxuICAgICAgICBDQUNIRURfRU5EUE9JTlRfU09DS0VUX1RJTUVPVVRfTVMsXG4gICAgICAgIGVuZHBvaW50LFxuICAgICAgKS5waXBlKEVmZmVjdC5yZXN1bHQpO1xuICAgICAgaWYgKFJlc3VsdC5pc1N1Y2Nlc3MoY2FjaGVkU29ja2V0KSkge1xuICAgICAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihzZWxlY3RlZC5pZGVudGl0eSk7XG4gICAgICAgIHJldHVybiBhdXRob3JpemVkKHNlbGVjdGVkLnRva2VuLCBjYWNoZWRTb2NrZXQuc3VjY2Vzcyk7XG4gICAgICB9XG4gICAgICBpZiAoY2FjaGVkU29ja2V0LmZhaWx1cmUuX3RhZyA9PT0gXCJDb25uZWN0aW9uQmxvY2tlZEVycm9yXCIpIHtcbiAgICAgICAgcmV0dXJuIHlpZWxkKiBtYXBEcG9wU29ja2V0RXJyb3IoY2FjaGVkU29ja2V0LmZhaWx1cmUpO1xuICAgICAgfVxuICAgICAgLy8gQW4gdW5yZWFjaGFibGUgZGlyZWN0IGFkZHJlc3Mgc2F5cyBub3RoaW5nIGFib3V0IHRoZSB0b2tlbiwgc28ga2VlcFxuICAgICAgLy8gaXQgZm9yIHRoZSBUMyBDb25uZWN0IHJvdXRlIHJhdGhlciB0aGFuIGZvcmNpbmcgYSByZWxheSByb3VuZCB0cmlwLlxuICAgICAgaWYgKGVuZHBvaW50ICE9PSB1bmRlZmluZWQgJiYgY2FjaGVkU29ja2V0LmZhaWx1cmUuX3RhZyAhPT0gXCJFbnZpcm9ubWVudEF1dGhJbnZhbGlkRXJyb3JcIikge1xuICAgICAgICByZXR1cm4geWllbGQqIG1hcERwb3BTb2NrZXRFcnJvcihjYWNoZWRTb2NrZXQuZmFpbHVyZSk7XG4gICAgICB9XG4gICAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihzZWxlY3RlZC5pZGVudGl0eSk7XG4gICAgICBzZWxlY3RlZCA9IHlpZWxkKiBnZXREcG9wVG9rZW4oe1xuICAgICAgICAuLi5pbnB1dCxcbiAgICAgICAgcmVqZWN0ZWRBY2Nlc3NUb2tlbjogc2VsZWN0ZWQudG9rZW4uYWNjZXNzVG9rZW4sXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3Qgc29ja2V0ID0geWllbGQqIGNyZWF0ZURwb3BTb2NrZXRVcmwoc2VsZWN0ZWQudG9rZW4sIHVuZGVmaW5lZCwgZW5kcG9pbnQpLnBpcGUoXG4gICAgICBFZmZlY3QucmVzdWx0LFxuICAgICk7XG4gICAgaWYgKFJlc3VsdC5pc0ZhaWx1cmUoc29ja2V0KSkge1xuICAgICAgaWYgKGVuZHBvaW50ID09PSB1bmRlZmluZWQgfHwgc29ja2V0LmZhaWx1cmUuX3RhZyA9PT0gXCJDb25uZWN0aW9uQmxvY2tlZEVycm9yXCIpIHtcbiAgICAgICAgeWllbGQqIHRva2VuTG9jay53aXRoUGVybWl0cygxKShcbiAgICAgICAgICByZW1vdmVSZWplY3RlZFRva2VuKGlucHV0LmV4cGVjdGVkRW52aXJvbm1lbnRJZCwgc2VsZWN0ZWQudG9rZW4uYWNjZXNzVG9rZW4pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHlpZWxkKiBtYXBEcG9wU29ja2V0RXJyb3Ioc29ja2V0LmZhaWx1cmUpO1xuICAgIH1cbiAgICB5aWVsZCogYXNzZXJ0U2Vzc2lvbihzZWxlY3RlZC5pZGVudGl0eSk7XG4gICAgcmV0dXJuIGF1dGhvcml6ZWQoc2VsZWN0ZWQudG9rZW4sIHNvY2tldC5zdWNjZXNzKTtcbiAgfSk7XG5cbiAgcmV0dXJuIFJlbW90ZUVudmlyb25tZW50QXV0aG9yaXphdGlvbi5vZih7XG4gICAgYXV0aG9yaXplQmVhcmVyLFxuICAgIGF1dGhvcml6ZURwb3A6IChpbnB1dCkgPT5cbiAgICAgIGF1dGhvcml6ZURwb3AoaW5wdXQpLnBpcGUoRWZmZWN0LndpdGhTcGFuKFwiZW52aXJvbm1lbnQuYXV0aG9yaXphdGlvblwiKSksXG4gICAgYXV0aG9yaXplRHBvcEh0dHA6IChpbnB1dCkgPT5cbiAgICAgIGdldERwb3BUb2tlbihpbnB1dCkucGlwZShcbiAgICAgICAgRWZmZWN0Lm1hcCgoeyB0b2tlbiB9KSA9PiBodHRwQXV0aG9yaXphdGlvbih0b2tlbikpLFxuICAgICAgICBFZmZlY3Qud2l0aFNwYW4oXCJlbnZpcm9ubWVudC5hdXRob3JpemF0aW9uLmh0dHBcIiksXG4gICAgICAgIHdpdGhSZWxheUNsaWVudFRyYWNpbmcsXG4gICAgICApLFxuICB9KTtcbn0pO1xuXG5leHBvcnQgY29uc3QgbGF5ZXIgPSBMYXllci5lZmZlY3QoUmVtb3RlRW52aXJvbm1lbnRBdXRob3JpemF0aW9uLCBtYWtlKTtcbiJdLCJmaWxlIjoiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9wYWNrYWdlcy9jbGllbnQtcnVudGltZS9zcmMvYXV0aG9yaXphdGlvbi9zZXJ2aWNlLnRzIn0=

//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2F1dGhvcml6YXRpb24vc2VydmljZS50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2F1dGhvcml6YXRpb24vc2VydmljZS50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiLCIxNCIsIjE1IiwiMTYiLCIxNyIsIjE4IiwiMTkiLCIyMCIsIjIxIiwiMjIiLCIyMyIsIjI0IiwiMjUiLCIyNiIsIjI3IiwiMjgiLCIyOSJdLFtdLFsiOCIsIjkiLCIxMCIsIjExIiwiMTIiLCIxMyIsIjE0IiwiMTUiLCIxNiIsIjE3IiwiMTgiLCIxOSIsIjIwIiwiMjEiLCIyMiIsIjIzIiwiMjQiLCIyNSIsIjI2IiwiMjciLCIyOCIsIjI5Il0se30sIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY29udHJhY3RzL3NyYy9pbmRleC50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY29udHJhY3RzL3NyYy9yZWxheS50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvc2hhcmVkL3NyYy9yZWxheVRyYWNpbmcudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9hdXRob3JpemF0aW9uL3JlbW90ZS50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Nvbm5lY3Rpb24vZXJyb3JzLnRzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9wYWNrYWdlcy9jbGllbnQtcnVudGltZS9zcmMvY29ubmVjdGlvbi9tb2RlbC50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Vudmlyb25tZW50L2Rlc2NyaXB0b3IudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9lbnZpcm9ubWVudC9lbmRwb2ludC50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL3BsYXRmb3JtL2NhcGFiaWxpdGllcy50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL3JlbGF5L21hbmFnZWRSZWxheS50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2F1dGhvcml6YXRpb24vdG9rZW5TdG9yZS50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvQ2xvY2suanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L0NvbnRleHQuanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L0VmZmVjdC5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvRmliZXIuanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L0xheWVyLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9PcHRpb24uanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L1JlZi5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvUmVzdWx0LmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9TY29wZS5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvU2VtYXBob3JlLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9odHRwL0h0dHBDbGllbnQuanMiXQ==