mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-19 16:18:58 +01:00
527 lines
45 KiB
JavaScript
527 lines
45 KiB
JavaScript
"use strict";
|
|
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const child_process_1 = require("child_process");
|
|
const fs_1 = require("fs");
|
|
const path = require("path");
|
|
const byline = require("byline");
|
|
const ripgrep_1 = require("@vscode/ripgrep");
|
|
const Parser = require("tree-sitter");
|
|
const node_fetch_1 = require("node-fetch");
|
|
const { typescript } = require('tree-sitter-typescript');
|
|
const product = require('../../product.json');
|
|
const packageJson = require('../../package.json');
|
|
function isNlsString(value) {
|
|
return value ? typeof value !== 'string' : false;
|
|
}
|
|
function isStringArray(value) {
|
|
return !value.some(s => isNlsString(s));
|
|
}
|
|
function isNlsStringArray(value) {
|
|
return value.every(s => isNlsString(s));
|
|
}
|
|
var PolicyType;
|
|
(function (PolicyType) {
|
|
PolicyType[PolicyType["StringEnum"] = 0] = "StringEnum";
|
|
})(PolicyType || (PolicyType = {}));
|
|
function renderADMLString(prefix, moduleName, nlsString, translations) {
|
|
let value;
|
|
if (translations) {
|
|
const moduleTranslations = translations[moduleName];
|
|
if (moduleTranslations) {
|
|
value = moduleTranslations[nlsString.nlsKey];
|
|
}
|
|
}
|
|
if (!value) {
|
|
value = nlsString.value;
|
|
}
|
|
return `<string id="${prefix}_${nlsString.nlsKey}">${value}</string>`;
|
|
}
|
|
class BasePolicy {
|
|
policyType;
|
|
name;
|
|
category;
|
|
minimumVersion;
|
|
description;
|
|
moduleName;
|
|
constructor(policyType, name, category, minimumVersion, description, moduleName) {
|
|
this.policyType = policyType;
|
|
this.name = name;
|
|
this.category = category;
|
|
this.minimumVersion = minimumVersion;
|
|
this.description = description;
|
|
this.moduleName = moduleName;
|
|
}
|
|
renderADMLString(nlsString, translations) {
|
|
return renderADMLString(this.name, this.moduleName, nlsString, translations);
|
|
}
|
|
renderADMX(regKey) {
|
|
return [
|
|
`<policy name="${this.name}" class="Both" displayName="$(string.${this.name})" explainText="$(string.${this.name}_${this.description.nlsKey})" key="Software\\Policies\\Microsoft\\${regKey}" presentation="$(presentation.${this.name})">`,
|
|
` <parentCategory ref="${this.category.name.nlsKey}" />`,
|
|
` <supportedOn ref="Supported_${this.minimumVersion.replace(/\./g, '_')}" />`,
|
|
` <elements>`,
|
|
...this.renderADMXElements(),
|
|
` </elements>`,
|
|
`</policy>`
|
|
];
|
|
}
|
|
renderADMLStrings(translations) {
|
|
return [
|
|
`<string id="${this.name}">${this.name}</string>`,
|
|
this.renderADMLString(this.description, translations)
|
|
];
|
|
}
|
|
renderADMLPresentation() {
|
|
return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
|
|
}
|
|
}
|
|
class BooleanPolicy extends BasePolicy {
|
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
|
const type = getStringProperty(settingNode, 'type');
|
|
if (type !== 'boolean') {
|
|
return undefined;
|
|
}
|
|
return new BooleanPolicy(name, category, minimumVersion, description, moduleName);
|
|
}
|
|
constructor(name, category, minimumVersion, description, moduleName) {
|
|
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
|
|
}
|
|
renderADMXElements() {
|
|
return [
|
|
`<boolean id="${this.name}" valueName="${this.name}">`,
|
|
` <trueValue><decimal value="1" /></trueValue><falseValue><decimal value="0" /></falseValue>`,
|
|
`</boolean>`
|
|
];
|
|
}
|
|
renderADMLPresentationContents() {
|
|
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
|
|
}
|
|
}
|
|
class IntPolicy extends BasePolicy {
|
|
defaultValue;
|
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
|
const type = getStringProperty(settingNode, 'type');
|
|
if (type !== 'number') {
|
|
return undefined;
|
|
}
|
|
const defaultValue = getIntProperty(settingNode, 'default');
|
|
if (typeof defaultValue === 'undefined') {
|
|
throw new Error(`Missing required 'default' property.`);
|
|
}
|
|
return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue);
|
|
}
|
|
constructor(name, category, minimumVersion, description, moduleName, defaultValue) {
|
|
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
|
|
this.defaultValue = defaultValue;
|
|
}
|
|
renderADMXElements() {
|
|
return [
|
|
`<decimal id="${this.name}" valueName="${this.name}" />`
|
|
// `<decimal id="Quarantine_PurgeItemsAfterDelay" valueName="PurgeItemsAfterDelay" minValue="0" maxValue="10000000" />`
|
|
];
|
|
}
|
|
renderADMLPresentationContents() {
|
|
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
|
|
}
|
|
}
|
|
class StringPolicy extends BasePolicy {
|
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
|
const type = getStringProperty(settingNode, 'type');
|
|
if (type !== 'string') {
|
|
return undefined;
|
|
}
|
|
return new StringPolicy(name, category, minimumVersion, description, moduleName);
|
|
}
|
|
constructor(name, category, minimumVersion, description, moduleName) {
|
|
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
|
|
}
|
|
renderADMXElements() {
|
|
return [`<text id="${this.name}" valueName="${this.name}" required="true" />`];
|
|
}
|
|
renderADMLPresentationContents() {
|
|
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
|
|
}
|
|
}
|
|
class StringEnumPolicy extends BasePolicy {
|
|
enum_;
|
|
enumDescriptions;
|
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
|
const type = getStringProperty(settingNode, 'type');
|
|
if (type !== 'string') {
|
|
return undefined;
|
|
}
|
|
const enum_ = getStringArrayProperty(settingNode, 'enum');
|
|
if (!enum_) {
|
|
return undefined;
|
|
}
|
|
if (!isStringArray(enum_)) {
|
|
throw new Error(`Property 'enum' should not be localized.`);
|
|
}
|
|
const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions');
|
|
if (!enumDescriptions) {
|
|
throw new Error(`Missing required 'enumDescriptions' property.`);
|
|
}
|
|
else if (!isNlsStringArray(enumDescriptions)) {
|
|
throw new Error(`Property 'enumDescriptions' should be localized.`);
|
|
}
|
|
return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions);
|
|
}
|
|
constructor(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions) {
|
|
super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName);
|
|
this.enum_ = enum_;
|
|
this.enumDescriptions = enumDescriptions;
|
|
}
|
|
renderADMXElements() {
|
|
return [
|
|
`<enum id="${this.name}" valueName="${this.name}">`,
|
|
...this.enum_.map((value, index) => ` <item displayName="$(string.${this.name}_${this.enumDescriptions[index].nlsKey})"><value><string>${value}</string></value></item>`),
|
|
`</enum>`
|
|
];
|
|
}
|
|
renderADMLStrings(translations) {
|
|
return [
|
|
...super.renderADMLStrings(translations),
|
|
...this.enumDescriptions.map(e => this.renderADMLString(e, translations))
|
|
];
|
|
}
|
|
renderADMLPresentationContents() {
|
|
return `<dropdownList refId="${this.name}" />`;
|
|
}
|
|
}
|
|
const IntQ = {
|
|
Q: `(number) @value`,
|
|
value(matches) {
|
|
const match = matches[0];
|
|
if (!match) {
|
|
return undefined;
|
|
}
|
|
const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
|
|
if (!value) {
|
|
throw new Error(`Missing required 'value' property.`);
|
|
}
|
|
return parseInt(value);
|
|
}
|
|
};
|
|
const StringQ = {
|
|
Q: `[
|
|
(string (string_fragment) @value)
|
|
(call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize))
|
|
]`,
|
|
value(matches) {
|
|
const match = matches[0];
|
|
if (!match) {
|
|
return undefined;
|
|
}
|
|
const value = match.captures.filter(c => c.name === 'value')[0]?.node.text;
|
|
if (!value) {
|
|
throw new Error(`Missing required 'value' property.`);
|
|
}
|
|
const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text;
|
|
if (nlsKey) {
|
|
return { value, nlsKey };
|
|
}
|
|
else {
|
|
return value;
|
|
}
|
|
}
|
|
};
|
|
const StringArrayQ = {
|
|
Q: `(array ${StringQ.Q})`,
|
|
value(matches) {
|
|
if (matches.length === 0) {
|
|
return undefined;
|
|
}
|
|
return matches.map(match => {
|
|
return StringQ.value([match]);
|
|
});
|
|
}
|
|
};
|
|
function getProperty(qtype, node, key) {
|
|
const query = new Parser.Query(typescript, `(
|
|
(pair
|
|
key: [(property_identifier)(string)] @key
|
|
value: ${qtype.Q}
|
|
)
|
|
(#eq? @key ${key})
|
|
)`);
|
|
return qtype.value(query.matches(node));
|
|
}
|
|
function getIntProperty(node, key) {
|
|
return getProperty(IntQ, node, key);
|
|
}
|
|
function getStringProperty(node, key) {
|
|
return getProperty(StringQ, node, key);
|
|
}
|
|
function getStringArrayProperty(node, key) {
|
|
return getProperty(StringArrayQ, node, key);
|
|
}
|
|
// TODO: add more policy types
|
|
const PolicyTypes = [
|
|
BooleanPolicy,
|
|
IntPolicy,
|
|
StringEnumPolicy,
|
|
StringPolicy,
|
|
];
|
|
function getPolicy(moduleName, configurationNode, settingNode, policyNode, categories) {
|
|
const name = getStringProperty(policyNode, 'name');
|
|
if (!name) {
|
|
throw new Error(`Missing required 'name' property.`);
|
|
}
|
|
else if (isNlsString(name)) {
|
|
throw new Error(`Property 'name' should be a literal string.`);
|
|
}
|
|
const categoryName = getStringProperty(configurationNode, 'title');
|
|
if (!categoryName) {
|
|
throw new Error(`Missing required 'title' property.`);
|
|
}
|
|
else if (!isNlsString(categoryName)) {
|
|
throw new Error(`Property 'title' should be localized.`);
|
|
}
|
|
const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`;
|
|
let category = categories.get(categoryKey);
|
|
if (!category) {
|
|
category = { moduleName, name: categoryName };
|
|
categories.set(categoryKey, category);
|
|
}
|
|
const minimumVersion = getStringProperty(policyNode, 'minimumVersion');
|
|
if (!minimumVersion) {
|
|
throw new Error(`Missing required 'minimumVersion' property.`);
|
|
}
|
|
else if (isNlsString(minimumVersion)) {
|
|
throw new Error(`Property 'minimumVersion' should be a literal string.`);
|
|
}
|
|
const description = getStringProperty(settingNode, 'description');
|
|
if (!description) {
|
|
throw new Error(`Missing required 'description' property.`);
|
|
}
|
|
if (!isNlsString(description)) {
|
|
throw new Error(`Property 'description' should be localized.`);
|
|
}
|
|
let result;
|
|
for (const policyType of PolicyTypes) {
|
|
if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) {
|
|
break;
|
|
}
|
|
}
|
|
if (!result) {
|
|
throw new Error(`Failed to parse policy '${name}'.`);
|
|
}
|
|
return result;
|
|
}
|
|
function getPolicies(moduleName, node) {
|
|
const query = new Parser.Query(typescript, `
|
|
(
|
|
(call_expression
|
|
function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration)
|
|
arguments: (arguments (object (pair
|
|
key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties)
|
|
value: (object (pair
|
|
key: [(property_identifier)(string)]
|
|
value: (object (pair
|
|
key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy)
|
|
value: (object) @policy
|
|
)) @setting
|
|
))
|
|
)) @configuration)
|
|
)
|
|
)
|
|
`);
|
|
const categories = new Map();
|
|
return query.matches(node).map(m => {
|
|
const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node;
|
|
const settingNode = m.captures.filter(c => c.name === 'setting')[0].node;
|
|
const policyNode = m.captures.filter(c => c.name === 'policy')[0].node;
|
|
return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories);
|
|
});
|
|
}
|
|
async function getFiles(root) {
|
|
return new Promise((c, e) => {
|
|
const result = [];
|
|
const rg = (0, child_process_1.spawn)(ripgrep_1.rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]);
|
|
const stream = byline(rg.stdout.setEncoding('utf8'));
|
|
stream.on('data', path => result.push(path));
|
|
stream.on('error', err => e(err));
|
|
stream.on('end', () => c(result));
|
|
});
|
|
}
|
|
function renderADMX(regKey, versions, categories, policies) {
|
|
versions = versions.map(v => v.replace(/\./g, '_'));
|
|
return `<?xml version="1.0" encoding="utf-8"?>
|
|
<policyDefinitions revision="1.1" schemaVersion="1.0">
|
|
<policyNamespaces>
|
|
<target prefix="${regKey}" namespace="Microsoft.Policies.${regKey}" />
|
|
</policyNamespaces>
|
|
<resources minRequiredRevision="1.0" />
|
|
<supportedOn>
|
|
<definitions>
|
|
${versions.map(v => `<definition name="Supported_${v}" displayName="$(string.Supported_${v})" />`).join(`\n `)}
|
|
</definitions>
|
|
</supportedOn>
|
|
<categories>
|
|
<category displayName="$(string.Application)" name="Application" />
|
|
${categories.map(c => `<category displayName="$(string.Category_${c.name.nlsKey})" name="${c.name.nlsKey}"><parentCategory ref="Application" /></category>`).join(`\n `)}
|
|
</categories>
|
|
<policies>
|
|
${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)}
|
|
</policies>
|
|
</policyDefinitions>
|
|
`;
|
|
}
|
|
function renderADML(appName, versions, categories, policies, translations) {
|
|
return `<?xml version="1.0" encoding="utf-8"?>
|
|
<policyDefinitionResources revision="1.0" schemaVersion="1.0">
|
|
<displayName />
|
|
<description />
|
|
<resources>
|
|
<stringTable>
|
|
<string id="Application">${appName}</string>
|
|
${versions.map(v => `<string id="Supported_${v.replace(/\./g, '_')}">${appName} >= ${v}</string>`)}
|
|
${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))}
|
|
${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)}
|
|
</stringTable>
|
|
<presentationTable>
|
|
${policies.map(p => p.renderADMLPresentation()).join(`\n `)}
|
|
</presentationTable>
|
|
</resources>
|
|
</policyDefinitionResources>
|
|
`;
|
|
}
|
|
function renderGP(policies, translations) {
|
|
const appName = product.nameLong;
|
|
const regKey = product.win32RegValueName;
|
|
const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
|
|
const categories = [...new Set(policies.map(p => p.category))];
|
|
return {
|
|
admx: renderADMX(regKey, versions, categories, policies),
|
|
adml: [
|
|
{ languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) },
|
|
...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) }))
|
|
]
|
|
};
|
|
}
|
|
const Languages = {
|
|
'fr': 'fr-fr',
|
|
'it': 'it-it',
|
|
'de': 'de-de',
|
|
'es': 'es-es',
|
|
'ru': 'ru-ru',
|
|
'zh-hans': 'zh-cn',
|
|
'zh-hant': 'zh-tw',
|
|
'ja': 'ja-jp',
|
|
'ko': 'ko-kr',
|
|
'cs': 'cs-cz',
|
|
'pt-br': 'pt-br',
|
|
'tr': 'tr-tr',
|
|
'pl': 'pl-pl',
|
|
};
|
|
async function getSpecificNLS(resourceUrlTemplate, languageId, version) {
|
|
const resource = {
|
|
publisher: 'ms-ceintl',
|
|
name: `vscode-language-pack-${languageId}`,
|
|
version: `${version[0]}.${version[1]}.${version[2]}`,
|
|
path: 'extension/translations/main.i18n.json'
|
|
};
|
|
const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key]);
|
|
const res = await (0, node_fetch_1.default)(url);
|
|
if (res.status !== 200) {
|
|
throw new Error(`[${res.status}] Error downloading language pack ${languageId}@${version}`);
|
|
}
|
|
const { contents: result } = await res.json();
|
|
return result;
|
|
}
|
|
function parseVersion(version) {
|
|
const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
|
|
return [parseInt(major), parseInt(minor), parseInt(patch)];
|
|
}
|
|
function compareVersions(a, b) {
|
|
if (a[0] !== b[0]) {
|
|
return a[0] - b[0];
|
|
}
|
|
if (a[1] !== b[1]) {
|
|
return a[1] - b[1];
|
|
}
|
|
return a[2] - b[2];
|
|
}
|
|
async function queryVersions(serviceUrl, languageId) {
|
|
const res = await (0, node_fetch_1.default)(`${serviceUrl}/extensionquery`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Accept': 'application/json;api-version=3.0-preview.1',
|
|
'Content-Type': 'application/json',
|
|
'User-Agent': 'VS Code Build',
|
|
},
|
|
body: JSON.stringify({
|
|
filters: [{ criteria: [{ filterType: 7, value: `ms-ceintl.vscode-language-pack-${languageId}` }] }],
|
|
flags: 0x1
|
|
})
|
|
});
|
|
if (res.status !== 200) {
|
|
throw new Error(`[${res.status}] Error querying for extension: ${languageId}`);
|
|
}
|
|
const result = await res.json();
|
|
return result.results[0].extensions[0].versions.map(v => parseVersion(v.version)).sort(compareVersions);
|
|
}
|
|
async function getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version) {
|
|
const versions = await queryVersions(extensionGalleryServiceUrl, languageId);
|
|
const nextMinor = [version[0], version[1] + 1, 0];
|
|
const compatibleVersions = versions.filter(v => compareVersions(v, nextMinor) < 0);
|
|
const latestCompatibleVersion = compatibleVersions.at(-1); // order is newest to oldest
|
|
if (!latestCompatibleVersion) {
|
|
throw new Error(`No compatible language pack found for ${languageId} for version ${version}`);
|
|
}
|
|
return await getSpecificNLS(resourceUrlTemplate, languageId, latestCompatibleVersion);
|
|
}
|
|
async function parsePolicies() {
|
|
const parser = new Parser();
|
|
parser.setLanguage(typescript);
|
|
const files = await getFiles(process.cwd());
|
|
const base = path.join(process.cwd(), 'src');
|
|
const policies = [];
|
|
for (const file of files) {
|
|
const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/');
|
|
const contents = await fs_1.promises.readFile(file, { encoding: 'utf8' });
|
|
const tree = parser.parse(contents);
|
|
policies.push(...getPolicies(moduleName, tree.rootNode));
|
|
}
|
|
return policies;
|
|
}
|
|
async function getTranslations() {
|
|
const extensionGalleryServiceUrl = product.extensionsGallery?.serviceUrl;
|
|
if (!extensionGalleryServiceUrl) {
|
|
console.warn(`Skipping policy localization: No 'extensionGallery.serviceUrl' found in 'product.json'.`);
|
|
return [];
|
|
}
|
|
const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate;
|
|
if (!resourceUrlTemplate) {
|
|
console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`);
|
|
return [];
|
|
}
|
|
const version = parseVersion(packageJson.version);
|
|
const languageIds = Object.keys(Languages);
|
|
return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
|
|
.then(languageTranslations => ({ languageId, languageTranslations }))));
|
|
}
|
|
async function main() {
|
|
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
|
|
const { admx, adml } = await renderGP(policies, translations);
|
|
const root = '.build/policies/win32';
|
|
await fs_1.promises.rm(root, { recursive: true, force: true });
|
|
await fs_1.promises.mkdir(root, { recursive: true });
|
|
await fs_1.promises.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
|
|
for (const { languageId, contents } of adml) {
|
|
const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]);
|
|
await fs_1.promises.mkdir(languagePath, { recursive: true });
|
|
await fs_1.promises.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
|
|
}
|
|
}
|
|
if (require.main === module) {
|
|
main().catch(err => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWNpZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwb2xpY2llcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztnR0FHZ0c7O0FBRWhHLGlEQUFzQztBQUN0QywyQkFBb0M7QUFDcEMsNkJBQTZCO0FBQzdCLGlDQUFpQztBQUNqQyw2Q0FBeUM7QUFDekMsc0NBQXNDO0FBQ3RDLDJDQUErQjtBQUMvQixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDekQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFDOUMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFJbEQsU0FBUyxXQUFXLENBQUMsS0FBcUM7SUFDekQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2xELENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxLQUE2QjtJQUNuRCxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLEtBQTZCO0lBQ3RELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFPRCxJQUFLLFVBRUo7QUFGRCxXQUFLLFVBQVU7SUFDZCx1REFBVSxDQUFBO0FBQ1gsQ0FBQyxFQUZJLFVBQVUsS0FBVixVQUFVLFFBRWQ7QUFVRCxTQUFTLGdCQUFnQixDQUFDLE1BQWMsRUFBRSxVQUFrQixFQUFFLFNBQW9CLEVBQUUsWUFBbUM7SUFDdEgsSUFBSSxLQUF5QixDQUFDO0lBRTlCLElBQUksWUFBWSxFQUFF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
|