import { __assign, __awaiter, __generator } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { invariant, newInvariantError } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29"; import { equal } from "/_nuxt/node_modules/@wry/equality/lib/index.js?v=e4f18c29"; import { execute } from "/_nuxt/node_modules/@apollo/client/link/core/index.js?v=e4f18c29"; import { addNonReactiveToNamedFragments, hasDirectives, isExecutionPatchIncrementalResult, isExecutionPatchResult, isFullyUnmaskedOperation, removeDirectivesFromDocument, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { canonicalStringify } from "/_nuxt/node_modules/@apollo/client/cache/index.js?v=e4f18c29"; import { getDefaultValues, getOperationDefinition, getOperationName, hasClientExports, graphQLResultHasError, getGraphQLErrorsFromResult, Observable, asyncMap, isNonEmptyArray, Concast, makeUniqueId, isDocumentNode, isNonNullObject, DocumentTransform, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { mergeIncrementalData } from "/_nuxt/node_modules/@apollo/client/utilities/common/incrementalResult.js?v=e4f18c29"; import { ApolloError, isApolloError, graphQLResultHasProtocolErrors, } from "/_nuxt/node_modules/@apollo/client/errors/index.js?v=e4f18c29"; import { ObservableQuery, logMissingFieldErrors } from "/_nuxt/node_modules/@apollo/client/core/ObservableQuery.js?v=e4f18c29"; import { NetworkStatus, isNetworkRequestInFlight } from "/_nuxt/node_modules/@apollo/client/core/networkStatus.js?v=e4f18c29"; import { QueryInfo, shouldWriteResult, } from "/_nuxt/node_modules/@apollo/client/core/QueryInfo.js?v=e4f18c29"; import { PROTOCOL_ERRORS_SYMBOL } from "/_nuxt/node_modules/@apollo/client/errors/index.js?v=e4f18c29"; import { print } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; var hasOwnProperty = Object.prototype.hasOwnProperty; var IGNORE = Object.create(null); import { Trie } from "/_nuxt/node_modules/@wry/trie/lib/index.js?v=e4f18c29"; import { AutoCleanedWeakCache, cacheSizes } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { maskFragment, maskOperation } from "/_nuxt/node_modules/@apollo/client/masking/index.js?v=e4f18c29"; var QueryManager = /** @class */ (function () { function QueryManager(options) { var _this = this; this.clientAwareness = {}; // All the queries that the QueryManager is currently managing (not // including mutations and subscriptions). this.queries = new Map(); // Maps from queryId strings to Promise rejection functions for // currently active queries and fetches. // Use protected instead of private field so // @apollo/experimental-nextjs-app-support can access type info. this.fetchCancelFns = new Map(); this.transformCache = new AutoCleanedWeakCache(cacheSizes["queryManager.getDocumentInfo"] || 2000 /* defaultCacheSizes["queryManager.getDocumentInfo"] */); this.queryIdCounter = 1; this.requestIdCounter = 1; this.mutationIdCounter = 1; // Use protected instead of private field so // @apollo/experimental-nextjs-app-support can access type info. this.inFlightLinkObservables = new Trie(false); this.noCacheWarningsByQueryId = new Set(); var defaultDocumentTransform = new DocumentTransform(function (document) { return _this.cache.transformDocument(document); }, // Allow the apollo cache to manage its own transform caches { cache: false }); this.cache = options.cache; this.link = options.link; this.defaultOptions = options.defaultOptions; this.queryDeduplication = options.queryDeduplication; this.clientAwareness = options.clientAwareness; this.localState = options.localState; this.ssrMode = options.ssrMode; this.assumeImmutableResults = options.assumeImmutableResults; this.dataMasking = options.dataMasking; var documentTransform = options.documentTransform; this.documentTransform = documentTransform ? defaultDocumentTransform .concat(documentTransform) // The custom document transform may add new fragment spreads or new // field selections, so we want to give the cache a chance to run // again. For example, the InMemoryCache adds __typename to field // selections and fragments from the fragment registry. .concat(defaultDocumentTransform) : defaultDocumentTransform; this.defaultContext = options.defaultContext || Object.create(null); if ((this.onBroadcast = options.onBroadcast)) { this.mutationStore = Object.create(null); } } /** * Call this method to terminate any active query processes, making it safe * to dispose of this QueryManager instance. */ QueryManager.prototype.stop = function () { var _this = this; this.queries.forEach(function (_info, queryId) { _this.stopQueryNoBroadcast(queryId); }); this.cancelPendingFetches(newInvariantError(27)); }; QueryManager.prototype.cancelPendingFetches = function (error) { this.fetchCancelFns.forEach(function (cancel) { return cancel(error); }); this.fetchCancelFns.clear(); }; QueryManager.prototype.mutate = function (_a) { return __awaiter(this, arguments, void 0, function (_b) { var mutationId, hasClientExports, mutationStoreValue, isOptimistic, self; var _c, _d; var mutation = _b.mutation, variables = _b.variables, optimisticResponse = _b.optimisticResponse, updateQueries = _b.updateQueries, _e = _b.refetchQueries, refetchQueries = _e === void 0 ? [] : _e, _f = _b.awaitRefetchQueries, awaitRefetchQueries = _f === void 0 ? false : _f, updateWithProxyFn = _b.update, onQueryUpdated = _b.onQueryUpdated, _g = _b.fetchPolicy, fetchPolicy = _g === void 0 ? ((_c = this.defaultOptions.mutate) === null || _c === void 0 ? void 0 : _c.fetchPolicy) || "network-only" : _g, _h = _b.errorPolicy, errorPolicy = _h === void 0 ? ((_d = this.defaultOptions.mutate) === null || _d === void 0 ? void 0 : _d.errorPolicy) || "none" : _h, keepRootFields = _b.keepRootFields, context = _b.context; return __generator(this, function (_j) { switch (_j.label) { case 0: invariant(mutation, 28); invariant(fetchPolicy === "network-only" || fetchPolicy === "no-cache", 29); mutationId = this.generateMutationId(); mutation = this.cache.transformForLink(this.transform(mutation)); hasClientExports = this.getDocumentInfo(mutation).hasClientExports; variables = this.getVariables(mutation, variables); if (!hasClientExports) return [3 /*break*/, 2]; return [4 /*yield*/, this.localState.addExportedVariables(mutation, variables, context)]; case 1: variables = (_j.sent()); _j.label = 2; case 2: mutationStoreValue = this.mutationStore && (this.mutationStore[mutationId] = { mutation: mutation, variables: variables, loading: true, error: null, }); isOptimistic = optimisticResponse && this.markMutationOptimistic(optimisticResponse, { mutationId: mutationId, document: mutation, variables: variables, fetchPolicy: fetchPolicy, errorPolicy: errorPolicy, context: context, updateQueries: updateQueries, update: updateWithProxyFn, keepRootFields: keepRootFields, }); this.broadcastQueries(); self = this; return [2 /*return*/, new Promise(function (resolve, reject) { return asyncMap(self.getObservableFromLink(mutation, __assign(__assign({}, context), { optimisticResponse: isOptimistic ? optimisticResponse : void 0 }), variables, {}, false), function (result) { if (graphQLResultHasError(result) && errorPolicy === "none") { throw new ApolloError({ graphQLErrors: getGraphQLErrorsFromResult(result), }); } if (mutationStoreValue) { mutationStoreValue.loading = false; mutationStoreValue.error = null; } var storeResult = __assign({}, result); if (typeof refetchQueries === "function") { refetchQueries = refetchQueries(storeResult); } if (errorPolicy === "ignore" && graphQLResultHasError(storeResult)) { delete storeResult.errors; } return self.markMutationResult({ mutationId: mutationId, result: storeResult, document: mutation, variables: variables, fetchPolicy: fetchPolicy, errorPolicy: errorPolicy, context: context, update: updateWithProxyFn, updateQueries: updateQueries, awaitRefetchQueries: awaitRefetchQueries, refetchQueries: refetchQueries, removeOptimistic: isOptimistic ? mutationId : void 0, onQueryUpdated: onQueryUpdated, keepRootFields: keepRootFields, }); }).subscribe({ next: function (storeResult) { self.broadcastQueries(); // Since mutations might receive multiple payloads from the // ApolloLink chain (e.g. when used with @defer), // we resolve with a SingleExecutionResult or after the final // ExecutionPatchResult has arrived and we have assembled the // multipart response into a single result. if (!("hasNext" in storeResult) || storeResult.hasNext === false) { resolve(__assign(__assign({}, storeResult), { data: self.maskOperation({ document: mutation, data: storeResult.data, fetchPolicy: fetchPolicy, id: mutationId, }) })); } }, error: function (err) { if (mutationStoreValue) { mutationStoreValue.loading = false; mutationStoreValue.error = err; } if (isOptimistic) { self.cache.removeOptimistic(mutationId); } self.broadcastQueries(); reject(err instanceof ApolloError ? err : (new ApolloError({ networkError: err, }))); }, }); })]; } }); }); }; QueryManager.prototype.markMutationResult = function (mutation, cache) { var _this = this; if (cache === void 0) { cache = this.cache; } var result = mutation.result; var cacheWrites = []; var skipCache = mutation.fetchPolicy === "no-cache"; if (!skipCache && shouldWriteResult(result, mutation.errorPolicy)) { if (!isExecutionPatchIncrementalResult(result)) { cacheWrites.push({ result: result.data, dataId: "ROOT_MUTATION", query: mutation.document, variables: mutation.variables, }); } if (isExecutionPatchIncrementalResult(result) && isNonEmptyArray(result.incremental)) { var diff = cache.diff({ id: "ROOT_MUTATION", // The cache complains if passed a mutation where it expects a // query, so we transform mutations and subscriptions to queries // (only once, thanks to this.transformCache). query: this.getDocumentInfo(mutation.document).asQuery, variables: mutation.variables, optimistic: false, returnPartialData: true, }); var mergedData = void 0; if (diff.result) { mergedData = mergeIncrementalData(diff.result, result); } if (typeof mergedData !== "undefined") { // cast the ExecutionPatchResult to FetchResult here since // ExecutionPatchResult never has `data` when returned from the server result.data = mergedData; cacheWrites.push({ result: mergedData, dataId: "ROOT_MUTATION", query: mutation.document, variables: mutation.variables, }); } } var updateQueries_1 = mutation.updateQueries; if (updateQueries_1) { this.queries.forEach(function (_a, queryId) { var observableQuery = _a.observableQuery; var queryName = observableQuery && observableQuery.queryName; if (!queryName || !hasOwnProperty.call(updateQueries_1, queryName)) { return; } var updater = updateQueries_1[queryName]; var _b = _this.queries.get(queryId), document = _b.document, variables = _b.variables; // Read the current query result from the store. var _c = cache.diff({ query: document, variables: variables, returnPartialData: true, optimistic: false, }), currentQueryResult = _c.result, complete = _c.complete; if (complete && currentQueryResult) { // Run our reducer using the current query result and the mutation result. var nextQueryResult = updater(currentQueryResult, { mutationResult: result, queryName: (document && getOperationName(document)) || void 0, queryVariables: variables, }); // Write the modified result back into the store if we got a new result. if (nextQueryResult) { cacheWrites.push({ result: nextQueryResult, dataId: "ROOT_QUERY", query: document, variables: variables, }); } } }); } } if (cacheWrites.length > 0 || (mutation.refetchQueries || "").length > 0 || mutation.update || mutation.onQueryUpdated || mutation.removeOptimistic) { var results_1 = []; this.refetchQueries({ updateCache: function (cache) { if (!skipCache) { cacheWrites.forEach(function (write) { return cache.write(write); }); } // If the mutation has some writes associated with it then we need to // apply those writes to the store by running this reducer again with // a write action. var update = mutation.update; // Determine whether result is a SingleExecutionResult, // or the final ExecutionPatchResult. var isFinalResult = !isExecutionPatchResult(result) || (isExecutionPatchIncrementalResult(result) && !result.hasNext); if (update) { if (!skipCache) { // Re-read the ROOT_MUTATION data we just wrote into the cache // (the first cache.write call in the cacheWrites.forEach loop // above), so field read functions have a chance to run for // fields within mutation result objects. var diff = cache.diff({ id: "ROOT_MUTATION", // The cache complains if passed a mutation where it expects a // query, so we transform mutations and subscriptions to queries // (only once, thanks to this.transformCache). query: _this.getDocumentInfo(mutation.document).asQuery, variables: mutation.variables, optimistic: false, returnPartialData: true, }); if (diff.complete) { result = __assign(__assign({}, result), { data: diff.result }); if ("incremental" in result) { delete result.incremental; } if ("hasNext" in result) { delete result.hasNext; } } } // If we've received the whole response, // either a SingleExecutionResult or the final ExecutionPatchResult, // call the update function. if (isFinalResult) { update(cache, result, { context: mutation.context, variables: mutation.variables, }); } } // TODO Do this with cache.evict({ id: 'ROOT_MUTATION' }) but make it // shallow to allow rolling back optimistic evictions. if (!skipCache && !mutation.keepRootFields && isFinalResult) { cache.modify({ id: "ROOT_MUTATION", fields: function (value, _a) { var fieldName = _a.fieldName, DELETE = _a.DELETE; return fieldName === "__typename" ? value : DELETE; }, }); } }, include: mutation.refetchQueries, // Write the final mutation.result to the root layer of the cache. optimistic: false, // Remove the corresponding optimistic layer at the same time as we // write the final non-optimistic result. removeOptimistic: mutation.removeOptimistic, // Let the caller of client.mutate optionally determine the refetching // behavior for watched queries after the mutation.update function runs. // If no onQueryUpdated function was provided for this mutation, pass // null instead of undefined to disable the default refetching behavior. onQueryUpdated: mutation.onQueryUpdated || null, }).forEach(function (result) { return results_1.push(result); }); if (mutation.awaitRefetchQueries || mutation.onQueryUpdated) { // Returning a promise here makes the mutation await that promise, so we // include results in that promise's work if awaitRefetchQueries or an // onQueryUpdated function was specified. return Promise.all(results_1).then(function () { return result; }); } } return Promise.resolve(result); }; QueryManager.prototype.markMutationOptimistic = function (optimisticResponse, mutation) { var _this = this; var data = typeof optimisticResponse === "function" ? optimisticResponse(mutation.variables, { IGNORE: IGNORE }) : optimisticResponse; if (data === IGNORE) { return false; } this.cache.recordOptimisticTransaction(function (cache) { try { _this.markMutationResult(__assign(__assign({}, mutation), { result: { data: data } }), cache); } catch (error) { globalThis.__DEV__ !== false && invariant.error(error); } }, mutation.mutationId); return true; }; QueryManager.prototype.fetchQuery = function (queryId, options, networkStatus) { return this.fetchConcastWithInfo(this.getOrCreateQuery(queryId), options, networkStatus).concast.promise; }; QueryManager.prototype.getQueryStore = function () { var store = Object.create(null); this.queries.forEach(function (info, queryId) { store[queryId] = { variables: info.variables, networkStatus: info.networkStatus, networkError: info.networkError, graphQLErrors: info.graphQLErrors, }; }); return store; }; QueryManager.prototype.resetErrors = function (queryId) { var queryInfo = this.queries.get(queryId); if (queryInfo) { queryInfo.networkError = undefined; queryInfo.graphQLErrors = []; } }; QueryManager.prototype.transform = function (document) { return this.documentTransform.transformDocument(document); }; QueryManager.prototype.getDocumentInfo = function (document) { var transformCache = this.transformCache; if (!transformCache.has(document)) { var cacheEntry = { // TODO These three calls (hasClientExports, shouldForceResolvers, and // usesNonreactiveDirective) are performing independent full traversals // of the transformed document. We should consider merging these // traversals into a single pass in the future, though the work is // cached after the first time. hasClientExports: hasClientExports(document), hasForcedResolvers: this.localState.shouldForceResolvers(document), hasNonreactiveDirective: hasDirectives(["nonreactive"], document), nonReactiveQuery: addNonReactiveToNamedFragments(document), clientQuery: this.localState.clientQuery(document), serverQuery: removeDirectivesFromDocument([ { name: "client", remove: true }, { name: "connection" }, { name: "nonreactive" }, { name: "unmask" }, ], document), defaultVars: getDefaultValues(getOperationDefinition(document)), // Transform any mutation or subscription operations to query operations // so we can read/write them from/to the cache. asQuery: __assign(__assign({}, document), { definitions: document.definitions.map(function (def) { if (def.kind === "OperationDefinition" && def.operation !== "query") { return __assign(__assign({}, def), { operation: "query" }); } return def; }) }), }; transformCache.set(document, cacheEntry); } return transformCache.get(document); }; QueryManager.prototype.getVariables = function (document, variables) { return __assign(__assign({}, this.getDocumentInfo(document).defaultVars), variables); }; QueryManager.prototype.watchQuery = function (options) { var query = this.transform(options.query); // assign variable default values if supplied // NOTE: We don't modify options.query here with the transformed query to // ensure observable.options.query is set to the raw untransformed query. options = __assign(__assign({}, options), { variables: this.getVariables(query, options.variables) }); if (typeof options.notifyOnNetworkStatusChange === "undefined") { options.notifyOnNetworkStatusChange = false; } var queryInfo = new QueryInfo(this); var observable = new ObservableQuery({ queryManager: this, queryInfo: queryInfo, options: options, }); observable["lastQuery"] = query; if (!ObservableQuery["inactiveOnCreation"].getValue()) { this.queries.set(observable.queryId, queryInfo); } // We give queryInfo the transformed query to ensure the first cache diff // uses the transformed query instead of the raw query queryInfo.init({ document: query, observableQuery: observable, variables: observable.variables, }); return observable; }; QueryManager.prototype.query = function (options, queryId) { var _this = this; if (queryId === void 0) { queryId = this.generateQueryId(); } invariant(options.query, 30); invariant(options.query.kind === "Document", 31); invariant(!options.returnPartialData, 32); invariant(!options.pollInterval, 33); var query = this.transform(options.query); return this.fetchQuery(queryId, __assign(__assign({}, options), { query: query })) .then(function (result) { return result && __assign(__assign({}, result), { data: _this.maskOperation({ document: query, data: result.data, fetchPolicy: options.fetchPolicy, id: queryId, }) }); }) .finally(function () { return _this.stopQuery(queryId); }); }; QueryManager.prototype.generateQueryId = function () { return String(this.queryIdCounter++); }; QueryManager.prototype.generateRequestId = function () { return this.requestIdCounter++; }; QueryManager.prototype.generateMutationId = function () { return String(this.mutationIdCounter++); }; QueryManager.prototype.stopQueryInStore = function (queryId) { this.stopQueryInStoreNoBroadcast(queryId); this.broadcastQueries(); }; QueryManager.prototype.stopQueryInStoreNoBroadcast = function (queryId) { var queryInfo = this.queries.get(queryId); if (queryInfo) queryInfo.stop(); }; QueryManager.prototype.clearStore = function (options) { if (options === void 0) { options = { discardWatches: true, }; } // Before we have sent the reset action to the store, we can no longer // rely on the results returned by in-flight requests since these may // depend on values that previously existed in the data portion of the // store. So, we cancel the promises and observers that we have issued // so far and not yet resolved (in the case of queries). this.cancelPendingFetches(newInvariantError(34)); this.queries.forEach(function (queryInfo) { if (queryInfo.observableQuery) { // Set loading to true so listeners don't trigger unless they want // results with partial data. queryInfo.networkStatus = NetworkStatus.loading; } else { queryInfo.stop(); } }); if (this.mutationStore) { this.mutationStore = Object.create(null); } // begin removing data from the store return this.cache.reset(options); }; QueryManager.prototype.getObservableQueries = function (include) { var _this = this; if (include === void 0) { include = "active"; } var queries = new Map(); var queryNames = new Map(); var queryNamesAndQueryStrings = new Map(); var legacyQueryOptions = new Set(); if (Array.isArray(include)) { include.forEach(function (desc) { if (typeof desc === "string") { queryNames.set(desc, desc); queryNamesAndQueryStrings.set(desc, false); } else if (isDocumentNode(desc)) { var queryString = print(_this.transform(desc)); queryNames.set(queryString, getOperationName(desc)); queryNamesAndQueryStrings.set(queryString, false); } else if (isNonNullObject(desc) && desc.query) { legacyQueryOptions.add(desc); } }); } this.queries.forEach(function (_a, queryId) { var oq = _a.observableQuery, document = _a.document; if (oq) { if (include === "all") { queries.set(queryId, oq); return; } var queryName = oq.queryName, fetchPolicy = oq.options.fetchPolicy; if (fetchPolicy === "standby" || (include === "active" && !oq.hasObservers())) { return; } if (include === "active" || (queryName && queryNamesAndQueryStrings.has(queryName)) || (document && queryNamesAndQueryStrings.has(print(document)))) { queries.set(queryId, oq); if (queryName) queryNamesAndQueryStrings.set(queryName, true); if (document) queryNamesAndQueryStrings.set(print(document), true); } } }); if (legacyQueryOptions.size) { legacyQueryOptions.forEach(function (options) { // We will be issuing a fresh network request for this query, so we // pre-allocate a new query ID here, using a special prefix to enable // cleaning up these temporary queries later, after fetching. var queryId = makeUniqueId("legacyOneTimeQuery"); var queryInfo = _this.getOrCreateQuery(queryId).init({ document: options.query, variables: options.variables, }); var oq = new ObservableQuery({ queryManager: _this, queryInfo: queryInfo, options: __assign(__assign({}, options), { fetchPolicy: "network-only" }), }); invariant(oq.queryId === queryId); queryInfo.setObservableQuery(oq); queries.set(queryId, oq); }); } if (globalThis.__DEV__ !== false && queryNamesAndQueryStrings.size) { queryNamesAndQueryStrings.forEach(function (included, nameOrQueryString) { if (!included) { var queryName = queryNames.get(nameOrQueryString); if (queryName) { globalThis.__DEV__ !== false && invariant.warn(35, queryName); } else { globalThis.__DEV__ !== false && invariant.warn(36); } } }); } return queries; }; QueryManager.prototype.reFetchObservableQueries = function (includeStandby) { var _this = this; if (includeStandby === void 0) { includeStandby = false; } var observableQueryPromises = []; this.getObservableQueries(includeStandby ? "all" : "active").forEach(function (observableQuery, queryId) { var fetchPolicy = observableQuery.options.fetchPolicy; observableQuery.resetLastResults(); if (includeStandby || (fetchPolicy !== "standby" && fetchPolicy !== "cache-only")) { observableQueryPromises.push(observableQuery.refetch()); } (_this.queries.get(queryId) || observableQuery["queryInfo"]).setDiff(null); }); this.broadcastQueries(); return Promise.all(observableQueryPromises); }; QueryManager.prototype.startGraphQLSubscription = function (options) { var _this = this; var query = options.query, variables = options.variables; var fetchPolicy = options.fetchPolicy, _a = options.errorPolicy, errorPolicy = _a === void 0 ? "none" : _a, _b = options.context, context = _b === void 0 ? {} : _b, _c = options.extensions, extensions = _c === void 0 ? {} : _c; query = this.transform(query); variables = this.getVariables(query, variables); var makeObservable = function (variables) { return _this.getObservableFromLink(query, context, variables, extensions).map(function (result) { if (fetchPolicy !== "no-cache") { // the subscription interface should handle not sending us results we no longer subscribe to. // XXX I don't think we ever send in an object with errors, but we might in the future... if (shouldWriteResult(result, errorPolicy)) { _this.cache.write({ query: query, result: result.data, dataId: "ROOT_SUBSCRIPTION", variables: variables, }); } _this.broadcastQueries(); } var hasErrors = graphQLResultHasError(result); var hasProtocolErrors = graphQLResultHasProtocolErrors(result); if (hasErrors || hasProtocolErrors) { var errors = {}; if (hasErrors) { errors.graphQLErrors = result.errors; } if (hasProtocolErrors) { errors.protocolErrors = result.extensions[PROTOCOL_ERRORS_SYMBOL]; } // `errorPolicy` is a mechanism for handling GraphQL errors, according // to our documentation, so we throw protocol errors regardless of the // set error policy. if (errorPolicy === "none" || hasProtocolErrors) { throw new ApolloError(errors); } } if (errorPolicy === "ignore") { delete result.errors; } return result; }); }; if (this.getDocumentInfo(query).hasClientExports) { var observablePromise_1 = this.localState .addExportedVariables(query, variables, context) .then(makeObservable); return new Observable(function (observer) { var sub = null; observablePromise_1.then(function (observable) { return (sub = observable.subscribe(observer)); }, observer.error); return function () { return sub && sub.unsubscribe(); }; }); } return makeObservable(variables); }; QueryManager.prototype.stopQuery = function (queryId) { this.stopQueryNoBroadcast(queryId); this.broadcastQueries(); }; QueryManager.prototype.stopQueryNoBroadcast = function (queryId) { this.stopQueryInStoreNoBroadcast(queryId); this.removeQuery(queryId); }; QueryManager.prototype.removeQuery = function (queryId) { var _a; // teardown all links // Both `QueryManager.fetchRequest` and `QueryManager.query` create separate promises // that each add their reject functions to fetchCancelFns. // A query created with `QueryManager.query()` could trigger a `QueryManager.fetchRequest`. // The same queryId could have two rejection fns for two promises this.fetchCancelFns.delete(queryId); if (this.queries.has(queryId)) { (_a = this.queries.get(queryId)) === null || _a === void 0 ? void 0 : _a.stop(); this.queries.delete(queryId); } }; QueryManager.prototype.broadcastQueries = function () { if (this.onBroadcast) this.onBroadcast(); this.queries.forEach(function (info) { var _a; return (_a = info.observableQuery) === null || _a === void 0 ? void 0 : _a["notify"](); }); }; QueryManager.prototype.getLocalState = function () { return this.localState; }; QueryManager.prototype.getObservableFromLink = function (query, context, variables, extensions, // Prefer context.queryDeduplication if specified. deduplication) { var _this = this; var _a; if (deduplication === void 0) { deduplication = (_a = context === null || context === void 0 ? void 0 : context.queryDeduplication) !== null && _a !== void 0 ? _a : this.queryDeduplication; } var observable; var _b = this.getDocumentInfo(query), serverQuery = _b.serverQuery, clientQuery = _b.clientQuery; if (serverQuery) { var _c = this, inFlightLinkObservables_1 = _c.inFlightLinkObservables, link = _c.link; var operation = { query: serverQuery, variables: variables, operationName: getOperationName(serverQuery) || void 0, context: this.prepareContext(__assign(__assign({}, context), { forceFetch: !deduplication })), extensions: extensions, }; context = operation.context; if (deduplication) { var printedServerQuery_1 = print(serverQuery); var varJson_1 = canonicalStringify(variables); var entry = inFlightLinkObservables_1.lookup(printedServerQuery_1, varJson_1); observable = entry.observable; if (!observable) { var concast_1 = new Concast([ execute(link, operation), ]); observable = entry.observable = concast_1; concast_1.beforeNext(function cb(method, arg) { if (method === "next" && "hasNext" in arg && arg.hasNext) { concast_1.beforeNext(cb); } else { inFlightLinkObservables_1.remove(printedServerQuery_1, varJson_1); } }); } } else { observable = new Concast([ execute(link, operation), ]); } } else { observable = new Concast([Observable.of({ data: {} })]); context = this.prepareContext(context); } if (clientQuery) { observable = asyncMap(observable, function (result) { return _this.localState.runResolvers({ document: clientQuery, remoteResult: result, context: context, variables: variables, }); }); } return observable; }; QueryManager.prototype.getResultsFromLink = function (queryInfo, cacheWriteBehavior, options) { var requestId = (queryInfo.lastRequestId = this.generateRequestId()); // Performing transformForLink here gives this.cache a chance to fill in // missing fragment definitions (for example) before sending this document // through the link chain. var linkDocument = this.cache.transformForLink(options.query); return asyncMap(this.getObservableFromLink(linkDocument, options.context, options.variables), function (result) { var graphQLErrors = getGraphQLErrorsFromResult(result); var hasErrors = graphQLErrors.length > 0; var errorPolicy = options.errorPolicy; // If we interrupted this request by calling getResultsFromLink again // with the same QueryInfo object, we ignore the old results. if (requestId >= queryInfo.lastRequestId) { if (hasErrors && errorPolicy === "none") { // Throwing here effectively calls observer.error. throw queryInfo.markError(new ApolloError({ graphQLErrors: graphQLErrors, })); } // Use linkDocument rather than queryInfo.document so the // operation/fragments used to write the result are the same as the // ones used to obtain it from the link. queryInfo.markResult(result, linkDocument, options, cacheWriteBehavior); queryInfo.markReady(); } var aqr = { data: result.data, loading: false, networkStatus: NetworkStatus.ready, }; // In the case we start multiple network requests simulatenously, we // want to ensure we properly set `data` if we're reporting on an old // result which will not be caught by the conditional above that ends up // throwing the markError result. if (hasErrors && errorPolicy === "none") { aqr.data = void 0; } if (hasErrors && errorPolicy !== "ignore") { aqr.errors = graphQLErrors; aqr.networkStatus = NetworkStatus.error; } return aqr; }, function (networkError) { var error = isApolloError(networkError) ? networkError : (new ApolloError({ networkError: networkError })); // Avoid storing errors from older interrupted queries. if (requestId >= queryInfo.lastRequestId) { queryInfo.markError(error); } throw error; }); }; QueryManager.prototype.fetchConcastWithInfo = function (queryInfo, options, // The initial networkStatus for this fetch, most often // NetworkStatus.loading, but also possibly fetchMore, poll, refetch, // or setVariables. networkStatus, query) { var _this = this; if (networkStatus === void 0) { networkStatus = NetworkStatus.loading; } if (query === void 0) { query = options.query; } var variables = this.getVariables(query, options.variables); var defaults = this.defaultOptions.watchQuery; var _a = options.fetchPolicy, fetchPolicy = _a === void 0 ? (defaults && defaults.fetchPolicy) || "cache-first" : _a, _b = options.errorPolicy, errorPolicy = _b === void 0 ? (defaults && defaults.errorPolicy) || "none" : _b, _c = options.returnPartialData, returnPartialData = _c === void 0 ? false : _c, _d = options.notifyOnNetworkStatusChange, notifyOnNetworkStatusChange = _d === void 0 ? false : _d, _e = options.context, context = _e === void 0 ? {} : _e; var normalized = Object.assign({}, options, { query: query, variables: variables, fetchPolicy: fetchPolicy, errorPolicy: errorPolicy, returnPartialData: returnPartialData, notifyOnNetworkStatusChange: notifyOnNetworkStatusChange, context: context, }); var fromVariables = function (variables) { // Since normalized is always a fresh copy of options, it's safe to // modify its properties here, rather than creating yet another new // WatchQueryOptions object. normalized.variables = variables; var sourcesWithInfo = _this.fetchQueryByPolicy(queryInfo, normalized, networkStatus); if ( // If we're in standby, postpone advancing options.fetchPolicy using // applyNextFetchPolicy. normalized.fetchPolicy !== "standby" && // The "standby" policy currently returns [] from fetchQueryByPolicy, so // this is another way to detect when nothing was done/fetched. sourcesWithInfo.sources.length > 0 && queryInfo.observableQuery) { queryInfo.observableQuery["applyNextFetchPolicy"]("after-fetch", options); } return sourcesWithInfo; }; // This cancel function needs to be set before the concast is created, // in case concast creation synchronously cancels the request. var cleanupCancelFn = function () { return _this.fetchCancelFns.delete(queryInfo.queryId); }; this.fetchCancelFns.set(queryInfo.queryId, function (reason) { cleanupCancelFn(); // This delay ensures the concast variable has been initialized. setTimeout(function () { return concast.cancel(reason); }); }); var concast, containsDataFromLink; // If the query has @export(as: ...) directives, then we need to // process those directives asynchronously. When there are no // @export directives (the common case), we deliberately avoid // wrapping the result of this.fetchQueryByPolicy in a Promise, // since the timing of result delivery is (unfortunately) important // for backwards compatibility. TODO This code could be simpler if // we deprecated and removed LocalState. if (this.getDocumentInfo(normalized.query).hasClientExports) { concast = new Concast(this.localState .addExportedVariables(normalized.query, normalized.variables, normalized.context) .then(fromVariables) .then(function (sourcesWithInfo) { return sourcesWithInfo.sources; })); // there is just no way we can synchronously get the *right* value here, // so we will assume `true`, which is the behaviour before the bug fix in // #10597. This means that bug is not fixed in that case, and is probably // un-fixable with reasonable effort for the edge case of @export as // directives. containsDataFromLink = true; } else { var sourcesWithInfo = fromVariables(normalized.variables); containsDataFromLink = sourcesWithInfo.fromLink; concast = new Concast(sourcesWithInfo.sources); } concast.promise.then(cleanupCancelFn, cleanupCancelFn); return { concast: concast, fromLink: containsDataFromLink, }; }; QueryManager.prototype.refetchQueries = function (_a) { var _this = this; var updateCache = _a.updateCache, include = _a.include, _b = _a.optimistic, optimistic = _b === void 0 ? false : _b, _c = _a.removeOptimistic, removeOptimistic = _c === void 0 ? optimistic ? makeUniqueId("refetchQueries") : void 0 : _c, onQueryUpdated = _a.onQueryUpdated; var includedQueriesById = new Map(); if (include) { this.getObservableQueries(include).forEach(function (oq, queryId) { includedQueriesById.set(queryId, { oq: oq, lastDiff: (_this.queries.get(queryId) || oq["queryInfo"]).getDiff(), }); }); } var results = new Map(); if (updateCache) { this.cache.batch({ update: updateCache, // Since you can perform any combination of cache reads and/or writes in // the cache.batch update function, its optimistic option can be either // a boolean or a string, representing three distinct modes of // operation: // // * false: read/write only the root layer // * true: read/write the topmost layer // * string: read/write a fresh optimistic layer with that ID string // // When typeof optimistic === "string", a new optimistic layer will be // temporarily created within cache.batch with that string as its ID. If // we then pass that same string as the removeOptimistic option, we can // make cache.batch immediately remove the optimistic layer after // running the updateCache function, triggering only one broadcast. // // However, the refetchQueries method accepts only true or false for its // optimistic option (not string). We interpret true to mean a temporary // optimistic layer should be created, to allow efficiently rolling back // the effect of the updateCache function, which involves passing a // string instead of true as the optimistic option to cache.batch, when // refetchQueries receives optimistic: true. // // In other words, we are deliberately not supporting the use case of // writing to an *existing* optimistic layer (using the refetchQueries // updateCache function), since that would potentially interfere with // other optimistic updates in progress. Instead, you can read/write // only the root layer by passing optimistic: false to refetchQueries, // or you can read/write a brand new optimistic layer that will be // automatically removed by passing optimistic: true. optimistic: (optimistic && removeOptimistic) || false, // The removeOptimistic option can also be provided by itself, even if // optimistic === false, to remove some previously-added optimistic // layer safely and efficiently, like we do in markMutationResult. // // If an explicit removeOptimistic string is provided with optimistic: // true, the removeOptimistic string will determine the ID of the // temporary optimistic layer, in case that ever matters. removeOptimistic: removeOptimistic, onWatchUpdated: function (watch, diff, lastDiff) { var oq = watch.watcher instanceof QueryInfo && watch.watcher.observableQuery; if (oq) { if (onQueryUpdated) { // Since we're about to handle this query now, remove it from // includedQueriesById, in case it was added earlier because of // options.include. includedQueriesById.delete(oq.queryId); var result = onQueryUpdated(oq, diff, lastDiff); if (result === true) { // The onQueryUpdated function requested the default refetching // behavior by returning true. result = oq.refetch(); } // Record the result in the results Map, as long as onQueryUpdated // did not return false to skip/ignore this result. if (result !== false) { results.set(oq, result); } // Allow the default cache broadcast to happen, except when // onQueryUpdated returns false. return result; } if (onQueryUpdated !== null) { // If we don't have an onQueryUpdated function, and onQueryUpdated // was not disabled by passing null, make sure this query is // "included" like any other options.include-specified query. includedQueriesById.set(oq.queryId, { oq: oq, lastDiff: lastDiff, diff: diff }); } } }, }); } if (includedQueriesById.size) { includedQueriesById.forEach(function (_a, queryId) { var oq = _a.oq, lastDiff = _a.lastDiff, diff = _a.diff; var result; // If onQueryUpdated is provided, we want to use it for all included // queries, even the QueryOptions ones. if (onQueryUpdated) { if (!diff) { diff = _this.cache.diff(oq["queryInfo"]["getDiffOptions"]()); } result = onQueryUpdated(oq, diff, lastDiff); } // Otherwise, we fall back to refetching. if (!onQueryUpdated || result === true) { result = oq.refetch(); } if (result !== false) { results.set(oq, result); } if (queryId.indexOf("legacyOneTimeQuery") >= 0) { _this.stopQueryNoBroadcast(queryId); } }); } if (removeOptimistic) { // In case no updateCache callback was provided (so cache.batch was not // called above, and thus did not already remove the optimistic layer), // remove it here. Since this is a no-op when the layer has already been // removed, we do it even if we called cache.batch above, since it's // possible this.cache is an instance of some ApolloCache subclass other // than InMemoryCache, and does not fully support the removeOptimistic // option for cache.batch. this.cache.removeOptimistic(removeOptimistic); } return results; }; QueryManager.prototype.maskOperation = function (options) { var _a, _b, _c; var document = options.document, data = options.data; if (globalThis.__DEV__ !== false) { var fetchPolicy = options.fetchPolicy, id = options.id; var operationType = (_a = getOperationDefinition(document)) === null || _a === void 0 ? void 0 : _a.operation; var operationId = ((_b = operationType === null || operationType === void 0 ? void 0 : operationType[0]) !== null && _b !== void 0 ? _b : "o") + id; if (this.dataMasking && fetchPolicy === "no-cache" && !isFullyUnmaskedOperation(document) && !this.noCacheWarningsByQueryId.has(operationId)) { this.noCacheWarningsByQueryId.add(operationId); globalThis.__DEV__ !== false && invariant.warn( 37, (_c = getOperationName(document)) !== null && _c !== void 0 ? _c : "Unnamed ".concat(operationType !== null && operationType !== void 0 ? operationType : "operation") ); } } return (this.dataMasking ? maskOperation(data, document, this.cache) : data); }; QueryManager.prototype.maskFragment = function (options) { var data = options.data, fragment = options.fragment, fragmentName = options.fragmentName; return this.dataMasking ? maskFragment(data, fragment, this.cache, fragmentName) : data; }; QueryManager.prototype.fetchQueryByPolicy = function (queryInfo, _a, // The initial networkStatus for this fetch, most often // NetworkStatus.loading, but also possibly fetchMore, poll, refetch, // or setVariables. networkStatus) { var _this = this; var query = _a.query, variables = _a.variables, fetchPolicy = _a.fetchPolicy, refetchWritePolicy = _a.refetchWritePolicy, errorPolicy = _a.errorPolicy, returnPartialData = _a.returnPartialData, context = _a.context, notifyOnNetworkStatusChange = _a.notifyOnNetworkStatusChange; var oldNetworkStatus = queryInfo.networkStatus; queryInfo.init({ document: query, variables: variables, networkStatus: networkStatus, }); var readCache = function () { return queryInfo.getDiff(); }; var resultsFromCache = function (diff, networkStatus) { if (networkStatus === void 0) { networkStatus = queryInfo.networkStatus || NetworkStatus.loading; } var data = diff.result; if (globalThis.__DEV__ !== false && !returnPartialData && !equal(data, {})) { logMissingFieldErrors(diff.missing); } var fromData = function (data) { return Observable.of(__assign({ data: data, loading: isNetworkRequestInFlight(networkStatus), networkStatus: networkStatus }, (diff.complete ? null : { partial: true }))); }; if (data && _this.getDocumentInfo(query).hasForcedResolvers) { return _this.localState .runResolvers({ document: query, remoteResult: { data: data }, context: context, variables: variables, onlyRunForcedResolvers: true, }) .then(function (resolved) { return fromData(resolved.data || void 0); }); } // Resolves https://github.com/apollographql/apollo-client/issues/10317. // If errorPolicy is 'none' and notifyOnNetworkStatusChange is true, // data was incorrectly returned from the cache on refetch: // if diff.missing exists, we should not return cache data. if (errorPolicy === "none" && networkStatus === NetworkStatus.refetch && Array.isArray(diff.missing)) { return fromData(void 0); } return fromData(data); }; var cacheWriteBehavior = fetchPolicy === "no-cache" ? 0 /* CacheWriteBehavior.FORBID */ // Watched queries must opt into overwriting existing data on refetch, // by passing refetchWritePolicy: "overwrite" in their WatchQueryOptions. : (networkStatus === NetworkStatus.refetch && refetchWritePolicy !== "merge") ? 1 /* CacheWriteBehavior.OVERWRITE */ : 2 /* CacheWriteBehavior.MERGE */; var resultsFromLink = function () { return _this.getResultsFromLink(queryInfo, cacheWriteBehavior, { query: query, variables: variables, context: context, fetchPolicy: fetchPolicy, errorPolicy: errorPolicy, }); }; var shouldNotify = notifyOnNetworkStatusChange && typeof oldNetworkStatus === "number" && oldNetworkStatus !== networkStatus && isNetworkRequestInFlight(networkStatus); switch (fetchPolicy) { default: case "cache-first": { var diff = readCache(); if (diff.complete) { return { fromLink: false, sources: [resultsFromCache(diff, queryInfo.markReady())], }; } if (returnPartialData || shouldNotify) { return { fromLink: true, sources: [resultsFromCache(diff), resultsFromLink()], }; } return { fromLink: true, sources: [resultsFromLink()] }; } case "cache-and-network": { var diff = readCache(); if (diff.complete || returnPartialData || shouldNotify) { return { fromLink: true, sources: [resultsFromCache(diff), resultsFromLink()], }; } return { fromLink: true, sources: [resultsFromLink()] }; } case "cache-only": return { fromLink: false, sources: [resultsFromCache(readCache(), queryInfo.markReady())], }; case "network-only": if (shouldNotify) { return { fromLink: true, sources: [resultsFromCache(readCache()), resultsFromLink()], }; } return { fromLink: true, sources: [resultsFromLink()] }; case "no-cache": if (shouldNotify) { return { fromLink: true, // Note that queryInfo.getDiff() for no-cache queries does not call // cache.diff, but instead returns a { complete: false } stub result // when there is no queryInfo.diff already defined. sources: [resultsFromCache(queryInfo.getDiff()), resultsFromLink()], }; } return { fromLink: true, sources: [resultsFromLink()] }; case "standby": return { fromLink: false, sources: [] }; } }; QueryManager.prototype.getOrCreateQuery = function (queryId) { if (queryId && !this.queries.has(queryId)) { this.queries.set(queryId, new QueryInfo(this, queryId)); } return this.queries.get(queryId); }; QueryManager.prototype.prepareContext = function (context) { if (context === void 0) { context = {}; } var newContext = this.localState.prepareContext(context); return __assign(__assign(__assign({}, this.defaultContext), newContext), { clientAwareness: this.clientAwareness }); }; return QueryManager; }()); export { QueryManager }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUXVlcnlNYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvUXVlcnlNYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFLN0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd0QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDaEQsT0FBTyxFQUNMLDhCQUE4QixFQUU5QixhQUFhLEVBQ2IsaUNBQWlDLEVBQ2pDLHNCQUFzQixFQUN0Qix3QkFBd0IsRUFDeEIsNEJBQTRCLEdBQzdCLE1BQU0sdUJBQXVCLENBQUM7QUFFL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFNdkQsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixzQkFBc0IsRUFDdEIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLFVBQVUsRUFDVixRQUFRLEVBQ1IsZUFBZSxFQUNmLE9BQU8sRUFDUCxZQUFZLEVBQ1osY0FBYyxFQUNkLGVBQWUsRUFDZixpQkFBaUIsR0FDbEIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNoRixPQUFPLEVBQ0wsV0FBVyxFQUNYLGFBQWEsRUFDYiw4QkFBOEIsR0FDL0IsTUFBTSxvQkFBb0IsQ0FBQztBQVU1QixPQUFPLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDOUUsT0FBTyxFQUFFLGFBQWEsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBZTdFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsaUJBQWlCLEdBRWxCLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBSXRDLElBQUEsY0FBYyxHQUFLLE1BQU0sQ0FBQyxTQUFTLGVBQXJCLENBQXNCO0FBRTVDLElBQU0sTUFBTSxHQUFtQixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBdUJuRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBK0JsRTtJQThCRSxzQkFBWSxPQUFvQztRQUFoRCxpQkFnQ0M7UUFsRE8sb0JBQWUsR0FBMkIsRUFBRSxDQUFDO1FBUXJELG1FQUFtRTtRQUNuRSwwQ0FBMEM7UUFDbEMsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO1FBRS9DLCtEQUErRDtRQUMvRCx3Q0FBd0M7UUFDeEMsNENBQTRDO1FBQzVDLGdFQUFnRTtRQUN0RCxtQkFBYyxHQUFHLElBQUksR0FBRyxFQUErQixDQUFDO1FBMmdCMUQsbUJBQWMsR0FBRyxJQUFJLG9CQUFvQixDQUkvQyxVQUFVLENBQUMsOEJBQThCLENBQUM7d0VBQ1MsQ0FDcEQsQ0FBQztRQWlKTSxtQkFBYyxHQUFHLENBQUMsQ0FBQztRQUtuQixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFLckIsc0JBQWlCLEdBQUcsQ0FBQyxDQUFDO1FBNFI5Qiw0Q0FBNEM7UUFDNUMsZ0VBQWdFO1FBQ3RELDRCQUF1QixHQUFHLElBQUksSUFBSSxDQUV6QyxLQUFLLENBQUMsQ0FBQztRQXdiRiw2QkFBd0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBajRDbkQsSUFBTSx3QkFBd0IsR0FBRyxJQUFJLGlCQUFpQixDQUNwRCxVQUFDLFFBQVEsSUFBSyxPQUFBLEtBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEVBQXRDLENBQXNDO1FBQ3BELDREQUE0RDtRQUM1RCxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FDakIsQ0FBQztRQUVGLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQzdDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDckQsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO1FBQy9DLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDL0IsSUFBSSxDQUFDLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQztRQUM3RCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDdkMsSUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFDcEQsSUFBSSxDQUFDLGlCQUFpQjtZQUNwQixpQkFBaUIsQ0FBQyxDQUFDO2dCQUNqQix3QkFBd0I7cUJBQ3JCLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztvQkFDMUIsb0VBQW9FO29CQUNwRSxpRUFBaUU7b0JBQ2pFLGlFQUFpRTtvQkFDakUsdURBQXVEO3FCQUN0RCxNQUFNLENBQUMsd0JBQXdCLENBQUM7Z0JBQ3JDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQztRQUM3QixJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVwRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSSwyQkFBSSxHQUFYO1FBQUEsaUJBUUM7UUFQQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUssRUFBRSxPQUFPO1lBQ2xDLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxvQkFBb0IsQ0FDdkIsaUJBQWlCLENBQUMsZ0RBQWdELENBQUMsQ0FDcEUsQ0FBQztJQUNKLENBQUM7SUFFTywyQ0FBb0IsR0FBNUIsVUFBNkIsS0FBWTtRQUN2QyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxVQUFDLE1BQU0sSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFWSw2QkFBTSxHQUFuQjs0REFLRSxFQWE2Qzs7O2dCQVo3QyxRQUFRLGNBQUEsRUFDUixTQUFTLGVBQUEsRUFDVCxrQkFBa0Isd0JBQUEsRUFDbEIsYUFBYSxtQkFBQSxFQUNiLHNCQUFtQixFQUFuQixjQUFjLG1CQUFHLEVBQUUsS0FBQSxFQUNuQiwyQkFBMkIsRUFBM0IsbUJBQW1CLG1CQUFHLEtBQUssS0FBQSxFQUNuQixpQkFBaUIsWUFBQSxFQUN6QixjQUFjLG9CQUFBLEVBQ2QsbUJBQXVFLEVBQXZFLFdBQVcsbUJBQUcsQ0FBQSxNQUFBLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSwwQ0FBRSxXQUFXLEtBQUksY0FBYyxLQUFBLEVBQ3ZFLG1CQUErRCxFQUEvRCxXQUFXLG1CQUFHLENBQUEsTUFBQSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sMENBQUUsV0FBVyxLQUFJLE1BQU0sS0FBQSxFQUMvRCxjQUFjLG9CQUFBLEVBQ2QsT0FBTyxhQUFBOzs7O3dCQUlQLFNBQVMsQ0FDUCxRQUFRLEVBQ1IsNkZBQTZGLENBQzlGLENBQUM7d0JBRUYsU0FBUyxDQUNQLFdBQVcsS0FBSyxjQUFjLElBQUksV0FBVyxLQUFLLFVBQVUsRUFDNUQsNE1BQTRNLENBQzdNLENBQUM7d0JBRUksVUFBVSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO3dCQUU3QyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7d0JBQ3pELGdCQUFnQixHQUFLLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLGlCQUFuQyxDQUFvQzt3QkFFNUQsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBZSxDQUFDOzZCQUM3RCxnQkFBZ0IsRUFBaEIsd0JBQWdCO3dCQUNMLHFCQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQ3JELFFBQVEsRUFDUixTQUFTLEVBQ1QsT0FBTyxDQUNSLEVBQUE7O3dCQUpELFNBQVMsR0FBRyxDQUFDLFNBSVosQ0FBZSxDQUFDOzs7d0JBR2Isa0JBQWtCLEdBQ3RCLElBQUksQ0FBQyxhQUFhOzRCQUNsQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEdBQUc7Z0NBQ2hDLFFBQVEsVUFBQTtnQ0FDUixTQUFTLFdBQUE7Z0NBQ1QsT0FBTyxFQUFFLElBQUk7Z0NBQ2IsS0FBSyxFQUFFLElBQUk7NkJBQ1UsQ0FBQyxDQUFDO3dCQUVyQixZQUFZLEdBQ2hCLGtCQUFrQjs0QkFDbEIsSUFBSSxDQUFDLHNCQUFzQixDQUN6QixrQkFBa0IsRUFDbEI7Z0NBQ0UsVUFBVSxZQUFBO2dDQUNWLFFBQVEsRUFBRSxRQUFRO2dDQUNsQixTQUFTLFdBQUE7Z0NBQ1QsV0FBVyxhQUFBO2dDQUNYLFdBQVcsYUFBQTtnQ0FDWCxPQUFPLFNBQUE7Z0NBQ1AsYUFBYSxlQUFBO2dDQUNiLE1BQU0sRUFBRSxpQkFBaUI7Z0NBQ3pCLGNBQWMsZ0JBQUE7NkJBQ2YsQ0FDRixDQUFDO3dCQUVKLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO3dCQUVsQixJQUFJLEdBQUcsSUFBSSxDQUFDO3dCQUVsQixzQkFBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO2dDQUNqQyxPQUFPLFFBQVEsQ0FDYixJQUFJLENBQUMscUJBQXFCLENBQ3hCLFFBQVEsd0JBRUgsT0FBTyxLQUNWLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUVoRSxTQUFTLEVBQ1QsRUFBRSxFQUNGLEtBQUssQ0FDTixFQUVELFVBQUMsTUFBMEI7b0NBQ3pCLElBQUkscUJBQXFCLENBQUMsTUFBTSxDQUFDLElBQUksV0FBVyxLQUFLLE1BQU0sRUFBRSxDQUFDO3dDQUM1RCxNQUFNLElBQUksV0FBVyxDQUFDOzRDQUNwQixhQUFhLEVBQUUsMEJBQTBCLENBQUMsTUFBTSxDQUFDO3lDQUNsRCxDQUFDLENBQUM7b0NBQ0wsQ0FBQztvQ0FFRCxJQUFJLGtCQUFrQixFQUFFLENBQUM7d0NBQ3ZCLGtCQUFrQixDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7d0NBQ25DLGtCQUFrQixDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7b0NBQ2xDLENBQUM7b0NBRUQsSUFBTSxXQUFXLGdCQUF1QixNQUFNLENBQUUsQ0FBQztvQ0FFakQsSUFBSSxPQUFPLGNBQWMsS0FBSyxVQUFVLEVBQUUsQ0FBQzt3Q0FDekMsY0FBYyxHQUFHLGNBQWMsQ0FDN0IsV0FBMkMsQ0FDNUMsQ0FBQztvQ0FDSixDQUFDO29DQUVELElBQUksV0FBVyxLQUFLLFFBQVEsSUFBSSxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO3dDQUNuRSxPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUM7b0NBQzVCLENBQUM7b0NBRUQsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQXNDO3dDQUNsRSxVQUFVLFlBQUE7d0NBQ1YsTUFBTSxFQUFFLFdBQVc7d0NBQ25CLFFBQVEsRUFBRSxRQUFRO3dDQUNsQixTQUFTLFdBQUE7d0NBQ1QsV0FBVyxhQUFBO3dDQUNYLFdBQVcsYUFBQTt3Q0FDWCxPQUFPLFNBQUE7d0NBQ1AsTUFBTSxFQUFFLGlCQUFpQjt3Q0FDekIsYUFBYSxlQUFBO3dDQUNiLG1CQUFtQixxQkFBQTt3Q0FDbkIsY0FBYyxnQkFBQTt3Q0FDZCxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO3dDQUNwRCxjQUFjLGdCQUFBO3dDQUNkLGNBQWMsZ0JBQUE7cUNBQ2YsQ0FBQyxDQUFDO2dDQUNMLENBQUMsQ0FDRixDQUFDLFNBQVMsQ0FBQztvQ0FDVixJQUFJLFlBQUMsV0FBVzt3Q0FDZCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzt3Q0FFeEIsMkRBQTJEO3dDQUMzRCxpREFBaUQ7d0NBQ2pELDZEQUE2RDt3Q0FDN0QsNkRBQTZEO3dDQUM3RCwyQ0FBMkM7d0NBQzNDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxXQUFXLENBQUMsSUFBSSxXQUFXLENBQUMsT0FBTyxLQUFLLEtBQUssRUFBRSxDQUFDOzRDQUNqRSxPQUFPLHVCQUNGLFdBQVcsS0FDZCxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQztvREFDdkIsUUFBUSxFQUFFLFFBQVE7b0RBQ2xCLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSTtvREFDdEIsV0FBVyxhQUFBO29EQUNYLEVBQUUsRUFBRSxVQUFVO2lEQUNmLENBQVEsSUFDVCxDQUFDO3dDQUNMLENBQUM7b0NBQ0gsQ0FBQztvQ0FFRCxLQUFLLFlBQUMsR0FBVTt3Q0FDZCxJQUFJLGtCQUFrQixFQUFFLENBQUM7NENBQ3ZCLGtCQUFrQixDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7NENBQ25DLGtCQUFrQixDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7d0NBQ2pDLENBQUM7d0NBRUQsSUFBSSxZQUFZLEVBQUUsQ0FBQzs0Q0FDakIsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQzt3Q0FDMUMsQ0FBQzt3Q0FFRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzt3Q0FFeEIsTUFBTSxDQUNKLEdBQUcsWUFBWSxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FDakMsSUFBSSxXQUFXLENBQUM7NENBQ2QsWUFBWSxFQUFFLEdBQUc7eUNBQ2xCLENBQUMsQ0FDSCxDQUNGLENBQUM7b0NBQ0osQ0FBQztpQ0FDRixDQUFDLENBQUM7NEJBQ0wsQ0FBQyxDQUFDLEVBQUM7Ozs7S0FDSjtJQUVNLHlDQUFrQixHQUF6QixVQU1FLFFBZUMsRUFDRCxLQUFrQjtRQXRCcEIsaUJBaU5DO1FBM0xDLHNCQUFBLEVBQUEsUUFBUSxJQUFJLENBQUMsS0FBSztRQUVaLElBQUEsTUFBTSxHQUFLLFFBQVEsT0FBYixDQUFjO1FBQzFCLElBQU0sV0FBVyxHQUF5QixFQUFFLENBQUM7UUFDN0MsSUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFdBQVcsS0FBSyxVQUFVLENBQUM7UUFFdEQsSUFBSSxDQUFDLFNBQVMsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDbEUsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQy9DLFdBQVcsQ0FBQyxJQUFJLENBQUM7b0JBQ2YsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJO29CQUNuQixNQUFNLEVBQUUsZUFBZTtvQkFDdkIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxRQUFRO29CQUN4QixTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7aUJBQzlCLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxJQUNFLGlDQUFpQyxDQUFDLE1BQU0sQ0FBQztnQkFDekMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFDbkMsQ0FBQztnQkFDRCxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFRO29CQUM3QixFQUFFLEVBQUUsZUFBZTtvQkFDbkIsOERBQThEO29CQUM5RCxnRUFBZ0U7b0JBQ2hFLDhDQUE4QztvQkFDOUMsS0FBSyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU87b0JBQ3RELFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztvQkFDN0IsVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLGlCQUFpQixFQUFFLElBQUk7aUJBQ3hCLENBQUMsQ0FBQztnQkFDSCxJQUFJLFVBQVUsU0FBQSxDQUFDO2dCQUNmLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNoQixVQUFVLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDekQsQ0FBQztnQkFDRCxJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsRUFBRSxDQUFDO29CQUN0QywwREFBMEQ7b0JBQzFELHNFQUFzRTtvQkFDckUsTUFBc0IsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO29CQUMxQyxXQUFXLENBQUMsSUFBSSxDQUFDO3dCQUNmLE1BQU0sRUFBRSxVQUFVO3dCQUNsQixNQUFNLEVBQUUsZUFBZTt3QkFDdkIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxRQUFRO3dCQUN4QixTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7cUJBQzlCLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztZQUVPLElBQUEsZUFBYSxHQUFLLFFBQVEsY0FBYixDQUFjO1lBQ25DLElBQUksZUFBYSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsRUFBbUIsRUFBRSxPQUFPO3dCQUExQixlQUFlLHFCQUFBO29CQUNyQyxJQUFNLFNBQVMsR0FBRyxlQUFlLElBQUksZUFBZSxDQUFDLFNBQVMsQ0FBQztvQkFDL0QsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBYSxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUM7d0JBQ2pFLE9BQU87b0JBQ1QsQ0FBQztvQkFDRCxJQUFNLE9BQU8sR0FBRyxlQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ25DLElBQUEsS0FBMEIsS0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFFLEVBQWxELFFBQVEsY0FBQSxFQUFFLFNBQVMsZUFBK0IsQ0FBQztvQkFFM0QsZ0RBQWdEO29CQUMxQyxJQUFBLEtBQTJDLEtBQUssQ0FBQyxJQUFJLENBQVE7d0JBQ2pFLEtBQUssRUFBRSxRQUFTO3dCQUNoQixTQUFTLFdBQUE7d0JBQ1QsaUJBQWlCLEVBQUUsSUFBSTt3QkFDdkIsVUFBVSxFQUFFLEtBQUs7cUJBQ2xCLENBQUMsRUFMYyxrQkFBa0IsWUFBQSxFQUFFLFFBQVEsY0FLMUMsQ0FBQztvQkFFSCxJQUFJLFFBQVEsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO3dCQUNuQywwRUFBMEU7d0JBQzFFLElBQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTs0QkFDbEQsY0FBYyxFQUFFLE1BQXNDOzRCQUN0RCxTQUFTLEVBQUUsQ0FBQyxRQUFRLElBQUksZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUM7NEJBQzdELGNBQWMsRUFBRSxTQUFVO3lCQUMzQixDQUFDLENBQUM7d0JBRUgsd0VBQXdFO3dCQUN4RSxJQUFJLGVBQWUsRUFBRSxDQUFDOzRCQUNwQixXQUFXLENBQUMsSUFBSSxDQUFDO2dDQUNmLE1BQU0sRUFBRSxlQUFlO2dDQUN2QixNQUFNLEVBQUUsWUFBWTtnQ0FDcEIsS0FBSyxFQUFFLFFBQVM7Z0NBQ2hCLFNBQVMsV0FBQTs2QkFDVixDQUFDLENBQUM7d0JBQ0wsQ0FBQztvQkFDSCxDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFFRCxJQUNFLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUN0QixDQUFDLFFBQVEsQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU07WUFDZixRQUFRLENBQUMsY0FBYztZQUN2QixRQUFRLENBQUMsZ0JBQWdCLEVBQ3pCLENBQUM7WUFDRCxJQUFNLFNBQU8sR0FBVSxFQUFFLENBQUM7WUFFMUIsSUFBSSxDQUFDLGNBQWMsQ0FBQztnQkFDbEIsV0FBVyxFQUFFLFVBQUMsS0FBSztvQkFDakIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO3dCQUNmLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFsQixDQUFrQixDQUFDLENBQUM7b0JBQ3JELENBQUM7b0JBRUQscUVBQXFFO29CQUNyRSxxRUFBcUU7b0JBQ3JFLGtCQUFrQjtvQkFDVixJQUFBLE1BQU0sR0FBSyxRQUFRLE9BQWIsQ0FBYztvQkFDNUIsdURBQXVEO29CQUN2RCxxQ0FBcUM7b0JBQ3JDLElBQU0sYUFBYSxHQUNqQixDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQzt3QkFDL0IsQ0FBQyxpQ0FBaUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFFakUsSUFBSSxNQUFNLEVBQUUsQ0FBQzt3QkFDWCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7NEJBQ2YsOERBQThEOzRCQUM5RCw4REFBOEQ7NEJBQzlELDJEQUEyRDs0QkFDM0QseUNBQXlDOzRCQUN6QyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFRO2dDQUM3QixFQUFFLEVBQUUsZUFBZTtnQ0FDbkIsOERBQThEO2dDQUM5RCxnRUFBZ0U7Z0NBQ2hFLDhDQUE4QztnQ0FDOUMsS0FBSyxFQUFFLEtBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU87Z0NBQ3RELFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztnQ0FDN0IsVUFBVSxFQUFFLEtBQUs7Z0NBQ2pCLGlCQUFpQixFQUFFLElBQUk7NkJBQ3hCLENBQUMsQ0FBQzs0QkFFSCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQ0FDbEIsTUFBTSx5QkFBUyxNQUFzQixLQUFFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFFLENBQUM7Z0NBQzNELElBQUksYUFBYSxJQUFJLE1BQU0sRUFBRSxDQUFDO29DQUM1QixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUM7Z0NBQzVCLENBQUM7Z0NBQ0QsSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7b0NBQ3hCLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztnQ0FDeEIsQ0FBQzs0QkFDSCxDQUFDO3dCQUNILENBQUM7d0JBRUQsd0NBQXdDO3dCQUN4QyxvRUFBb0U7d0JBQ3BFLDRCQUE0Qjt3QkFDNUIsSUFBSSxhQUFhLEVBQUUsQ0FBQzs0QkFDbEIsTUFBTSxDQUFDLEtBQWUsRUFBRSxNQUFzQyxFQUFFO2dDQUM5RCxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0NBQ3pCLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUzs2QkFDOUIsQ0FBQyxDQUFDO3dCQUNMLENBQUM7b0JBQ0gsQ0FBQztvQkFFRCxxRUFBcUU7b0JBQ3JFLHNEQUFzRDtvQkFDdEQsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLElBQUksYUFBYSxFQUFFLENBQUM7d0JBQzVELEtBQUssQ0FBQyxNQUFNLENBQUM7NEJBQ1gsRUFBRSxFQUFFLGVBQWU7NEJBQ25CLE1BQU0sWUFBQyxLQUFLLEVBQUUsRUFBcUI7b0NBQW5CLFNBQVMsZUFBQSxFQUFFLE1BQU0sWUFBQTtnQ0FDL0IsT0FBTyxTQUFTLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQzs0QkFDckQsQ0FBQzt5QkFDRixDQUFDLENBQUM7b0JBQ0wsQ0FBQztnQkFDSCxDQUFDO2dCQUVELE9BQU8sRUFBRSxRQUFRLENBQUMsY0FBYztnQkFFaEMsa0VBQWtFO2dCQUNsRSxVQUFVLEVBQUUsS0FBSztnQkFFakIsbUVBQW1FO2dCQUNuRSx5Q0FBeUM7Z0JBQ3pDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxnQkFBZ0I7Z0JBRTNDLHNFQUFzRTtnQkFDdEUsd0VBQXdFO2dCQUN4RSxxRUFBcUU7Z0JBQ3JFLHdFQUF3RTtnQkFDeEUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxjQUFjLElBQUksSUFBSTthQUNoRCxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTSxJQUFLLE9BQUEsU0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBcEIsQ0FBb0IsQ0FBQyxDQUFDO1lBRTdDLElBQUksUUFBUSxDQUFDLG1CQUFtQixJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDNUQsd0VBQXdFO2dCQUN4RSxzRUFBc0U7Z0JBQ3RFLHlDQUF5QztnQkFDekMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFNLE9BQUEsTUFBTSxFQUFOLENBQU0sQ0FBQyxDQUFDO1lBQ2pELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFTSw2Q0FBc0IsR0FBN0IsVUFNRSxrQkFBdUIsRUFDdkIsUUFVQztRQWpCSCxpQkEyQ0M7UUF4QkMsSUFBTSxJQUFJLEdBQ1IsT0FBTyxrQkFBa0IsS0FBSyxVQUFVLENBQUMsQ0FBQztZQUN4QyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxRQUFBLEVBQUUsQ0FBQztZQUNwRCxDQUFDLENBQUMsa0JBQWtCLENBQUM7UUFFdkIsSUFBSSxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDcEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxVQUFDLEtBQUs7WUFDM0MsSUFBSSxDQUFDO2dCQUNILEtBQUksQ0FBQyxrQkFBa0IsdUJBRWhCLFFBQVEsS0FDWCxNQUFNLEVBQUUsRUFBRSxJQUFJLE1BQUEsRUFBRSxLQUVsQixLQUFLLENBQ04sQ0FBQztZQUNKLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUMsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFeEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0saUNBQVUsR0FBakIsVUFDRSxPQUFlLEVBQ2YsT0FBd0MsRUFDeEMsYUFBNkI7UUFFN0IsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQzlCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsRUFDOUIsT0FBTyxFQUNQLGFBQWEsQ0FDZCxDQUFDLE9BQU8sQ0FBQyxPQUFlLENBQUM7SUFDNUIsQ0FBQztJQUVNLG9DQUFhLEdBQXBCO1FBQ0UsSUFBTSxLQUFLLEdBQW9DLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFJLEVBQUUsT0FBTztZQUNqQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUc7Z0JBQ2YsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUN6QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7Z0JBQ2pDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtnQkFDL0IsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO2FBQ2xDLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVNLGtDQUFXLEdBQWxCLFVBQW1CLE9BQWU7UUFDaEMsSUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLFNBQVMsQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1lBQ25DLFNBQVMsQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRU0sZ0NBQVMsR0FBaEIsVUFBaUIsUUFBc0I7UUFDckMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQVVNLHNDQUFlLEdBQXRCLFVBQXVCLFFBQXNCO1FBQ25DLElBQUEsY0FBYyxHQUFLLElBQUksZUFBVCxDQUFVO1FBRWhDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDbEMsSUFBTSxVQUFVLEdBQXdCO2dCQUN0QyxzRUFBc0U7Z0JBQ3RFLHVFQUF1RTtnQkFDdkUsZ0VBQWdFO2dCQUNoRSxrRUFBa0U7Z0JBQ2xFLCtCQUErQjtnQkFDL0IsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsUUFBUSxDQUFDO2dCQUM1QyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztnQkFDbEUsdUJBQXVCLEVBQUUsYUFBYSxDQUFDLENBQUMsYUFBYSxDQUFDLEVBQUUsUUFBUSxDQUFDO2dCQUNqRSxnQkFBZ0IsRUFBRSw4QkFBOEIsQ0FBQyxRQUFRLENBQUM7Z0JBQzFELFdBQVcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUM7Z0JBQ2xELFdBQVcsRUFBRSw0QkFBNEIsQ0FDdkM7b0JBQ0UsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRTtvQkFDdEIsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFO29CQUN2QixFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7aUJBQ25CLEVBQ0QsUUFBUSxDQUNUO2dCQUNELFdBQVcsRUFBRSxnQkFBZ0IsQ0FDM0Isc0JBQXNCLENBQUMsUUFBUSxDQUFDLENBQ1g7Z0JBQ3ZCLHdFQUF3RTtnQkFDeEUsK0NBQStDO2dCQUMvQyxPQUFPLHdCQUNGLFFBQVEsS0FDWCxXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBQyxHQUFHO3dCQUN4QyxJQUNFLEdBQUcsQ0FBQyxJQUFJLEtBQUsscUJBQXFCOzRCQUNsQyxHQUFHLENBQUMsU0FBUyxLQUFLLE9BQU8sRUFDekIsQ0FBQzs0QkFDRCw2QkFBWSxHQUFHLEtBQUUsU0FBUyxFQUFFLE9BQTRCLElBQUc7d0JBQzdELENBQUM7d0JBQ0QsT0FBTyxHQUFHLENBQUM7b0JBQ2IsQ0FBQyxDQUFDLEdBQ0g7YUFDRixDQUFDO1lBRUYsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRU8sbUNBQVksR0FBcEIsVUFDRSxRQUFzQixFQUN0QixTQUFzQjtRQUV0Qiw2QkFDSyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVcsR0FDMUMsU0FBUyxFQUNaO0lBQ0osQ0FBQztJQUVNLGlDQUFVLEdBQWpCLFVBR0UsT0FBeUM7UUFDekMsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFNUMsNkNBQTZDO1FBQzdDLHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUsT0FBTyx5QkFDRixPQUFPLEtBQ1YsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQWUsR0FDckUsQ0FBQztRQUVGLElBQUksT0FBTyxPQUFPLENBQUMsMkJBQTJCLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0QsT0FBTyxDQUFDLDJCQUEyQixHQUFHLEtBQUssQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBTSxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLENBQWdCO1lBQ3BELFlBQVksRUFBRSxJQUFJO1lBQ2xCLFNBQVMsV0FBQTtZQUNULE9BQU8sU0FBQTtTQUNSLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxXQUFXLENBQUMsR0FBRyxLQUFLLENBQUM7UUFFaEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQseUVBQXlFO1FBQ3pFLHNEQUFzRDtRQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2IsUUFBUSxFQUFFLEtBQUs7WUFDZixlQUFlLEVBQUUsVUFBVTtZQUMzQixTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVM7U0FDaEMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVNLDRCQUFLLEdBQVosVUFDRSxPQUFtQyxFQUNuQyxPQUFnQztRQUZsQyxpQkF5Q0M7UUF2Q0Msd0JBQUEsRUFBQSxVQUFVLElBQUksQ0FBQyxlQUFlLEVBQUU7UUFFaEMsU0FBUyxDQUNQLE9BQU8sQ0FBQyxLQUFLLEVBQ2IsbUVBQW1FO1lBQ2pFLHNCQUFzQixDQUN6QixDQUFDO1FBRUYsU0FBUyxDQUNQLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFDakMsZ0RBQWdELENBQ2pELENBQUM7UUFFRixTQUFTLENBQ1AsQ0FBRSxPQUFlLENBQUMsaUJBQWlCLEVBQ25DLHdEQUF3RCxDQUN6RCxDQUFDO1FBRUYsU0FBUyxDQUNQLENBQUUsT0FBZSxDQUFDLFlBQVksRUFDOUIsbURBQW1ELENBQ3BELENBQUM7UUFFRixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU1QyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQWUsT0FBTyx3QkFBTyxPQUFPLEtBQUUsS0FBSyxPQUFBLElBQUc7YUFDakUsSUFBSSxDQUNILFVBQUMsTUFBTTtZQUNMLE9BQUEsTUFBTSwwQkFDRCxNQUFNLEtBQ1QsSUFBSSxFQUFFLEtBQUksQ0FBQyxhQUFhLENBQUM7b0JBQ3ZCLFFBQVEsRUFBRSxLQUFLO29CQUNmLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtvQkFDakIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO29CQUNoQyxFQUFFLEVBQUUsT0FBTztpQkFDWixDQUFDLEdBQ0g7UUFSRCxDQVFDLENBQ0o7YUFDQSxPQUFPLENBQUMsY0FBTSxPQUFBLEtBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQXZCLENBQXVCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBR00sc0NBQWUsR0FBdEI7UUFDRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBR00sd0NBQWlCLEdBQXhCO1FBQ0UsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBR00seUNBQWtCLEdBQXpCO1FBQ0UsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU0sdUNBQWdCLEdBQXZCLFVBQXdCLE9BQWU7UUFDckMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFTyxrREFBMkIsR0FBbkMsVUFBb0MsT0FBZTtRQUNqRCxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxJQUFJLFNBQVM7WUFBRSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVNLGlDQUFVLEdBQWpCLFVBQ0UsT0FFQztRQUZELHdCQUFBLEVBQUE7WUFDRSxjQUFjLEVBQUUsSUFBSTtTQUNyQjtRQUVELHNFQUFzRTtRQUN0RSxxRUFBcUU7UUFDckUsc0VBQXNFO1FBQ3RFLHNFQUFzRTtRQUN0RSx3REFBd0Q7UUFDeEQsSUFBSSxDQUFDLG9CQUFvQixDQUN2QixpQkFBaUIsQ0FDZixxRUFBcUUsQ0FDdEUsQ0FDRixDQUFDO1FBRUYsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQyxTQUFTO1lBQzdCLElBQUksU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUM5QixrRUFBa0U7Z0JBQ2xFLDZCQUE2QjtnQkFDN0IsU0FBUyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDO1lBQ2xELENBQUM7aUJBQU0sQ0FBQztnQkFDTixTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFFRCxxQ0FBcUM7UUFDckMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRU0sMkNBQW9CLEdBQTNCLFVBQ0UsT0FBaUQ7UUFEbkQsaUJBa0dDO1FBakdDLHdCQUFBLEVBQUEsa0JBQWlEO1FBRWpELElBQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFnQyxDQUFDO1FBQ3hELElBQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO1FBQ3BELElBQU0seUJBQXlCLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7UUFDN0QsSUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBZ0IsQ0FBQztRQUVuRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsSUFBSTtnQkFDbkIsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDN0IsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQzNCLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzdDLENBQUM7cUJBQU0sSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDaEMsSUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLEtBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDaEQsVUFBVSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDcEQseUJBQXlCLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDcEQsQ0FBQztxQkFBTSxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQy9DLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDL0IsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsRUFBaUMsRUFBRSxPQUFPO2dCQUF2QixFQUFFLHFCQUFBLEVBQUUsUUFBUSxjQUFBO1lBQ25ELElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQ1AsSUFBSSxPQUFPLEtBQUssS0FBSyxFQUFFLENBQUM7b0JBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUN6QixPQUFPO2dCQUNULENBQUM7Z0JBR0MsSUFBQSxTQUFTLEdBRVAsRUFBRSxVQUZLLEVBQ0UsV0FBVyxHQUNwQixFQUFFLG9CQURrQixDQUNqQjtnQkFFUCxJQUNFLFdBQVcsS0FBSyxTQUFTO29CQUN6QixDQUFDLE9BQU8sS0FBSyxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUMsRUFDNUMsQ0FBQztvQkFDRCxPQUFPO2dCQUNULENBQUM7Z0JBRUQsSUFDRSxPQUFPLEtBQUssUUFBUTtvQkFDcEIsQ0FBQyxTQUFTLElBQUkseUJBQXlCLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUN2RCxDQUFDLFFBQVEsSUFBSSx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFDNUQsQ0FBQztvQkFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDekIsSUFBSSxTQUFTO3dCQUFFLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQzlELElBQUksUUFBUTt3QkFBRSx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNyRSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1QixrQkFBa0IsQ0FBQyxPQUFPLENBQUMsVUFBQyxPQUFxQjtnQkFDL0MsbUVBQW1FO2dCQUNuRSxxRUFBcUU7Z0JBQ3JFLDZEQUE2RDtnQkFDN0QsSUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLG9CQUFvQixDQUFDLENBQUM7Z0JBQ25ELElBQU0sU0FBUyxHQUFHLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ3BELFFBQVEsRUFBRSxPQUFPLENBQUMsS0FBSztvQkFDdkIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO2lCQUM3QixDQUFDLENBQUM7Z0JBQ0gsSUFBTSxFQUFFLEdBQUcsSUFBSSxlQUFlLENBQUM7b0JBQzdCLFlBQVksRUFBRSxLQUFJO29CQUNsQixTQUFTLFdBQUE7b0JBQ1QsT0FBTyx3QkFDRixPQUFPLEtBQ1YsV0FBVyxFQUFFLGNBQWMsR0FDNUI7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxDQUFDO2dCQUNsQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksT0FBTyxJQUFJLHlCQUF5QixDQUFDLElBQUksRUFBRSxDQUFDO1lBQzlDLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxVQUFDLFFBQVEsRUFBRSxpQkFBaUI7Z0JBQzVELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDZCxJQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBRXBELElBQUksU0FBUyxFQUFFLENBQUM7d0JBQ2QsU0FBUyxDQUFDLElBQUksQ0FDWiw4RUFBNEUsRUFDNUUsU0FBUyxDQUNWLENBQUM7b0JBQ0osQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLFNBQVMsQ0FBQyxJQUFJLENBQ1osMkVBQTJFLENBQzVFLENBQUM7b0JBQ0osQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVNLCtDQUF3QixHQUEvQixVQUNFLGNBQStCO1FBRGpDLGlCQXdCQztRQXZCQywrQkFBQSxFQUFBLHNCQUErQjtRQUUvQixJQUFNLHVCQUF1QixHQUFzQyxFQUFFLENBQUM7UUFFdEUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQ2xFLFVBQUMsZUFBZSxFQUFFLE9BQU87WUFDZixJQUFBLFdBQVcsR0FBSyxlQUFlLENBQUMsT0FBTyxZQUE1QixDQUE2QjtZQUNoRCxlQUFlLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNuQyxJQUNFLGNBQWM7Z0JBQ2QsQ0FBQyxXQUFXLEtBQUssU0FBUyxJQUFJLFdBQVcsS0FBSyxZQUFZLENBQUMsRUFDM0QsQ0FBQztnQkFDRCx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDMUQsQ0FBQztZQUNELENBQUMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUNqRSxJQUFJLENBQ0wsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUYsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVNLCtDQUF3QixHQUEvQixVQUNFLE9BQTRCO1FBRDlCLGlCQTJFQztRQXhFTyxJQUFBLEtBQUssR0FBZ0IsT0FBTyxNQUF2QixFQUFFLFNBQVMsR0FBSyxPQUFPLFVBQVosQ0FBYTtRQUVqQyxJQUFBLFdBQVcsR0FJVCxPQUFPLFlBSkUsRUFDWCxLQUdFLE9BQU8sWUFIVyxFQUFwQixXQUFXLG1CQUFHLE1BQU0sS0FBQSxFQUNwQixLQUVFLE9BQU8sUUFGRyxFQUFaLE9BQU8sbUJBQUcsRUFBRSxLQUFBLEVBQ1osS0FDRSxPQUFPLFdBRE0sRUFBZixVQUFVLG1CQUFHLEVBQUUsS0FBQSxDQUNMO1FBRVosS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRWhELElBQU0sY0FBYyxHQUFHLFVBQUMsU0FBNkI7WUFDbkQsT0FBQSxLQUFJLENBQUMscUJBQXFCLENBQUksS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUN0RSxVQUFDLE1BQU07Z0JBQ0wsSUFBSSxXQUFXLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQy9CLDZGQUE2RjtvQkFDN0YseUZBQXlGO29CQUN6RixJQUFJLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDO3dCQUMzQyxLQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQzs0QkFDZixLQUFLLE9BQUE7NEJBQ0wsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJOzRCQUNuQixNQUFNLEVBQUUsbUJBQW1COzRCQUMzQixTQUFTLEVBQUUsU0FBUzt5QkFDckIsQ0FBQyxDQUFDO29CQUNMLENBQUM7b0JBRUQsS0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzFCLENBQUM7Z0JBRUQsSUFBTSxTQUFTLEdBQUcscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2hELElBQU0saUJBQWlCLEdBQUcsOEJBQThCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksU0FBUyxJQUFJLGlCQUFpQixFQUFFLENBQUM7b0JBQ25DLElBQU0sTUFBTSxHQUF1QixFQUFFLENBQUM7b0JBQ3RDLElBQUksU0FBUyxFQUFFLENBQUM7d0JBQ2QsTUFBTSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO29CQUN2QyxDQUFDO29CQUNELElBQUksaUJBQWlCLEVBQUUsQ0FBQzt3QkFDdEIsTUFBTSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLHNCQUFzQixDQUFDLENBQUM7b0JBQ3BFLENBQUM7b0JBRUQsc0VBQXNFO29CQUN0RSxzRUFBc0U7b0JBQ3RFLG9CQUFvQjtvQkFDcEIsSUFBSSxXQUFXLEtBQUssTUFBTSxJQUFJLGlCQUFpQixFQUFFLENBQUM7d0JBQ2hELE1BQU0sSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2hDLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLFdBQVcsS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDN0IsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUN2QixDQUFDO2dCQUVELE9BQU8sTUFBTSxDQUFDO1lBQ2hCLENBQUMsQ0FDRjtRQTFDRCxDQTBDQyxDQUFDO1FBRUosSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDakQsSUFBTSxtQkFBaUIsR0FBRyxJQUFJLENBQUMsVUFBVTtpQkFDdEMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUM7aUJBQy9DLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4QixPQUFPLElBQUksVUFBVSxDQUFpQixVQUFDLFFBQVE7Z0JBQzdDLElBQUksR0FBRyxHQUFrQyxJQUFJLENBQUM7Z0JBQzlDLG1CQUFpQixDQUFDLElBQUksQ0FDcEIsVUFBQyxVQUFVLElBQUssT0FBQSxDQUFDLEdBQUcsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQXRDLENBQXNDLEVBQ3RELFFBQVEsQ0FBQyxLQUFLLENBQ2YsQ0FBQztnQkFDRixPQUFPLGNBQU0sT0FBQSxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUF4QixDQUF3QixDQUFDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxnQ0FBUyxHQUFoQixVQUFpQixPQUFlO1FBQzlCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sMkNBQW9CLEdBQTVCLFVBQTZCLE9BQWU7UUFDMUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVNLGtDQUFXLEdBQWxCLFVBQW1CLE9BQWU7O1FBQ2hDLHFCQUFxQjtRQUNyQixxRkFBcUY7UUFDckYsMERBQTBEO1FBQzFELDJGQUEyRjtRQUMzRixpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLDBDQUFFLElBQUksRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRU0sdUNBQWdCLEdBQXZCO1FBQ0UsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUksWUFBSyxPQUFBLE1BQUEsSUFBSSxDQUFDLGVBQWUsMENBQUcsUUFBUSxHQUFHLENBQUEsRUFBQSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVNLG9DQUFhLEdBQXBCO1FBQ0UsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFRTyw0Q0FBcUIsR0FBN0IsVUFDRSxLQUFtQixFQUNuQixPQUFZLEVBQ1osU0FBOEIsRUFDOUIsVUFBZ0M7SUFDaEMsa0RBQWtEO0lBQ2xELGFBQ3lCO1FBUDNCLGlCQTBFQzs7UUFwRUMsOEJBQUEsRUFBQSxzQkFBeUIsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLGtCQUFrQixtQ0FDbEQsSUFBSSxDQUFDLGtCQUFrQjtRQUV6QixJQUFJLFVBQWtELENBQUM7UUFFakQsSUFBQSxLQUErQixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxFQUF4RCxXQUFXLGlCQUFBLEVBQUUsV0FBVyxpQkFBZ0MsQ0FBQztRQUNqRSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ1YsSUFBQSxLQUFvQyxJQUFJLEVBQXRDLHlCQUF1Qiw2QkFBQSxFQUFFLElBQUksVUFBUyxDQUFDO1lBRS9DLElBQU0sU0FBUyxHQUFHO2dCQUNoQixLQUFLLEVBQUUsV0FBVztnQkFDbEIsU0FBUyxXQUFBO2dCQUNULGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLENBQUM7Z0JBQ3RELE9BQU8sRUFBRSxJQUFJLENBQUMsY0FBYyx1QkFDdkIsT0FBTyxLQUNWLFVBQVUsRUFBRSxDQUFDLGFBQWEsSUFDMUI7Z0JBQ0YsVUFBVSxZQUFBO2FBQ1gsQ0FBQztZQUVGLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDO1lBRTVCLElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLElBQU0sb0JBQWtCLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUM5QyxJQUFNLFNBQU8sR0FBRyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFOUMsSUFBTSxLQUFLLEdBQUcseUJBQXVCLENBQUMsTUFBTSxDQUMxQyxvQkFBa0IsRUFDbEIsU0FBTyxDQUNSLENBQUM7Z0JBRUYsVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDaEIsSUFBTSxTQUFPLEdBQUcsSUFBSSxPQUFPLENBQUM7d0JBQzFCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUErQjtxQkFDdkQsQ0FBQyxDQUFDO29CQUNILFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxHQUFHLFNBQU8sQ0FBQztvQkFFeEMsU0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLEVBQUUsR0FBZ0I7d0JBQ3JELElBQUksTUFBTSxLQUFLLE1BQU0sSUFBSSxTQUFTLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQzs0QkFDekQsU0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDekIsQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLHlCQUF1QixDQUFDLE1BQU0sQ0FBQyxvQkFBa0IsRUFBRSxTQUFPLENBQUMsQ0FBQzt3QkFDOUQsQ0FBQztvQkFDSCxDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQztvQkFDdkIsT0FBTyxDQUFDLElBQUksRUFBRSxTQUFTLENBQStCO2lCQUN2RCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixVQUFVLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsRUFBRSxVQUFDLE1BQU07Z0JBQ3ZDLE9BQU8sS0FBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7b0JBQ2xDLFFBQVEsRUFBRSxXQUFXO29CQUNyQixZQUFZLEVBQUUsTUFBTTtvQkFDcEIsT0FBTyxTQUFBO29CQUNQLFNBQVMsV0FBQTtpQkFDVixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRU8seUNBQWtCLEdBQTFCLFVBQ0UsU0FBb0IsRUFDcEIsa0JBQXNDLEVBQ3RDLE9BR0M7UUFFRCxJQUFNLFNBQVMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUV2RSx3RUFBd0U7UUFDeEUsMEVBQTBFO1FBQzFFLDBCQUEwQjtRQUMxQixJQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVoRSxPQUFPLFFBQVEsQ0FDYixJQUFJLENBQUMscUJBQXFCLENBQ3hCLFlBQVksRUFDWixPQUFPLENBQUMsT0FBTyxFQUNmLE9BQU8sQ0FBQyxTQUFTLENBQ2xCLEVBRUQsVUFBQyxNQUFNO1lBQ0wsSUFBTSxhQUFhLEdBQUcsMEJBQTBCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekQsSUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBQSxXQUFXLEdBQUssT0FBTyxZQUFaLENBQWE7WUFFaEMscUVBQXFFO1lBQ3JFLDZEQUE2RDtZQUM3RCxJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksU0FBUyxJQUFJLFdBQVcsS0FBSyxNQUFNLEVBQUUsQ0FBQztvQkFDeEMsa0RBQWtEO29CQUNsRCxNQUFNLFNBQVMsQ0FBQyxTQUFTLENBQ3ZCLElBQUksV0FBVyxDQUFDO3dCQUNkLGFBQWEsZUFBQTtxQkFDZCxDQUFDLENBQ0gsQ0FBQztnQkFDSixDQUFDO2dCQUNELHlEQUF5RDtnQkFDekQsbUVBQW1FO2dCQUNuRSx3Q0FBd0M7Z0JBQ3hDLFNBQVMsQ0FBQyxVQUFVLENBQ2xCLE1BQU0sRUFDTixZQUFZLEVBQ1osT0FBTyxFQUNQLGtCQUFrQixDQUNuQixDQUFDO2dCQUNGLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN4QixDQUFDO1lBRUQsSUFBTSxHQUFHLEdBQTZCO2dCQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLE9BQU8sRUFBRSxLQUFLO2dCQUNkLGFBQWEsRUFBRSxhQUFhLENBQUMsS0FBSzthQUNuQyxDQUFDO1lBRUYsb0VBQW9FO1lBQ3BFLHFFQUFxRTtZQUNyRSx3RUFBd0U7WUFDeEUsaUNBQWlDO1lBQ2pDLElBQUksU0FBUyxJQUFJLFdBQVcsS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDeEMsR0FBRyxDQUFDLElBQUksR0FBRyxLQUFLLENBQVUsQ0FBQztZQUM3QixDQUFDO1lBRUQsSUFBSSxTQUFTLElBQUksV0FBVyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMxQyxHQUFHLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQztnQkFDM0IsR0FBRyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDO1lBQzFDLENBQUM7WUFFRCxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUMsRUFFRCxVQUFDLFlBQVk7WUFDWCxJQUFNLEtBQUssR0FDVCxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FDM0MsSUFBSSxXQUFXLENBQUMsRUFBRSxZQUFZLGNBQUEsRUFBRSxDQUFDLENBQ2xDLENBQUM7WUFFSix1REFBdUQ7WUFDdkQsSUFBSSxTQUFTLElBQUksU0FBUyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN6QyxTQUFTLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzdCLENBQUM7WUFFRCxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVPLDJDQUFvQixHQUE1QixVQUNFLFNBQW9CLEVBQ3BCLE9BQXdDO0lBQ3hDLHVEQUF1RDtJQUN2RCxxRUFBcUU7SUFDckUsbUJBQW1CO0lBQ25CLGFBQXFDLEVBQ3JDLEtBQXFCO1FBUHZCLGlCQTJHQztRQXJHQyw4QkFBQSxFQUFBLGdCQUFnQixhQUFhLENBQUMsT0FBTztRQUNyQyxzQkFBQSxFQUFBLFFBQVEsT0FBTyxDQUFDLEtBQUs7UUFFckIsSUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBVSxDQUFDO1FBRXZFLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO1FBRTlDLElBQUEsS0FLRSxPQUFPLFlBTHdELEVBQWpFLFdBQVcsbUJBQUcsQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLGFBQWEsS0FBQSxFQUNqRSxLQUlFLE9BQU8sWUFKaUQsRUFBMUQsV0FBVyxtQkFBRyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksTUFBTSxLQUFBLEVBQzFELEtBR0UsT0FBTyxrQkFIZ0IsRUFBekIsaUJBQWlCLG1CQUFHLEtBQUssS0FBQSxFQUN6QixLQUVFLE9BQU8sNEJBRjBCLEVBQW5DLDJCQUEyQixtQkFBRyxLQUFLLEtBQUEsRUFDbkMsS0FDRSxPQUFPLFFBREcsRUFBWixPQUFPLG1CQUFHLEVBQUUsS0FBQSxDQUNGO1FBRVosSUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFO1lBQzVDLEtBQUssT0FBQTtZQUNMLFNBQVMsV0FBQTtZQUNULFdBQVcsYUFBQTtZQUNYLFdBQVcsYUFBQTtZQUNYLGlCQUFpQixtQkFBQTtZQUNqQiwyQkFBMkIsNkJBQUE7WUFDM0IsT0FBTyxTQUFBO1NBQ1IsQ0FBQyxDQUFDO1FBRUgsSUFBTSxhQUFhLEdBQUcsVUFBQyxTQUFnQjtZQUNyQyxtRUFBbUU7WUFDbkUsbUVBQW1FO1lBQ25FLDRCQUE0QjtZQUM1QixVQUFVLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUVqQyxJQUFNLGVBQWUsR0FBRyxLQUFJLENBQUMsa0JBQWtCLENBQzdDLFNBQVMsRUFDVCxVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFFRjtZQUNFLG9FQUFvRTtZQUNwRSx3QkFBd0I7WUFDeEIsVUFBVSxDQUFDLFdBQVcsS0FBSyxTQUFTO2dCQUNwQyx3RUFBd0U7Z0JBQ3hFLCtEQUErRDtnQkFDL0QsZUFBZSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDbEMsU0FBUyxDQUFDLGVBQWUsRUFDekIsQ0FBQztnQkFDRCxTQUFTLENBQUMsZUFBZSxDQUFDLHNCQUFzQixDQUFDLENBQy9DLGFBQWEsRUFDYixPQUFPLENBQ1IsQ0FBQztZQUNKLENBQUM7WUFFRCxPQUFPLGVBQWUsQ0FBQztRQUN6QixDQUFDLENBQUM7UUFFRixzRUFBc0U7UUFDdEUsOERBQThEO1FBQzlELElBQU0sZUFBZSxHQUFHLGNBQU0sT0FBQSxLQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQTdDLENBQTZDLENBQUM7UUFDNUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFDLE1BQU07WUFDaEQsZUFBZSxFQUFFLENBQUM7WUFDbEIsZ0VBQWdFO1lBQ2hFLFVBQVUsQ0FBQyxjQUFNLE9BQUEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBdEIsQ0FBc0IsQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxPQUEwQyxFQUM1QyxvQkFBNkIsQ0FBQztRQUNoQyxnRUFBZ0U7UUFDaEUsNkRBQTZEO1FBQzdELDhEQUE4RDtRQUM5RCwrREFBK0Q7UUFDL0QsbUVBQW1FO1FBQ25FLGtFQUFrRTtRQUNsRSx3Q0FBd0M7UUFDeEMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzVELE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FDbkIsSUFBSSxDQUFDLFVBQVU7aUJBQ1osb0JBQW9CLENBQ25CLFVBQVUsQ0FBQyxLQUFLLEVBQ2hCLFVBQVUsQ0FBQyxTQUFTLEVBQ3BCLFVBQVUsQ0FBQyxPQUFPLENBQ25CO2lCQUNBLElBQUksQ0FBQyxhQUFhLENBQUM7aUJBQ25CLElBQUksQ0FBQyxVQUFDLGVBQWUsSUFBSyxPQUFBLGVBQWUsQ0FBQyxPQUFPLEVBQXZCLENBQXVCLENBQUMsQ0FDdEQsQ0FBQztZQUNGLHdFQUF3RTtZQUN4RSx5RUFBeUU7WUFDekUseUVBQXlFO1lBQ3pFLG9FQUFvRTtZQUNwRSxjQUFjO1lBQ2Qsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1FBQzlCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBTSxlQUFlLEdBQUcsYUFBYSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1RCxvQkFBb0IsR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDO1lBQ2hELE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUV2RCxPQUFPO1lBQ0wsT0FBTyxTQUFBO1lBQ1AsUUFBUSxFQUFFLG9CQUFvQjtTQUMvQixDQUFDO0lBQ0osQ0FBQztJQUVNLHFDQUFjLEdBQXJCLFVBQStCLEVBUzlCO1FBVEQsaUJBbUtDO1lBbEtDLFdBQVcsaUJBQUEsRUFDWCxPQUFPLGFBQUEsRUFDUCxrQkFBa0IsRUFBbEIsVUFBVSxtQkFBRyxLQUFLLEtBQUEsRUFDbEIsd0JBQXVFLEVBQXZFLGdCQUFnQixtQkFBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBQSxFQUN2RSxjQUFjLG9CQUFBO1FBS2QsSUFBTSxtQkFBbUIsR0FBRyxJQUFJLEdBQUcsRUFPaEMsQ0FBQztRQUVKLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsRUFBRSxFQUFFLE9BQU87Z0JBQ3JELG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUU7b0JBQy9CLEVBQUUsSUFBQTtvQkFDRixRQUFRLEVBQUUsQ0FBQyxLQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUU7aUJBQ25FLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQU0sT0FBTyxHQUF1QyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRTlELElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7Z0JBQ2YsTUFBTSxFQUFFLFdBQVc7Z0JBRW5CLHdFQUF3RTtnQkFDeEUsdUVBQXVFO2dCQUN2RSw4REFBOEQ7Z0JBQzlELGFBQWE7Z0JBQ2IsRUFBRTtnQkFDRiwwQ0FBMEM7Z0JBQzFDLHVDQUF1QztnQkFDdkMsb0VBQW9FO2dCQUNwRSxFQUFFO2dCQUNGLHNFQUFzRTtnQkFDdEUsd0VBQXdFO2dCQUN4RSx1RUFBdUU7Z0JBQ3ZFLGlFQUFpRTtnQkFDakUsbUVBQW1FO2dCQUNuRSxFQUFFO2dCQUNGLHdFQUF3RTtnQkFDeEUsd0VBQXdFO2dCQUN4RSx3RUFBd0U7Z0JBQ3hFLG1FQUFtRTtnQkFDbkUsdUVBQXVFO2dCQUN2RSw0Q0FBNEM7Z0JBQzVDLEVBQUU7Z0JBQ0YscUVBQXFFO2dCQUNyRSxzRUFBc0U7Z0JBQ3RFLHFFQUFxRTtnQkFDckUsb0VBQW9FO2dCQUNwRSxzRUFBc0U7Z0JBQ3RFLGtFQUFrRTtnQkFDbEUscURBQXFEO2dCQUNyRCxVQUFVLEVBQUUsQ0FBQyxVQUFVLElBQUksZ0JBQWdCLENBQUMsSUFBSSxLQUFLO2dCQUVyRCxzRUFBc0U7Z0JBQ3RFLG1FQUFtRTtnQkFDbkUsa0VBQWtFO2dCQUNsRSxFQUFFO2dCQUNGLHNFQUFzRTtnQkFDdEUsaUVBQWlFO2dCQUNqRSx5REFBeUQ7Z0JBQ3pELGdCQUFnQixrQkFBQTtnQkFFaEIsY0FBYyxZQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUTtvQkFDbEMsSUFBTSxFQUFFLEdBQ04sS0FBSyxDQUFDLE9BQU8sWUFBWSxTQUFTLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUM7b0JBRXRFLElBQUksRUFBRSxFQUFFLENBQUM7d0JBQ1AsSUFBSSxjQUFjLEVBQUUsQ0FBQzs0QkFDbkIsNkRBQTZEOzRCQUM3RCwrREFBK0Q7NEJBQy9ELG1CQUFtQjs0QkFDbkIsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQzs0QkFFdkMsSUFBSSxNQUFNLEdBQ1IsY0FBYyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7NEJBRXJDLElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO2dDQUNwQiwrREFBK0Q7Z0NBQy9ELDhCQUE4QjtnQ0FDOUIsTUFBTSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQzs0QkFDeEIsQ0FBQzs0QkFFRCxrRUFBa0U7NEJBQ2xFLG1EQUFtRDs0QkFDbkQsSUFBSSxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7Z0NBQ3JCLE9BQU8sQ0FBQyxHQUFHLENBQ1QsRUFBRSxFQUNGLE1BQStDLENBQ2hELENBQUM7NEJBQ0osQ0FBQzs0QkFFRCwyREFBMkQ7NEJBQzNELGdDQUFnQzs0QkFDaEMsT0FBTyxNQUFNLENBQUM7d0JBQ2hCLENBQUM7d0JBRUQsSUFBSSxjQUFjLEtBQUssSUFBSSxFQUFFLENBQUM7NEJBQzVCLGtFQUFrRTs0QkFDbEUsNERBQTREOzRCQUM1RCw2REFBNkQ7NEJBQzdELG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFBLEVBQUUsUUFBUSxVQUFBLEVBQUUsSUFBSSxNQUFBLEVBQUUsQ0FBQyxDQUFDO3dCQUM5RCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxJQUFJLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQzdCLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxVQUFDLEVBQXNCLEVBQUUsT0FBTztvQkFBN0IsRUFBRSxRQUFBLEVBQUUsUUFBUSxjQUFBLEVBQUUsSUFBSSxVQUFBO2dCQUMvQyxJQUFJLE1BSVMsQ0FBQztnQkFFZCxvRUFBb0U7Z0JBQ3BFLHVDQUF1QztnQkFDdkMsSUFBSSxjQUFjLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO3dCQUNWLElBQUksR0FBRyxLQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQzlELENBQUM7b0JBQ0QsTUFBTSxHQUFHLGNBQWMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM5QyxDQUFDO2dCQUVELHlDQUF5QztnQkFDekMsSUFBSSxDQUFDLGNBQWMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ3ZDLE1BQU0sR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3hCLENBQUM7Z0JBRUQsSUFBSSxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE1BQStDLENBQUMsQ0FBQztnQkFDbkUsQ0FBQztnQkFFRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDL0MsS0FBSSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNyQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLHVFQUF1RTtZQUN2RSx1RUFBdUU7WUFDdkUsd0VBQXdFO1lBQ3hFLG9FQUFvRTtZQUNwRSx3RUFBd0U7WUFDeEUsc0VBQXNFO1lBQ3RFLDBCQUEwQjtZQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFJTSxvQ0FBYSxHQUFwQixVQUNFLE9BQW9DOztRQUU1QixJQUFBLFFBQVEsR0FBVyxPQUFPLFNBQWxCLEVBQUUsSUFBSSxHQUFLLE9BQU8sS0FBWixDQUFhO1FBRW5DLElBQUksT0FBTyxFQUFFLENBQUM7WUFDSixJQUFBLFdBQVcsR0FBUyxPQUFPLFlBQWhCLEVBQUUsRUFBRSxHQUFLLE9BQU8sR0FBWixDQUFhO1lBQ3BDLElBQU0sYUFBYSxHQUFHLE1BQUEsc0JBQXNCLENBQUMsUUFBUSxDQUFDLDBDQUFFLFNBQVMsQ0FBQztZQUNsRSxJQUFNLFdBQVcsR0FBRyxDQUFDLE1BQUEsYUFBYSxhQUFiLGFBQWEsdUJBQWIsYUFBYSxDQUFHLENBQUMsQ0FBQyxtQ0FBSSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7WUFFckQsSUFDRSxJQUFJLENBQUMsV0FBVztnQkFDaEIsV0FBVyxLQUFLLFVBQVU7Z0JBQzFCLENBQUMsd0JBQXdCLENBQUMsUUFBUSxDQUFDO2dCQUNuQyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQy9DLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFFL0MsU0FBUyxDQUFDLElBQUksQ0FDWiw4SkFBOEosRUFDOUosTUFBQSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsbUNBQ3hCLGtCQUFXLGFBQWEsYUFBYixhQUFhLGNBQWIsYUFBYSxHQUFJLFdBQVcsQ0FBRSxDQUM1QyxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLENBQ0wsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2hCLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDM0MsQ0FBQyxDQUFDLElBQUksQ0FBdUIsQ0FBQztJQUNsQyxDQUFDO0lBRU0sbUNBQVksR0FBbkIsVUFBcUMsT0FBbUM7UUFDOUQsSUFBQSxJQUFJLEdBQTZCLE9BQU8sS0FBcEMsRUFBRSxRQUFRLEdBQW1CLE9BQU8sU0FBMUIsRUFBRSxZQUFZLEdBQUssT0FBTyxhQUFaLENBQWE7UUFFakQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDckIsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUM7WUFDeEQsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNYLENBQUM7SUFFTyx5Q0FBa0IsR0FBMUIsVUFDRSxTQUFvQixFQUNwQixFQVNrQztJQUNsQyx1REFBdUQ7SUFDdkQscUVBQXFFO0lBQ3JFLG1CQUFtQjtJQUNuQixhQUE0QjtRQWY5QixpQkFxS0M7WUFsS0csS0FBSyxXQUFBLEVBQ0wsU0FBUyxlQUFBLEVBQ1QsV0FBVyxpQkFBQSxFQUNYLGtCQUFrQix3QkFBQSxFQUNsQixXQUFXLGlCQUFBLEVBQ1gsaUJBQWlCLHVCQUFBLEVBQ2pCLE9BQU8sYUFBQSxFQUNQLDJCQUEyQixpQ0FBQTtRQU83QixJQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUM7UUFFakQsU0FBUyxDQUFDLElBQUksQ0FBQztZQUNiLFFBQVEsRUFBRSxLQUFLO1lBQ2YsU0FBUyxXQUFBO1lBQ1QsYUFBYSxlQUFBO1NBQ2QsQ0FBQyxDQUFDO1FBRUgsSUFBTSxTQUFTLEdBQUcsY0FBTSxPQUFBLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBbkIsQ0FBbUIsQ0FBQztRQUU1QyxJQUFNLGdCQUFnQixHQUFHLFVBQ3ZCLElBQTZCLEVBQzdCLGFBQWdFO1lBQWhFLDhCQUFBLEVBQUEsZ0JBQWdCLFNBQVMsQ0FBQyxhQUFhLElBQUksYUFBYSxDQUFDLE9BQU87WUFFaEUsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUV6QixJQUFJLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEMsQ0FBQztZQUVELElBQU0sUUFBUSxHQUFHLFVBQUMsSUFBdUI7Z0JBQ3ZDLE9BQUEsVUFBVSxDQUFDLEVBQUUsQ0FBQyxXQUNaLElBQUksTUFBQSxFQUNKLE9BQU8sRUFBRSx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsRUFDaEQsYUFBYSxlQUFBLElBQ1YsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQ2xCLENBQUM7WUFMOUIsQ0FLOEIsQ0FBQztZQUVqQyxJQUFJLElBQUksSUFBSSxLQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQzNELE9BQU8sS0FBSSxDQUFDLFVBQVU7cUJBQ25CLFlBQVksQ0FBQztvQkFDWixRQUFRLEVBQUUsS0FBSztvQkFDZixZQUFZLEVBQUUsRUFBRSxJQUFJLE1BQUEsRUFBRTtvQkFDdEIsT0FBTyxTQUFBO29CQUNQLFNBQVMsV0FBQTtvQkFDVCxzQkFBc0IsRUFBRSxJQUFJO2lCQUM3QixDQUFDO3FCQUNELElBQUksQ0FBQyxVQUFDLFFBQVEsSUFBSyxPQUFBLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQWpDLENBQWlDLENBQUMsQ0FBQztZQUMzRCxDQUFDO1lBRUQsd0VBQXdFO1lBQ3hFLG9FQUFvRTtZQUNwRSwyREFBMkQ7WUFDM0QsMkRBQTJEO1lBQzNELElBQ0UsV0FBVyxLQUFLLE1BQU07Z0JBQ3RCLGFBQWEsS0FBSyxhQUFhLENBQUMsT0FBTztnQkFDdkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQzNCLENBQUM7Z0JBQ0QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUMxQixDQUFDO1lBRUQsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEIsQ0FBQyxDQUFDO1FBRUYsSUFBTSxrQkFBa0IsR0FDdEIsV0FBVyxLQUFLLFVBQVUsQ0FBQyxDQUFDO1lBQzFCLHNFQUFzRTtZQUN0RSx5RUFBeUU7WUFDM0UsQ0FBQyxDQUFDLENBQ0EsYUFBYSxLQUFLLGFBQWEsQ0FBQyxPQUFPO2dCQUN2QyxrQkFBa0IsS0FBSyxPQUFPLENBQy9CLENBQUMsQ0FBQzs7Z0JBRUgsQ0FBQyxpQ0FBeUIsQ0FBQztRQUU3QixJQUFNLGVBQWUsR0FBRztZQUN0QixPQUFBLEtBQUksQ0FBQyxrQkFBa0IsQ0FBZSxTQUFTLEVBQUUsa0JBQWtCLEVBQUU7Z0JBQ25FLEtBQUssT0FBQTtnQkFDTCxTQUFTLFdBQUE7Z0JBQ1QsT0FBTyxTQUFBO2dCQUNQLFdBQVcsYUFBQTtnQkFDWCxXQUFXLGFBQUE7YUFDWixDQUFDO1FBTkYsQ0FNRSxDQUFDO1FBRUwsSUFBTSxZQUFZLEdBQ2hCLDJCQUEyQjtZQUMzQixPQUFPLGdCQUFnQixLQUFLLFFBQVE7WUFDcEMsZ0JBQWdCLEtBQUssYUFBYTtZQUNsQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUUxQyxRQUFRLFdBQVcsRUFBRSxDQUFDO1lBQ3BCLFFBQVE7WUFDUixLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLElBQU0sSUFBSSxHQUFHLFNBQVMsRUFBRSxDQUFDO2dCQUV6QixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDbEIsT0FBTzt3QkFDTCxRQUFRLEVBQUUsS0FBSzt3QkFDZixPQUFPLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7cUJBQ3pELENBQUM7Z0JBQ0osQ0FBQztnQkFFRCxJQUFJLGlCQUFpQixJQUFJLFlBQVksRUFBRSxDQUFDO29CQUN0QyxPQUFPO3dCQUNMLFFBQVEsRUFBRSxJQUFJO3dCQUNkLE9BQU8sRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLGVBQWUsRUFBRSxDQUFDO3FCQUNyRCxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsZUFBZSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzFELENBQUM7WUFFRCxLQUFLLG1CQUFtQixDQUFDLENBQUMsQ0FBQztnQkFDekIsSUFBTSxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7Z0JBRXpCLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxpQkFBaUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDdkQsT0FBTzt3QkFDTCxRQUFRLEVBQUUsSUFBSTt3QkFDZCxPQUFPLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQztxQkFDckQsQ0FBQztnQkFDSixDQUFDO2dCQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxDQUFDO1lBRUQsS0FBSyxZQUFZO2dCQUNmLE9BQU87b0JBQ0wsUUFBUSxFQUFFLEtBQUs7b0JBQ2YsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7aUJBQ2hFLENBQUM7WUFFSixLQUFLLGNBQWM7Z0JBQ2pCLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLE9BQU87d0JBQ0wsUUFBUSxFQUFFLElBQUk7d0JBQ2QsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQztxQkFDNUQsQ0FBQztnQkFDSixDQUFDO2dCQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUUxRCxLQUFLLFVBQVU7Z0JBQ2IsSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDakIsT0FBTzt3QkFDTCxRQUFRLEVBQUUsSUFBSTt3QkFDZCxtRUFBbUU7d0JBQ25FLG9FQUFvRTt3QkFDcEUsbURBQW1EO3dCQUNuRCxPQUFPLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxlQUFlLEVBQUUsQ0FBQztxQkFDcEUsQ0FBQztnQkFDSixDQUFDO2dCQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUUxRCxLQUFLLFNBQVM7Z0JBQ1osT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBRU0sdUNBQWdCLEdBQXZCLFVBQXdCLE9BQWU7UUFDckMsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRU8scUNBQWMsR0FBdEIsVUFBdUIsT0FBWTtRQUFaLHdCQUFBLEVBQUEsWUFBWTtRQUNqQyxJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzRCxzQ0FDSyxJQUFJLENBQUMsY0FBYyxHQUNuQixVQUFVLEtBQ2IsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlLElBQ3JDO0lBQ0osQ0FBQztJQUNILG1CQUFDO0FBQUQsQ0FBQyxBQWhvREQsSUFnb0RDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW52YXJpYW50LCBuZXdJbnZhcmlhbnRFcnJvciB9IGZyb20gXCIuLi91dGlsaXRpZXMvZ2xvYmFscy9pbmRleC5qc1wiO1xuXG5pbXBvcnQgdHlwZSB7IERvY3VtZW50Tm9kZSB9IGZyb20gXCJncmFwaHFsXCI7XG4vLyBUT0RPKGJyaWFuKTogQSBoYWNrIHVudGlsIHRoaXMgaXNzdWUgaXMgcmVzb2x2ZWQgKGh0dHBzOi8vZ2l0aHViLmNvbS9ncmFwaHFsL2dyYXBocWwtanMvaXNzdWVzLzMzNTYpXG50eXBlIE9wZXJhdGlvblR5cGVOb2RlID0gYW55O1xuaW1wb3J0IHsgZXF1YWwgfSBmcm9tIFwiQHdyeS9lcXVhbGl0eVwiO1xuXG5pbXBvcnQgdHlwZSB7IEFwb2xsb0xpbmssIEZldGNoUmVzdWx0IH0gZnJvbSBcIi4uL2xpbmsvY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgZXhlY3V0ZSB9IGZyb20gXCIuLi9saW5rL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCB7XG4gIGFkZE5vblJlYWN0aXZlVG9OYW1lZEZyYWdtZW50cyxcbiAgZGVmYXVsdENhY2hlU2l6ZXMsXG4gIGhhc0RpcmVjdGl2ZXMsXG4gIGlzRXhlY3V0aW9uUGF0Y2hJbmNyZW1lbnRhbFJlc3VsdCxcbiAgaXNFeGVjdXRpb25QYXRjaFJlc3VsdCxcbiAgaXNGdWxseVVubWFza2VkT3BlcmF0aW9uLFxuICByZW1vdmVEaXJlY3RpdmVzRnJvbURvY3VtZW50LFxufSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IENhY2hlLCBBcG9sbG9DYWNoZSB9IGZyb20gXCIuLi9jYWNoZS9pbmRleC5qc1wiO1xuaW1wb3J0IHsgY2Fub25pY2FsU3RyaW5naWZ5IH0gZnJvbSBcIi4uL2NhY2hlL2luZGV4LmpzXCI7XG5cbmltcG9ydCB0eXBlIHtcbiAgT2JzZXJ2YWJsZVN1YnNjcmlwdGlvbixcbiAgQ29uY2FzdFNvdXJjZXNBcnJheSxcbn0gZnJvbSBcIi4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHtcbiAgZ2V0RGVmYXVsdFZhbHVlcyxcbiAgZ2V0T3BlcmF0aW9uRGVmaW5pdGlvbixcbiAgZ2V0T3BlcmF0aW9uTmFtZSxcbiAgaGFzQ2xpZW50RXhwb3J0cyxcbiAgZ3JhcGhRTFJlc3VsdEhhc0Vycm9yLFxuICBnZXRHcmFwaFFMRXJyb3JzRnJvbVJlc3VsdCxcbiAgT2JzZXJ2YWJsZSxcbiAgYXN5bmNNYXAsXG4gIGlzTm9uRW1wdHlBcnJheSxcbiAgQ29uY2FzdCxcbiAgbWFrZVVuaXF1ZUlkLFxuICBpc0RvY3VtZW50Tm9kZSxcbiAgaXNOb25OdWxsT2JqZWN0LFxuICBEb2N1bWVudFRyYW5zZm9ybSxcbn0gZnJvbSBcIi4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgbWVyZ2VJbmNyZW1lbnRhbERhdGEgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2NvbW1vbi9pbmNyZW1lbnRhbFJlc3VsdC5qc1wiO1xuaW1wb3J0IHtcbiAgQXBvbGxvRXJyb3IsXG4gIGlzQXBvbGxvRXJyb3IsXG4gIGdyYXBoUUxSZXN1bHRIYXNQcm90b2NvbEVycm9ycyxcbn0gZnJvbSBcIi4uL2Vycm9ycy9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUge1xuICBRdWVyeU9wdGlvbnMsXG4gIFdhdGNoUXVlcnlPcHRpb25zLFxuICBTdWJzY3JpcHRpb25PcHRpb25zLFxuICBNdXRhdGlvbk9wdGlvbnMsXG4gIEVycm9yUG9saWN5LFxuICBNdXRhdGlvbkZldGNoUG9saWN5LFxuICBXYXRjaFF1ZXJ5RmV0Y2hQb2xpY3ksXG59IGZyb20gXCIuL3dhdGNoUXVlcnlPcHRpb25zLmpzXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlUXVlcnksIGxvZ01pc3NpbmdGaWVsZEVycm9ycyB9IGZyb20gXCIuL09ic2VydmFibGVRdWVyeS5qc1wiO1xuaW1wb3J0IHsgTmV0d29ya1N0YXR1cywgaXNOZXR3b3JrUmVxdWVzdEluRmxpZ2h0IH0gZnJvbSBcIi4vbmV0d29ya1N0YXR1cy5qc1wiO1xuaW1wb3J0IHR5cGUge1xuICBBcG9sbG9RdWVyeVJlc3VsdCxcbiAgT3BlcmF0aW9uVmFyaWFibGVzLFxuICBNdXRhdGlvblVwZGF0ZXJGdW5jdGlvbixcbiAgT25RdWVyeVVwZGF0ZWQsXG4gIEludGVybmFsUmVmZXRjaFF1ZXJpZXNJbmNsdWRlLFxuICBJbnRlcm5hbFJlZmV0Y2hRdWVyaWVzT3B0aW9ucyxcbiAgSW50ZXJuYWxSZWZldGNoUXVlcmllc1Jlc3VsdCxcbiAgSW50ZXJuYWxSZWZldGNoUXVlcmllc01hcCxcbiAgRGVmYXVsdENvbnRleHQsXG59IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IExvY2FsU3RhdGUgfSBmcm9tIFwiLi9Mb2NhbFN0YXRlLmpzXCI7XG5cbmltcG9ydCB0eXBlIHsgUXVlcnlTdG9yZVZhbHVlIH0gZnJvbSBcIi4vUXVlcnlJbmZvLmpzXCI7XG5pbXBvcnQge1xuICBRdWVyeUluZm8sXG4gIHNob3VsZFdyaXRlUmVzdWx0LFxuICBDYWNoZVdyaXRlQmVoYXZpb3IsXG59IGZyb20gXCIuL1F1ZXJ5SW5mby5qc1wiO1xuaW1wb3J0IHR5cGUgeyBBcG9sbG9FcnJvck9wdGlvbnMgfSBmcm9tIFwiLi4vZXJyb3JzL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBQUk9UT0NPTF9FUlJPUlNfU1lNQk9MIH0gZnJvbSBcIi4uL2Vycm9ycy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgcHJpbnQgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IElnbm9yZU1vZGlmaWVyIH0gZnJvbSBcIi4uL2NhY2hlL2NvcmUvdHlwZXMvY29tbW9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFRPRE8gfSBmcm9tIFwiLi4vdXRpbGl0aWVzL3R5cGVzL1RPRE8uanNcIjtcblxuY29uc3QgeyBoYXNPd25Qcm9wZXJ0eSB9ID0gT2JqZWN0LnByb3RvdHlwZTtcblxuY29uc3QgSUdOT1JFOiBJZ25vcmVNb2RpZmllciA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmludGVyZmFjZSBNdXRhdGlvblN0b3JlVmFsdWUge1xuICBtdXRhdGlvbjogRG9jdW1lbnROb2RlO1xuICB2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIGxvYWRpbmc6IGJvb2xlYW47XG4gIGVycm9yOiBFcnJvciB8IG51bGw7XG59XG5cbnR5cGUgVXBkYXRlUXVlcmllczxURGF0YT4gPSBNdXRhdGlvbk9wdGlvbnM8VERhdGEsIGFueSwgYW55PltcInVwZGF0ZVF1ZXJpZXNcIl07XG5cbmludGVyZmFjZSBUcmFuc2Zvcm1DYWNoZUVudHJ5IHtcbiAgaGFzQ2xpZW50RXhwb3J0czogYm9vbGVhbjtcbiAgaGFzRm9yY2VkUmVzb2x2ZXJzOiBib29sZWFuO1xuICBoYXNOb25yZWFjdGl2ZURpcmVjdGl2ZTogYm9vbGVhbjtcbiAgbm9uUmVhY3RpdmVRdWVyeTogRG9jdW1lbnROb2RlO1xuICBjbGllbnRRdWVyeTogRG9jdW1lbnROb2RlIHwgbnVsbDtcbiAgc2VydmVyUXVlcnk6IERvY3VtZW50Tm9kZSB8IG51bGw7XG4gIGRlZmF1bHRWYXJzOiBPcGVyYXRpb25WYXJpYWJsZXM7XG4gIGFzUXVlcnk6IERvY3VtZW50Tm9kZTtcbn1cblxuaW1wb3J0IHR5cGUgeyBEZWZhdWx0T3B0aW9ucyB9IGZyb20gXCIuL0Fwb2xsb0NsaWVudC5qc1wiO1xuaW1wb3J0IHsgVHJpZSB9IGZyb20gXCJAd3J5L3RyaWVcIjtcbmltcG9ydCB7IEF1dG9DbGVhbmVkV2Vha0NhY2hlLCBjYWNoZVNpemVzIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgbWFza0ZyYWdtZW50LCBtYXNrT3BlcmF0aW9uIH0gZnJvbSBcIi4uL21hc2tpbmcvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgTWF5YmVNYXNrZWQsIFVubWFza2VkIH0gZnJvbSBcIi4uL21hc2tpbmcvaW5kZXguanNcIjtcblxuaW50ZXJmYWNlIE1hc2tGcmFnbWVudE9wdGlvbnM8VERhdGE+IHtcbiAgZnJhZ21lbnQ6IERvY3VtZW50Tm9kZTtcbiAgZGF0YTogVERhdGE7XG4gIGZyYWdtZW50TmFtZT86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIE1hc2tPcGVyYXRpb25PcHRpb25zPFREYXRhPiB7XG4gIGRvY3VtZW50OiBEb2N1bWVudE5vZGU7XG4gIGRhdGE6IFREYXRhO1xuICBpZDogc3RyaW5nO1xuICBmZXRjaFBvbGljeT86IFdhdGNoUXVlcnlGZXRjaFBvbGljeTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeU1hbmFnZXJPcHRpb25zPFRTdG9yZT4ge1xuICBjYWNoZTogQXBvbGxvQ2FjaGU8VFN0b3JlPjtcbiAgbGluazogQXBvbGxvTGluaztcbiAgZGVmYXVsdE9wdGlvbnM6IERlZmF1bHRPcHRpb25zO1xuICBkb2N1bWVudFRyYW5zZm9ybTogRG9jdW1lbnRUcmFuc2Zvcm0gfCBudWxsIHwgdW5kZWZpbmVkO1xuICBxdWVyeURlZHVwbGljYXRpb246IGJvb2xlYW47XG4gIG9uQnJvYWRjYXN0OiB1bmRlZmluZWQgfCAoKCkgPT4gdm9pZCk7XG4gIHNzck1vZGU6IGJvb2xlYW47XG4gIGNsaWVudEF3YXJlbmVzczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgbG9jYWxTdGF0ZTogTG9jYWxTdGF0ZTxUU3RvcmU+O1xuICBhc3N1bWVJbW11dGFibGVSZXN1bHRzOiBib29sZWFuO1xuICBkZWZhdWx0Q29udGV4dDogUGFydGlhbDxEZWZhdWx0Q29udGV4dD4gfCB1bmRlZmluZWQ7XG4gIGRhdGFNYXNraW5nOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgUXVlcnlNYW5hZ2VyPFRTdG9yZT4ge1xuICBwdWJsaWMgY2FjaGU6IEFwb2xsb0NhY2hlPFRTdG9yZT47XG4gIHB1YmxpYyBsaW5rOiBBcG9sbG9MaW5rO1xuICBwdWJsaWMgZGVmYXVsdE9wdGlvbnM6IERlZmF1bHRPcHRpb25zO1xuXG4gIHB1YmxpYyByZWFkb25seSBhc3N1bWVJbW11dGFibGVSZXN1bHRzOiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgZG9jdW1lbnRUcmFuc2Zvcm06IERvY3VtZW50VHJhbnNmb3JtO1xuICBwdWJsaWMgcmVhZG9ubHkgc3NyTW9kZTogYm9vbGVhbjtcbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb250ZXh0OiBQYXJ0aWFsPERlZmF1bHRDb250ZXh0PjtcbiAgcHVibGljIHJlYWRvbmx5IGRhdGFNYXNraW5nOiBib29sZWFuO1xuXG4gIHByaXZhdGUgcXVlcnlEZWR1cGxpY2F0aW9uOiBib29sZWFuO1xuICBwcml2YXRlIGNsaWVudEF3YXJlbmVzczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBwcml2YXRlIGxvY2FsU3RhdGU6IExvY2FsU3RhdGU8VFN0b3JlPjtcblxuICBwcml2YXRlIG9uQnJvYWRjYXN0PzogKCkgPT4gdm9pZDtcbiAgcHVibGljIG11dGF0aW9uU3RvcmU/OiB7XG4gICAgW211dGF0aW9uSWQ6IHN0cmluZ106IE11dGF0aW9uU3RvcmVWYWx1ZTtcbiAgfTtcblxuICAvLyBBbGwgdGhlIHF1ZXJpZXMgdGhhdCB0aGUgUXVlcnlNYW5hZ2VyIGlzIGN1cnJlbnRseSBtYW5hZ2luZyAobm90XG4gIC8vIGluY2x1ZGluZyBtdXRhdGlvbnMgYW5kIHN1YnNjcmlwdGlvbnMpLlxuICBwcml2YXRlIHF1ZXJpZXMgPSBuZXcgTWFwPHN0cmluZywgUXVlcnlJbmZvPigpO1xuXG4gIC8vIE1hcHMgZnJvbSBxdWVyeUlkIHN0cmluZ3MgdG8gUHJvbWlzZSByZWplY3Rpb24gZnVuY3Rpb25zIGZvclxuICAvLyBjdXJyZW50bHkgYWN0aXZlIHF1ZXJpZXMgYW5kIGZldGNoZXMuXG4gIC8vIFVzZSBwcm90ZWN0ZWQgaW5zdGVhZCBvZiBwcml2YXRlIGZpZWxkIHNvXG4gIC8vIEBhcG9sbG8vZXhwZXJpbWVudGFsLW5leHRqcy1hcHAtc3VwcG9ydCBjYW4gYWNjZXNzIHR5cGUgaW5mby5cbiAgcHJvdGVjdGVkIGZldGNoQ2FuY2VsRm5zID0gbmV3IE1hcDxzdHJpbmcsIChlcnJvcjogYW55KSA9PiBhbnk+KCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUXVlcnlNYW5hZ2VyT3B0aW9uczxUU3RvcmU+KSB7XG4gICAgY29uc3QgZGVmYXVsdERvY3VtZW50VHJhbnNmb3JtID0gbmV3IERvY3VtZW50VHJhbnNmb3JtKFxuICAgICAgKGRvY3VtZW50KSA9PiB0aGlzLmNhY2hlLnRyYW5zZm9ybURvY3VtZW50KGRvY3VtZW50KSxcbiAgICAgIC8vIEFsbG93IHRoZSBhcG9sbG8gY2FjaGUgdG8gbWFuYWdlIGl0cyBvd24gdHJhbnNmb3JtIGNhY2hlc1xuICAgICAgeyBjYWNoZTogZmFsc2UgfVxuICAgICk7XG5cbiAgICB0aGlzLmNhY2hlID0gb3B0aW9ucy5jYWNoZTtcbiAgICB0aGlzLmxpbmsgPSBvcHRpb25zLmxpbms7XG4gICAgdGhpcy5kZWZhdWx0T3B0aW9ucyA9IG9wdGlvbnMuZGVmYXVsdE9wdGlvbnM7XG4gICAgdGhpcy5xdWVyeURlZHVwbGljYXRpb24gPSBvcHRpb25zLnF1ZXJ5RGVkdXBsaWNhdGlvbjtcbiAgICB0aGlzLmNsaWVudEF3YXJlbmVzcyA9IG9wdGlvbnMuY2xpZW50QXdhcmVuZXNzO1xuICAgIHRoaXMubG9jYWxTdGF0ZSA9IG9wdGlvbnMubG9jYWxTdGF0ZTtcbiAgICB0aGlzLnNzck1vZGUgPSBvcHRpb25zLnNzck1vZGU7XG4gICAgdGhpcy5hc3N1bWVJbW11dGFibGVSZXN1bHRzID0gb3B0aW9ucy5hc3N1bWVJbW11dGFibGVSZXN1bHRzO1xuICAgIHRoaXMuZGF0YU1hc2tpbmcgPSBvcHRpb25zLmRhdGFNYXNraW5nO1xuICAgIGNvbnN0IGRvY3VtZW50VHJhbnNmb3JtID0gb3B0aW9ucy5kb2N1bWVudFRyYW5zZm9ybTtcbiAgICB0aGlzLmRvY3VtZW50VHJhbnNmb3JtID1cbiAgICAgIGRvY3VtZW50VHJhbnNmb3JtID9cbiAgICAgICAgZGVmYXVsdERvY3VtZW50VHJhbnNmb3JtXG4gICAgICAgICAgLmNvbmNhdChkb2N1bWVudFRyYW5zZm9ybSlcbiAgICAgICAgICAvLyBUaGUgY3VzdG9tIGRvY3VtZW50IHRyYW5zZm9ybSBtYXkgYWRkIG5ldyBmcmFnbWVudCBzcHJlYWRzIG9yIG5ld1xuICAgICAgICAgIC8vIGZpZWxkIHNlbGVjdGlvbnMsIHNvIHdlIHdhbnQgdG8gZ2l2ZSB0aGUgY2FjaGUgYSBjaGFuY2UgdG8gcnVuXG4gICAgICAgICAgLy8gYWdhaW4uIEZvciBleGFtcGxlLCB0aGUgSW5NZW1vcnlDYWNoZSBhZGRzIF9fdHlwZW5hbWUgdG8gZmllbGRcbiAgICAgICAgICAvLyBzZWxlY3Rpb25zIGFuZCBmcmFnbWVudHMgZnJvbSB0aGUgZnJhZ21lbnQgcmVnaXN0cnkuXG4gICAgICAgICAgLmNvbmNhdChkZWZhdWx0RG9jdW1lbnRUcmFuc2Zvcm0pXG4gICAgICA6IGRlZmF1bHREb2N1bWVudFRyYW5zZm9ybTtcbiAgICB0aGlzLmRlZmF1bHRDb250ZXh0ID0gb3B0aW9ucy5kZWZhdWx0Q29udGV4dCB8fCBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgaWYgKCh0aGlzLm9uQnJvYWRjYXN0ID0gb3B0aW9ucy5vbkJyb2FkY2FzdCkpIHtcbiAgICAgIHRoaXMubXV0YXRpb25TdG9yZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGwgdGhpcyBtZXRob2QgdG8gdGVybWluYXRlIGFueSBhY3RpdmUgcXVlcnkgcHJvY2Vzc2VzLCBtYWtpbmcgaXQgc2FmZVxuICAgKiB0byBkaXNwb3NlIG9mIHRoaXMgUXVlcnlNYW5hZ2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHN0b3AoKSB7XG4gICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKF9pbmZvLCBxdWVyeUlkKSA9PiB7XG4gICAgICB0aGlzLnN0b3BRdWVyeU5vQnJvYWRjYXN0KHF1ZXJ5SWQpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jYW5jZWxQZW5kaW5nRmV0Y2hlcyhcbiAgICAgIG5ld0ludmFyaWFudEVycm9yKFwiUXVlcnlNYW5hZ2VyIHN0b3BwZWQgd2hpbGUgcXVlcnkgd2FzIGluIGZsaWdodFwiKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNhbmNlbFBlbmRpbmdGZXRjaGVzKGVycm9yOiBFcnJvcikge1xuICAgIHRoaXMuZmV0Y2hDYW5jZWxGbnMuZm9yRWFjaCgoY2FuY2VsKSA9PiBjYW5jZWwoZXJyb3IpKTtcbiAgICB0aGlzLmZldGNoQ2FuY2VsRm5zLmNsZWFyKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbXV0YXRlPFxuICAgIFREYXRhLFxuICAgIFRWYXJpYWJsZXMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXMsXG4gICAgVENvbnRleHQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIFRDYWNoZSBleHRlbmRzIEFwb2xsb0NhY2hlPGFueT4sXG4gID4oe1xuICAgIG11dGF0aW9uLFxuICAgIHZhcmlhYmxlcyxcbiAgICBvcHRpbWlzdGljUmVzcG9uc2UsXG4gICAgdXBkYXRlUXVlcmllcyxcbiAgICByZWZldGNoUXVlcmllcyA9IFtdLFxuICAgIGF3YWl0UmVmZXRjaFF1ZXJpZXMgPSBmYWxzZSxcbiAgICB1cGRhdGU6IHVwZGF0ZVdpdGhQcm94eUZuLFxuICAgIG9uUXVlcnlVcGRhdGVkLFxuICAgIGZldGNoUG9saWN5ID0gdGhpcy5kZWZhdWx0T3B0aW9ucy5tdXRhdGU/LmZldGNoUG9saWN5IHx8IFwibmV0d29yay1vbmx5XCIsXG4gICAgZXJyb3JQb2xpY3kgPSB0aGlzLmRlZmF1bHRPcHRpb25zLm11dGF0ZT8uZXJyb3JQb2xpY3kgfHwgXCJub25lXCIsXG4gICAga2VlcFJvb3RGaWVsZHMsXG4gICAgY29udGV4dCxcbiAgfTogTXV0YXRpb25PcHRpb25zPFREYXRhLCBUVmFyaWFibGVzLCBUQ29udGV4dD4pOiBQcm9taXNlPFxuICAgIEZldGNoUmVzdWx0PE1heWJlTWFza2VkPFREYXRhPj5cbiAgPiB7XG4gICAgaW52YXJpYW50KFxuICAgICAgbXV0YXRpb24sXG4gICAgICBcIm11dGF0aW9uIG9wdGlvbiBpcyByZXF1aXJlZC4gWW91IG11c3Qgc3BlY2lmeSB5b3VyIEdyYXBoUUwgZG9jdW1lbnQgaW4gdGhlIG11dGF0aW9uIG9wdGlvbi5cIlxuICAgICk7XG5cbiAgICBpbnZhcmlhbnQoXG4gICAgICBmZXRjaFBvbGljeSA9PT0gXCJuZXR3b3JrLW9ubHlcIiB8fCBmZXRjaFBvbGljeSA9PT0gXCJuby1jYWNoZVwiLFxuICAgICAgXCJNdXRhdGlvbnMgc3VwcG9ydCBvbmx5ICduZXR3b3JrLW9ubHknIG9yICduby1jYWNoZScgZmV0Y2hQb2xpY3kgc3RyaW5ncy4gVGhlIGRlZmF1bHQgYG5ldHdvcmstb25seWAgYmVoYXZpb3IgYXV0b21hdGljYWxseSB3cml0ZXMgbXV0YXRpb24gcmVzdWx0cyB0byB0aGUgY2FjaGUuIFBhc3NpbmcgYG5vLWNhY2hlYCBza2lwcyB0aGUgY2FjaGUgd3JpdGUuXCJcbiAgICApO1xuXG4gICAgY29uc3QgbXV0YXRpb25JZCA9IHRoaXMuZ2VuZXJhdGVNdXRhdGlvbklkKCk7XG5cbiAgICBtdXRhdGlvbiA9IHRoaXMuY2FjaGUudHJhbnNmb3JtRm9yTGluayh0aGlzLnRyYW5zZm9ybShtdXRhdGlvbikpO1xuICAgIGNvbnN0IHsgaGFzQ2xpZW50RXhwb3J0cyB9ID0gdGhpcy5nZXREb2N1bWVudEluZm8obXV0YXRpb24pO1xuXG4gICAgdmFyaWFibGVzID0gdGhpcy5nZXRWYXJpYWJsZXMobXV0YXRpb24sIHZhcmlhYmxlcykgYXMgVFZhcmlhYmxlcztcbiAgICBpZiAoaGFzQ2xpZW50RXhwb3J0cykge1xuICAgICAgdmFyaWFibGVzID0gKGF3YWl0IHRoaXMubG9jYWxTdGF0ZS5hZGRFeHBvcnRlZFZhcmlhYmxlcyhcbiAgICAgICAgbXV0YXRpb24sXG4gICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgY29udGV4dFxuICAgICAgKSkgYXMgVFZhcmlhYmxlcztcbiAgICB9XG5cbiAgICBjb25zdCBtdXRhdGlvblN0b3JlVmFsdWUgPVxuICAgICAgdGhpcy5tdXRhdGlvblN0b3JlICYmXG4gICAgICAodGhpcy5tdXRhdGlvblN0b3JlW211dGF0aW9uSWRdID0ge1xuICAgICAgICBtdXRhdGlvbixcbiAgICAgICAgdmFyaWFibGVzLFxuICAgICAgICBsb2FkaW5nOiB0cnVlLFxuICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgIH0gYXMgTXV0YXRpb25TdG9yZVZhbHVlKTtcblxuICAgIGNvbnN0IGlzT3B0aW1pc3RpYyA9XG4gICAgICBvcHRpbWlzdGljUmVzcG9uc2UgJiZcbiAgICAgIHRoaXMubWFya011dGF0aW9uT3B0aW1pc3RpYzxURGF0YSwgVFZhcmlhYmxlcywgVENvbnRleHQsIFRDYWNoZT4oXG4gICAgICAgIG9wdGltaXN0aWNSZXNwb25zZSxcbiAgICAgICAge1xuICAgICAgICAgIG11dGF0aW9uSWQsXG4gICAgICAgICAgZG9jdW1lbnQ6IG11dGF0aW9uLFxuICAgICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgICBmZXRjaFBvbGljeSxcbiAgICAgICAgICBlcnJvclBvbGljeSxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIHVwZGF0ZVF1ZXJpZXMsXG4gICAgICAgICAgdXBkYXRlOiB1cGRhdGVXaXRoUHJveHlGbixcbiAgICAgICAgICBrZWVwUm9vdEZpZWxkcyxcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgIHRoaXMuYnJvYWRjYXN0UXVlcmllcygpO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcmV0dXJuIGFzeW5jTWFwKFxuICAgICAgICBzZWxmLmdldE9ic2VydmFibGVGcm9tTGluayhcbiAgICAgICAgICBtdXRhdGlvbixcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5jb250ZXh0LFxuICAgICAgICAgICAgb3B0aW1pc3RpY1Jlc3BvbnNlOiBpc09wdGltaXN0aWMgPyBvcHRpbWlzdGljUmVzcG9uc2UgOiB2b2lkIDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB2YXJpYWJsZXMsXG4gICAgICAgICAge30sXG4gICAgICAgICAgZmFsc2VcbiAgICAgICAgKSxcblxuICAgICAgICAocmVzdWx0OiBGZXRjaFJlc3VsdDxURGF0YT4pID0+IHtcbiAgICAgICAgICBpZiAoZ3JhcGhRTFJlc3VsdEhhc0Vycm9yKHJlc3VsdCkgJiYgZXJyb3JQb2xpY3kgPT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBvbGxvRXJyb3Ioe1xuICAgICAgICAgICAgICBncmFwaFFMRXJyb3JzOiBnZXRHcmFwaFFMRXJyb3JzRnJvbVJlc3VsdChyZXN1bHQpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG11dGF0aW9uU3RvcmVWYWx1ZSkge1xuICAgICAgICAgICAgbXV0YXRpb25TdG9yZVZhbHVlLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIG11dGF0aW9uU3RvcmVWYWx1ZS5lcnJvciA9IG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3RvcmVSZXN1bHQ6IHR5cGVvZiByZXN1bHQgPSB7IC4uLnJlc3VsdCB9O1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiByZWZldGNoUXVlcmllcyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZWZldGNoUXVlcmllcyA9IHJlZmV0Y2hRdWVyaWVzKFxuICAgICAgICAgICAgICBzdG9yZVJlc3VsdCBhcyBGZXRjaFJlc3VsdDxVbm1hc2tlZDxURGF0YT4+XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChlcnJvclBvbGljeSA9PT0gXCJpZ25vcmVcIiAmJiBncmFwaFFMUmVzdWx0SGFzRXJyb3Ioc3RvcmVSZXN1bHQpKSB7XG4gICAgICAgICAgICBkZWxldGUgc3RvcmVSZXN1bHQuZXJyb3JzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBzZWxmLm1hcmtNdXRhdGlvblJlc3VsdDxURGF0YSwgVFZhcmlhYmxlcywgVENvbnRleHQsIFRDYWNoZT4oe1xuICAgICAgICAgICAgbXV0YXRpb25JZCxcbiAgICAgICAgICAgIHJlc3VsdDogc3RvcmVSZXN1bHQsXG4gICAgICAgICAgICBkb2N1bWVudDogbXV0YXRpb24sXG4gICAgICAgICAgICB2YXJpYWJsZXMsXG4gICAgICAgICAgICBmZXRjaFBvbGljeSxcbiAgICAgICAgICAgIGVycm9yUG9saWN5LFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHVwZGF0ZTogdXBkYXRlV2l0aFByb3h5Rm4sXG4gICAgICAgICAgICB1cGRhdGVRdWVyaWVzLFxuICAgICAgICAgICAgYXdhaXRSZWZldGNoUXVlcmllcyxcbiAgICAgICAgICAgIHJlZmV0Y2hRdWVyaWVzLFxuICAgICAgICAgICAgcmVtb3ZlT3B0aW1pc3RpYzogaXNPcHRpbWlzdGljID8gbXV0YXRpb25JZCA6IHZvaWQgMCxcbiAgICAgICAgICAgIG9uUXVlcnlVcGRhdGVkLFxuICAgICAgICAgICAga2VlcFJvb3RGaWVsZHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dChzdG9yZVJlc3VsdCkge1xuICAgICAgICAgIHNlbGYuYnJvYWRjYXN0UXVlcmllcygpO1xuXG4gICAgICAgICAgLy8gU2luY2UgbXV0YXRpb25zIG1pZ2h0IHJlY2VpdmUgbXVsdGlwbGUgcGF5bG9hZHMgZnJvbSB0aGVcbiAgICAgICAgICAvLyBBcG9sbG9MaW5rIGNoYWluIChlLmcuIHdoZW4gdXNlZCB3aXRoIEBkZWZlciksXG4gICAgICAgICAgLy8gd2UgcmVzb2x2ZSB3aXRoIGEgU2luZ2xlRXhlY3V0aW9uUmVzdWx0IG9yIGFmdGVyIHRoZSBmaW5hbFxuICAgICAgICAgIC8vIEV4ZWN1dGlvblBhdGNoUmVzdWx0IGhhcyBhcnJpdmVkIGFuZCB3ZSBoYXZlIGFzc2VtYmxlZCB0aGVcbiAgICAgICAgICAvLyBtdWx0aXBhcnQgcmVzcG9uc2UgaW50byBhIHNpbmdsZSByZXN1bHQuXG4gICAgICAgICAgaWYgKCEoXCJoYXNOZXh0XCIgaW4gc3RvcmVSZXN1bHQpIHx8IHN0b3JlUmVzdWx0Lmhhc05leHQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgLi4uc3RvcmVSZXN1bHQsXG4gICAgICAgICAgICAgIGRhdGE6IHNlbGYubWFza09wZXJhdGlvbih7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQ6IG11dGF0aW9uLFxuICAgICAgICAgICAgICAgIGRhdGE6IHN0b3JlUmVzdWx0LmRhdGEsXG4gICAgICAgICAgICAgICAgZmV0Y2hQb2xpY3ksXG4gICAgICAgICAgICAgICAgaWQ6IG11dGF0aW9uSWQsXG4gICAgICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBlcnJvcihlcnI6IEVycm9yKSB7XG4gICAgICAgICAgaWYgKG11dGF0aW9uU3RvcmVWYWx1ZSkge1xuICAgICAgICAgICAgbXV0YXRpb25TdG9yZVZhbHVlLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIG11dGF0aW9uU3RvcmVWYWx1ZS5lcnJvciA9IGVycjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNPcHRpbWlzdGljKSB7XG4gICAgICAgICAgICBzZWxmLmNhY2hlLnJlbW92ZU9wdGltaXN0aWMobXV0YXRpb25JZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZi5icm9hZGNhc3RRdWVyaWVzKCk7XG5cbiAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBBcG9sbG9FcnJvciA/IGVyciA6IChcbiAgICAgICAgICAgICAgbmV3IEFwb2xsb0Vycm9yKHtcbiAgICAgICAgICAgICAgICBuZXR3b3JrRXJyb3I6IGVycixcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbWFya011dGF0aW9uUmVzdWx0PFxuICAgIFREYXRhLFxuICAgIFRWYXJpYWJsZXMsXG4gICAgVENvbnRleHQsXG4gICAgVENhY2hlIGV4dGVuZHMgQXBvbGxvQ2FjaGU8YW55PixcbiAgPihcbiAgICBtdXRhdGlvbjoge1xuICAgICAgbXV0YXRpb25JZDogc3RyaW5nO1xuICAgICAgcmVzdWx0OiBGZXRjaFJlc3VsdDxURGF0YT47XG4gICAgICBkb2N1bWVudDogRG9jdW1lbnROb2RlO1xuICAgICAgdmFyaWFibGVzPzogVFZhcmlhYmxlcztcbiAgICAgIGZldGNoUG9saWN5PzogTXV0YXRpb25GZXRjaFBvbGljeTtcbiAgICAgIGVycm9yUG9saWN5OiBFcnJvclBvbGljeTtcbiAgICAgIGNvbnRleHQ/OiBUQ29udGV4dDtcbiAgICAgIHVwZGF0ZVF1ZXJpZXM6IFVwZGF0ZVF1ZXJpZXM8VERhdGE+O1xuICAgICAgdXBkYXRlPzogTXV0YXRpb25VcGRhdGVyRnVuY3Rpb248VERhdGEsIFRWYXJpYWJsZXMsIFRDb250ZXh0LCBUQ2FjaGU+O1xuICAgICAgYXdhaXRSZWZldGNoUXVlcmllcz86IGJvb2xlYW47XG4gICAgICByZWZldGNoUXVlcmllcz86IEludGVybmFsUmVmZXRjaFF1ZXJpZXNJbmNsdWRlO1xuICAgICAgcmVtb3ZlT3B0aW1pc3RpYz86IHN0cmluZztcbiAgICAgIG9uUXVlcnlVcGRhdGVkPzogT25RdWVyeVVwZGF0ZWQ8YW55PjtcbiAgICAgIGtlZXBSb290RmllbGRzPzogYm9vbGVhbjtcbiAgICB9LFxuICAgIGNhY2hlID0gdGhpcy5jYWNoZVxuICApOiBQcm9taXNlPEZldGNoUmVzdWx0PFREYXRhPj4ge1xuICAgIGxldCB7IHJlc3VsdCB9ID0gbXV0YXRpb247XG4gICAgY29uc3QgY2FjaGVXcml0ZXM6IENhY2hlLldyaXRlT3B0aW9uc1tdID0gW107XG4gICAgY29uc3Qgc2tpcENhY2hlID0gbXV0YXRpb24uZmV0Y2hQb2xpY3kgPT09IFwibm8tY2FjaGVcIjtcblxuICAgIGlmICghc2tpcENhY2hlICYmIHNob3VsZFdyaXRlUmVzdWx0KHJlc3VsdCwgbXV0YXRpb24uZXJyb3JQb2xpY3kpKSB7XG4gICAgICBpZiAoIWlzRXhlY3V0aW9uUGF0Y2hJbmNyZW1lbnRhbFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICAgIGNhY2hlV3JpdGVzLnB1c2goe1xuICAgICAgICAgIHJlc3VsdDogcmVzdWx0LmRhdGEsXG4gICAgICAgICAgZGF0YUlkOiBcIlJPT1RfTVVUQVRJT05cIixcbiAgICAgICAgICBxdWVyeTogbXV0YXRpb24uZG9jdW1lbnQsXG4gICAgICAgICAgdmFyaWFibGVzOiBtdXRhdGlvbi52YXJpYWJsZXMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICBpc0V4ZWN1dGlvblBhdGNoSW5jcmVtZW50YWxSZXN1bHQocmVzdWx0KSAmJlxuICAgICAgICBpc05vbkVtcHR5QXJyYXkocmVzdWx0LmluY3JlbWVudGFsKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBjYWNoZS5kaWZmPFREYXRhPih7XG4gICAgICAgICAgaWQ6IFwiUk9PVF9NVVRBVElPTlwiLFxuICAgICAgICAgIC8vIFRoZSBjYWNoZSBjb21wbGFpbnMgaWYgcGFzc2VkIGEgbXV0YXRpb24gd2hlcmUgaXQgZXhwZWN0cyBhXG4gICAgICAgICAgLy8gcXVlcnksIHNvIHdlIHRyYW5zZm9ybSBtdXRhdGlvbnMgYW5kIHN1YnNjcmlwdGlvbnMgdG8gcXVlcmllc1xuICAgICAgICAgIC8vIChvbmx5IG9uY2UsIHRoYW5rcyB0byB0aGlzLnRyYW5zZm9ybUNhY2hlKS5cbiAgICAgICAgICBxdWVyeTogdGhpcy5nZXREb2N1bWVudEluZm8obXV0YXRpb24uZG9jdW1lbnQpLmFzUXVlcnksXG4gICAgICAgICAgdmFyaWFibGVzOiBtdXRhdGlvbi52YXJpYWJsZXMsXG4gICAgICAgICAgb3B0aW1pc3RpYzogZmFsc2UsXG4gICAgICAgICAgcmV0dXJuUGFydGlhbERhdGE6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbWVyZ2VkRGF0YTtcbiAgICAgICAgaWYgKGRpZmYucmVzdWx0KSB7XG4gICAgICAgICAgbWVyZ2VkRGF0YSA9IG1lcmdlSW5jcmVtZW50YWxEYXRhKGRpZmYucmVzdWx0LCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbWVyZ2VkRGF0YSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIC8vIGNhc3QgdGhlIEV4ZWN1dGlvblBhdGNoUmVzdWx0IHRvIEZldGNoUmVzdWx0IGhlcmUgc2luY2VcbiAgICAgICAgICAvLyBFeGVjdXRpb25QYXRjaFJlc3VsdCBuZXZlciBoYXMgYGRhdGFgIHdoZW4gcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gICAgICAgICAgKHJlc3VsdCBhcyBGZXRjaFJlc3VsdCkuZGF0YSA9IG1lcmdlZERhdGE7XG4gICAgICAgICAgY2FjaGVXcml0ZXMucHVzaCh7XG4gICAgICAgICAgICByZXN1bHQ6IG1lcmdlZERhdGEsXG4gICAgICAgICAgICBkYXRhSWQ6IFwiUk9PVF9NVVRBVElPTlwiLFxuICAgICAgICAgICAgcXVlcnk6IG11dGF0aW9uLmRvY3VtZW50LFxuICAgICAgICAgICAgdmFyaWFibGVzOiBtdXRhdGlvbi52YXJpYWJsZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB1cGRhdGVRdWVyaWVzIH0gPSBtdXRhdGlvbjtcbiAgICAgIGlmICh1cGRhdGVRdWVyaWVzKSB7XG4gICAgICAgIHRoaXMucXVlcmllcy5mb3JFYWNoKCh7IG9ic2VydmFibGVRdWVyeSB9LCBxdWVyeUlkKSA9PiB7XG4gICAgICAgICAgY29uc3QgcXVlcnlOYW1lID0gb2JzZXJ2YWJsZVF1ZXJ5ICYmIG9ic2VydmFibGVRdWVyeS5xdWVyeU5hbWU7XG4gICAgICAgICAgaWYgKCFxdWVyeU5hbWUgfHwgIWhhc093blByb3BlcnR5LmNhbGwodXBkYXRlUXVlcmllcywgcXVlcnlOYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB1cGRhdGVyID0gdXBkYXRlUXVlcmllc1txdWVyeU5hbWVdO1xuICAgICAgICAgIGNvbnN0IHsgZG9jdW1lbnQsIHZhcmlhYmxlcyB9ID0gdGhpcy5xdWVyaWVzLmdldChxdWVyeUlkKSE7XG5cbiAgICAgICAgICAvLyBSZWFkIHRoZSBjdXJyZW50IHF1ZXJ5IHJlc3VsdCBmcm9tIHRoZSBzdG9yZS5cbiAgICAgICAgICBjb25zdCB7IHJlc3VsdDogY3VycmVudFF1ZXJ5UmVzdWx0LCBjb21wbGV0ZSB9ID0gY2FjaGUuZGlmZjxURGF0YT4oe1xuICAgICAgICAgICAgcXVlcnk6IGRvY3VtZW50ISxcbiAgICAgICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgICAgIHJldHVyblBhcnRpYWxEYXRhOiB0cnVlLFxuICAgICAgICAgICAgb3B0aW1pc3RpYzogZmFsc2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoY29tcGxldGUgJiYgY3VycmVudFF1ZXJ5UmVzdWx0KSB7XG4gICAgICAgICAgICAvLyBSdW4gb3VyIHJlZHVjZXIgdXNpbmcgdGhlIGN1cnJlbnQgcXVlcnkgcmVzdWx0IGFuZCB0aGUgbXV0YXRpb24gcmVzdWx0LlxuICAgICAgICAgICAgY29uc3QgbmV4dFF1ZXJ5UmVzdWx0ID0gdXBkYXRlcihjdXJyZW50UXVlcnlSZXN1bHQsIHtcbiAgICAgICAgICAgICAgbXV0YXRpb25SZXN1bHQ6IHJlc3VsdCBhcyBGZXRjaFJlc3VsdDxVbm1hc2tlZDxURGF0YT4+LFxuICAgICAgICAgICAgICBxdWVyeU5hbWU6IChkb2N1bWVudCAmJiBnZXRPcGVyYXRpb25OYW1lKGRvY3VtZW50KSkgfHwgdm9pZCAwLFxuICAgICAgICAgICAgICBxdWVyeVZhcmlhYmxlczogdmFyaWFibGVzISxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBXcml0ZSB0aGUgbW9kaWZpZWQgcmVzdWx0IGJhY2sgaW50byB0aGUgc3RvcmUgaWYgd2UgZ290IGEgbmV3IHJlc3VsdC5cbiAgICAgICAgICAgIGlmIChuZXh0UXVlcnlSZXN1bHQpIHtcbiAgICAgICAgICAgICAgY2FjaGVXcml0ZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgcmVzdWx0OiBuZXh0UXVlcnlSZXN1bHQsXG4gICAgICAgICAgICAgICAgZGF0YUlkOiBcIlJPT1RfUVVFUllcIixcbiAgICAgICAgICAgICAgICBxdWVyeTogZG9jdW1lbnQhLFxuICAgICAgICAgICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBjYWNoZVdyaXRlcy5sZW5ndGggPiAwIHx8XG4gICAgICAobXV0YXRpb24ucmVmZXRjaFF1ZXJpZXMgfHwgXCJcIikubGVuZ3RoID4gMCB8fFxuICAgICAgbXV0YXRpb24udXBkYXRlIHx8XG4gICAgICBtdXRhdGlvbi5vblF1ZXJ5VXBkYXRlZCB8fFxuICAgICAgbXV0YXRpb24ucmVtb3ZlT3B0aW1pc3RpY1xuICAgICkge1xuICAgICAgY29uc3QgcmVzdWx0czogYW55W10gPSBbXTtcblxuICAgICAgdGhpcy5yZWZldGNoUXVlcmllcyh7XG4gICAgICAgIHVwZGF0ZUNhY2hlOiAoY2FjaGUpID0+IHtcbiAgICAgICAgICBpZiAoIXNraXBDYWNoZSkge1xuICAgICAgICAgICAgY2FjaGVXcml0ZXMuZm9yRWFjaCgod3JpdGUpID0+IGNhY2hlLndyaXRlKHdyaXRlKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgdGhlIG11dGF0aW9uIGhhcyBzb21lIHdyaXRlcyBhc3NvY2lhdGVkIHdpdGggaXQgdGhlbiB3ZSBuZWVkIHRvXG4gICAgICAgICAgLy8gYXBwbHkgdGhvc2Ugd3JpdGVzIHRvIHRoZSBzdG9yZSBieSBydW5uaW5nIHRoaXMgcmVkdWNlciBhZ2FpbiB3aXRoXG4gICAgICAgICAgLy8gYSB3cml0ZSBhY3Rpb24uXG4gICAgICAgICAgY29uc3QgeyB1cGRhdGUgfSA9IG11dGF0aW9uO1xuICAgICAgICAgIC8vIERldGVybWluZSB3aGV0aGVyIHJlc3VsdCBpcyBhIFNpbmdsZUV4ZWN1dGlvblJlc3VsdCxcbiAgICAgICAgICAvLyBvciB0aGUgZmluYWwgRXhlY3V0aW9uUGF0Y2hSZXN1bHQuXG4gICAgICAgICAgY29uc3QgaXNGaW5hbFJlc3VsdCA9XG4gICAgICAgICAgICAhaXNFeGVjdXRpb25QYXRjaFJlc3VsdChyZXN1bHQpIHx8XG4gICAgICAgICAgICAoaXNFeGVjdXRpb25QYXRjaEluY3JlbWVudGFsUmVzdWx0KHJlc3VsdCkgJiYgIXJlc3VsdC5oYXNOZXh0KTtcblxuICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgIGlmICghc2tpcENhY2hlKSB7XG4gICAgICAgICAgICAgIC8vIFJlLXJlYWQgdGhlIFJPT1RfTVVUQVRJT04gZGF0YSB3ZSBqdXN0IHdyb3RlIGludG8gdGhlIGNhY2hlXG4gICAgICAgICAgICAgIC8vICh0aGUgZmlyc3QgY2FjaGUud3JpdGUgY2FsbCBpbiB0aGUgY2FjaGVXcml0ZXMuZm9yRWFjaCBsb29wXG4gICAgICAgICAgICAgIC8vIGFib3ZlKSwgc28gZmllbGQgcmVhZCBmdW5jdGlvbnMgaGF2ZSBhIGNoYW5jZSB0byBydW4gZm9yXG4gICAgICAgICAgICAgIC8vIGZpZWxkcyB3aXRoaW4gbXV0YXRpb24gcmVzdWx0IG9iamVjdHMuXG4gICAgICAgICAgICAgIGNvbnN0IGRpZmYgPSBjYWNoZS5kaWZmPFREYXRhPih7XG4gICAgICAgICAgICAgICAgaWQ6IFwiUk9PVF9NVVRBVElPTlwiLFxuICAgICAgICAgICAgICAgIC8vIFRoZSBjYWNoZSBjb21wbGFpbnMgaWYgcGFzc2VkIGEgbXV0YXRpb24gd2hlcmUgaXQgZXhwZWN0cyBhXG4gICAgICAgICAgICAgICAgLy8gcXVlcnksIHNvIHdlIHRyYW5zZm9ybSBtdXRhdGlvbnMgYW5kIHN1YnNjcmlwdGlvbnMgdG8gcXVlcmllc1xuICAgICAgICAgICAgICAgIC8vIChvbmx5IG9uY2UsIHRoYW5rcyB0byB0aGlzLnRyYW5zZm9ybUNhY2hlKS5cbiAgICAgICAgICAgICAgICBxdWVyeTogdGhpcy5nZXREb2N1bWVudEluZm8obXV0YXRpb24uZG9jdW1lbnQpLmFzUXVlcnksXG4gICAgICAgICAgICAgICAgdmFyaWFibGVzOiBtdXRhdGlvbi52YXJpYWJsZXMsXG4gICAgICAgICAgICAgICAgb3B0aW1pc3RpYzogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmV0dXJuUGFydGlhbERhdGE6IHRydWUsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmIChkaWZmLmNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0geyAuLi4ocmVzdWx0IGFzIEZldGNoUmVzdWx0KSwgZGF0YTogZGlmZi5yZXN1bHQgfTtcbiAgICAgICAgICAgICAgICBpZiAoXCJpbmNyZW1lbnRhbFwiIGluIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3VsdC5pbmNyZW1lbnRhbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKFwiaGFzTmV4dFwiIGluIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3VsdC5oYXNOZXh0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSd2ZSByZWNlaXZlZCB0aGUgd2hvbGUgcmVzcG9uc2UsXG4gICAgICAgICAgICAvLyBlaXRoZXIgYSBTaW5nbGVFeGVjdXRpb25SZXN1bHQgb3IgdGhlIGZpbmFsIEV4ZWN1dGlvblBhdGNoUmVzdWx0LFxuICAgICAgICAgICAgLy8gY2FsbCB0aGUgdXBkYXRlIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKGlzRmluYWxSZXN1bHQpIHtcbiAgICAgICAgICAgICAgdXBkYXRlKGNhY2hlIGFzIFRDYWNoZSwgcmVzdWx0IGFzIEZldGNoUmVzdWx0PFVubWFza2VkPFREYXRhPj4sIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiBtdXRhdGlvbi5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhcmlhYmxlczogbXV0YXRpb24udmFyaWFibGVzLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBUT0RPIERvIHRoaXMgd2l0aCBjYWNoZS5ldmljdCh7IGlkOiAnUk9PVF9NVVRBVElPTicgfSkgYnV0IG1ha2UgaXRcbiAgICAgICAgICAvLyBzaGFsbG93IHRvIGFsbG93IHJvbGxpbmcgYmFjayBvcHRpbWlzdGljIGV2aWN0aW9ucy5cbiAgICAgICAgICBpZiAoIXNraXBDYWNoZSAmJiAhbXV0YXRpb24ua2VlcFJvb3RGaWVsZHMgJiYgaXNGaW5hbFJlc3VsdCkge1xuICAgICAgICAgICAgY2FjaGUubW9kaWZ5KHtcbiAgICAgICAgICAgICAgaWQ6IFwiUk9PVF9NVVRBVElPTlwiLFxuICAgICAgICAgICAgICBmaWVsZHModmFsdWUsIHsgZmllbGROYW1lLCBERUxFVEUgfSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmaWVsZE5hbWUgPT09IFwiX190eXBlbmFtZVwiID8gdmFsdWUgOiBERUxFVEU7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5jbHVkZTogbXV0YXRpb24ucmVmZXRjaFF1ZXJpZXMsXG5cbiAgICAgICAgLy8gV3JpdGUgdGhlIGZpbmFsIG11dGF0aW9uLnJlc3VsdCB0byB0aGUgcm9vdCBsYXllciBvZiB0aGUgY2FjaGUuXG4gICAgICAgIG9wdGltaXN0aWM6IGZhbHNlLFxuXG4gICAgICAgIC8vIFJlbW92ZSB0aGUgY29ycmVzcG9uZGluZyBvcHRpbWlzdGljIGxheWVyIGF0IHRoZSBzYW1lIHRpbWUgYXMgd2VcbiAgICAgICAgLy8gd3JpdGUgdGhlIGZpbmFsIG5vbi1vcHRpbWlzdGljIHJlc3VsdC5cbiAgICAgICAgcmVtb3ZlT3B0aW1pc3RpYzogbXV0YXRpb24ucmVtb3ZlT3B0aW1pc3RpYyxcblxuICAgICAgICAvLyBMZXQgdGhlIGNhbGxlciBvZiBjbGllbnQubXV0YXRlIG9wdGlvbmFsbHkgZGV0ZXJtaW5lIHRoZSByZWZldGNoaW5nXG4gICAgICAgIC8vIGJlaGF2aW9yIGZvciB3YXRjaGVkIHF1ZXJpZXMgYWZ0ZXIgdGhlIG11dGF0aW9uLnVwZGF0ZSBmdW5jdGlvbiBydW5zLlxuICAgICAgICAvLyBJZiBubyBvblF1ZXJ5VXBkYXRlZCBmdW5jdGlvbiB3YXMgcHJvdmlkZWQgZm9yIHRoaXMgbXV0YXRpb24sIHBhc3NcbiAgICAgICAgLy8gbnVsbCBpbnN0ZWFkIG9mIHVuZGVmaW5lZCB0byBkaXNhYmxlIHRoZSBkZWZhdWx0IHJlZmV0Y2hpbmcgYmVoYXZpb3IuXG4gICAgICAgIG9uUXVlcnlVcGRhdGVkOiBtdXRhdGlvbi5vblF1ZXJ5VXBkYXRlZCB8fCBudWxsLFxuICAgICAgfSkuZm9yRWFjaCgocmVzdWx0KSA9PiByZXN1bHRzLnB1c2gocmVzdWx0KSk7XG5cbiAgICAgIGlmIChtdXRhdGlvbi5hd2FpdFJlZmV0Y2hRdWVyaWVzIHx8IG11dGF0aW9uLm9uUXVlcnlVcGRhdGVkKSB7XG4gICAgICAgIC8vIFJldHVybmluZyBhIHByb21pc2UgaGVyZSBtYWtlcyB0aGUgbXV0YXRpb24gYXdhaXQgdGhhdCBwcm9taXNlLCBzbyB3ZVxuICAgICAgICAvLyBpbmNsdWRlIHJlc3VsdHMgaW4gdGhhdCBwcm9taXNlJ3Mgd29yayBpZiBhd2FpdFJlZmV0Y2hRdWVyaWVzIG9yIGFuXG4gICAgICAgIC8vIG9uUXVlcnlVcGRhdGVkIGZ1bmN0aW9uIHdhcyBzcGVjaWZpZWQuXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChyZXN1bHRzKS50aGVuKCgpID0+IHJlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpO1xuICB9XG5cbiAgcHVibGljIG1hcmtNdXRhdGlvbk9wdGltaXN0aWM8XG4gICAgVERhdGEsXG4gICAgVFZhcmlhYmxlcyxcbiAgICBUQ29udGV4dCxcbiAgICBUQ2FjaGUgZXh0ZW5kcyBBcG9sbG9DYWNoZTxhbnk+LFxuICA+KFxuICAgIG9wdGltaXN0aWNSZXNwb25zZTogYW55LFxuICAgIG11dGF0aW9uOiB7XG4gICAgICBtdXRhdGlvbklkOiBzdHJpbmc7XG4gICAgICBkb2N1bWVudDogRG9jdW1lbnROb2RlO1xuICAgICAgdmFyaWFibGVzPzogVFZhcmlhYmxlcztcbiAgICAgIGZldGNoUG9saWN5PzogTXV0YXRpb25GZXRjaFBvbGljeTtcbiAgICAgIGVycm9yUG9saWN5OiBFcnJvclBvbGljeTtcbiAgICAgIGNvbnRleHQ/OiBUQ29udGV4dDtcbiAgICAgIHVwZGF0ZVF1ZXJpZXM6IFVwZGF0ZVF1ZXJpZXM8VERhdGE+O1xuICAgICAgdXBkYXRlPzogTXV0YXRpb25VcGRhdGVyRnVuY3Rpb248VERhdGEsIFRWYXJpYWJsZXMsIFRDb250ZXh0LCBUQ2FjaGU+O1xuICAgICAga2VlcFJvb3RGaWVsZHM/OiBib29sZWFuO1xuICAgIH1cbiAgKSB7XG4gICAgY29uc3QgZGF0YSA9XG4gICAgICB0eXBlb2Ygb3B0aW1pc3RpY1Jlc3BvbnNlID09PSBcImZ1bmN0aW9uXCIgP1xuICAgICAgICBvcHRpbWlzdGljUmVzcG9uc2UobXV0YXRpb24udmFyaWFibGVzLCB7IElHTk9SRSB9KVxuICAgICAgOiBvcHRpbWlzdGljUmVzcG9uc2U7XG5cbiAgICBpZiAoZGF0YSA9PT0gSUdOT1JFKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5jYWNoZS5yZWNvcmRPcHRpbWlzdGljVHJhbnNhY3Rpb24oKGNhY2hlKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLm1hcmtNdXRhdGlvblJlc3VsdDxURGF0YSwgVFZhcmlhYmxlcywgVENvbnRleHQsIFRDYWNoZT4oXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4ubXV0YXRpb24sXG4gICAgICAgICAgICByZXN1bHQ6IHsgZGF0YSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2FjaGVcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGludmFyaWFudC5lcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSwgbXV0YXRpb24ubXV0YXRpb25JZCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBmZXRjaFF1ZXJ5PFREYXRhLCBUVmFycyBleHRlbmRzIE9wZXJhdGlvblZhcmlhYmxlcz4oXG4gICAgcXVlcnlJZDogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJzLCBURGF0YT4sXG4gICAgbmV0d29ya1N0YXR1cz86IE5ldHdvcmtTdGF0dXNcbiAgKTogUHJvbWlzZTxBcG9sbG9RdWVyeVJlc3VsdDxURGF0YT4+IHtcbiAgICByZXR1cm4gdGhpcy5mZXRjaENvbmNhc3RXaXRoSW5mbyhcbiAgICAgIHRoaXMuZ2V0T3JDcmVhdGVRdWVyeShxdWVyeUlkKSxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBuZXR3b3JrU3RhdHVzXG4gICAgKS5jb25jYXN0LnByb21pc2UgYXMgVE9ETztcbiAgfVxuXG4gIHB1YmxpYyBnZXRRdWVyeVN0b3JlKCkge1xuICAgIGNvbnN0IHN0b3JlOiBSZWNvcmQ8c3RyaW5nLCBRdWVyeVN0b3JlVmFsdWU+ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLnF1ZXJpZXMuZm9yRWFjaCgoaW5mbywgcXVlcnlJZCkgPT4ge1xuICAgICAgc3RvcmVbcXVlcnlJZF0gPSB7XG4gICAgICAgIHZhcmlhYmxlczogaW5mby52YXJpYWJsZXMsXG4gICAgICAgIG5ldHdvcmtTdGF0dXM6IGluZm8ubmV0d29ya1N0YXR1cyxcbiAgICAgICAgbmV0d29ya0Vycm9yOiBpbmZvLm5ldHdvcmtFcnJvcixcbiAgICAgICAgZ3JhcGhRTEVycm9yczogaW5mby5ncmFwaFFMRXJyb3JzLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZXR1cm4gc3RvcmU7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRFcnJvcnMocXVlcnlJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgcXVlcnlJbmZvID0gdGhpcy5xdWVyaWVzLmdldChxdWVyeUlkKTtcbiAgICBpZiAocXVlcnlJbmZvKSB7XG4gICAgICBxdWVyeUluZm8ubmV0d29ya0Vycm9yID0gdW5kZWZpbmVkO1xuICAgICAgcXVlcnlJbmZvLmdyYXBoUUxFcnJvcnMgPSBbXTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdHJhbnNmb3JtKGRvY3VtZW50OiBEb2N1bWVudE5vZGUpIHtcbiAgICByZXR1cm4gdGhpcy5kb2N1bWVudFRyYW5zZm9ybS50cmFuc2Zvcm1Eb2N1bWVudChkb2N1bWVudCk7XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybUNhY2hlID0gbmV3IEF1dG9DbGVhbmVkV2Vha0NhY2hlPFxuICAgIERvY3VtZW50Tm9kZSxcbiAgICBUcmFuc2Zvcm1DYWNoZUVudHJ5XG4gID4oXG4gICAgY2FjaGVTaXplc1tcInF1ZXJ5TWFuYWdlci5nZXREb2N1bWVudEluZm9cIl0gfHxcbiAgICAgIGRlZmF1bHRDYWNoZVNpemVzW1wicXVlcnlNYW5hZ2VyLmdldERvY3VtZW50SW5mb1wiXVxuICApO1xuXG4gIHB1YmxpYyBnZXREb2N1bWVudEluZm8oZG9jdW1lbnQ6IERvY3VtZW50Tm9kZSkge1xuICAgIGNvbnN0IHsgdHJhbnNmb3JtQ2FjaGUgfSA9IHRoaXM7XG5cbiAgICBpZiAoIXRyYW5zZm9ybUNhY2hlLmhhcyhkb2N1bWVudCkpIHtcbiAgICAgIGNvbnN0IGNhY2hlRW50cnk6IFRyYW5zZm9ybUNhY2hlRW50cnkgPSB7XG4gICAgICAgIC8vIFRPRE8gVGhlc2UgdGhyZWUgY2FsbHMgKGhhc0NsaWVudEV4cG9ydHMsIHNob3VsZEZvcmNlUmVzb2x2ZXJzLCBhbmRcbiAgICAgICAgLy8gdXNlc05vbnJlYWN0aXZlRGlyZWN0aXZlKSBhcmUgcGVyZm9ybWluZyBpbmRlcGVuZGVudCBmdWxsIHRyYXZlcnNhbHNcbiAgICAgICAgLy8gb2YgdGhlIHRyYW5zZm9ybWVkIGRvY3VtZW50LiBXZSBzaG91bGQgY29uc2lkZXIgbWVyZ2luZyB0aGVzZVxuICAgICAgICAvLyB0cmF2ZXJzYWxzIGludG8gYSBzaW5nbGUgcGFzcyBpbiB0aGUgZnV0dXJlLCB0aG91Z2ggdGhlIHdvcmsgaXNcbiAgICAgICAgLy8gY2FjaGVkIGFmdGVyIHRoZSBmaXJzdCB0aW1lLlxuICAgICAgICBoYXNDbGllbnRFeHBvcnRzOiBoYXNDbGllbnRFeHBvcnRzKGRvY3VtZW50KSxcbiAgICAgICAgaGFzRm9yY2VkUmVzb2x2ZXJzOiB0aGlzLmxvY2FsU3RhdGUuc2hvdWxkRm9yY2VSZXNvbHZlcnMoZG9jdW1lbnQpLFxuICAgICAgICBoYXNOb25yZWFjdGl2ZURpcmVjdGl2ZTogaGFzRGlyZWN0aXZlcyhbXCJub25yZWFjdGl2ZVwiXSwgZG9jdW1lbnQpLFxuICAgICAgICBub25SZWFjdGl2ZVF1ZXJ5OiBhZGROb25SZWFjdGl2ZVRvTmFtZWRGcmFnbWVudHMoZG9jdW1lbnQpLFxuICAgICAgICBjbGllbnRRdWVyeTogdGhpcy5sb2NhbFN0YXRlLmNsaWVudFF1ZXJ5KGRvY3VtZW50KSxcbiAgICAgICAgc2VydmVyUXVlcnk6IHJlbW92ZURpcmVjdGl2ZXNGcm9tRG9jdW1lbnQoXG4gICAgICAgICAgW1xuICAgICAgICAgICAgeyBuYW1lOiBcImNsaWVudFwiLCByZW1vdmU6IHRydWUgfSxcbiAgICAgICAgICAgIHsgbmFtZTogXCJjb25uZWN0aW9uXCIgfSxcbiAgICAgICAgICAgIHsgbmFtZTogXCJub25yZWFjdGl2ZVwiIH0sXG4gICAgICAgICAgICB7IG5hbWU6IFwidW5tYXNrXCIgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRvY3VtZW50XG4gICAgICAgICksXG4gICAgICAgIGRlZmF1bHRWYXJzOiBnZXREZWZhdWx0VmFsdWVzKFxuICAgICAgICAgIGdldE9wZXJhdGlvbkRlZmluaXRpb24oZG9jdW1lbnQpXG4gICAgICAgICkgYXMgT3BlcmF0aW9uVmFyaWFibGVzLFxuICAgICAgICAvLyBUcmFuc2Zvcm0gYW55IG11dGF0aW9uIG9yIHN1YnNjcmlwdGlvbiBvcGVyYXRpb25zIHRvIHF1ZXJ5IG9wZXJhdGlvbnNcbiAgICAgICAgLy8gc28gd2UgY2FuIHJlYWQvd3JpdGUgdGhlbSBmcm9tL3RvIHRoZSBjYWNoZS5cbiAgICAgICAgYXNRdWVyeToge1xuICAgICAgICAgIC4uLmRvY3VtZW50LFxuICAgICAgICAgIGRlZmluaXRpb25zOiBkb2N1bWVudC5kZWZpbml0aW9ucy5tYXAoKGRlZikgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBkZWYua2luZCA9PT0gXCJPcGVyYXRpb25EZWZpbml0aW9uXCIgJiZcbiAgICAgICAgICAgICAgZGVmLm9wZXJhdGlvbiAhPT0gXCJxdWVyeVwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uZGVmLCBvcGVyYXRpb246IFwicXVlcnlcIiBhcyBPcGVyYXRpb25UeXBlTm9kZSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlZjtcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIHRyYW5zZm9ybUNhY2hlLnNldChkb2N1bWVudCwgY2FjaGVFbnRyeSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zZm9ybUNhY2hlLmdldChkb2N1bWVudCkhO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRWYXJpYWJsZXM8VFZhcmlhYmxlcz4oXG4gICAgZG9jdW1lbnQ6IERvY3VtZW50Tm9kZSxcbiAgICB2YXJpYWJsZXM/OiBUVmFyaWFibGVzXG4gICk6IE9wZXJhdGlvblZhcmlhYmxlcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZ2V0RG9jdW1lbnRJbmZvKGRvY3VtZW50KS5kZWZhdWx0VmFycyxcbiAgICAgIC4uLnZhcmlhYmxlcyxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHdhdGNoUXVlcnk8XG4gICAgVCxcbiAgICBUVmFyaWFibGVzIGV4dGVuZHMgT3BlcmF0aW9uVmFyaWFibGVzID0gT3BlcmF0aW9uVmFyaWFibGVzLFxuICA+KG9wdGlvbnM6IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJpYWJsZXMsIFQ+KTogT2JzZXJ2YWJsZVF1ZXJ5PFQsIFRWYXJpYWJsZXM+IHtcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMudHJhbnNmb3JtKG9wdGlvbnMucXVlcnkpO1xuXG4gICAgLy8gYXNzaWduIHZhcmlhYmxlIGRlZmF1bHQgdmFsdWVzIGlmIHN1cHBsaWVkXG4gICAgLy8gTk9URTogV2UgZG9uJ3QgbW9kaWZ5IG9wdGlvbnMucXVlcnkgaGVyZSB3aXRoIHRoZSB0cmFuc2Zvcm1lZCBxdWVyeSB0b1xuICAgIC8vIGVuc3VyZSBvYnNlcnZhYmxlLm9wdGlvbnMucXVlcnkgaXMgc2V0IHRvIHRoZSByYXcgdW50cmFuc2Zvcm1lZCBxdWVyeS5cbiAgICBvcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIHZhcmlhYmxlczogdGhpcy5nZXRWYXJpYWJsZXMocXVlcnksIG9wdGlvbnMudmFyaWFibGVzKSBhcyBUVmFyaWFibGVzLFxuICAgIH07XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMubm90aWZ5T25OZXR3b3JrU3RhdHVzQ2hhbmdlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBvcHRpb25zLm5vdGlmeU9uTmV0d29ya1N0YXR1c0NoYW5nZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5SW5mbyA9IG5ldyBRdWVyeUluZm8odGhpcyk7XG4gICAgY29uc3Qgb2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlUXVlcnk8VCwgVFZhcmlhYmxlcz4oe1xuICAgICAgcXVlcnlNYW5hZ2VyOiB0aGlzLFxuICAgICAgcXVlcnlJbmZvLFxuICAgICAgb3B0aW9ucyxcbiAgICB9KTtcbiAgICBvYnNlcnZhYmxlW1wibGFzdFF1ZXJ5XCJdID0gcXVlcnk7XG5cbiAgICBpZiAoIU9ic2VydmFibGVRdWVyeVtcImluYWN0aXZlT25DcmVhdGlvblwiXS5nZXRWYWx1ZSgpKSB7XG4gICAgICB0aGlzLnF1ZXJpZXMuc2V0KG9ic2VydmFibGUucXVlcnlJZCwgcXVlcnlJbmZvKTtcbiAgICB9XG5cbiAgICAvLyBXZSBnaXZlIHF1ZXJ5SW5mbyB0aGUgdHJhbnNmb3JtZWQgcXVlcnkgdG8gZW5zdXJlIHRoZSBmaXJzdCBjYWNoZSBkaWZmXG4gICAgLy8gdXNlcyB0aGUgdHJhbnNmb3JtZWQgcXVlcnkgaW5zdGVhZCBvZiB0aGUgcmF3IHF1ZXJ5XG4gICAgcXVlcnlJbmZvLmluaXQoe1xuICAgICAgZG9jdW1lbnQ6IHF1ZXJ5LFxuICAgICAgb2JzZXJ2YWJsZVF1ZXJ5OiBvYnNlcnZhYmxlLFxuICAgICAgdmFyaWFibGVzOiBvYnNlcnZhYmxlLnZhcmlhYmxlcyxcbiAgICB9KTtcblxuICAgIHJldHVybiBvYnNlcnZhYmxlO1xuICB9XG5cbiAgcHVibGljIHF1ZXJ5PFREYXRhLCBUVmFycyBleHRlbmRzIE9wZXJhdGlvblZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcz4oXG4gICAgb3B0aW9uczogUXVlcnlPcHRpb25zPFRWYXJzLCBURGF0YT4sXG4gICAgcXVlcnlJZCA9IHRoaXMuZ2VuZXJhdGVRdWVyeUlkKClcbiAgKTogUHJvbWlzZTxBcG9sbG9RdWVyeVJlc3VsdDxNYXliZU1hc2tlZDxURGF0YT4+PiB7XG4gICAgaW52YXJpYW50KFxuICAgICAgb3B0aW9ucy5xdWVyeSxcbiAgICAgIFwicXVlcnkgb3B0aW9uIGlzIHJlcXVpcmVkLiBZb3UgbXVzdCBzcGVjaWZ5IHlvdXIgR3JhcGhRTCBkb2N1bWVudCBcIiArXG4gICAgICAgIFwiaW4gdGhlIHF1ZXJ5IG9wdGlvbi5cIlxuICAgICk7XG5cbiAgICBpbnZhcmlhbnQoXG4gICAgICBvcHRpb25zLnF1ZXJ5LmtpbmQgPT09IFwiRG9jdW1lbnRcIixcbiAgICAgICdZb3UgbXVzdCB3cmFwIHRoZSBxdWVyeSBzdHJpbmcgaW4gYSBcImdxbFwiIHRhZy4nXG4gICAgKTtcblxuICAgIGludmFyaWFudChcbiAgICAgICEob3B0aW9ucyBhcyBhbnkpLnJldHVyblBhcnRpYWxEYXRhLFxuICAgICAgXCJyZXR1cm5QYXJ0aWFsRGF0YSBvcHRpb24gb25seSBzdXBwb3J0ZWQgb24gd2F0Y2hRdWVyeS5cIlxuICAgICk7XG5cbiAgICBpbnZhcmlhbnQoXG4gICAgICAhKG9wdGlvbnMgYXMgYW55KS5wb2xsSW50ZXJ2YWwsXG4gICAgICBcInBvbGxJbnRlcnZhbCBvcHRpb24gb25seSBzdXBwb3J0ZWQgb24gd2F0Y2hRdWVyeS5cIlxuICAgICk7XG5cbiAgICBjb25zdCBxdWVyeSA9IHRoaXMudHJhbnNmb3JtKG9wdGlvbnMucXVlcnkpO1xuXG4gICAgcmV0dXJuIHRoaXMuZmV0Y2hRdWVyeTxURGF0YSwgVFZhcnM+KHF1ZXJ5SWQsIHsgLi4ub3B0aW9ucywgcXVlcnkgfSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzdWx0KSA9PlxuICAgICAgICAgIHJlc3VsdCAmJiB7XG4gICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgICBkYXRhOiB0aGlzLm1hc2tPcGVyYXRpb24oe1xuICAgICAgICAgICAgICBkb2N1bWVudDogcXVlcnksXG4gICAgICAgICAgICAgIGRhdGE6IHJlc3VsdC5kYXRhLFxuICAgICAgICAgICAgICBmZXRjaFBvbGljeTogb3B0aW9ucy5mZXRjaFBvbGljeSxcbiAgICAgICAgICAgICAgaWQ6IHF1ZXJ5SWQsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9XG4gICAgICApXG4gICAgICAuZmluYWxseSgoKSA9PiB0aGlzLnN0b3BRdWVyeShxdWVyeUlkKSk7XG4gIH1cblxuICBwcml2YXRlIHF1ZXJ5SWRDb3VudGVyID0gMTtcbiAgcHVibGljIGdlbmVyYXRlUXVlcnlJZCgpIHtcbiAgICByZXR1cm4gU3RyaW5nKHRoaXMucXVlcnlJZENvdW50ZXIrKyk7XG4gIH1cblxuICBwcml2YXRlIHJlcXVlc3RJZENvdW50ZXIgPSAxO1xuICBwdWJsaWMgZ2VuZXJhdGVSZXF1ZXN0SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdElkQ291bnRlcisrO1xuICB9XG5cbiAgcHJpdmF0ZSBtdXRhdGlvbklkQ291bnRlciA9IDE7XG4gIHB1YmxpYyBnZW5lcmF0ZU11dGF0aW9uSWQoKSB7XG4gICAgcmV0dXJuIFN0cmluZyh0aGlzLm11dGF0aW9uSWRDb3VudGVyKyspO1xuICB9XG5cbiAgcHVibGljIHN0b3BRdWVyeUluU3RvcmUocXVlcnlJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zdG9wUXVlcnlJblN0b3JlTm9Ccm9hZGNhc3QocXVlcnlJZCk7XG4gICAgdGhpcy5icm9hZGNhc3RRdWVyaWVzKCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BRdWVyeUluU3RvcmVOb0Jyb2FkY2FzdChxdWVyeUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBxdWVyeUluZm8gPSB0aGlzLnF1ZXJpZXMuZ2V0KHF1ZXJ5SWQpO1xuICAgIGlmIChxdWVyeUluZm8pIHF1ZXJ5SW5mby5zdG9wKCk7XG4gIH1cblxuICBwdWJsaWMgY2xlYXJTdG9yZShcbiAgICBvcHRpb25zOiBDYWNoZS5SZXNldE9wdGlvbnMgPSB7XG4gICAgICBkaXNjYXJkV2F0Y2hlczogdHJ1ZSxcbiAgICB9XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEJlZm9yZSB3ZSBoYXZlIHNlbnQgdGhlIHJlc2V0IGFjdGlvbiB0byB0aGUgc3RvcmUsIHdlIGNhbiBubyBsb25nZXJcbiAgICAvLyByZWx5IG9uIHRoZSByZXN1bHRzIHJldHVybmVkIGJ5IGluLWZsaWdodCByZXF1ZXN0cyBzaW5jZSB0aGVzZSBtYXlcbiAgICAvLyBkZXBlbmQgb24gdmFsdWVzIHRoYXQgcHJldmlvdXNseSBleGlzdGVkIGluIHRoZSBkYXRhIHBvcnRpb24gb2YgdGhlXG4gICAgLy8gc3RvcmUuIFNvLCB3ZSBjYW5jZWwgdGhlIHByb21pc2VzIGFuZCBvYnNlcnZlcnMgdGhhdCB3ZSBoYXZlIGlzc3VlZFxuICAgIC8vIHNvIGZhciBhbmQgbm90IHlldCByZXNvbHZlZCAoaW4gdGhlIGNhc2Ugb2YgcXVlcmllcykuXG4gICAgdGhpcy5jYW5jZWxQZW5kaW5nRmV0Y2hlcyhcbiAgICAgIG5ld0ludmFyaWFudEVycm9yKFxuICAgICAgICBcIlN0b3JlIHJlc2V0IHdoaWxlIHF1ZXJ5IHdhcyBpbiBmbGlnaHQgKG5vdCBjb21wbGV0ZWQgaW4gbGluayBjaGFpbilcIlxuICAgICAgKVxuICAgICk7XG5cbiAgICB0aGlzLnF1ZXJpZXMuZm9yRWFjaCgocXVlcnlJbmZvKSA9PiB7XG4gICAgICBpZiAocXVlcnlJbmZvLm9ic2VydmFibGVRdWVyeSkge1xuICAgICAgICAvLyBTZXQgbG9hZGluZyB0byB0cnVlIHNvIGxpc3RlbmVycyBkb24ndCB0cmlnZ2VyIHVubGVzcyB0aGV5IHdhbnRcbiAgICAgICAgLy8gcmVzdWx0cyB3aXRoIHBhcnRpYWwgZGF0YS5cbiAgICAgICAgcXVlcnlJbmZvLm5ldHdvcmtTdGF0dXMgPSBOZXR3b3JrU3RhdHVzLmxvYWRpbmc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeUluZm8uc3RvcCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMubXV0YXRpb25TdG9yZSkge1xuICAgICAgdGhpcy5tdXRhdGlvblN0b3JlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB9XG5cbiAgICAvLyBiZWdpbiByZW1vdmluZyBkYXRhIGZyb20gdGhlIHN0b3JlXG4gICAgcmV0dXJuIHRoaXMuY2FjaGUucmVzZXQob3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0T2JzZXJ2YWJsZVF1ZXJpZXMoXG4gICAgaW5jbHVkZTogSW50ZXJuYWxSZWZldGNoUXVlcmllc0luY2x1ZGUgPSBcImFjdGl2ZVwiXG4gICkge1xuICAgIGNvbnN0IHF1ZXJpZXMgPSBuZXcgTWFwPHN0cmluZywgT2JzZXJ2YWJsZVF1ZXJ5PGFueT4+KCk7XG4gICAgY29uc3QgcXVlcnlOYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCBudWxsPigpO1xuICAgIGNvbnN0IHF1ZXJ5TmFtZXNBbmRRdWVyeVN0cmluZ3MgPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcbiAgICBjb25zdCBsZWdhY3lRdWVyeU9wdGlvbnMgPSBuZXcgU2V0PFF1ZXJ5T3B0aW9ucz4oKTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGluY2x1ZGUpKSB7XG4gICAgICBpbmNsdWRlLmZvckVhY2goKGRlc2MpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBkZXNjID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcXVlcnlOYW1lcy5zZXQoZGVzYywgZGVzYyk7XG4gICAgICAgICAgcXVlcnlOYW1lc0FuZFF1ZXJ5U3RyaW5ncy5zZXQoZGVzYywgZmFsc2UpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRG9jdW1lbnROb2RlKGRlc2MpKSB7XG4gICAgICAgICAgY29uc3QgcXVlcnlTdHJpbmcgPSBwcmludCh0aGlzLnRyYW5zZm9ybShkZXNjKSk7XG4gICAgICAgICAgcXVlcnlOYW1lcy5zZXQocXVlcnlTdHJpbmcsIGdldE9wZXJhdGlvbk5hbWUoZGVzYykpO1xuICAgICAgICAgIHF1ZXJ5TmFtZXNBbmRRdWVyeVN0cmluZ3Muc2V0KHF1ZXJ5U3RyaW5nLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNOb25OdWxsT2JqZWN0KGRlc2MpICYmIGRlc2MucXVlcnkpIHtcbiAgICAgICAgICBsZWdhY3lRdWVyeU9wdGlvbnMuYWRkKGRlc2MpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnF1ZXJpZXMuZm9yRWFjaCgoeyBvYnNlcnZhYmxlUXVlcnk6IG9xLCBkb2N1bWVudCB9LCBxdWVyeUlkKSA9PiB7XG4gICAgICBpZiAob3EpIHtcbiAgICAgICAgaWYgKGluY2x1ZGUgPT09IFwiYWxsXCIpIHtcbiAgICAgICAgICBxdWVyaWVzLnNldChxdWVyeUlkLCBvcSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIHF1ZXJ5TmFtZSxcbiAgICAgICAgICBvcHRpb25zOiB7IGZldGNoUG9saWN5IH0sXG4gICAgICAgIH0gPSBvcTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZmV0Y2hQb2xpY3kgPT09IFwic3RhbmRieVwiIHx8XG4gICAgICAgICAgKGluY2x1ZGUgPT09IFwiYWN0aXZlXCIgJiYgIW9xLmhhc09ic2VydmVycygpKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgaW5jbHVkZSA9PT0gXCJhY3RpdmVcIiB8fFxuICAgICAgICAgIChxdWVyeU5hbWUgJiYgcXVlcnlOYW1lc0FuZFF1ZXJ5U3RyaW5ncy5oYXMocXVlcnlOYW1lKSkgfHxcbiAgICAgICAgICAoZG9jdW1lbnQgJiYgcXVlcnlOYW1lc0FuZFF1ZXJ5U3RyaW5ncy5oYXMocHJpbnQoZG9jdW1lbnQpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgcXVlcmllcy5zZXQocXVlcnlJZCwgb3EpO1xuICAgICAgICAgIGlmIChxdWVyeU5hbWUpIHF1ZXJ5TmFtZXNBbmRRdWVyeVN0cmluZ3Muc2V0KHF1ZXJ5TmFtZSwgdHJ1ZSk7XG4gICAgICAgICAgaWYgKGRvY3VtZW50KSBxdWVyeU5hbWVzQW5kUXVlcnlTdHJpbmdzLnNldChwcmludChkb2N1bWVudCksIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAobGVnYWN5UXVlcnlPcHRpb25zLnNpemUpIHtcbiAgICAgIGxlZ2FjeVF1ZXJ5T3B0aW9ucy5mb3JFYWNoKChvcHRpb25zOiBRdWVyeU9wdGlvbnMpID0+IHtcbiAgICAgICAgLy8gV2Ugd2lsbCBiZSBpc3N1aW5nIGEgZnJlc2ggbmV0d29yayByZXF1ZXN0IGZvciB0aGlzIHF1ZXJ5LCBzbyB3ZVxuICAgICAgICAvLyBwcmUtYWxsb2NhdGUgYSBuZXcgcXVlcnkgSUQgaGVyZSwgdXNpbmcgYSBzcGVjaWFsIHByZWZpeCB0byBlbmFibGVcbiAgICAgICAgLy8gY2xlYW5pbmcgdXAgdGhlc2UgdGVtcG9yYXJ5IHF1ZXJpZXMgbGF0ZXIsIGFmdGVyIGZldGNoaW5nLlxuICAgICAgICBjb25zdCBxdWVyeUlkID0gbWFrZVVuaXF1ZUlkKFwibGVnYWN5T25lVGltZVF1ZXJ5XCIpO1xuICAgICAgICBjb25zdCBxdWVyeUluZm8gPSB0aGlzLmdldE9yQ3JlYXRlUXVlcnkocXVlcnlJZCkuaW5pdCh7XG4gICAgICAgICAgZG9jdW1lbnQ6IG9wdGlvbnMucXVlcnksXG4gICAgICAgICAgdmFyaWFibGVzOiBvcHRpb25zLnZhcmlhYmxlcyxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9xID0gbmV3IE9ic2VydmFibGVRdWVyeSh7XG4gICAgICAgICAgcXVlcnlNYW5hZ2VyOiB0aGlzLFxuICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgZmV0Y2hQb2xpY3k6IFwibmV0d29yay1vbmx5XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGludmFyaWFudChvcS5xdWVyeUlkID09PSBxdWVyeUlkKTtcbiAgICAgICAgcXVlcnlJbmZvLnNldE9ic2VydmFibGVRdWVyeShvcSk7XG4gICAgICAgIHF1ZXJpZXMuc2V0KHF1ZXJ5SWQsIG9xKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChfX0RFVl9fICYmIHF1ZXJ5TmFtZXNBbmRRdWVyeVN0cmluZ3Muc2l6ZSkge1xuICAgICAgcXVlcnlOYW1lc0FuZFF1ZXJ5U3RyaW5ncy5mb3JFYWNoKChpbmNsdWRlZCwgbmFtZU9yUXVlcnlTdHJpbmcpID0+IHtcbiAgICAgICAgaWYgKCFpbmNsdWRlZCkge1xuICAgICAgICAgIGNvbnN0IHF1ZXJ5TmFtZSA9IHF1ZXJ5TmFtZXMuZ2V0KG5hbWVPclF1ZXJ5U3RyaW5nKTtcblxuICAgICAgICAgIGlmIChxdWVyeU5hbWUpIHtcbiAgICAgICAgICAgIGludmFyaWFudC53YXJuKFxuICAgICAgICAgICAgICBgVW5rbm93biBxdWVyeSBuYW1lZCBcIiVzXCIgcmVxdWVzdGVkIGluIHJlZmV0Y2hRdWVyaWVzIG9wdGlvbnMuaW5jbHVkZSBhcnJheWAsXG4gICAgICAgICAgICAgIHF1ZXJ5TmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW52YXJpYW50Lndhcm4oXG4gICAgICAgICAgICAgIGBVbmtub3duIGFub255bW91cyBxdWVyeSByZXF1ZXN0ZWQgaW4gcmVmZXRjaFF1ZXJpZXMgb3B0aW9ucy5pbmNsdWRlIGFycmF5YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBxdWVyaWVzO1xuICB9XG5cbiAgcHVibGljIHJlRmV0Y2hPYnNlcnZhYmxlUXVlcmllcyhcbiAgICBpbmNsdWRlU3RhbmRieTogYm9vbGVhbiA9IGZhbHNlXG4gICk6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8YW55PltdPiB7XG4gICAgY29uc3Qgb2JzZXJ2YWJsZVF1ZXJ5UHJvbWlzZXM6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8YW55Pj5bXSA9IFtdO1xuXG4gICAgdGhpcy5nZXRPYnNlcnZhYmxlUXVlcmllcyhpbmNsdWRlU3RhbmRieSA/IFwiYWxsXCIgOiBcImFjdGl2ZVwiKS5mb3JFYWNoKFxuICAgICAgKG9ic2VydmFibGVRdWVyeSwgcXVlcnlJZCkgPT4ge1xuICAgICAgICBjb25zdCB7IGZldGNoUG9saWN5IH0gPSBvYnNlcnZhYmxlUXVlcnkub3B0aW9ucztcbiAgICAgICAgb2JzZXJ2YWJsZVF1ZXJ5LnJlc2V0TGFzdFJlc3VsdHMoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGluY2x1ZGVTdGFuZGJ5IHx8XG4gICAgICAgICAgKGZldGNoUG9saWN5ICE9PSBcInN0YW5kYnlcIiAmJiBmZXRjaFBvbGljeSAhPT0gXCJjYWNoZS1vbmx5XCIpXG4gICAgICAgICkge1xuICAgICAgICAgIG9ic2VydmFibGVRdWVyeVByb21pc2VzLnB1c2gob2JzZXJ2YWJsZVF1ZXJ5LnJlZmV0Y2goKSk7XG4gICAgICAgIH1cbiAgICAgICAgKHRoaXMucXVlcmllcy5nZXQocXVlcnlJZCkgfHwgb2JzZXJ2YWJsZVF1ZXJ5W1wicXVlcnlJbmZvXCJdKS5zZXREaWZmKFxuICAgICAgICAgIG51bGxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5icm9hZGNhc3RRdWVyaWVzKCk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwob2JzZXJ2YWJsZVF1ZXJ5UHJvbWlzZXMpO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0R3JhcGhRTFN1YnNjcmlwdGlvbjxUID0gYW55PihcbiAgICBvcHRpb25zOiBTdWJzY3JpcHRpb25PcHRpb25zXG4gICk6IE9ic2VydmFibGU8RmV0Y2hSZXN1bHQ8VD4+IHtcbiAgICBsZXQgeyBxdWVyeSwgdmFyaWFibGVzIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IHtcbiAgICAgIGZldGNoUG9saWN5LFxuICAgICAgZXJyb3JQb2xpY3kgPSBcIm5vbmVcIixcbiAgICAgIGNvbnRleHQgPSB7fSxcbiAgICAgIGV4dGVuc2lvbnMgPSB7fSxcbiAgICB9ID0gb3B0aW9ucztcblxuICAgIHF1ZXJ5ID0gdGhpcy50cmFuc2Zvcm0ocXVlcnkpO1xuICAgIHZhcmlhYmxlcyA9IHRoaXMuZ2V0VmFyaWFibGVzKHF1ZXJ5LCB2YXJpYWJsZXMpO1xuXG4gICAgY29uc3QgbWFrZU9ic2VydmFibGUgPSAodmFyaWFibGVzOiBPcGVyYXRpb25WYXJpYWJsZXMpID0+XG4gICAgICB0aGlzLmdldE9ic2VydmFibGVGcm9tTGluazxUPihxdWVyeSwgY29udGV4dCwgdmFyaWFibGVzLCBleHRlbnNpb25zKS5tYXAoXG4gICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICBpZiAoZmV0Y2hQb2xpY3kgIT09IFwibm8tY2FjaGVcIikge1xuICAgICAgICAgICAgLy8gdGhlIHN1YnNjcmlwdGlvbiBpbnRlcmZhY2Ugc2hvdWxkIGhhbmRsZSBub3Qgc2VuZGluZyB1cyByZXN1bHRzIHdlIG5vIGxvbmdlciBzdWJzY3JpYmUgdG8uXG4gICAgICAgICAgICAvLyBYWFggSSBkb24ndCB0aGluayB3ZSBldmVyIHNlbmQgaW4gYW4gb2JqZWN0IHdpdGggZXJyb3JzLCBidXQgd2UgbWlnaHQgaW4gdGhlIGZ1dHVyZS4uLlxuICAgICAgICAgICAgaWYgKHNob3VsZFdyaXRlUmVzdWx0KHJlc3VsdCwgZXJyb3JQb2xpY3kpKSB7XG4gICAgICAgICAgICAgIHRoaXMuY2FjaGUud3JpdGUoe1xuICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0LmRhdGEsXG4gICAgICAgICAgICAgICAgZGF0YUlkOiBcIlJPT1RfU1VCU0NSSVBUSU9OXCIsXG4gICAgICAgICAgICAgICAgdmFyaWFibGVzOiB2YXJpYWJsZXMsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmJyb2FkY2FzdFF1ZXJpZXMoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBoYXNFcnJvcnMgPSBncmFwaFFMUmVzdWx0SGFzRXJyb3IocmVzdWx0KTtcbiAgICAgICAgICBjb25zdCBoYXNQcm90b2NvbEVycm9ycyA9IGdyYXBoUUxSZXN1bHRIYXNQcm90b2NvbEVycm9ycyhyZXN1bHQpO1xuICAgICAgICAgIGlmIChoYXNFcnJvcnMgfHwgaGFzUHJvdG9jb2xFcnJvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yczogQXBvbGxvRXJyb3JPcHRpb25zID0ge307XG4gICAgICAgICAgICBpZiAoaGFzRXJyb3JzKSB7XG4gICAgICAgICAgICAgIGVycm9ycy5ncmFwaFFMRXJyb3JzID0gcmVzdWx0LmVycm9ycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChoYXNQcm90b2NvbEVycm9ycykge1xuICAgICAgICAgICAgICBlcnJvcnMucHJvdG9jb2xFcnJvcnMgPSByZXN1bHQuZXh0ZW5zaW9uc1tQUk9UT0NPTF9FUlJPUlNfU1lNQk9MXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gYGVycm9yUG9saWN5YCBpcyBhIG1lY2hhbmlzbSBmb3IgaGFuZGxpbmcgR3JhcGhRTCBlcnJvcnMsIGFjY29yZGluZ1xuICAgICAgICAgICAgLy8gdG8gb3VyIGRvY3VtZW50YXRpb24sIHNvIHdlIHRocm93IHByb3RvY29sIGVycm9ycyByZWdhcmRsZXNzIG9mIHRoZVxuICAgICAgICAgICAgLy8gc2V0IGVycm9yIHBvbGljeS5cbiAgICAgICAgICAgIGlmIChlcnJvclBvbGljeSA9PT0gXCJub25lXCIgfHwgaGFzUHJvdG9jb2xFcnJvcnMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEFwb2xsb0Vycm9yKGVycm9ycyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGVycm9yUG9saWN5ID09PSBcImlnbm9yZVwiKSB7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0LmVycm9ycztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgaWYgKHRoaXMuZ2V0RG9jdW1lbnRJbmZvKHF1ZXJ5KS5oYXNDbGllbnRFeHBvcnRzKSB7XG4gICAgICBjb25zdCBvYnNlcnZhYmxlUHJvbWlzZSA9IHRoaXMubG9jYWxTdGF0ZVxuICAgICAgICAuYWRkRXhwb3J0ZWRWYXJpYWJsZXMocXVlcnksIHZhcmlhYmxlcywgY29udGV4dClcbiAgICAgICAgLnRoZW4obWFrZU9ic2VydmFibGUpO1xuXG4gICAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8RmV0Y2hSZXN1bHQ8VD4+KChvYnNlcnZlcikgPT4ge1xuICAgICAgICBsZXQgc3ViOiBPYnNlcnZhYmxlU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIG9ic2VydmFibGVQcm9taXNlLnRoZW4oXG4gICAgICAgICAgKG9ic2VydmFibGUpID0+IChzdWIgPSBvYnNlcnZhYmxlLnN1YnNjcmliZShvYnNlcnZlcikpLFxuICAgICAgICAgIG9ic2VydmVyLmVycm9yXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiAoKSA9PiBzdWIgJiYgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFrZU9ic2VydmFibGUodmFyaWFibGVzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdG9wUXVlcnkocXVlcnlJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zdG9wUXVlcnlOb0Jyb2FkY2FzdChxdWVyeUlkKTtcbiAgICB0aGlzLmJyb2FkY2FzdFF1ZXJpZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFF1ZXJ5Tm9Ccm9hZGNhc3QocXVlcnlJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zdG9wUXVlcnlJblN0b3JlTm9Ccm9hZGNhc3QocXVlcnlJZCk7XG4gICAgdGhpcy5yZW1vdmVRdWVyeShxdWVyeUlkKTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVRdWVyeShxdWVyeUlkOiBzdHJpbmcpIHtcbiAgICAvLyB0ZWFyZG93biBhbGwgbGlua3NcbiAgICAvLyBCb3RoIGBRdWVyeU1hbmFnZXIuZmV0Y2hSZXF1ZXN0YCBhbmQgYFF1ZXJ5TWFuYWdlci5xdWVyeWAgY3JlYXRlIHNlcGFyYXRlIHByb21pc2VzXG4gICAgLy8gdGhhdCBlYWNoIGFkZCB0aGVpciByZWplY3QgZnVuY3Rpb25zIHRvIGZldGNoQ2FuY2VsRm5zLlxuICAgIC8vIEEgcXVlcnkgY3JlYXRlZCB3aXRoIGBRdWVyeU1hbmFnZXIucXVlcnkoKWAgY291bGQgdHJpZ2dlciBhIGBRdWVyeU1hbmFnZXIuZmV0Y2hSZXF1ZXN0YC5cbiAgICAvLyBUaGUgc2FtZSBxdWVyeUlkIGNvdWxkIGhhdmUgdHdvIHJlamVjdGlvbiBmbnMgZm9yIHR3byBwcm9taXNlc1xuICAgIHRoaXMuZmV0Y2hDYW5jZWxGbnMuZGVsZXRlKHF1ZXJ5SWQpO1xuICAgIGlmICh0aGlzLnF1ZXJpZXMuaGFzKHF1ZXJ5SWQpKSB7XG4gICAgICB0aGlzLnF1ZXJpZXMuZ2V0KHF1ZXJ5SWQpPy5zdG9wKCk7XG4gICAgICB0aGlzLnF1ZXJpZXMuZGVsZXRlKHF1ZXJ5SWQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBicm9hZGNhc3RRdWVyaWVzKCkge1xuICAgIGlmICh0aGlzLm9uQnJvYWRjYXN0KSB0aGlzLm9uQnJvYWRjYXN0KCk7XG4gICAgdGhpcy5xdWVyaWVzLmZvckVhY2goKGluZm8pID0+IGluZm8ub2JzZXJ2YWJsZVF1ZXJ5Py5bXCJub3RpZnlcIl0oKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0TG9jYWxTdGF0ZSgpOiBMb2NhbFN0YXRlPFRTdG9yZT4ge1xuICAgIHJldHVybiB0aGlzLmxvY2FsU3RhdGU7XG4gIH1cblxuICAvLyBVc2UgcHJvdGVjdGVkIGluc3RlYWQgb2YgcHJpdmF0ZSBmaWVsZCBzb1xuICAvLyBAYXBvbGxvL2V4cGVyaW1lbnRhbC1uZXh0anMtYXBwLXN1cHBvcnQgY2FuIGFjY2VzcyB0eXBlIGluZm8uXG4gIHByb3RlY3RlZCBpbkZsaWdodExpbmtPYnNlcnZhYmxlcyA9IG5ldyBUcmllPHtcbiAgICBvYnNlcnZhYmxlPzogT2JzZXJ2YWJsZTxGZXRjaFJlc3VsdDxhbnk+PjtcbiAgfT4oZmFsc2UpO1xuXG4gIHByaXZhdGUgZ2V0T2JzZXJ2YWJsZUZyb21MaW5rPFQgPSBhbnk+KFxuICAgIHF1ZXJ5OiBEb2N1bWVudE5vZGUsXG4gICAgY29udGV4dDogYW55LFxuICAgIHZhcmlhYmxlcz86IE9wZXJhdGlvblZhcmlhYmxlcyxcbiAgICBleHRlbnNpb25zPzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAvLyBQcmVmZXIgY29udGV4dC5xdWVyeURlZHVwbGljYXRpb24gaWYgc3BlY2lmaWVkLlxuICAgIGRlZHVwbGljYXRpb246IGJvb2xlYW4gPSBjb250ZXh0Py5xdWVyeURlZHVwbGljYXRpb24gPz9cbiAgICAgIHRoaXMucXVlcnlEZWR1cGxpY2F0aW9uXG4gICk6IE9ic2VydmFibGU8RmV0Y2hSZXN1bHQ8VD4+IHtcbiAgICBsZXQgb2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxGZXRjaFJlc3VsdDxUPj4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCB7IHNlcnZlclF1ZXJ5LCBjbGllbnRRdWVyeSB9ID0gdGhpcy5nZXREb2N1bWVudEluZm8ocXVlcnkpO1xuICAgIGlmIChzZXJ2ZXJRdWVyeSkge1xuICAgICAgY29uc3QgeyBpbkZsaWdodExpbmtPYnNlcnZhYmxlcywgbGluayB9ID0gdGhpcztcblxuICAgICAgY29uc3Qgb3BlcmF0aW9uID0ge1xuICAgICAgICBxdWVyeTogc2VydmVyUXVlcnksXG4gICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgb3BlcmF0aW9uTmFtZTogZ2V0T3BlcmF0aW9uTmFtZShzZXJ2ZXJRdWVyeSkgfHwgdm9pZCAwLFxuICAgICAgICBjb250ZXh0OiB0aGlzLnByZXBhcmVDb250ZXh0KHtcbiAgICAgICAgICAuLi5jb250ZXh0LFxuICAgICAgICAgIGZvcmNlRmV0Y2g6ICFkZWR1cGxpY2F0aW9uLFxuICAgICAgICB9KSxcbiAgICAgICAgZXh0ZW5zaW9ucyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnRleHQgPSBvcGVyYXRpb24uY29udGV4dDtcblxuICAgICAgaWYgKGRlZHVwbGljYXRpb24pIHtcbiAgICAgICAgY29uc3QgcHJpbnRlZFNlcnZlclF1ZXJ5ID0gcHJpbnQoc2VydmVyUXVlcnkpO1xuICAgICAgICBjb25zdCB2YXJKc29uID0gY2Fub25pY2FsU3RyaW5naWZ5KHZhcmlhYmxlcyk7XG5cbiAgICAgICAgY29uc3QgZW50cnkgPSBpbkZsaWdodExpbmtPYnNlcnZhYmxlcy5sb29rdXAoXG4gICAgICAgICAgcHJpbnRlZFNlcnZlclF1ZXJ5LFxuICAgICAgICAgIHZhckpzb25cbiAgICAgICAgKTtcblxuICAgICAgICBvYnNlcnZhYmxlID0gZW50cnkub2JzZXJ2YWJsZTtcbiAgICAgICAgaWYgKCFvYnNlcnZhYmxlKSB7XG4gICAgICAgICAgY29uc3QgY29uY2FzdCA9IG5ldyBDb25jYXN0KFtcbiAgICAgICAgICAgIGV4ZWN1dGUobGluaywgb3BlcmF0aW9uKSBhcyBPYnNlcnZhYmxlPEZldGNoUmVzdWx0PFQ+PixcbiAgICAgICAgICBdKTtcbiAgICAgICAgICBvYnNlcnZhYmxlID0gZW50cnkub2JzZXJ2YWJsZSA9IGNvbmNhc3Q7XG5cbiAgICAgICAgICBjb25jYXN0LmJlZm9yZU5leHQoZnVuY3Rpb24gY2IobWV0aG9kLCBhcmc6IEZldGNoUmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAobWV0aG9kID09PSBcIm5leHRcIiAmJiBcImhhc05leHRcIiBpbiBhcmcgJiYgYXJnLmhhc05leHQpIHtcbiAgICAgICAgICAgICAgY29uY2FzdC5iZWZvcmVOZXh0KGNiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGluRmxpZ2h0TGlua09ic2VydmFibGVzLnJlbW92ZShwcmludGVkU2VydmVyUXVlcnksIHZhckpzb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYnNlcnZhYmxlID0gbmV3IENvbmNhc3QoW1xuICAgICAgICAgIGV4ZWN1dGUobGluaywgb3BlcmF0aW9uKSBhcyBPYnNlcnZhYmxlPEZldGNoUmVzdWx0PFQ+PixcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ic2VydmFibGUgPSBuZXcgQ29uY2FzdChbT2JzZXJ2YWJsZS5vZih7IGRhdGE6IHt9IH0gYXMgRmV0Y2hSZXN1bHQ8VD4pXSk7XG4gICAgICBjb250ZXh0ID0gdGhpcy5wcmVwYXJlQ29udGV4dChjb250ZXh0KTtcbiAgICB9XG5cbiAgICBpZiAoY2xpZW50UXVlcnkpIHtcbiAgICAgIG9ic2VydmFibGUgPSBhc3luY01hcChvYnNlcnZhYmxlLCAocmVzdWx0KSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsU3RhdGUucnVuUmVzb2x2ZXJzKHtcbiAgICAgICAgICBkb2N1bWVudDogY2xpZW50UXVlcnksXG4gICAgICAgICAgcmVtb3RlUmVzdWx0OiByZXN1bHQsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICB2YXJpYWJsZXMsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9ic2VydmFibGU7XG4gIH1cblxuICBwcml2YXRlIGdldFJlc3VsdHNGcm9tTGluazxURGF0YSwgVFZhcnMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXM+KFxuICAgIHF1ZXJ5SW5mbzogUXVlcnlJbmZvLFxuICAgIGNhY2hlV3JpdGVCZWhhdmlvcjogQ2FjaGVXcml0ZUJlaGF2aW9yLFxuICAgIG9wdGlvbnM6IFBpY2s8XG4gICAgICBXYXRjaFF1ZXJ5T3B0aW9uczxUVmFycywgVERhdGE+LFxuICAgICAgXCJxdWVyeVwiIHwgXCJ2YXJpYWJsZXNcIiB8IFwiY29udGV4dFwiIHwgXCJmZXRjaFBvbGljeVwiIHwgXCJlcnJvclBvbGljeVwiXG4gICAgPlxuICApOiBPYnNlcnZhYmxlPEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPj4ge1xuICAgIGNvbnN0IHJlcXVlc3RJZCA9IChxdWVyeUluZm8ubGFzdFJlcXVlc3RJZCA9IHRoaXMuZ2VuZXJhdGVSZXF1ZXN0SWQoKSk7XG5cbiAgICAvLyBQZXJmb3JtaW5nIHRyYW5zZm9ybUZvckxpbmsgaGVyZSBnaXZlcyB0aGlzLmNhY2hlIGEgY2hhbmNlIHRvIGZpbGwgaW5cbiAgICAvLyBtaXNzaW5nIGZyYWdtZW50IGRlZmluaXRpb25zIChmb3IgZXhhbXBsZSkgYmVmb3JlIHNlbmRpbmcgdGhpcyBkb2N1bWVudFxuICAgIC8vIHRocm91Z2ggdGhlIGxpbmsgY2hhaW4uXG4gICAgY29uc3QgbGlua0RvY3VtZW50ID0gdGhpcy5jYWNoZS50cmFuc2Zvcm1Gb3JMaW5rKG9wdGlvbnMucXVlcnkpO1xuXG4gICAgcmV0dXJuIGFzeW5jTWFwKFxuICAgICAgdGhpcy5nZXRPYnNlcnZhYmxlRnJvbUxpbmsoXG4gICAgICAgIGxpbmtEb2N1bWVudCxcbiAgICAgICAgb3B0aW9ucy5jb250ZXh0LFxuICAgICAgICBvcHRpb25zLnZhcmlhYmxlc1xuICAgICAgKSxcblxuICAgICAgKHJlc3VsdCkgPT4ge1xuICAgICAgICBjb25zdCBncmFwaFFMRXJyb3JzID0gZ2V0R3JhcGhRTEVycm9yc0Zyb21SZXN1bHQocmVzdWx0KTtcbiAgICAgICAgY29uc3QgaGFzRXJyb3JzID0gZ3JhcGhRTEVycm9ycy5sZW5ndGggPiAwO1xuICAgICAgICBjb25zdCB7IGVycm9yUG9saWN5IH0gPSBvcHRpb25zO1xuXG4gICAgICAgIC8vIElmIHdlIGludGVycnVwdGVkIHRoaXMgcmVxdWVzdCBieSBjYWxsaW5nIGdldFJlc3VsdHNGcm9tTGluayBhZ2FpblxuICAgICAgICAvLyB3aXRoIHRoZSBzYW1lIFF1ZXJ5SW5mbyBvYmplY3QsIHdlIGlnbm9yZSB0aGUgb2xkIHJlc3VsdHMuXG4gICAgICAgIGlmIChyZXF1ZXN0SWQgPj0gcXVlcnlJbmZvLmxhc3RSZXF1ZXN0SWQpIHtcbiAgICAgICAgICBpZiAoaGFzRXJyb3JzICYmIGVycm9yUG9saWN5ID09PSBcIm5vbmVcIikge1xuICAgICAgICAgICAgLy8gVGhyb3dpbmcgaGVyZSBlZmZlY3RpdmVseSBjYWxscyBvYnNlcnZlci5lcnJvci5cbiAgICAgICAgICAgIHRocm93IHF1ZXJ5SW5mby5tYXJrRXJyb3IoXG4gICAgICAgICAgICAgIG5ldyBBcG9sbG9FcnJvcih7XG4gICAgICAgICAgICAgICAgZ3JhcGhRTEVycm9ycyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFVzZSBsaW5rRG9jdW1lbnQgcmF0aGVyIHRoYW4gcXVlcnlJbmZvLmRvY3VtZW50IHNvIHRoZVxuICAgICAgICAgIC8vIG9wZXJhdGlvbi9mcmFnbWVudHMgdXNlZCB0byB3cml0ZSB0aGUgcmVzdWx0IGFyZSB0aGUgc2FtZSBhcyB0aGVcbiAgICAgICAgICAvLyBvbmVzIHVzZWQgdG8gb2J0YWluIGl0IGZyb20gdGhlIGxpbmsuXG4gICAgICAgICAgcXVlcnlJbmZvLm1hcmtSZXN1bHQoXG4gICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICBsaW5rRG9jdW1lbnQsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgY2FjaGVXcml0ZUJlaGF2aW9yXG4gICAgICAgICAgKTtcbiAgICAgICAgICBxdWVyeUluZm8ubWFya1JlYWR5KCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcXI6IEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPiA9IHtcbiAgICAgICAgICBkYXRhOiByZXN1bHQuZGF0YSxcbiAgICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICBuZXR3b3JrU3RhdHVzOiBOZXR3b3JrU3RhdHVzLnJlYWR5LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEluIHRoZSBjYXNlIHdlIHN0YXJ0IG11bHRpcGxlIG5ldHdvcmsgcmVxdWVzdHMgc2ltdWxhdGVub3VzbHksIHdlXG4gICAgICAgIC8vIHdhbnQgdG8gZW5zdXJlIHdlIHByb3Blcmx5IHNldCBgZGF0YWAgaWYgd2UncmUgcmVwb3J0aW5nIG9uIGFuIG9sZFxuICAgICAgICAvLyByZXN1bHQgd2hpY2ggd2lsbCBub3QgYmUgY2F1Z2h0IGJ5IHRoZSBjb25kaXRpb25hbCBhYm92ZSB0aGF0IGVuZHMgdXBcbiAgICAgICAgLy8gdGhyb3dpbmcgdGhlIG1hcmtFcnJvciByZXN1bHQuXG4gICAgICAgIGlmIChoYXNFcnJvcnMgJiYgZXJyb3JQb2xpY3kgPT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgYXFyLmRhdGEgPSB2b2lkIDAgYXMgVERhdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzRXJyb3JzICYmIGVycm9yUG9saWN5ICE9PSBcImlnbm9yZVwiKSB7XG4gICAgICAgICAgYXFyLmVycm9ycyA9IGdyYXBoUUxFcnJvcnM7XG4gICAgICAgICAgYXFyLm5ldHdvcmtTdGF0dXMgPSBOZXR3b3JrU3RhdHVzLmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFxcjtcbiAgICAgIH0sXG5cbiAgICAgIChuZXR3b3JrRXJyb3IpID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPVxuICAgICAgICAgIGlzQXBvbGxvRXJyb3IobmV0d29ya0Vycm9yKSA/IG5ldHdvcmtFcnJvciA6IChcbiAgICAgICAgICAgIG5ldyBBcG9sbG9FcnJvcih7IG5ldHdvcmtFcnJvciB9KVxuICAgICAgICAgICk7XG5cbiAgICAgICAgLy8gQXZvaWQgc3RvcmluZyBlcnJvcnMgZnJvbSBvbGRlciBpbnRlcnJ1cHRlZCBxdWVyaWVzLlxuICAgICAgICBpZiAocmVxdWVzdElkID49IHF1ZXJ5SW5mby5sYXN0UmVxdWVzdElkKSB7XG4gICAgICAgICAgcXVlcnlJbmZvLm1hcmtFcnJvcihlcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaENvbmNhc3RXaXRoSW5mbzxURGF0YSwgVFZhcnMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXM+KFxuICAgIHF1ZXJ5SW5mbzogUXVlcnlJbmZvLFxuICAgIG9wdGlvbnM6IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJzLCBURGF0YT4sXG4gICAgLy8gVGhlIGluaXRpYWwgbmV0d29ya1N0YXR1cyBmb3IgdGhpcyBmZXRjaCwgbW9zdCBvZnRlblxuICAgIC8vIE5ldHdvcmtTdGF0dXMubG9hZGluZywgYnV0IGFsc28gcG9zc2libHkgZmV0Y2hNb3JlLCBwb2xsLCByZWZldGNoLFxuICAgIC8vIG9yIHNldFZhcmlhYmxlcy5cbiAgICBuZXR3b3JrU3RhdHVzID0gTmV0d29ya1N0YXR1cy5sb2FkaW5nLFxuICAgIHF1ZXJ5ID0gb3B0aW9ucy5xdWVyeVxuICApOiBDb25jYXN0QW5kSW5mbzxURGF0YT4ge1xuICAgIGNvbnN0IHZhcmlhYmxlcyA9IHRoaXMuZ2V0VmFyaWFibGVzKHF1ZXJ5LCBvcHRpb25zLnZhcmlhYmxlcykgYXMgVFZhcnM7XG5cbiAgICBjb25zdCBkZWZhdWx0cyA9IHRoaXMuZGVmYXVsdE9wdGlvbnMud2F0Y2hRdWVyeTtcbiAgICBsZXQge1xuICAgICAgZmV0Y2hQb2xpY3kgPSAoZGVmYXVsdHMgJiYgZGVmYXVsdHMuZmV0Y2hQb2xpY3kpIHx8IFwiY2FjaGUtZmlyc3RcIixcbiAgICAgIGVycm9yUG9saWN5ID0gKGRlZmF1bHRzICYmIGRlZmF1bHRzLmVycm9yUG9saWN5KSB8fCBcIm5vbmVcIixcbiAgICAgIHJldHVyblBhcnRpYWxEYXRhID0gZmFsc2UsXG4gICAgICBub3RpZnlPbk5ldHdvcmtTdGF0dXNDaGFuZ2UgPSBmYWxzZSxcbiAgICAgIGNvbnRleHQgPSB7fSxcbiAgICB9ID0gb3B0aW9ucztcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7XG4gICAgICBxdWVyeSxcbiAgICAgIHZhcmlhYmxlcyxcbiAgICAgIGZldGNoUG9saWN5LFxuICAgICAgZXJyb3JQb2xpY3ksXG4gICAgICByZXR1cm5QYXJ0aWFsRGF0YSxcbiAgICAgIG5vdGlmeU9uTmV0d29ya1N0YXR1c0NoYW5nZSxcbiAgICAgIGNvbnRleHQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBmcm9tVmFyaWFibGVzID0gKHZhcmlhYmxlczogVFZhcnMpID0+IHtcbiAgICAgIC8vIFNpbmNlIG5vcm1hbGl6ZWQgaXMgYWx3YXlzIGEgZnJlc2ggY29weSBvZiBvcHRpb25zLCBpdCdzIHNhZmUgdG9cbiAgICAgIC8vIG1vZGlmeSBpdHMgcHJvcGVydGllcyBoZXJlLCByYXRoZXIgdGhhbiBjcmVhdGluZyB5ZXQgYW5vdGhlciBuZXdcbiAgICAgIC8vIFdhdGNoUXVlcnlPcHRpb25zIG9iamVjdC5cbiAgICAgIG5vcm1hbGl6ZWQudmFyaWFibGVzID0gdmFyaWFibGVzO1xuXG4gICAgICBjb25zdCBzb3VyY2VzV2l0aEluZm8gPSB0aGlzLmZldGNoUXVlcnlCeVBvbGljeTxURGF0YSwgVFZhcnM+KFxuICAgICAgICBxdWVyeUluZm8sXG4gICAgICAgIG5vcm1hbGl6ZWQsXG4gICAgICAgIG5ldHdvcmtTdGF0dXNcbiAgICAgICk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgLy8gSWYgd2UncmUgaW4gc3RhbmRieSwgcG9zdHBvbmUgYWR2YW5jaW5nIG9wdGlvbnMuZmV0Y2hQb2xpY3kgdXNpbmdcbiAgICAgICAgLy8gYXBwbHlOZXh0RmV0Y2hQb2xpY3kuXG4gICAgICAgIG5vcm1hbGl6ZWQuZmV0Y2hQb2xpY3kgIT09IFwic3RhbmRieVwiICYmXG4gICAgICAgIC8vIFRoZSBcInN0YW5kYnlcIiBwb2xpY3kgY3VycmVudGx5IHJldHVybnMgW10gZnJvbSBmZXRjaFF1ZXJ5QnlQb2xpY3ksIHNvXG4gICAgICAgIC8vIHRoaXMgaXMgYW5vdGhlciB3YXkgdG8gZGV0ZWN0IHdoZW4gbm90aGluZyB3YXMgZG9uZS9mZXRjaGVkLlxuICAgICAgICBzb3VyY2VzV2l0aEluZm8uc291cmNlcy5sZW5ndGggPiAwICYmXG4gICAgICAgIHF1ZXJ5SW5mby5vYnNlcnZhYmxlUXVlcnlcbiAgICAgICkge1xuICAgICAgICBxdWVyeUluZm8ub2JzZXJ2YWJsZVF1ZXJ5W1wiYXBwbHlOZXh0RmV0Y2hQb2xpY3lcIl0oXG4gICAgICAgICAgXCJhZnRlci1mZXRjaFwiLFxuICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvdXJjZXNXaXRoSW5mbztcbiAgICB9O1xuXG4gICAgLy8gVGhpcyBjYW5jZWwgZnVuY3Rpb24gbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSB0aGUgY29uY2FzdCBpcyBjcmVhdGVkLFxuICAgIC8vIGluIGNhc2UgY29uY2FzdCBjcmVhdGlvbiBzeW5jaHJvbm91c2x5IGNhbmNlbHMgdGhlIHJlcXVlc3QuXG4gICAgY29uc3QgY2xlYW51cENhbmNlbEZuID0gKCkgPT4gdGhpcy5mZXRjaENhbmNlbEZucy5kZWxldGUocXVlcnlJbmZvLnF1ZXJ5SWQpO1xuICAgIHRoaXMuZmV0Y2hDYW5jZWxGbnMuc2V0KHF1ZXJ5SW5mby5xdWVyeUlkLCAocmVhc29uKSA9PiB7XG4gICAgICBjbGVhbnVwQ2FuY2VsRm4oKTtcbiAgICAgIC8vIFRoaXMgZGVsYXkgZW5zdXJlcyB0aGUgY29uY2FzdCB2YXJpYWJsZSBoYXMgYmVlbiBpbml0aWFsaXplZC5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gY29uY2FzdC5jYW5jZWwocmVhc29uKSk7XG4gICAgfSk7XG5cbiAgICBsZXQgY29uY2FzdDogQ29uY2FzdDxBcG9sbG9RdWVyeVJlc3VsdDxURGF0YT4+LFxuICAgICAgY29udGFpbnNEYXRhRnJvbUxpbms6IGJvb2xlYW47XG4gICAgLy8gSWYgdGhlIHF1ZXJ5IGhhcyBAZXhwb3J0KGFzOiAuLi4pIGRpcmVjdGl2ZXMsIHRoZW4gd2UgbmVlZCB0b1xuICAgIC8vIHByb2Nlc3MgdGhvc2UgZGlyZWN0aXZlcyBhc3luY2hyb25vdXNseS4gV2hlbiB0aGVyZSBhcmUgbm9cbiAgICAvLyBAZXhwb3J0IGRpcmVjdGl2ZXMgKHRoZSBjb21tb24gY2FzZSksIHdlIGRlbGliZXJhdGVseSBhdm9pZFxuICAgIC8vIHdyYXBwaW5nIHRoZSByZXN1bHQgb2YgdGhpcy5mZXRjaFF1ZXJ5QnlQb2xpY3kgaW4gYSBQcm9taXNlLFxuICAgIC8vIHNpbmNlIHRoZSB0aW1pbmcgb2YgcmVzdWx0IGRlbGl2ZXJ5IGlzICh1bmZvcnR1bmF0ZWx5KSBpbXBvcnRhbnRcbiAgICAvLyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuIFRPRE8gVGhpcyBjb2RlIGNvdWxkIGJlIHNpbXBsZXIgaWZcbiAgICAvLyB3ZSBkZXByZWNhdGVkIGFuZCByZW1vdmVkIExvY2FsU3RhdGUuXG4gICAgaWYgKHRoaXMuZ2V0RG9jdW1lbnRJbmZvKG5vcm1hbGl6ZWQucXVlcnkpLmhhc0NsaWVudEV4cG9ydHMpIHtcbiAgICAgIGNvbmNhc3QgPSBuZXcgQ29uY2FzdChcbiAgICAgICAgdGhpcy5sb2NhbFN0YXRlXG4gICAgICAgICAgLmFkZEV4cG9ydGVkVmFyaWFibGVzKFxuICAgICAgICAgICAgbm9ybWFsaXplZC5xdWVyeSxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWQudmFyaWFibGVzLFxuICAgICAgICAgICAgbm9ybWFsaXplZC5jb250ZXh0XG4gICAgICAgICAgKVxuICAgICAgICAgIC50aGVuKGZyb21WYXJpYWJsZXMpXG4gICAgICAgICAgLnRoZW4oKHNvdXJjZXNXaXRoSW5mbykgPT4gc291cmNlc1dpdGhJbmZvLnNvdXJjZXMpXG4gICAgICApO1xuICAgICAgLy8gdGhlcmUgaXMganVzdCBubyB3YXkgd2UgY2FuIHN5bmNocm9ub3VzbHkgZ2V0IHRoZSAqcmlnaHQqIHZhbHVlIGhlcmUsXG4gICAgICAvLyBzbyB3ZSB3aWxsIGFzc3VtZSBgdHJ1ZWAsIHdoaWNoIGlzIHRoZSBiZWhhdmlvdXIgYmVmb3JlIHRoZSBidWcgZml4IGluXG4gICAgICAvLyAjMTA1OTcuIFRoaXMgbWVhbnMgdGhhdCBidWcgaXMgbm90IGZpeGVkIGluIHRoYXQgY2FzZSwgYW5kIGlzIHByb2JhYmx5XG4gICAgICAvLyB1bi1maXhhYmxlIHdpdGggcmVhc29uYWJsZSBlZmZvcnQgZm9yIHRoZSBlZGdlIGNhc2Ugb2YgQGV4cG9ydCBhc1xuICAgICAgLy8gZGlyZWN0aXZlcy5cbiAgICAgIGNvbnRhaW5zRGF0YUZyb21MaW5rID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc291cmNlc1dpdGhJbmZvID0gZnJvbVZhcmlhYmxlcyhub3JtYWxpemVkLnZhcmlhYmxlcyk7XG4gICAgICBjb250YWluc0RhdGFGcm9tTGluayA9IHNvdXJjZXNXaXRoSW5mby5mcm9tTGluaztcbiAgICAgIGNvbmNhc3QgPSBuZXcgQ29uY2FzdChzb3VyY2VzV2l0aEluZm8uc291cmNlcyk7XG4gICAgfVxuXG4gICAgY29uY2FzdC5wcm9taXNlLnRoZW4oY2xlYW51cENhbmNlbEZuLCBjbGVhbnVwQ2FuY2VsRm4pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmNhc3QsXG4gICAgICBmcm9tTGluazogY29udGFpbnNEYXRhRnJvbUxpbmssXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyByZWZldGNoUXVlcmllczxUUmVzdWx0Pih7XG4gICAgdXBkYXRlQ2FjaGUsXG4gICAgaW5jbHVkZSxcbiAgICBvcHRpbWlzdGljID0gZmFsc2UsXG4gICAgcmVtb3ZlT3B0aW1pc3RpYyA9IG9wdGltaXN0aWMgPyBtYWtlVW5pcXVlSWQoXCJyZWZldGNoUXVlcmllc1wiKSA6IHZvaWQgMCxcbiAgICBvblF1ZXJ5VXBkYXRlZCxcbiAgfTogSW50ZXJuYWxSZWZldGNoUXVlcmllc09wdGlvbnM8XG4gICAgQXBvbGxvQ2FjaGU8VFN0b3JlPixcbiAgICBUUmVzdWx0XG4gID4pOiBJbnRlcm5hbFJlZmV0Y2hRdWVyaWVzTWFwPFRSZXN1bHQ+IHtcbiAgICBjb25zdCBpbmNsdWRlZFF1ZXJpZXNCeUlkID0gbmV3IE1hcDxcbiAgICAgIHN0cmluZyxcbiAgICAgIHtcbiAgICAgICAgb3E6IE9ic2VydmFibGVRdWVyeTxhbnk+O1xuICAgICAgICBsYXN0RGlmZj86IENhY2hlLkRpZmZSZXN1bHQ8YW55PjtcbiAgICAgICAgZGlmZj86IENhY2hlLkRpZmZSZXN1bHQ8YW55PjtcbiAgICAgIH1cbiAgICA+KCk7XG5cbiAgICBpZiAoaW5jbHVkZSkge1xuICAgICAgdGhpcy5nZXRPYnNlcnZhYmxlUXVlcmllcyhpbmNsdWRlKS5mb3JFYWNoKChvcSwgcXVlcnlJZCkgPT4ge1xuICAgICAgICBpbmNsdWRlZFF1ZXJpZXNCeUlkLnNldChxdWVyeUlkLCB7XG4gICAgICAgICAgb3EsXG4gICAgICAgICAgbGFzdERpZmY6ICh0aGlzLnF1ZXJpZXMuZ2V0KHF1ZXJ5SWQpIHx8IG9xW1wicXVlcnlJbmZvXCJdKS5nZXREaWZmKCksXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0czogSW50ZXJuYWxSZWZldGNoUXVlcmllc01hcDxUUmVzdWx0PiA9IG5ldyBNYXAoKTtcblxuICAgIGlmICh1cGRhdGVDYWNoZSkge1xuICAgICAgdGhpcy5jYWNoZS5iYXRjaCh7XG4gICAgICAgIHVwZGF0ZTogdXBkYXRlQ2FjaGUsXG5cbiAgICAgICAgLy8gU2luY2UgeW91IGNhbiBwZXJmb3JtIGFueSBjb21iaW5hdGlvbiBvZiBjYWNoZSByZWFkcyBhbmQvb3Igd3JpdGVzIGluXG4gICAgICAgIC8vIHRoZSBjYWNoZS5iYXRjaCB1cGRhdGUgZnVuY3Rpb24sIGl0cyBvcHRpbWlzdGljIG9wdGlvbiBjYW4gYmUgZWl0aGVyXG4gICAgICAgIC8vIGEgYm9vbGVhbiBvciBhIHN0cmluZywgcmVwcmVzZW50aW5nIHRocmVlIGRpc3RpbmN0IG1vZGVzIG9mXG4gICAgICAgIC8vIG9wZXJhdGlvbjpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gKiBmYWxzZTogcmVhZC93cml0ZSBvbmx5IHRoZSByb290IGxheWVyXG4gICAgICAgIC8vICogdHJ1ZTogcmVhZC93cml0ZSB0aGUgdG9wbW9zdCBsYXllclxuICAgICAgICAvLyAqIHN0cmluZzogcmVhZC93cml0ZSBhIGZyZXNoIG9wdGltaXN0aWMgbGF5ZXIgd2l0aCB0aGF0IElEIHN0cmluZ1xuICAgICAgICAvL1xuICAgICAgICAvLyBXaGVuIHR5cGVvZiBvcHRpbWlzdGljID09PSBcInN0cmluZ1wiLCBhIG5ldyBvcHRpbWlzdGljIGxheWVyIHdpbGwgYmVcbiAgICAgICAgLy8gdGVtcG9yYXJpbHkgY3JlYXRlZCB3aXRoaW4gY2FjaGUuYmF0Y2ggd2l0aCB0aGF0IHN0cmluZyBhcyBpdHMgSUQuIElmXG4gICAgICAgIC8vIHdlIHRoZW4gcGFzcyB0aGF0IHNhbWUgc3RyaW5nIGFzIHRoZSByZW1vdmVPcHRpbWlzdGljIG9wdGlvbiwgd2UgY2FuXG4gICAgICAgIC8vIG1ha2UgY2FjaGUuYmF0Y2ggaW1tZWRpYXRlbHkgcmVtb3ZlIHRoZSBvcHRpbWlzdGljIGxheWVyIGFmdGVyXG4gICAgICAgIC8vIHJ1bm5pbmcgdGhlIHVwZGF0ZUNhY2hlIGZ1bmN0aW9uLCB0cmlnZ2VyaW5nIG9ubHkgb25lIGJyb2FkY2FzdC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSG93ZXZlciwgdGhlIHJlZmV0Y2hRdWVyaWVzIG1ldGhvZCBhY2NlcHRzIG9ubHkgdHJ1ZSBvciBmYWxzZSBmb3IgaXRzXG4gICAgICAgIC8vIG9wdGltaXN0aWMgb3B0aW9uIChub3Qgc3RyaW5nKS4gV2UgaW50ZXJwcmV0IHRydWUgdG8gbWVhbiBhIHRlbXBvcmFyeVxuICAgICAgICAvLyBvcHRpbWlzdGljIGxheWVyIHNob3VsZCBiZSBjcmVhdGVkLCB0byBhbGxvdyBlZmZpY2llbnRseSByb2xsaW5nIGJhY2tcbiAgICAgICAgLy8gdGhlIGVmZmVjdCBvZiB0aGUgdXBkYXRlQ2FjaGUgZnVuY3Rpb24sIHdoaWNoIGludm9sdmVzIHBhc3NpbmcgYVxuICAgICAgICAvLyBzdHJpbmcgaW5zdGVhZCBvZiB0cnVlIGFzIHRoZSBvcHRpbWlzdGljIG9wdGlvbiB0byBjYWNoZS5iYXRjaCwgd2hlblxuICAgICAgICAvLyByZWZldGNoUXVlcmllcyByZWNlaXZlcyBvcHRpbWlzdGljOiB0cnVlLlxuICAgICAgICAvL1xuICAgICAgICAvLyBJbiBvdGhlciB3b3Jkcywgd2UgYXJlIGRlbGliZXJhdGVseSBub3Qgc3VwcG9ydGluZyB0aGUgdXNlIGNhc2Ugb2ZcbiAgICAgICAgLy8gd3JpdGluZyB0byBhbiAqZXhpc3RpbmcqIG9wdGltaXN0aWMgbGF5ZXIgKHVzaW5nIHRoZSByZWZldGNoUXVlcmllc1xuICAgICAgICAvLyB1cGRhdGVDYWNoZSBmdW5jdGlvbiksIHNpbmNlIHRoYXQgd291bGQgcG90ZW50aWFsbHkgaW50ZXJmZXJlIHdpdGhcbiAgICAgICAgLy8gb3RoZXIgb3B0aW1pc3RpYyB1cGRhdGVzIGluIHByb2dyZXNzLiBJbnN0ZWFkLCB5b3UgY2FuIHJlYWQvd3JpdGVcbiAgICAgICAgLy8gb25seSB0aGUgcm9vdCBsYXllciBieSBwYXNzaW5nIG9wdGltaXN0aWM6IGZhbHNlIHRvIHJlZmV0Y2hRdWVyaWVzLFxuICAgICAgICAvLyBvciB5b3UgY2FuIHJlYWQvd3JpdGUgYSBicmFuZCBuZXcgb3B0aW1pc3RpYyBsYXllciB0aGF0IHdpbGwgYmVcbiAgICAgICAgLy8gYXV0b21hdGljYWxseSByZW1vdmVkIGJ5IHBhc3Npbmcgb3B0aW1pc3RpYzogdHJ1ZS5cbiAgICAgICAgb3B0aW1pc3RpYzogKG9wdGltaXN0aWMgJiYgcmVtb3ZlT3B0aW1pc3RpYykgfHwgZmFsc2UsXG5cbiAgICAgICAgLy8gVGhlIHJlbW92ZU9wdGltaXN0aWMgb3B0aW9uIGNhbiBhbHNvIGJlIHByb3ZpZGVkIGJ5IGl0c2VsZiwgZXZlbiBpZlxuICAgICAgICAvLyBvcHRpbWlzdGljID09PSBmYWxzZSwgdG8gcmVtb3ZlIHNvbWUgcHJldmlvdXNseS1hZGRlZCBvcHRpbWlzdGljXG4gICAgICAgIC8vIGxheWVyIHNhZmVseSBhbmQgZWZmaWNpZW50bHksIGxpa2Ugd2UgZG8gaW4gbWFya011dGF0aW9uUmVzdWx0LlxuICAgICAgICAvL1xuICAgICAgICAvLyBJZiBhbiBleHBsaWNpdCByZW1vdmVPcHRpbWlzdGljIHN0cmluZyBpcyBwcm92aWRlZCB3aXRoIG9wdGltaXN0aWM6XG4gICAgICAgIC8vIHRydWUsIHRoZSByZW1vdmVPcHRpbWlzdGljIHN0cmluZyB3aWxsIGRldGVybWluZSB0aGUgSUQgb2YgdGhlXG4gICAgICAgIC8vIHRlbXBvcmFyeSBvcHRpbWlzdGljIGxheWVyLCBpbiBjYXNlIHRoYXQgZXZlciBtYXR0ZXJzLlxuICAgICAgICByZW1vdmVPcHRpbWlzdGljLFxuXG4gICAgICAgIG9uV2F0Y2hVcGRhdGVkKHdhdGNoLCBkaWZmLCBsYXN0RGlmZikge1xuICAgICAgICAgIGNvbnN0IG9xID1cbiAgICAgICAgICAgIHdhdGNoLndhdGNoZXIgaW5zdGFuY2VvZiBRdWVyeUluZm8gJiYgd2F0Y2gud2F0Y2hlci5vYnNlcnZhYmxlUXVlcnk7XG5cbiAgICAgICAgICBpZiAob3EpIHtcbiAgICAgICAgICAgIGlmIChvblF1ZXJ5VXBkYXRlZCkge1xuICAgICAgICAgICAgICAvLyBTaW5jZSB3ZSdyZSBhYm91dCB0byBoYW5kbGUgdGhpcyBxdWVyeSBub3csIHJlbW92ZSBpdCBmcm9tXG4gICAgICAgICAgICAgIC8vIGluY2x1ZGVkUXVlcmllc0J5SWQsIGluIGNhc2UgaXQgd2FzIGFkZGVkIGVhcmxpZXIgYmVjYXVzZSBvZlxuICAgICAgICAgICAgICAvLyBvcHRpb25zLmluY2x1ZGUuXG4gICAgICAgICAgICAgIGluY2x1ZGVkUXVlcmllc0J5SWQuZGVsZXRlKG9xLnF1ZXJ5SWQpO1xuXG4gICAgICAgICAgICAgIGxldCByZXN1bHQ6IFRSZXN1bHQgfCBib29sZWFuIHwgUHJvbWlzZTxBcG9sbG9RdWVyeVJlc3VsdDxhbnk+PiA9XG4gICAgICAgICAgICAgICAgb25RdWVyeVVwZGF0ZWQob3EsIGRpZmYsIGxhc3REaWZmKTtcblxuICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIG9uUXVlcnlVcGRhdGVkIGZ1bmN0aW9uIHJlcXVlc3RlZCB0aGUgZGVmYXVsdCByZWZldGNoaW5nXG4gICAgICAgICAgICAgICAgLy8gYmVoYXZpb3IgYnkgcmV0dXJuaW5nIHRydWUuXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gb3EucmVmZXRjaCgpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSByZXN1bHQgaW4gdGhlIHJlc3VsdHMgTWFwLCBhcyBsb25nIGFzIG9uUXVlcnlVcGRhdGVkXG4gICAgICAgICAgICAgIC8vIGRpZCBub3QgcmV0dXJuIGZhbHNlIHRvIHNraXAvaWdub3JlIHRoaXMgcmVzdWx0LlxuICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMuc2V0KFxuICAgICAgICAgICAgICAgICAgb3EsXG4gICAgICAgICAgICAgICAgICByZXN1bHQgYXMgSW50ZXJuYWxSZWZldGNoUXVlcmllc1Jlc3VsdDxUUmVzdWx0PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBBbGxvdyB0aGUgZGVmYXVsdCBjYWNoZSBicm9hZGNhc3QgdG8gaGFwcGVuLCBleGNlcHQgd2hlblxuICAgICAgICAgICAgICAvLyBvblF1ZXJ5VXBkYXRlZCByZXR1cm5zIGZhbHNlLlxuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob25RdWVyeVVwZGF0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbiBvblF1ZXJ5VXBkYXRlZCBmdW5jdGlvbiwgYW5kIG9uUXVlcnlVcGRhdGVkXG4gICAgICAgICAgICAgIC8vIHdhcyBub3QgZGlzYWJsZWQgYnkgcGFzc2luZyBudWxsLCBtYWtlIHN1cmUgdGhpcyBxdWVyeSBpc1xuICAgICAgICAgICAgICAvLyBcImluY2x1ZGVkXCIgbGlrZSBhbnkgb3RoZXIgb3B0aW9ucy5pbmNsdWRlLXNwZWNpZmllZCBxdWVyeS5cbiAgICAgICAgICAgICAgaW5jbHVkZWRRdWVyaWVzQnlJZC5zZXQob3EucXVlcnlJZCwgeyBvcSwgbGFzdERpZmYsIGRpZmYgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGluY2x1ZGVkUXVlcmllc0J5SWQuc2l6ZSkge1xuICAgICAgaW5jbHVkZWRRdWVyaWVzQnlJZC5mb3JFYWNoKCh7IG9xLCBsYXN0RGlmZiwgZGlmZiB9LCBxdWVyeUlkKSA9PiB7XG4gICAgICAgIGxldCByZXN1bHQ6XG4gICAgICAgICAgfCBUUmVzdWx0XG4gICAgICAgICAgfCBib29sZWFuXG4gICAgICAgICAgfCBQcm9taXNlPEFwb2xsb1F1ZXJ5UmVzdWx0PGFueT4+XG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gSWYgb25RdWVyeVVwZGF0ZWQgaXMgcHJvdmlkZWQsIHdlIHdhbnQgdG8gdXNlIGl0IGZvciBhbGwgaW5jbHVkZWRcbiAgICAgICAgLy8gcXVlcmllcywgZXZlbiB0aGUgUXVlcnlPcHRpb25zIG9uZXMuXG4gICAgICAgIGlmIChvblF1ZXJ5VXBkYXRlZCkge1xuICAgICAgICAgIGlmICghZGlmZikge1xuICAgICAgICAgICAgZGlmZiA9IHRoaXMuY2FjaGUuZGlmZihvcVtcInF1ZXJ5SW5mb1wiXVtcImdldERpZmZPcHRpb25zXCJdKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBvblF1ZXJ5VXBkYXRlZChvcSwgZGlmZiwgbGFzdERpZmYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSBmYWxsIGJhY2sgdG8gcmVmZXRjaGluZy5cbiAgICAgICAgaWYgKCFvblF1ZXJ5VXBkYXRlZCB8fCByZXN1bHQgPT09IHRydWUpIHtcbiAgICAgICAgICByZXN1bHQgPSBvcS5yZWZldGNoKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0ICE9PSBmYWxzZSkge1xuICAgICAgICAgIHJlc3VsdHMuc2V0KG9xLCByZXN1bHQgYXMgSW50ZXJuYWxSZWZldGNoUXVlcmllc1Jlc3VsdDxUUmVzdWx0Pik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocXVlcnlJZC5pbmRleE9mKFwibGVnYWN5T25lVGltZVF1ZXJ5XCIpID49IDApIHtcbiAgICAgICAgICB0aGlzLnN0b3BRdWVyeU5vQnJvYWRjYXN0KHF1ZXJ5SWQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAocmVtb3ZlT3B0aW1pc3RpYykge1xuICAgICAgLy8gSW4gY2FzZSBubyB1cGRhdGVDYWNoZSBjYWxsYmFjayB3YXMgcHJvdmlkZWQgKHNvIGNhY2hlLmJhdGNoIHdhcyBub3RcbiAgICAgIC8vIGNhbGxlZCBhYm92ZSwgYW5kIHRodXMgZGlkIG5vdCBhbHJlYWR5IHJlbW92ZSB0aGUgb3B0aW1pc3RpYyBsYXllciksXG4gICAgICAvLyByZW1vdmUgaXQgaGVyZS4gU2luY2UgdGhpcyBpcyBhIG5vLW9wIHdoZW4gdGhlIGxheWVyIGhhcyBhbHJlYWR5IGJlZW5cbiAgICAgIC8vIHJlbW92ZWQsIHdlIGRvIGl0IGV2ZW4gaWYgd2UgY2FsbGVkIGNhY2hlLmJhdGNoIGFib3ZlLCBzaW5jZSBpdCdzXG4gICAgICAvLyBwb3NzaWJsZSB0aGlzLmNhY2hlIGlzIGFuIGluc3RhbmNlIG9mIHNvbWUgQXBvbGxvQ2FjaGUgc3ViY2xhc3Mgb3RoZXJcbiAgICAgIC8vIHRoYW4gSW5NZW1vcnlDYWNoZSwgYW5kIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIHJlbW92ZU9wdGltaXN0aWNcbiAgICAgIC8vIG9wdGlvbiBmb3IgY2FjaGUuYmF0Y2guXG4gICAgICB0aGlzLmNhY2hlLnJlbW92ZU9wdGltaXN0aWMocmVtb3ZlT3B0aW1pc3RpYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBwcml2YXRlIG5vQ2FjaGVXYXJuaW5nc0J5UXVlcnlJZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIHB1YmxpYyBtYXNrT3BlcmF0aW9uPFREYXRhID0gdW5rbm93bj4oXG4gICAgb3B0aW9uczogTWFza09wZXJhdGlvbk9wdGlvbnM8VERhdGE+XG4gICk6IE1heWJlTWFza2VkPFREYXRhPiB7XG4gICAgY29uc3QgeyBkb2N1bWVudCwgZGF0YSB9ID0gb3B0aW9ucztcblxuICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICBjb25zdCB7IGZldGNoUG9saWN5LCBpZCB9ID0gb3B0aW9ucztcbiAgICAgIGNvbnN0IG9wZXJhdGlvblR5cGUgPSBnZXRPcGVyYXRpb25EZWZpbml0aW9uKGRvY3VtZW50KT8ub3BlcmF0aW9uO1xuICAgICAgY29uc3Qgb3BlcmF0aW9uSWQgPSAob3BlcmF0aW9uVHlwZT8uWzBdID8/IFwib1wiKSArIGlkO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuZGF0YU1hc2tpbmcgJiZcbiAgICAgICAgZmV0Y2hQb2xpY3kgPT09IFwibm8tY2FjaGVcIiAmJlxuICAgICAgICAhaXNGdWxseVVubWFza2VkT3BlcmF0aW9uKGRvY3VtZW50KSAmJlxuICAgICAgICAhdGhpcy5ub0NhY2hlV2FybmluZ3NCeVF1ZXJ5SWQuaGFzKG9wZXJhdGlvbklkKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMubm9DYWNoZVdhcm5pbmdzQnlRdWVyeUlkLmFkZChvcGVyYXRpb25JZCk7XG5cbiAgICAgICAgaW52YXJpYW50Lndhcm4oXG4gICAgICAgICAgJ1slc106IEZyYWdtZW50cyBtYXNrZWQgYnkgZGF0YSBtYXNraW5nIGFyZSBpbmFjY2Vzc2libGUgd2hlbiB1c2luZyBmZXRjaCBwb2xpY3kgXCJuby1jYWNoZVwiLiBQbGVhc2UgYWRkIGBAdW5tYXNrYCB0byBlYWNoIGZyYWdtZW50IHNwcmVhZCB0byBhY2Nlc3MgdGhlIGRhdGEuJyxcbiAgICAgICAgICBnZXRPcGVyYXRpb25OYW1lKGRvY3VtZW50KSA/P1xuICAgICAgICAgICAgYFVubmFtZWQgJHtvcGVyYXRpb25UeXBlID8/IFwib3BlcmF0aW9uXCJ9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmRhdGFNYXNraW5nID9cbiAgICAgICAgbWFza09wZXJhdGlvbihkYXRhLCBkb2N1bWVudCwgdGhpcy5jYWNoZSlcbiAgICAgIDogZGF0YSkgYXMgTWF5YmVNYXNrZWQ8VERhdGE+O1xuICB9XG5cbiAgcHVibGljIG1hc2tGcmFnbWVudDxURGF0YSA9IHVua25vd24+KG9wdGlvbnM6IE1hc2tGcmFnbWVudE9wdGlvbnM8VERhdGE+KSB7XG4gICAgY29uc3QgeyBkYXRhLCBmcmFnbWVudCwgZnJhZ21lbnROYW1lIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIHRoaXMuZGF0YU1hc2tpbmcgP1xuICAgICAgICBtYXNrRnJhZ21lbnQoZGF0YSwgZnJhZ21lbnQsIHRoaXMuY2FjaGUsIGZyYWdtZW50TmFtZSlcbiAgICAgIDogZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hRdWVyeUJ5UG9saWN5PFREYXRhLCBUVmFycyBleHRlbmRzIE9wZXJhdGlvblZhcmlhYmxlcz4oXG4gICAgcXVlcnlJbmZvOiBRdWVyeUluZm8sXG4gICAge1xuICAgICAgcXVlcnksXG4gICAgICB2YXJpYWJsZXMsXG4gICAgICBmZXRjaFBvbGljeSxcbiAgICAgIHJlZmV0Y2hXcml0ZVBvbGljeSxcbiAgICAgIGVycm9yUG9saWN5LFxuICAgICAgcmV0dXJuUGFydGlhbERhdGEsXG4gICAgICBjb250ZXh0LFxuICAgICAgbm90aWZ5T25OZXR3b3JrU3RhdHVzQ2hhbmdlLFxuICAgIH06IFdhdGNoUXVlcnlPcHRpb25zPFRWYXJzLCBURGF0YT4sXG4gICAgLy8gVGhlIGluaXRpYWwgbmV0d29ya1N0YXR1cyBmb3IgdGhpcyBmZXRjaCwgbW9zdCBvZnRlblxuICAgIC8vIE5ldHdvcmtTdGF0dXMubG9hZGluZywgYnV0IGFsc28gcG9zc2libHkgZmV0Y2hNb3JlLCBwb2xsLCByZWZldGNoLFxuICAgIC8vIG9yIHNldFZhcmlhYmxlcy5cbiAgICBuZXR3b3JrU3RhdHVzOiBOZXR3b3JrU3RhdHVzXG4gICk6IFNvdXJjZXNBbmRJbmZvPFREYXRhPiB7XG4gICAgY29uc3Qgb2xkTmV0d29ya1N0YXR1cyA9IHF1ZXJ5SW5mby5uZXR3b3JrU3RhdHVzO1xuXG4gICAgcXVlcnlJbmZvLmluaXQoe1xuICAgICAgZG9jdW1lbnQ6IHF1ZXJ5LFxuICAgICAgdmFyaWFibGVzLFxuICAgICAgbmV0d29ya1N0YXR1cyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlYWRDYWNoZSA9ICgpID0+IHF1ZXJ5SW5mby5nZXREaWZmKCk7XG5cbiAgICBjb25zdCByZXN1bHRzRnJvbUNhY2hlID0gKFxuICAgICAgZGlmZjogQ2FjaGUuRGlmZlJlc3VsdDxURGF0YT4sXG4gICAgICBuZXR3b3JrU3RhdHVzID0gcXVlcnlJbmZvLm5ldHdvcmtTdGF0dXMgfHwgTmV0d29ya1N0YXR1cy5sb2FkaW5nXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gZGlmZi5yZXN1bHQ7XG5cbiAgICAgIGlmIChfX0RFVl9fICYmICFyZXR1cm5QYXJ0aWFsRGF0YSAmJiAhZXF1YWwoZGF0YSwge30pKSB7XG4gICAgICAgIGxvZ01pc3NpbmdGaWVsZEVycm9ycyhkaWZmLm1pc3NpbmcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmcm9tRGF0YSA9IChkYXRhOiBURGF0YSB8IHVuZGVmaW5lZCkgPT5cbiAgICAgICAgT2JzZXJ2YWJsZS5vZih7XG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBsb2FkaW5nOiBpc05ldHdvcmtSZXF1ZXN0SW5GbGlnaHQobmV0d29ya1N0YXR1cyksXG4gICAgICAgICAgbmV0d29ya1N0YXR1cyxcbiAgICAgICAgICAuLi4oZGlmZi5jb21wbGV0ZSA/IG51bGwgOiB7IHBhcnRpYWw6IHRydWUgfSksXG4gICAgICAgIH0gYXMgQXBvbGxvUXVlcnlSZXN1bHQ8VERhdGE+KTtcblxuICAgICAgaWYgKGRhdGEgJiYgdGhpcy5nZXREb2N1bWVudEluZm8ocXVlcnkpLmhhc0ZvcmNlZFJlc29sdmVycykge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbFN0YXRlXG4gICAgICAgICAgLnJ1blJlc29sdmVycyh7XG4gICAgICAgICAgICBkb2N1bWVudDogcXVlcnksXG4gICAgICAgICAgICByZW1vdGVSZXN1bHQ6IHsgZGF0YSB9LFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgICAgIG9ubHlSdW5Gb3JjZWRSZXNvbHZlcnM6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbigocmVzb2x2ZWQpID0+IGZyb21EYXRhKHJlc29sdmVkLmRhdGEgfHwgdm9pZCAwKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc29sdmVzIGh0dHBzOi8vZ2l0aHViLmNvbS9hcG9sbG9ncmFwaHFsL2Fwb2xsby1jbGllbnQvaXNzdWVzLzEwMzE3LlxuICAgICAgLy8gSWYgZXJyb3JQb2xpY3kgaXMgJ25vbmUnIGFuZCBub3RpZnlPbk5ldHdvcmtTdGF0dXNDaGFuZ2UgaXMgdHJ1ZSxcbiAgICAgIC8vIGRhdGEgd2FzIGluY29ycmVjdGx5IHJldHVybmVkIGZyb20gdGhlIGNhY2hlIG9uIHJlZmV0Y2g6XG4gICAgICAvLyBpZiBkaWZmLm1pc3NpbmcgZXhpc3RzLCB3ZSBzaG91bGQgbm90IHJldHVybiBjYWNoZSBkYXRhLlxuICAgICAgaWYgKFxuICAgICAgICBlcnJvclBvbGljeSA9PT0gXCJub25lXCIgJiZcbiAgICAgICAgbmV0d29ya1N0YXR1cyA9PT0gTmV0d29ya1N0YXR1cy5yZWZldGNoICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkoZGlmZi5taXNzaW5nKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBmcm9tRGF0YSh2b2lkIDApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZnJvbURhdGEoZGF0YSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNhY2hlV3JpdGVCZWhhdmlvciA9XG4gICAgICBmZXRjaFBvbGljeSA9PT0gXCJuby1jYWNoZVwiID8gQ2FjaGVXcml0ZUJlaGF2aW9yLkZPUkJJRFxuICAgICAgICAvLyBXYXRjaGVkIHF1ZXJpZXMgbXVzdCBvcHQgaW50byBvdmVyd3JpdGluZyBleGlzdGluZyBkYXRhIG9uIHJlZmV0Y2gsXG4gICAgICAgIC8vIGJ5IHBhc3NpbmcgcmVmZXRjaFdyaXRlUG9saWN5OiBcIm92ZXJ3cml0ZVwiIGluIHRoZWlyIFdhdGNoUXVlcnlPcHRpb25zLlxuICAgICAgOiAoXG4gICAgICAgIG5ldHdvcmtTdGF0dXMgPT09IE5ldHdvcmtTdGF0dXMucmVmZXRjaCAmJlxuICAgICAgICByZWZldGNoV3JpdGVQb2xpY3kgIT09IFwibWVyZ2VcIlxuICAgICAgKSA/XG4gICAgICAgIENhY2hlV3JpdGVCZWhhdmlvci5PVkVSV1JJVEVcbiAgICAgIDogQ2FjaGVXcml0ZUJlaGF2aW9yLk1FUkdFO1xuXG4gICAgY29uc3QgcmVzdWx0c0Zyb21MaW5rID0gKCkgPT5cbiAgICAgIHRoaXMuZ2V0UmVzdWx0c0Zyb21MaW5rPFREYXRhLCBUVmFycz4ocXVlcnlJbmZvLCBjYWNoZVdyaXRlQmVoYXZpb3IsIHtcbiAgICAgICAgcXVlcnksXG4gICAgICAgIHZhcmlhYmxlcyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgZmV0Y2hQb2xpY3ksXG4gICAgICAgIGVycm9yUG9saWN5LFxuICAgICAgfSk7XG5cbiAgICBjb25zdCBzaG91bGROb3RpZnkgPVxuICAgICAgbm90aWZ5T25OZXR3b3JrU3RhdHVzQ2hhbmdlICYmXG4gICAgICB0eXBlb2Ygb2xkTmV0d29ya1N0YXR1cyA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgb2xkTmV0d29ya1N0YXR1cyAhPT0gbmV0d29ya1N0YXR1cyAmJlxuICAgICAgaXNOZXR3b3JrUmVxdWVzdEluRmxpZ2h0KG5ldHdvcmtTdGF0dXMpO1xuXG4gICAgc3dpdGNoIChmZXRjaFBvbGljeSkge1xuICAgICAgZGVmYXVsdDpcbiAgICAgIGNhc2UgXCJjYWNoZS1maXJzdFwiOiB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSByZWFkQ2FjaGUoKTtcblxuICAgICAgICBpZiAoZGlmZi5jb21wbGV0ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmcm9tTGluazogZmFsc2UsXG4gICAgICAgICAgICBzb3VyY2VzOiBbcmVzdWx0c0Zyb21DYWNoZShkaWZmLCBxdWVyeUluZm8ubWFya1JlYWR5KCkpXSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJldHVyblBhcnRpYWxEYXRhIHx8IHNob3VsZE5vdGlmeSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmcm9tTGluazogdHJ1ZSxcbiAgICAgICAgICAgIHNvdXJjZXM6IFtyZXN1bHRzRnJvbUNhY2hlKGRpZmYpLCByZXN1bHRzRnJvbUxpbmsoKV0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGZyb21MaW5rOiB0cnVlLCBzb3VyY2VzOiBbcmVzdWx0c0Zyb21MaW5rKCldIH07XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJjYWNoZS1hbmQtbmV0d29ya1wiOiB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSByZWFkQ2FjaGUoKTtcblxuICAgICAgICBpZiAoZGlmZi5jb21wbGV0ZSB8fCByZXR1cm5QYXJ0aWFsRGF0YSB8fCBzaG91bGROb3RpZnkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZnJvbUxpbms6IHRydWUsXG4gICAgICAgICAgICBzb3VyY2VzOiBbcmVzdWx0c0Zyb21DYWNoZShkaWZmKSwgcmVzdWx0c0Zyb21MaW5rKCldLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBmcm9tTGluazogdHJ1ZSwgc291cmNlczogW3Jlc3VsdHNGcm9tTGluaygpXSB9O1xuICAgICAgfVxuXG4gICAgICBjYXNlIFwiY2FjaGUtb25seVwiOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGZyb21MaW5rOiBmYWxzZSxcbiAgICAgICAgICBzb3VyY2VzOiBbcmVzdWx0c0Zyb21DYWNoZShyZWFkQ2FjaGUoKSwgcXVlcnlJbmZvLm1hcmtSZWFkeSgpKV0sXG4gICAgICAgIH07XG5cbiAgICAgIGNhc2UgXCJuZXR3b3JrLW9ubHlcIjpcbiAgICAgICAgaWYgKHNob3VsZE5vdGlmeSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmcm9tTGluazogdHJ1ZSxcbiAgICAgICAgICAgIHNvdXJjZXM6IFtyZXN1bHRzRnJvbUNhY2hlKHJlYWRDYWNoZSgpKSwgcmVzdWx0c0Zyb21MaW5rKCldLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBmcm9tTGluazogdHJ1ZSwgc291cmNlczogW3Jlc3VsdHNGcm9tTGluaygpXSB9O1xuXG4gICAgICBjYXNlIFwibm8tY2FjaGVcIjpcbiAgICAgICAgaWYgKHNob3VsZE5vdGlmeSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmcm9tTGluazogdHJ1ZSxcbiAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBxdWVyeUluZm8uZ2V0RGlmZigpIGZvciBuby1jYWNoZSBxdWVyaWVzIGRvZXMgbm90IGNhbGxcbiAgICAgICAgICAgIC8vIGNhY2hlLmRpZmYsIGJ1dCBpbnN0ZWFkIHJldHVybnMgYSB7IGNvbXBsZXRlOiBmYWxzZSB9IHN0dWIgcmVzdWx0XG4gICAgICAgICAgICAvLyB3aGVuIHRoZXJlIGlzIG5vIHF1ZXJ5SW5mby5kaWZmIGFscmVhZHkgZGVmaW5lZC5cbiAgICAgICAgICAgIHNvdXJjZXM6IFtyZXN1bHRzRnJvbUNhY2hlKHF1ZXJ5SW5mby5nZXREaWZmKCkpLCByZXN1bHRzRnJvbUxpbmsoKV0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGZyb21MaW5rOiB0cnVlLCBzb3VyY2VzOiBbcmVzdWx0c0Zyb21MaW5rKCldIH07XG5cbiAgICAgIGNhc2UgXCJzdGFuZGJ5XCI6XG4gICAgICAgIHJldHVybiB7IGZyb21MaW5rOiBmYWxzZSwgc291cmNlczogW10gfTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0T3JDcmVhdGVRdWVyeShxdWVyeUlkOiBzdHJpbmcpOiBRdWVyeUluZm8ge1xuICAgIGlmIChxdWVyeUlkICYmICF0aGlzLnF1ZXJpZXMuaGFzKHF1ZXJ5SWQpKSB7XG4gICAgICB0aGlzLnF1ZXJpZXMuc2V0KHF1ZXJ5SWQsIG5ldyBRdWVyeUluZm8odGhpcywgcXVlcnlJZCkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5xdWVyaWVzLmdldChxdWVyeUlkKSE7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVDb250ZXh0KGNvbnRleHQgPSB7fSkge1xuICAgIGNvbnN0IG5ld0NvbnRleHQgPSB0aGlzLmxvY2FsU3RhdGUucHJlcGFyZUNvbnRleHQoY29udGV4dCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZGVmYXVsdENvbnRleHQsXG4gICAgICAuLi5uZXdDb250ZXh0LFxuICAgICAgY2xpZW50QXdhcmVuZXNzOiB0aGlzLmNsaWVudEF3YXJlbmVzcyxcbiAgICB9O1xuICB9XG59XG5cbi8vIFJldHVybiB0eXBlcyB1c2VkIGJ5IGZldGNoUXVlcnlCeVBvbGljeSBhbmQgb3RoZXIgcHJpdmF0ZSBtZXRob2RzIGFib3ZlLlxuaW50ZXJmYWNlIEZldGNoQ29uY2FzdEluZm8ge1xuICAvLyBNZXRhZGF0YSBwcm9wZXJ0aWVzIHRoYXQgY2FuIGJlIHJldHVybmVkIGluIGFkZGl0aW9uIHRvIHRoZSBDb25jYXN0LlxuICBmcm9tTGluazogYm9vbGVhbjtcbn1cbmludGVyZmFjZSBTb3VyY2VzQW5kSW5mbzxURGF0YT4gZXh0ZW5kcyBGZXRjaENvbmNhc3RJbmZvIHtcbiAgc291cmNlczogQ29uY2FzdFNvdXJjZXNBcnJheTxBcG9sbG9RdWVyeVJlc3VsdDxURGF0YT4+O1xufVxuaW50ZXJmYWNlIENvbmNhc3RBbmRJbmZvPFREYXRhPiBleHRlbmRzIEZldGNoQ29uY2FzdEluZm8ge1xuICBjb25jYXN0OiBDb25jYXN0PEFwb2xsb1F1ZXJ5UmVzdWx0PFREYXRhPj47XG59XG4iXSwieF9nb29nbGVfaWdub3JlTGlzdCI6WzBdfQ==