UNPKG

@oaklean/profiler-core

Version:

Part of the @oaklean suite. It provides all basic functions to work with the `.oak` file format. It allows parsing the `.oak` file format as well as tools for analyzing the measurement values. It also provides all necessary capabilities required for prec

443 lines 44.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SensorValues = exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = exports.EXTERN_SENSOR_VALUE_NAMES = exports.INTERN_SENSOR_VALUE_NAMES = exports.AGGREGATED_SENSOR_VALUE_NAMES = exports.SENSOR_VALUES_BYTE_SIZE_MAP = void 0; const BaseModel_1 = require("./BaseModel"); const BufferHelper_1 = require("../helper/BufferHelper"); // Types const types_1 = require("../types"); const UnitHelper_1 = require("../helper/UnitHelper"); exports.SENSOR_VALUES_BYTE_SIZE_MAP = { profilerHits: types_1.PrimitiveBufferTypes.UInt, selfCPUTime: types_1.PrimitiveBufferTypes.UInt, aggregatedCPUTime: types_1.PrimitiveBufferTypes.UInt, internCPUTime: types_1.PrimitiveBufferTypes.UInt, externCPUTime: types_1.PrimitiveBufferTypes.UInt, langInternalCPUTime: types_1.PrimitiveBufferTypes.UInt, selfCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, aggregatedCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, internCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, externCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, langInternalCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, selfRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, aggregatedRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, internRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, externRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, langInternalRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double }; exports.AGGREGATED_SENSOR_VALUE_NAMES = [ 'aggregatedCPUTime', 'aggregatedCPUEnergyConsumption', 'aggregatedRAMEnergyConsumption' ]; exports.INTERN_SENSOR_VALUE_NAMES = [ 'internCPUTime', 'internCPUEnergyConsumption', 'internRAMEnergyConsumption' ]; exports.EXTERN_SENSOR_VALUE_NAMES = [ 'externCPUTime', 'externCPUEnergyConsumption', 'externRAMEnergyConsumption' ]; exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = [ 'langInternalCPUTime', 'langInternalCPUEnergyConsumption', 'langInternalRAMEnergyConsumption' ]; class SensorValues extends BaseModel_1.BaseModel { constructor({ profilerHits, selfCPUTime, aggregatedCPUTime, internCPUTime, externCPUTime, langInternalCPUTime, selfCPUEnergyConsumption, aggregatedCPUEnergyConsumption, internCPUEnergyConsumption, externCPUEnergyConsumption, langInternalCPUEnergyConsumption, selfRAMEnergyConsumption, aggregatedRAMEnergyConsumption, internRAMEnergyConsumption, externRAMEnergyConsumption, langInternalRAMEnergyConsumption }) { super(); this._profilerHits = profilerHits; this._selfCPUTime = selfCPUTime; this._aggregatedCPUTime = aggregatedCPUTime; this._internCPUTime = internCPUTime; this._externCPUTime = externCPUTime; this._langInternalCPUTime = langInternalCPUTime; this._selfCPUEnergyConsumption = selfCPUEnergyConsumption; this._aggregatedCPUEnergyConsumption = aggregatedCPUEnergyConsumption; this._internCPUEnergyConsumption = internCPUEnergyConsumption; this._externCPUEnergyConsumption = externCPUEnergyConsumption; this._langInternalCPUEnergyConsumption = langInternalCPUEnergyConsumption; this._selfRAMEnergyConsumption = selfRAMEnergyConsumption; this._aggregatedRAMEnergyConsumption = aggregatedRAMEnergyConsumption; this._internRAMEnergyConsumption = internRAMEnergyConsumption; this._externRAMEnergyConsumption = externRAMEnergyConsumption; this._langInternalRAMEnergyConsumption = langInternalRAMEnergyConsumption; } set profilerHits(v) { this._profilerHits = v; } get profilerHits() { return this._profilerHits || 0; } // CPU Time set selfCPUTime(v) { this._selfCPUTime = v; } get selfCPUTime() { return this._selfCPUTime || 0; } set aggregatedCPUTime(v) { this._aggregatedCPUTime = v; } get aggregatedCPUTime() { return this._aggregatedCPUTime || 0; } set internCPUTime(v) { this._internCPUTime = v; } get internCPUTime() { return this._internCPUTime || 0; } set externCPUTime(v) { this._externCPUTime = v; } get externCPUTime() { return this._externCPUTime || 0; } set langInternalCPUTime(v) { this._langInternalCPUTime = v; } get langInternalCPUTime() { return this._langInternalCPUTime || 0; } // CPU Energy set selfCPUEnergyConsumption(v) { this._selfCPUEnergyConsumption = v; } get selfCPUEnergyConsumption() { return this._selfCPUEnergyConsumption || 0; } set aggregatedCPUEnergyConsumption(v) { this._aggregatedCPUEnergyConsumption = v; } get aggregatedCPUEnergyConsumption() { return this._aggregatedCPUEnergyConsumption || 0; } set internCPUEnergyConsumption(v) { this._internCPUEnergyConsumption = v; } get internCPUEnergyConsumption() { return this._internCPUEnergyConsumption || 0; } set externCPUEnergyConsumption(v) { this._externCPUEnergyConsumption = v; } get externCPUEnergyConsumption() { return this._externCPUEnergyConsumption || 0; } set langInternalCPUEnergyConsumption(v) { this._langInternalCPUEnergyConsumption = v; } get langInternalCPUEnergyConsumption() { return this._langInternalCPUEnergyConsumption || 0; } // RAM Energy set selfRAMEnergyConsumption(v) { this._selfRAMEnergyConsumption = v; } get selfRAMEnergyConsumption() { return this._selfRAMEnergyConsumption || 0; } set aggregatedRAMEnergyConsumption(v) { this._aggregatedRAMEnergyConsumption = v; } get aggregatedRAMEnergyConsumption() { return this._aggregatedRAMEnergyConsumption || 0; } set internRAMEnergyConsumption(v) { this._internRAMEnergyConsumption = v; } get internRAMEnergyConsumption() { return this._internRAMEnergyConsumption || 0; } set externRAMEnergyConsumption(v) { this._externRAMEnergyConsumption = v; } get externRAMEnergyConsumption() { return this._externRAMEnergyConsumption || 0; } set langInternalRAMEnergyConsumption(v) { this._langInternalRAMEnergyConsumption = v; } get langInternalRAMEnergyConsumption() { return this._langInternalRAMEnergyConsumption || 0; } validate(path, identifier) { const valid = (this.profilerHits >= 0 && this.selfCPUTime >= 0 && this.aggregatedCPUTime >= 0 && this.internCPUTime >= 0 && this.externCPUTime >= 0 && this.langInternalCPUTime >= 0 && this.selfCPUEnergyConsumption >= 0 && this.aggregatedCPUEnergyConsumption >= 0 && this.internCPUEnergyConsumption >= 0 && this.externCPUEnergyConsumption >= 0 && this.langInternalCPUEnergyConsumption >= 0, this.selfRAMEnergyConsumption >= 0 && this.aggregatedRAMEnergyConsumption >= 0 && this.internRAMEnergyConsumption >= 0 && this.externRAMEnergyConsumption >= 0 && this.langInternalRAMEnergyConsumption >= 0); if (!valid) { throw new Error(`SourceNodeMetaData.validate: Assertion error (SourceNode validation) ${path}:${identifier} \n` + JSON.stringify(this, null, 2) + '\n'); } } // IMPORTANT to change when new measurement type gets added static sum(...args) { const result = new SensorValues({}); for (const sensorValues of args) { result.profilerHits += sensorValues.profilerHits; result.selfCPUTime = (result.selfCPUTime + sensorValues.selfCPUTime); result.aggregatedCPUTime = (result.aggregatedCPUTime + sensorValues.aggregatedCPUTime); result.internCPUTime = (result.internCPUTime + sensorValues.internCPUTime); result.externCPUTime = (result.externCPUTime + sensorValues.externCPUTime); result.langInternalCPUTime = (result.langInternalCPUTime + sensorValues.langInternalCPUTime); result.selfCPUEnergyConsumption = (result.selfCPUEnergyConsumption + sensorValues.selfCPUEnergyConsumption); result.aggregatedCPUEnergyConsumption = (result.aggregatedCPUEnergyConsumption + sensorValues.aggregatedCPUEnergyConsumption); result.internCPUEnergyConsumption = (result.internCPUEnergyConsumption + sensorValues.internCPUEnergyConsumption); result.externCPUEnergyConsumption = (result.externCPUEnergyConsumption + sensorValues.externCPUEnergyConsumption); result.langInternalCPUEnergyConsumption = (result.langInternalCPUEnergyConsumption + sensorValues.langInternalCPUEnergyConsumption); result.selfRAMEnergyConsumption = (result.selfRAMEnergyConsumption + sensorValues.selfRAMEnergyConsumption); result.aggregatedRAMEnergyConsumption = (result.aggregatedRAMEnergyConsumption + sensorValues.aggregatedRAMEnergyConsumption); result.internRAMEnergyConsumption = (result.internRAMEnergyConsumption + sensorValues.internRAMEnergyConsumption); result.externRAMEnergyConsumption = (result.externRAMEnergyConsumption + sensorValues.externRAMEnergyConsumption); result.langInternalRAMEnergyConsumption = (result.langInternalRAMEnergyConsumption + sensorValues.langInternalRAMEnergyConsumption); } return result; } // IMPORTANT to change when new measurement type gets added static max(...args) { const result = new SensorValues({}); for (const sensorValues of args) { result.profilerHits = Math.max(result.profilerHits, sensorValues.profilerHits); result.selfCPUTime = Math.max(result.selfCPUTime, sensorValues.selfCPUTime); result.aggregatedCPUTime = Math.max(result.aggregatedCPUTime, sensorValues.aggregatedCPUTime); result.internCPUTime = Math.max(result.internCPUTime, sensorValues.internCPUTime); result.externCPUTime = Math.max(result.externCPUTime, sensorValues.externCPUTime); result.langInternalCPUTime = Math.max(result.langInternalCPUTime, sensorValues.langInternalCPUTime); result.selfCPUEnergyConsumption = Math.max(result.selfCPUEnergyConsumption, sensorValues.selfCPUEnergyConsumption); result.aggregatedCPUEnergyConsumption = Math.max(result.aggregatedCPUEnergyConsumption, sensorValues.aggregatedCPUEnergyConsumption); result.internCPUEnergyConsumption = Math.max(result.internCPUEnergyConsumption, sensorValues.internCPUEnergyConsumption); result.externCPUEnergyConsumption = Math.max(result.externCPUEnergyConsumption, sensorValues.externCPUEnergyConsumption); result.langInternalCPUEnergyConsumption = Math.max(result.langInternalCPUEnergyConsumption, sensorValues.langInternalCPUEnergyConsumption); result.selfRAMEnergyConsumption = Math.max(result.selfRAMEnergyConsumption, sensorValues.selfRAMEnergyConsumption); result.aggregatedRAMEnergyConsumption = Math.max(result.aggregatedRAMEnergyConsumption, sensorValues.aggregatedRAMEnergyConsumption); result.internRAMEnergyConsumption = Math.max(result.internRAMEnergyConsumption, sensorValues.internRAMEnergyConsumption); result.externRAMEnergyConsumption = Math.max(result.externRAMEnergyConsumption, sensorValues.externRAMEnergyConsumption); result.langInternalRAMEnergyConsumption = Math.max(result.langInternalRAMEnergyConsumption, sensorValues.langInternalRAMEnergyConsumption); } return result; } // IMPORTANT to change when new measurement type gets added static equals(...args) { if (args.length === 0) { return true; } const compare = args[0]; for (let i = 1; i < args.length; i++) { const a = args[i]; if (a.profilerHits !== compare.profilerHits || a.selfCPUTime !== compare.selfCPUTime || a.aggregatedCPUTime !== compare.aggregatedCPUTime || a.internCPUTime !== compare.internCPUTime || a.externCPUTime !== compare.externCPUTime || a.langInternalCPUTime !== compare.langInternalCPUTime || a.selfCPUEnergyConsumption !== compare.selfCPUEnergyConsumption || a.aggregatedCPUEnergyConsumption !== compare.aggregatedCPUEnergyConsumption || a.internCPUEnergyConsumption !== compare.internCPUEnergyConsumption || a.externCPUEnergyConsumption !== compare.externCPUEnergyConsumption || a.langInternalCPUEnergyConsumption !== compare.langInternalCPUEnergyConsumption || a.selfRAMEnergyConsumption !== compare.selfRAMEnergyConsumption || a.aggregatedRAMEnergyConsumption !== compare.aggregatedRAMEnergyConsumption || a.internRAMEnergyConsumption !== compare.internRAMEnergyConsumption || a.externRAMEnergyConsumption !== compare.externRAMEnergyConsumption || a.langInternalRAMEnergyConsumption !== compare.langInternalRAMEnergyConsumption) { return false; } } return true; } undefinedIfZero(value) { if (value === 0) { return undefined; } return value; } toJSON() { return { profilerHits: this.undefinedIfZero(this.profilerHits), selfCPUTime: this.undefinedIfZero(this.selfCPUTime), aggregatedCPUTime: this.undefinedIfZero(this.aggregatedCPUTime), internCPUTime: this.undefinedIfZero(this.internCPUTime), externCPUTime: this.undefinedIfZero(this.externCPUTime), langInternalCPUTime: this.undefinedIfZero(this.langInternalCPUTime), selfCPUEnergyConsumption: this.undefinedIfZero(this.selfCPUEnergyConsumption), aggregatedCPUEnergyConsumption: this.undefinedIfZero(this.aggregatedCPUEnergyConsumption), internCPUEnergyConsumption: this.undefinedIfZero(this.internCPUEnergyConsumption), externCPUEnergyConsumption: this.undefinedIfZero(this.externCPUEnergyConsumption), langInternalCPUEnergyConsumption: this.undefinedIfZero(this.langInternalCPUEnergyConsumption), selfRAMEnergyConsumption: this.undefinedIfZero(this.selfRAMEnergyConsumption), aggregatedRAMEnergyConsumption: this.undefinedIfZero(this.aggregatedRAMEnergyConsumption), internRAMEnergyConsumption: this.undefinedIfZero(this.internRAMEnergyConsumption), externRAMEnergyConsumption: this.undefinedIfZero(this.externRAMEnergyConsumption), langInternalRAMEnergyConsumption: this.undefinedIfZero(this.langInternalRAMEnergyConsumption) }; } static fromJSON(json) { let data; if (typeof json === 'string') { data = JSON.parse(json); } else { data = json; } const result = new SensorValues({ profilerHits: data.profilerHits || 0, selfCPUTime: data.selfCPUTime || 0, aggregatedCPUTime: data.aggregatedCPUTime || 0, internCPUTime: data.internCPUTime || 0, externCPUTime: data.externCPUTime || 0, langInternalCPUTime: data.langInternalCPUTime || 0, selfCPUEnergyConsumption: data.selfCPUEnergyConsumption || 0, aggregatedCPUEnergyConsumption: data.aggregatedCPUEnergyConsumption || 0, internCPUEnergyConsumption: data.internCPUEnergyConsumption || 0, externCPUEnergyConsumption: data.externCPUEnergyConsumption || 0, langInternalCPUEnergyConsumption: data.langInternalCPUEnergyConsumption || 0, selfRAMEnergyConsumption: data.selfRAMEnergyConsumption || 0, aggregatedRAMEnergyConsumption: data.aggregatedRAMEnergyConsumption || 0, internRAMEnergyConsumption: data.internRAMEnergyConsumption || 0, externRAMEnergyConsumption: data.externRAMEnergyConsumption || 0, langInternalRAMEnergyConsumption: data.langInternalRAMEnergyConsumption || 0 }); return result; } toBuffer(tag) { return BufferHelper_1.BufferHelper.numberMapToBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, // eslint-disable-next-line @typescript-eslint/no-explicit-any this, 0, tag + '.SensorValues.toBuffer'); } static consumeFromBuffer(buffer) { const { instance, remainingBuffer } = BufferHelper_1.BufferHelper.numberMapFromBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, buffer); return { instance: new SensorValues(instance), remainingBuffer }; } // IMPORTANT to change when new measurement type gets added addToSelf(other, sign = 1) { this.selfCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.selfCPUTime, other.selfCPUTime, sign); this.selfCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign); this.selfRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addToAggregated(other, sign = 1) { this.aggregatedCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.aggregatedCPUTime, other.aggregatedCPUTime, sign); this.aggregatedCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.aggregatedRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addToIntern(other, sign = 1) { this.internCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.internCPUTime, other.aggregatedCPUTime, sign); this.internCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.internRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addToExtern(other, sign = 1) { this.externCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.externCPUTime, other.aggregatedCPUTime, sign); this.externCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.externRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addSelfToExtern(other, sign = 1) { this.externCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.externCPUTime, other.selfCPUTime, sign); this.externCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign); this.externRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addToLangInternal(other, sign = 1) { this.langInternalCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.langInternalCPUTime, other.aggregatedCPUTime, sign); this.langInternalCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.langInternalRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); return this; } // IMPORTANT to change when new measurement type gets added addSelfToLangInternal(other, sign = 1) { this.langInternalCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.langInternalCPUTime, other.selfCPUTime, sign); this.langInternalCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign); this.langInternalRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign); return this; } add({ internSensorValues, externSensorValues, langInternalSensorValues }) { const result = SensorValues.fromJSON(this.toJSON()); if (internSensorValues) { result.addToAggregated(internSensorValues); result.addToIntern(internSensorValues); } if (externSensorValues) { result.addToAggregated(externSensorValues); result.addToExtern(externSensorValues); } if (langInternalSensorValues) { result.addToAggregated(langInternalSensorValues); result.addToLangInternal(langInternalSensorValues); } return result; } clone() { return new SensorValues(this.toJSON()); } // clones the object but removes all reference values to other objects // the aggregated values equal the self values cloneAsIsolated() { // IMPORTANT to change when new measurement type gets added return new SensorValues({ profilerHits: this.profilerHits, selfCPUTime: this.selfCPUTime, aggregatedCPUTime: this.selfCPUTime, selfCPUEnergyConsumption: this.selfCPUEnergyConsumption, aggregatedCPUEnergyConsumption: this.selfCPUEnergyConsumption, selfRAMEnergyConsumption: this.selfRAMEnergyConsumption, aggregatedRAMEnergyConsumption: this.selfRAMEnergyConsumption }); } // clones the object but only the aggregated values cloneAsAggregated() { const result = new SensorValues({}); result.addToAggregated(this); return result; } } exports.SensorValues = SensorValues; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2Vuc29yVmFsdWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVsL1NlbnNvclZhbHVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFFdkMseURBQXFEO0FBQ3JELFFBQVE7QUFDUixvQ0FTaUI7QUFDakIscURBQWlEO0FBRXBDLFFBQUEsMkJBQTJCLEdBQTZCO0lBQ3BFLFlBQVksRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBRXZDLFdBQVcsRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBQ3RDLGlCQUFpQixFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDNUMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsbUJBQW1CLEVBQUUsNEJBQW9CLENBQUMsSUFBSTtJQUU5Qyx3QkFBd0IsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3JELDhCQUE4QixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDM0QsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCwwQkFBMEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3ZELGdDQUFnQyxFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFFN0Qsd0JBQXdCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUNyRCw4QkFBOEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQzNELDBCQUEwQixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDdkQsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCxnQ0FBZ0MsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0NBQzdELENBQUE7QUFFWSxRQUFBLDZCQUE2QixHQUE0QjtJQUNyRSxtQkFBbUI7SUFDbkIsZ0NBQWdDO0lBQ2hDLGdDQUFnQztDQUNoQyxDQUFBO0FBRVksUUFBQSx5QkFBeUIsR0FBNEI7SUFDakUsZUFBZTtJQUNmLDRCQUE0QjtJQUM1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