UNPKG

patchwork-mapconverter

Version:

Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator

726 lines 68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.jsonToWar = jsonToWar; exports.warToJson = warToJson; const TriggerDataRegistry_1 = require("../enhancements/TriggerDataRegistry"); const TriggerContent_1 = require("./data/content/TriggerContent"); const ContentTypeEnumConverter_1 = require("./util/ContentTypeEnumConverter"); const StatementTypeEnumConverter_1 = require("./util/StatementTypeEnumConverter"); const StatementType_1 = require("./data/statement/StatementType"); const ParameterTypeEnumConverter_1 = require("./util/ParameterTypeEnumConverter"); const HexBuffer_1 = require("../wc3maptranslator/HexBuffer"); const W3Buffer_1 = require("../wc3maptranslator/W3Buffer"); const LoggerFactory_1 = require("../logging/LoggerFactory"); const TriggerDefaults_1 = require("./default/TriggerDefaults"); const log = LoggerFactory_1.LoggerFactory.createLogger('TriggersTranslator'); function jsonToWar(json, formatVersion, variableFormatVersion, formatSubversion) { if (formatVersion < 0 || formatVersion > 0x80000004) { throw new Error(`Unknown map scripts format version=${formatVersion}, expected value from range [0, 0x80000004]`); } if (variableFormatVersion < 0 || variableFormatVersion > 2) { throw new Error(`Unknown map triggers->variable format version=${variableFormatVersion}, expected value [0, 2]`); } const output = new HexBuffer_1.HexBuffer(); output.addChars('WTG!'); output.addUInt(formatVersion); if (formatVersion > 0x7FFFFFFF) { if (!formatSubversion || formatSubversion < 0 || formatSubversion > 7) { throw new Error(`Unknown map triggers format subversion=${formatSubversion ?? 'undefined'}, expected value from range [0, 7]`); } output.addUInt(formatSubversion); } const finalFormatSubversion = formatSubversion ?? 0x7FFFFFFF; const parentReference = new Map(); const elementReference = new Map(); let headerCount = 0; let libraryCount = 0; let categoryCount = 0; let triggerCount = 0; let commentCount = 0; let customScriptCount = 0; let variableCount = 0; const triggerStack = [json.root]; const triggersByContentType = new Map(); while (triggerStack.length > 0) { const currentTrigger = triggerStack.pop(); if (currentTrigger == null) continue; let elementId; switch (currentTrigger.contentType) { case TriggerContent_1.ContentType.HEADER: elementId = 0x00000000 + headerCount++; triggerStack.push(...currentTrigger.children); for (const childTrigger of currentTrigger.children) { parentReference.set(childTrigger, elementId); } break; case TriggerContent_1.ContentType.LIBRARY: elementId = 0x01000000 + libraryCount++; triggerStack.push(...currentTrigger.children); for (const childTrigger of currentTrigger.children) { parentReference.set(childTrigger, elementId); } break; case TriggerContent_1.ContentType.CATEGORY: elementId = 0x02000000 + categoryCount++; triggerStack.push(...currentTrigger.children); break; case TriggerContent_1.ContentType.TRIGGER: case TriggerContent_1.ContentType.TRIGGER_SCRIPTED: elementId = 0x03000000 + triggerCount++; break; case TriggerContent_1.ContentType.COMMENT: elementId = 0x04000000 + commentCount++; break; case TriggerContent_1.ContentType.CUSTOM_SCRIPT: elementId = 0x05000000 + customScriptCount++; break; case TriggerContent_1.ContentType.VARIABLE: elementId = 0x06000000 + variableCount++; break; default: continue; } elementReference.set(currentTrigger, elementId); let contentType = currentTrigger.contentType; if (contentType === TriggerContent_1.ContentType.TRIGGER_SCRIPTED) { // Must persist order of scripts, therefore these 2 must not be processed seperately // Otherwise there will be a mismatch of script contents from .wct and .wtg script elements contentType = TriggerContent_1.ContentType.CUSTOM_SCRIPT; } if (triggersByContentType.has(contentType)) { triggersByContentType.get(contentType)?.push(currentTrigger); } else { triggersByContentType.set(contentType, [currentTrigger]); } } const saveGlobals = function (variables, parentReference) { output.addInt(variableFormatVersion); output.addInt(variables.length); for (const variable of variables) { output.addString(variable.name); output.addString(variable.type); output.addInt(+variable.userDefined); output.addInt(+variable.isArray); if (variableFormatVersion >= 2) { output.addInt(variable.arrayLength); } if (variableFormatVersion !== 0) { output.addInt(+variable.isInitialized); } output.addString(variable.initialValue); if (formatVersion >= 2147483648) { const elementId = elementReference.get(variable); if (elementId == null) { throw new Error(`Variable ${variable.name} missing ID`); } output.addInt(elementId); output.addInt(parentReference.get(variable)); } } }; const saveContainer = function (elementId, container, parentContainerId) { output.addInt(elementId); output.addString(container.name); if (formatVersion > 6) { output.addInt(+(container.contentType === TriggerContent_1.ContentType.COMMENT)); // should always be false } if (finalFormatSubversion >= 0x80000000) { output.addInt(+container.isExpanded); output.addInt(parentContainerId); } }; const saveTrigger = function (elementId, trigger, parentContainerId) { const triggerName = trigger.name; let triggerDescription; let isComment; let isEnabled; let isCustomScript; let initiallyOff; let runOnMapInit; let triggerFunctionCount; switch (trigger.contentType) { case TriggerContent_1.ContentType.HEADER: case TriggerContent_1.ContentType.LIBRARY: case TriggerContent_1.ContentType.CATEGORY: throw new Error('Cannot save container as a trigger?'); case TriggerContent_1.ContentType.TRIGGER: triggerDescription = trigger.description ?? TriggerDefaults_1.TriggerDefaults.description; isComment = false; isEnabled = trigger?.isEnabled ?? TriggerDefaults_1.TriggerDefaults.isEnabled; isCustomScript = false; initiallyOff = trigger?.initiallyOff ?? TriggerDefaults_1.TriggerDefaults.initiallyOff; runOnMapInit = trigger?.runOnMapInit ?? TriggerDefaults_1.TriggerDefaults.runOnMapInit; triggerFunctionCount = (function (trigger) { return (trigger.events ?? TriggerDefaults_1.TriggerDefaults.events).length + (trigger.conditions ?? TriggerDefaults_1.TriggerDefaults.conditions).length + (trigger.actions ?? TriggerDefaults_1.TriggerDefaults.actions).length; })(trigger); break; case TriggerContent_1.ContentType.TRIGGER_SCRIPTED: triggerDescription = trigger.description ?? TriggerDefaults_1.TriggerDefaults.description; isComment = false; isEnabled = trigger?.isEnabled ?? TriggerDefaults_1.TriggerDefaults.isEnabled; isCustomScript = true; initiallyOff = TriggerDefaults_1.TriggerDefaults.initiallyOff; runOnMapInit = trigger?.runOnMapInit ?? TriggerDefaults_1.TriggerDefaults.runOnMapInit; triggerFunctionCount = 0; break; case TriggerContent_1.ContentType.CUSTOM_SCRIPT: triggerDescription = trigger.description ?? TriggerDefaults_1.TriggerDefaults.description; isComment = false; isEnabled = trigger?.isEnabled ?? TriggerDefaults_1.TriggerDefaults.isEnabled; isCustomScript = true; initiallyOff = false; runOnMapInit = false; triggerFunctionCount = 0; break; case TriggerContent_1.ContentType.COMMENT: triggerDescription = trigger.comment ?? TriggerDefaults_1.TriggerDefaults.description; isComment = true; isEnabled = true; isCustomScript = false; initiallyOff = false; runOnMapInit = false; triggerFunctionCount = 0; break; case TriggerContent_1.ContentType.VARIABLE: default: throw new Error('Cannot save variable as a trigger?'); } // Output starts here output.addString(triggerName); output.addString(triggerDescription); if (formatVersion >= 5) { output.addInt(+isComment); } if (formatVersion < 5 || finalFormatSubversion > 0x7FFFFFFF) { if (finalFormatSubversion > 0x80000000) { output.addInt(elementId); } output.addInt(+(isEnabled)); output.addInt(+(isCustomScript)); if (formatVersion > 1) { output.addInt(+initiallyOff); } if (formatVersion > 3) { output.addInt(+runOnMapInit); } output.addInt(parentContainerId); output.addInt(triggerFunctionCount); if (triggerFunctionCount > 0) { saveTriggerFunctions(trigger); } } }; const saveTriggerFunctions = function (trigger) { for (const event of trigger.events) { output.addInt(StatementTypeEnumConverter_1.StatementTypeEnumConverter.toIdentifier(event.type)); saveTriggerFunction(event); } for (const condition of trigger.conditions) { output.addInt(StatementTypeEnumConverter_1.StatementTypeEnumConverter.toIdentifier(condition.type)); saveTriggerFunction(condition); } for (const action of trigger.actions) { output.addInt(StatementTypeEnumConverter_1.StatementTypeEnumConverter.toIdentifier(action.type)); saveTriggerFunction(action); } }; const saveTriggerFunction = function (triggerFunction) { output.addString(triggerFunction.name); if (formatVersion > 2) { output.addInt(+triggerFunction.isEnabled); } const paramCount = TriggerDataRegistry_1.TriggerDataRegistry.getParameterCount(triggerFunction.type, triggerFunction.name); const triggerParams = triggerFunction?.parameters ?? TriggerDefaults_1.TriggerDefaults.parameters; if (paramCount == null) { throw new Error(`Missing parameter count for type ${triggerFunction.type} - function ${triggerFunction.name} in triggerdata.txt`); } else if (paramCount !== triggerParams.length) { throw new Error(`Parameter count does not match for type ${triggerFunction.type} - function ${triggerFunction.name}, expected ${paramCount}, found ${triggerParams.length}`); } for (const triggerParam of triggerParams) { saveTriggerFunctionParameter(triggerParam); } if (formatVersion > 5) { const childTriggerFunctions = triggerFunction?.statements ?? TriggerDefaults_1.TriggerDefaults.statements; for (const [groupIndex, groupFunctions] of Object.entries(childTriggerFunctions)) { for (const childTriggerFunction of groupFunctions) { output.addInt(StatementTypeEnumConverter_1.StatementTypeEnumConverter.toIdentifier(childTriggerFunction.type)); output.addInt(groupIndex); saveTriggerFunction(childTriggerFunction); } } } }; const saveTriggerFunctionParameter = function (param) { output.addInt(ParameterTypeEnumConverter_1.ParameterTypeEnumConverter.toIdentifier(param.type)); output.addString(param.value); output.addInt(+(param.statement != null)); if (param.statement != null) { output.addInt(StatementTypeEnumConverter_1.StatementTypeEnumConverter.toIdentifier(param.statement.type)); saveTriggerFunction(param.statement); } output.addInt(+(param.arrayIndex != null)); if (param.arrayIndex != null) { saveTriggerFunctionParameter(param.arrayIndex); } }; const saveTriggerVariable = function (elementId, variable, parentContainerId) { output.addInt(elementId); output.addString(variable.name); output.addInt(parentContainerId); }; let totalElements = 0; for (const elements of triggersByContentType.values()) { totalElements = totalElements + elements.length; } if (formatVersion < 2147483648) { output.addInt(triggersByContentType[TriggerContent_1.ContentType.CATEGORY].length); for (const category of triggersByContentType[TriggerContent_1.ContentType.CATEGORY]) { saveContainer(elementReference.get(category), category, parentReference.get(category)); } saveGlobals(triggersByContentType.get(TriggerContent_1.ContentType.VARIABLE), parentReference); const triggerContentCount = triggersByContentType.get(TriggerContent_1.ContentType.COMMENT).length + triggersByContentType.get(TriggerContent_1.ContentType.CUSTOM_SCRIPT).length + triggersByContentType.get(TriggerContent_1.ContentType.TRIGGER).length; output.addInt(triggerContentCount); for (const comment of triggersByContentType[TriggerContent_1.ContentType.COMMENT]) { saveTrigger(elementReference.get(comment), comment, parentReference.get(comment)); } for (const trigger of triggersByContentType[TriggerContent_1.ContentType.TRIGGER]) { saveTrigger(elementReference.get(trigger), trigger, parentReference.get(trigger)); } for (const script of triggersByContentType[TriggerContent_1.ContentType.CUSTOM_SCRIPT]) { saveTrigger(elementReference.get(script), script, parentReference.get(script)); } } else { output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.HEADER).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.LIBRARY).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.CATEGORY).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.TRIGGER).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.COMMENT).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.CUSTOM_SCRIPT).length); output.addInt(0); // deleted count output.addInt(triggersByContentType.get(TriggerContent_1.ContentType.VARIABLE).length); output.addInt(0); // deleted count output.addInt(0); // Unknown content type, they just take up space, dunno what they were output.addInt(0); // deleted count saveGlobals(triggersByContentType.get(TriggerContent_1.ContentType.VARIABLE), parentReference); output.addInt(totalElements); for (const header of triggersByContentType.get(TriggerContent_1.ContentType.HEADER) ?? [{ isExpanded: TriggerDefaults_1.TriggerDefaults.isExpanded, children: TriggerDefaults_1.TriggerDefaults.children, name: '', contentType: TriggerContent_1.ContentType.HEADER, script: '', description: TriggerDefaults_1.TriggerDefaults.description }]) { saveContainer(elementReference.get(header) ?? 0, header, 0); } for (const library of triggersByContentType.get(TriggerContent_1.ContentType.LIBRARY)) { saveContainer(elementReference.get(library), library, parentReference.get(library)); } for (const container of triggersByContentType.get(TriggerContent_1.ContentType.CATEGORY)) { saveContainer(elementReference.get(container), container, parentReference.get(container)); } for (const trigger of triggersByContentType.get(TriggerContent_1.ContentType.TRIGGER)) { saveTrigger(elementReference.get(trigger), trigger, parentReference.get(trigger)); } for (const comment of triggersByContentType.get(TriggerContent_1.ContentType.COMMENT)) { saveTrigger(elementReference.get(comment), comment, parentReference.get(comment)); } for (const customScript of triggersByContentType.get(TriggerContent_1.ContentType.CUSTOM_SCRIPT)) { saveTrigger(elementReference.get(customScript), customScript, parentReference.get(customScript)); } for (const variable of triggersByContentType.get(TriggerContent_1.ContentType.VARIABLE)) { saveTriggerVariable(elementReference.get(variable), variable, parentReference.get(variable)); } } return output.getBuffer(); } function warToJson(buffer) { const input = new W3Buffer_1.W3Buffer(buffer); try { const fileId = input.readChars(4); // WTG! if (fileId !== 'WTG!') { log.warn(`Mismatched file format magic number, found '${fileId}', expected 'WTG!', will attempt parsing...`); } const formatVersion = input.readUint(); // 04 00 00 80 if (formatVersion < 0 || formatVersion > 2147483652) { log.warn(`Unknown terrain file format version '${formatVersion}', expected value [3, 2147483652], will attempt parsing...`); } let formatSubversion; if (formatVersion > 2147483647) { formatSubversion = input.readInt(); // 4 = Roc, 7 = TFT } else { formatSubversion = 0x7FFFFFFF; } const elementRelations = new Map(); const containers = {}; const content = {}; const customScripts = []; const allGlobalVariables = {}; const loadGlobals = function () { const variableFormatVersion = input.readInt(); // [0, 2] const existingVariablesCount = input.readInt(); for (let i = 0; i < existingVariablesCount; i++) { const name = input.readString(); const type = input.readString(); const userDefined = !!input.readInt(); // always 1? const isArray = !!input.readInt(); let arrayLength; if (variableFormatVersion >= 2) { arrayLength = input.readInt(); } else { arrayLength = 1; } let isInitialized = false; if (variableFormatVersion !== 0) { isInitialized = !!input.readInt(); } const initialValue = input.readString(); if (variableFormatVersion === 0) { isInitialized = initialValue.length > 0; } const globalVariable = { name, contentType: TriggerContent_1.ContentType.VARIABLE, type, userDefined, isArray, arrayLength, isInitialized, initialValue }; if (formatVersion >= 2147483648) { const variableId = input.readInt(); // last byte 06? allGlobalVariables[variableId] = globalVariable; content[variableId] = globalVariable; elementRelations.set(variableId, input.readInt()); } else { allGlobalVariables[i] = globalVariable; content[i] = globalVariable; // TODO: required something? } } }; const loadContainer = function (type) { const elementId = input.readInt(); const name = input.readString(); if (formatVersion > 6) { const isComment = !!input.readInt(); // pretty sure containers cannot be comments... } let isExpanded; if (formatSubversion >= 0x80000000) { isExpanded = !!input.readInt(); const parentContainerId = input.readInt(); elementRelations.set(elementId, parentContainerId); } else { isExpanded = false; } const container = { name, isExpanded, contentType: type, children: [] }; containers[elementId] = container; return container; }; const loadTrigger = function (index, contentType) { const name = input.readString(); const description = input.readString(); let isComment; if (formatVersion >= 5) { isComment = !!input.readInt(); } else { isComment = false; } if (formatVersion < 5 || formatSubversion > 0x7FFFFFFF) { let elementId; // Double check this if (formatSubversion >= 0x80000000) { elementId = input.readInt(); } else { elementId = index; } const isEnabled = !!input.readInt(); const isCustomScript = !!input.readInt(); let initiallyOff; if (formatVersion > 1) { initiallyOff = !!input.readInt(); } else { initiallyOff = false; } let runOnMapInit; if (formatVersion > 3) { runOnMapInit = !!input.readInt(); } else { runOnMapInit = false; } const parentContainerId = input.readInt(); elementRelations.set(elementId, parentContainerId); const triggerFunctionCount = input.readInt(); if (contentType === TriggerContent_1.ContentType.TRIGGER && isCustomScript) { contentType = TriggerContent_1.ContentType.TRIGGER_SCRIPTED; } else if (contentType === TriggerContent_1.ContentType.TRIGGER && isComment) { contentType = TriggerContent_1.ContentType.COMMENT; } let triggerContent = null; switch (contentType) { case TriggerContent_1.ContentType.TRIGGER: triggerContent = { name, contentType, description, isEnabled, initiallyOff, runOnMapInit, events: [], conditions: [], actions: [] }; content[elementId] = triggerContent; customScripts.push(null); break; case TriggerContent_1.ContentType.TRIGGER_SCRIPTED: triggerContent = { name, contentType, description, isEnabled, runOnMapInit, script: '' }; content[elementId] = triggerContent; customScripts.push(triggerContent); break; case TriggerContent_1.ContentType.COMMENT: content[elementId] = { name, contentType, comment: description }; break; case TriggerContent_1.ContentType.CUSTOM_SCRIPT: triggerContent = { name, contentType, description, isEnabled, script: '' }; content[elementId] = triggerContent; customScripts.push(triggerContent); break; } for (let i = 0; i < triggerFunctionCount; i++) { const functionType = StatementTypeEnumConverter_1.StatementTypeEnumConverter.toEnum(input.readInt()); const triggerFunction = loadTriggerFunction(functionType); if (triggerContent != null && triggerContent.contentType === TriggerContent_1.ContentType.TRIGGER) { const trigger = triggerContent; switch (triggerFunction.type) { case StatementType_1.StatementType.EVENT: trigger.events.push(triggerFunction); break; case StatementType_1.StatementType.CONDITION: trigger.conditions.push(triggerFunction); break; case StatementType_1.StatementType.ACTION: trigger.actions.push(triggerFunction); break; case StatementType_1.StatementType.CALL: log.warn(`Sussy statement call when ECA expected - trigger: ${triggerContent.name} - function: ${triggerFunction.name}`); // sounds illegal - ignore? break; } } } } }; const loadTriggerFunction = function (type) { const name = input.readString(); let isEnabled; if (formatVersion > 2) { isEnabled = !!input.readInt(); } else { isEnabled = true; } const paramCount = TriggerDataRegistry_1.TriggerDataRegistry.getParameterCount(type, name); if (paramCount == null) { throw new Error(`Missing parameter count for type ${type} - function ${name} in triggerdata.txt`); } const triggerFunction = { name, type, isEnabled, parameters: [], statements: {} }; for (let i = 0; i < paramCount; i++) { triggerFunction.parameters[i] = loadTriggerFunctionParameter(); } if (formatVersion > 5) { const triggerFunctionCount = input.readInt(); for (let i = 0; i < triggerFunctionCount; i++) { const functionType = StatementTypeEnumConverter_1.StatementTypeEnumConverter.toEnum(input.readInt()); const groupIndex = input.readInt(); // if-then-else groups let statements; if (triggerFunction.statements[groupIndex] == null) { statements = triggerFunction.statements[groupIndex] = []; } else { statements = triggerFunction.statements[groupIndex]; } statements.push(loadTriggerFunction(functionType)); } } return triggerFunction; }; const loadTriggerFunctionParameter = function () { const type = ParameterTypeEnumConverter_1.ParameterTypeEnumConverter.toEnum(input.readInt()); const value = input.readString(); const hasSubParams = !!input.readInt(); let statement; if (hasSubParams) { const functionType = StatementTypeEnumConverter_1.StatementTypeEnumConverter.toEnum(input.readInt()); statement = loadTriggerFunction(functionType); } const isArray = !!input.readInt(); let arrayIndex; if (isArray) { arrayIndex = loadTriggerFunctionParameter(); } return { type, value, statement, arrayIndex }; }; const loadTriggerVariable = function () { const elementId = input.readInt(); const name = input.readString(); // excess data const parentContainerId = input.readInt(); elementRelations.set(elementId, parentContainerId); }; if (formatVersion < 2147483648) { const header = { name: 'header', description: '', contentType: TriggerContent_1.ContentType.HEADER, isExpanded: true, script: '', children: [] }; customScripts.push(header); const triggerCategoryCount = input.readInt(); for (let i = 0; i < triggerCategoryCount; i++) { loadContainer(TriggerContent_1.ContentType.CATEGORY); } loadGlobals(); const triggerCount = input.readInt(); for (let i = 0; i < triggerCount; i++) { loadTrigger(i, TriggerContent_1.ContentType.TRIGGER); } } else { // counts: headers. libraries, categories, triggers, comments, custom scripts, variables, unknown element for (let i = 0; i < 8; i++) { const elementCount = input.readInt(); for (let j = 0; j < elementCount; j++) { input.readInt(); // deleted element id } } loadGlobals(); const elementCount = input.readInt(); for (let i = 0; i < elementCount; i++) { let element; const type = ContentTypeEnumConverter_1.ContentTypeEnumConverter.toEnum(input.readInt()); switch (type) { case TriggerContent_1.ContentType.HEADER: case TriggerContent_1.ContentType.LIBRARY: case TriggerContent_1.ContentType.CATEGORY: element = loadContainer(type); if (type === TriggerContent_1.ContentType.HEADER) { customScripts.push(element); } break; case TriggerContent_1.ContentType.TRIGGER: case TriggerContent_1.ContentType.COMMENT: case TriggerContent_1.ContentType.CUSTOM_SCRIPT: loadTrigger(i, type); break; case TriggerContent_1.ContentType.VARIABLE: loadTriggerVariable(); break; } } } let root = null; const missingElements = []; // Generate data tree structure for (const [elementId, parentId] of elementRelations.entries()) { if (parentId === -1) { if (containers[elementId] != null) { root = containers[elementId]; } } else { let parent; if (containers[parentId] != null) { parent = containers[parentId]; } let element; if (containers[elementId] != null) { element = containers[elementId]; } else if (content[elementId] != null) { element = content[elementId]; } if (parent == null || element == null) { missingElements.push({ foundElement: element != null, foundParent: parent != null, elementId, parentId, data: parent != null ? parent : element }); continue; } parent.children.push(element); } } return [{ root: root ?? { isExpanded: false, children: [], name: '', contentType: TriggerContent_1.ContentType.HEADER }, scriptReferences: customScripts }, formatVersion, formatSubversion]; } catch (e) { log.error(`Error at offset: ${input._offset}`); throw e; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJpZ2dlcnNUcmFuc2xhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zbGF0b3IvVHJpZ2dlcnNUcmFuc2xhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBK0JBLDhCQXFXQztBQUVELDhCQXlZQztBQS93QkQsNkVBQXlFO0FBRXpFLGtFQUFnRjtBQUNoRiw4RUFBMEU7QUFPMUUsa0ZBQThFO0FBQzlFLGtFQUE4RDtBQUM5RCxrRkFBOEU7QUFFOUUsNkRBQXlEO0FBQ3pELDJEQUF1RDtBQUd2RCw0REFBd0Q7QUFJeEQsK0RBQTJEO0FBRTNELE1BQU0sR0FBRyxHQUFHLDZCQUFhLENBQUMsWUFBWSxDQUFDLG9CQUFvQixDQUFDLENBQUE7QUFPNUQsU0FBZ0IsU0FBUyxDQUFFLElBQTZCLEVBQUUsYUFBc0IsRUFBRSxxQkFBOEIsRUFBRSxnQkFBMEI7SUFDMUksSUFBSSxhQUFhLEdBQUcsQ0FBQyxJQUFJLGFBQWEsR0FBRyxVQUFVLEVBQUUsQ0FBQztRQUNwRCxNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxhQUFhLDZDQUE2QyxDQUFDLENBQUE7SUFDbkgsQ0FBQztJQUVELElBQUkscUJBQXFCLEdBQUcsQ0FBQyxJQUFJLHFCQUFxQixHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNELE1BQU0sSUFBSSxLQUFLLENBQUMsaURBQWlELHFCQUFxQix5QkFBeUIsQ0FBQyxDQUFBO0lBQ2xILENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLHFCQUFTLEVBQUUsQ0FBQTtJQUM5QixNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3ZCLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDN0IsSUFBSSxhQUFhLEdBQUcsVUFBVSxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLGdCQUFnQixJQUFJLGdCQUFnQixHQUFHLENBQUMsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUs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