UNPKG

@angular/compiler

Version:

Angular - the compiler library

470 lines • 85.1 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define("@angular/compiler/src/render3/r3_template_transform", ["require", "exports", "tslib", "@angular/compiler/src/ml_parser/ast", "@angular/compiler/src/ml_parser/html_whitespaces", "@angular/compiler/src/ml_parser/tags", "@angular/compiler/src/parse_util", "@angular/compiler/src/style_url_resolver", "@angular/compiler/src/template_parser/template_preparser", "@angular/compiler/src/render3/r3_ast", "@angular/compiler/src/render3/view/i18n/util"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.htmlAstToRender3Ast = void 0; var tslib_1 = require("tslib"); var html = require("@angular/compiler/src/ml_parser/ast"); var html_whitespaces_1 = require("@angular/compiler/src/ml_parser/html_whitespaces"); var tags_1 = require("@angular/compiler/src/ml_parser/tags"); var parse_util_1 = require("@angular/compiler/src/parse_util"); var style_url_resolver_1 = require("@angular/compiler/src/style_url_resolver"); var template_preparser_1 = require("@angular/compiler/src/template_parser/template_preparser"); var t = require("@angular/compiler/src/render3/r3_ast"); var util_1 = require("@angular/compiler/src/render3/view/i18n/util"); var BIND_NAME_REGEXP = /^(?:(bind-)|(let-)|(ref-|#)|(on-)|(bindon-)|(@))(.*)$/; // Group 1 = "bind-" var KW_BIND_IDX = 1; // Group 2 = "let-" var KW_LET_IDX = 2; // Group 3 = "ref-/#" var KW_REF_IDX = 3; // Group 4 = "on-" var KW_ON_IDX = 4; // Group 5 = "bindon-" var KW_BINDON_IDX = 5; // Group 6 = "@" var KW_AT_IDX = 6; // Group 7 = the identifier after "bind-", "let-", "ref-/#", "on-", "bindon-" or "@" var IDENT_KW_IDX = 7; var BINDING_DELIMS = { BANANA_BOX: { start: '[(', end: ')]' }, PROPERTY: { start: '[', end: ']' }, EVENT: { start: '(', end: ')' }, }; var TEMPLATE_ATTR_PREFIX = '*'; function htmlAstToRender3Ast(htmlNodes, bindingParser, options) { var transformer = new HtmlAstToIvyAst(bindingParser, options); var ivyNodes = html.visitAll(transformer, htmlNodes); // Errors might originate in either the binding parser or the html to ivy transformer var allErrors = bindingParser.errors.concat(transformer.errors); var result = { nodes: ivyNodes, errors: allErrors, styleUrls: transformer.styleUrls, styles: transformer.styles, ngContentSelectors: transformer.ngContentSelectors }; if (options.collectCommentNodes) { result.commentNodes = transformer.commentNodes; } return result; } exports.htmlAstToRender3Ast = htmlAstToRender3Ast; var HtmlAstToIvyAst = /** @class */ (function () { function HtmlAstToIvyAst(bindingParser, options) { this.bindingParser = bindingParser; this.options = options; this.errors = []; this.styles = []; this.styleUrls = []; this.ngContentSelectors = []; // This array will be populated if `Render3ParseOptions['collectCommentNodes']` is true this.commentNodes = []; this.inI18nBlock = false; } // HTML visitor HtmlAstToIvyAst.prototype.visitElement = function (element) { var e_1, _a; var _this = this; var isI18nRootElement = util_1.isI18nRootNode(element.i18n); if (isI18nRootElement) { if (this.inI18nBlock) { this.reportError('Cannot mark an element as translatable inside of a translatable section. Please remove the nested i18n marker.', element.sourceSpan); } this.inI18nBlock = true; } var preparsedElement = template_preparser_1.preparseElement(element); if (preparsedElement.type === template_preparser_1.PreparsedElementType.SCRIPT) { return null; } else if (preparsedElement.type === template_preparser_1.PreparsedElementType.STYLE) { var contents = textContents(element); if (contents !== null) { this.styles.push(contents); } return null; } else if (preparsedElement.type === template_preparser_1.PreparsedElementType.STYLESHEET && style_url_resolver_1.isStyleUrlResolvable(preparsedElement.hrefAttr)) { this.styleUrls.push(preparsedElement.hrefAttr); return null; } // Whether the element is a `<ng-template>` var isTemplateElement = tags_1.isNgTemplate(element.name); var parsedProperties = []; var boundEvents = []; var variables = []; var references = []; var attributes = []; var i18nAttrsMeta = {}; var templateParsedProperties = []; var templateVariables = []; // Whether the element has any *-attribute var elementHasInlineTemplate = false; try { for (var _b = tslib_1.__values(element.attrs), _c = _b.next(); !_c.done; _c = _b.next()) { var attribute = _c.value; var hasBinding = false; var normalizedName = normalizeAttributeName(attribute.name); // `*attr` defines template bindings var isTemplateBinding = false; if (attribute.i18n) { i18nAttrsMeta[attribute.name] = attribute.i18n; } if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) { // *-attributes if (elementHasInlineTemplate) { this.reportError("Can't have multiple template bindings on one element. Use only one attribute prefixed with *", attribute.sourceSpan); } isTemplateBinding = true; elementHasInlineTemplate = true; var templateValue = attribute.value; var templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX.length); var parsedVariables = []; var absoluteValueOffset = attribute.valueSpan ? attribute.valueSpan.start.offset : // If there is no value span the attribute does not have a value, like `attr` in //`<div attr></div>`. In this case, point to one character beyond the last character of // the attribute name. attribute.sourceSpan.start.offset + attribute.name.length; this.bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables, true /* isIvyAst */); templateVariables.push.apply(templateVariables, tslib_1.__spreadArray([], tslib_1.__read(parsedVariables.map(function (v) { return new t.Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan); })))); } else { // Check for variables, events, property bindings, interpolation hasBinding = this.parseAttribute(isTemplateElement, attribute, [], parsedProperties, boundEvents, variables, references); } if (!hasBinding && !isTemplateBinding) { // don't include the bindings as attributes as well in the AST attributes.push(this.visitAttribute(attribute)); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } var children = html.visitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children); var parsedElement; if (preparsedElement.type === template_preparser_1.PreparsedElementType.NG_CONTENT) { // `<ng-content>` if (element.children && !element.children.every(function (node) { return isEmptyTextNode(node) || isCommentNode(node); })) { this.reportError("<ng-content> element cannot have content.", element.sourceSpan); } var selector = preparsedElement.selectAttr; var attrs = element.attrs.map(function (attr) { return _this.visitAttribute(attr); }); parsedElement = new t.Content(selector, attrs, element.sourceSpan, element.i18n); this.ngContentSelectors.push(selector); } else if (isTemplateElement) { // `<ng-template>` var attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); parsedElement = new t.Template(element.name, attributes, attrs.bound, boundEvents, [ /* no template attributes */], children, references, variables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); } else { var attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); parsedElement = new t.Element(element.name, attributes, attrs.bound, boundEvents, children, references, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); } if (elementHasInlineTemplate) { // If this node is an inline-template (e.g. has *ngFor) then we need to create a template // node that contains this node. // Moreover, if the node is an element, then we need to hoist its attributes to the template // node for matching against content projection selectors. var attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta); var templateAttrs_1 = []; attrs.literal.forEach(function (attr) { return templateAttrs_1.push(attr); }); attrs.bound.forEach(function (attr) { return templateAttrs_1.push(attr); }); var hoistedAttrs = parsedElement instanceof t.Element ? { attributes: parsedElement.attributes, inputs: parsedElement.inputs, outputs: parsedElement.outputs, } : { attributes: [], inputs: [], outputs: [] }; // For <ng-template>s with structural directives on them, avoid passing i18n information to // the wrapping template to prevent unnecessary i18n instructions from being generated. The // necessary i18n meta information will be extracted from child elements. var i18n_1 = isTemplateElement && isI18nRootElement ? undefined : element.i18n; // TODO(pk): test for this case parsedElement = new t.Template(parsedElement.name, hoistedAttrs.attributes, hoistedAttrs.inputs, hoistedAttrs.outputs, templateAttrs_1, [parsedElement], [ /* no references */], templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, i18n_1); } if (isI18nRootElement) { this.inI18nBlock = false; } return parsedElement; }; HtmlAstToIvyAst.prototype.visitAttribute = function (attribute) { return new t.TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n); }; HtmlAstToIvyAst.prototype.visitText = function (text) { return this._visitTextWithInterpolation(text.value, text.sourceSpan, text.i18n); }; HtmlAstToIvyAst.prototype.visitExpansion = function (expansion) { var _this = this; if (!expansion.i18n) { // do not generate Icu in case it was created // outside of i18n block in a template return null; } if (!util_1.isI18nRootNode(expansion.i18n)) { throw new Error("Invalid type \"" + expansion.i18n.constructor + "\" for \"i18n\" property of " + expansion.sourceSpan.toString() + ". Expected a \"Message\""); } var message = expansion.i18n; var vars = {}; var placeholders = {}; // extract VARs from ICUs - we process them separately while // assembling resulting message via goog.getMsg function, since // we need to pass them to top-level goog.getMsg call Object.keys(message.placeholders).forEach(function (key) { var value = message.placeholders[key]; if (key.startsWith(util_1.I18N_ICU_VAR_PREFIX)) { // Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g. // `{count, select , ...}`), these spaces are also included into the key names in ICU vars // (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be // converted into `_` symbols while normalizing placeholder names, which might lead to // mismatches at runtime (i.e. placeholder will not be replaced with the correct value). var formattedKey = key.trim(); var ast = _this.bindingParser.parseInterpolationExpression(value.text, value.sourceSpan); vars[formattedKey] = new t.BoundText(ast, value.sourceSpan); } else { placeholders[key] = _this._visitTextWithInterpolation(value.text, value.sourceSpan); } }); return new t.Icu(vars, placeholders, expansion.sourceSpan, message); }; HtmlAstToIvyAst.prototype.visitExpansionCase = function (expansionCase) { return null; }; HtmlAstToIvyAst.prototype.visitComment = function (comment) { if (this.options.collectCommentNodes) { this.commentNodes.push(new t.Comment(comment.value || '', comment.sourceSpan)); } return null; }; // convert view engine `ParsedProperty` to a format suitable for IVY HtmlAstToIvyAst.prototype.extractAttributes = function (elementName, properties, i18nPropsMeta) { var _this = this; var bound = []; var literal = []; properties.forEach(function (prop) { var i18n = i18nPropsMeta[prop.name]; if (prop.isLiteral) { literal.push(new t.TextAttribute(prop.name, prop.expression.source || '', prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n)); } else { // Note that validation is skipped and property mapping is disabled // due to the fact that we need to make sure a given prop is not an // input of a directive and directive matching happens at runtime. var bep = _this.bindingParser.createBoundElementProperty(elementName, prop, /* skipValidation */ true, /* mapPropertyName */ false); bound.push(t.BoundAttribute.fromBoundElementProperty(bep, i18n)); } }); return { bound: bound, literal: literal }; }; HtmlAstToIvyAst.prototype.parseAttribute = function (isTemplateElement, attribute, matchableAttributes, parsedProperties, boundEvents, variables, references) { var name = normalizeAttributeName(attribute.name); var value = attribute.value; var srcSpan = attribute.sourceSpan; var absoluteOffset = attribute.valueSpan ? attribute.valueSpan.start.offset : srcSpan.start.offset; function createKeySpan(srcSpan, prefix, identifier) { // We need to adjust the start location for the keySpan to account for the removed 'data-' // prefix from `normalizeAttributeName`. var normalizationAdjustment = attribute.name.length - name.length; var keySpanStart = srcSpan.start.moveBy(prefix.length + normalizationAdjustment); var keySpanEnd = keySpanStart.moveBy(identifier.length); return new parse_util_1.ParseSourceSpan(keySpanStart, keySpanEnd, keySpanStart, identifier); } var bindParts = name.match(BIND_NAME_REGEXP); if (bindParts) { if (bindParts[KW_BIND_IDX] != null) { var identifier = bindParts[IDENT_KW_IDX]; var keySpan_1 = createKeySpan(srcSpan, bindParts[KW_BIND_IDX], identifier); this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_1); } else if (bindParts[KW_LET_IDX]) { if (isTemplateElement) { var identifier = bindParts[IDENT_KW_IDX]; var keySpan_2 = createKeySpan(srcSpan, bindParts[KW_LET_IDX], identifier); this.parseVariable(identifier, value, srcSpan, keySpan_2, attribute.valueSpan, variables); } else { this.reportError("\"let-\" is only supported on ng-template elements.", srcSpan); } } else if (bindParts[KW_REF_IDX]) { var identifier = bindParts[IDENT_KW_IDX]; var keySpan_3 = createKeySpan(srcSpan, bindParts[KW_REF_IDX], identifier); this.parseReference(identifier, value, srcSpan, keySpan_3, attribute.valueSpan, references); } else if (bindParts[KW_ON_IDX]) { var events = []; var identifier = bindParts[IDENT_KW_IDX]; var keySpan_4 = createKeySpan(srcSpan, bindParts[KW_ON_IDX], identifier); this.bindingParser.parseEvent(identifier, value, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan_4); addEvents(events, boundEvents); } else if (bindParts[KW_BINDON_IDX]) { var identifier = bindParts[IDENT_KW_IDX]; var keySpan_5 = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX], identifier); this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_5); this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan_5); } else if (bindParts[KW_AT_IDX]) { var keySpan_6 = createKeySpan(srcSpan, '', name); this.bindingParser.parseLiteralAttr(name, value, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_6); } return true; } // We didn't see a kw-prefixed property binding, but we have not yet checked // for the []/()/[()] syntax. var delims = null; if (name.startsWith(BINDING_DELIMS.BANANA_BOX.start)) { delims = BINDING_DELIMS.BANANA_BOX; } else if (name.startsWith(BINDING_DELIMS.PROPERTY.start)) { delims = BINDING_DELIMS.PROPERTY; } else if (name.startsWith(BINDING_DELIMS.EVENT.start)) { delims = BINDING_DELIMS.EVENT; } if (delims !== null && // NOTE: older versions of the parser would match a start/end delimited // binding iff the property name was terminated by the ending delimiter // and the identifier in the binding was non-empty. // TODO(ayazhafiz): update this to handle malformed bindings. name.endsWith(delims.end) && name.length > delims.start.length + delims.end.length) { var identifier = name.substring(delims.start.length, name.length - delims.end.length); var keySpan_7 = createKeySpan(srcSpan, delims.start, identifier); if (delims.start === BINDING_DELIMS.BANANA_BOX.start) { this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_7); this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan_7); } else if (delims.start === BINDING_DELIMS.PROPERTY.start) { this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_7); } else { var events = []; this.bindingParser.parseEvent(identifier, value, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan_7); addEvents(events, boundEvents); } return true; } // No explicit binding found. var keySpan = createKeySpan(srcSpan, '' /* prefix */, name); var hasBinding = this.bindingParser.parsePropertyInterpolation(name, value, srcSpan, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan); return hasBinding; }; HtmlAstToIvyAst.prototype._visitTextWithInterpolation = function (value, sourceSpan, i18n) { var valueNoNgsp = html_whitespaces_1.replaceNgsp(value); var expr = this.bindingParser.parseInterpolation(valueNoNgsp, sourceSpan); return expr ? new t.BoundText(expr, sourceSpan, i18n) : new t.Text(valueNoNgsp, sourceSpan); }; HtmlAstToIvyAst.prototype.parseVariable = function (identifier, value, sourceSpan, keySpan, valueSpan, variables) { if (identifier.indexOf('-') > -1) { this.reportError("\"-\" is not allowed in variable names", sourceSpan); } else if (identifier.length === 0) { this.reportError("Variable does not have a name", sourceSpan); } variables.push(new t.Variable(identifier, value, sourceSpan, keySpan, valueSpan)); }; HtmlAstToIvyAst.prototype.parseReference = function (identifier, value, sourceSpan, keySpan, valueSpan, references) { if (identifier.indexOf('-') > -1) { this.reportError("\"-\" is not allowed in reference names", sourceSpan); } else if (identifier.length === 0) { this.reportError("Reference does not have a name", sourceSpan); } else if (references.some(function (reference) { return reference.name === identifier; })) { this.reportError("Reference \"#" + identifier + "\" is defined more than once", sourceSpan); } references.push(new t.Reference(identifier, value, sourceSpan, keySpan, valueSpan)); }; HtmlAstToIvyAst.prototype.parseAssignmentEvent = function (name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) { var events = []; this.bindingParser.parseEvent(name + "Change", expression + "=$event", sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan); addEvents(events, boundEvents); }; HtmlAstToIvyAst.prototype.reportError = function (message, sourceSpan, level) { if (level === void 0) { level = parse_util_1.ParseErrorLevel.ERROR; } this.errors.push(new parse_util_1.ParseError(sourceSpan, message, level)); }; return HtmlAstToIvyAst; }()); var NonBindableVisitor = /** @class */ (function () { function NonBindableVisitor() { } NonBindableVisitor.prototype.visitElement = function (ast) { var preparsedElement = template_preparser_1.preparseElement(ast); if (preparsedElement.type === template_preparser_1.PreparsedElementType.SCRIPT || preparsedElement.type === template_preparser_1.PreparsedElementType.STYLE || preparsedElement.type === template_preparser_1.PreparsedElementType.STYLESHEET) { // Skipping <script> for security reasons // Skipping <style> and stylesheets as we already processed them // in the StyleCompiler return null; } var children = html.visitAll(this, ast.children, null); return new t.Element(ast.name, html.visitAll(this, ast.attrs), /* inputs */ [], /* outputs */ [], children, /* references */ [], ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan); }; NonBindableVisitor.prototype.visitComment = function (comment) { return null; }; NonBindableVisitor.prototype.visitAttribute = function (attribute) { return new t.TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n); }; NonBindableVisitor.prototype.visitText = function (text) { return new t.Text(text.value, text.sourceSpan); }; NonBindableVisitor.prototype.visitExpansion = function (expansion) { return null; }; NonBindableVisitor.prototype.visitExpansionCase = function (expansionCase) { return null; }; return NonBindableVisitor; }()); var NON_BINDABLE_VISITOR = new NonBindableVisitor(); function normalizeAttributeName(attrName) { return /^data-/i.test(attrName) ? attrName.substring(5) : attrName; } function addEvents(events, boundEvents) { boundEvents.push.apply(boundEvents, tslib_1.__spreadArray([], tslib_1.__read(events.map(function (e) { return t.BoundEvent.fromParsedEvent(e); })))); } function isEmptyTextNode(node) { return node instanceof html.Text && node.value.trim().length == 0; } function isCommentNode(node) { return node instanceof html.Comment; } function textContents(node) { if (node.children.length !== 1 || !(node.children[0] instanceof html.Text)) { return null; } else { return node.children[0].value; } } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfdGVtcGxhdGVfdHJhbnNmb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvcjNfdGVtcGxhdGVfdHJhbnNmb3JtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7Ozs7SUFJSCwwREFBeUM7SUFDekMscUZBQTBEO0lBQzFELDZEQUErQztJQUMvQywrREFBMkU7SUFDM0UsK0VBQTJEO0lBRTNELCtGQUE0RjtJQUU1Rix3REFBOEI7SUFDOUIscUVBQXFFO0lBRXJFLElBQU0sZ0JBQWdCLEdBQUcsdURBQXVELENBQUM7SUFFakYsb0JBQW9CO0lBQ3BCLElBQU0sV0FBVyxHQUFHLENBQUMsQ0FBQztJQUN0QixtQkFBbUI7SUFDbkIsSUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLHFCQUFxQjtJQUNyQixJQUFNLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDckIsa0JBQWtCO0lBQ2xCLElBQU0sU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNwQixzQkFBc0I7SUFDdEIsSUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBQ3hCLGdCQUFnQjtJQUNoQixJQUFNLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDcEIsb0ZBQW9GO0lBQ3BGLElBQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztJQUV2QixJQUFNLGNBQWMsR0FBRztRQUNyQixVQUFVLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUM7UUFDcEMsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFDO1FBQ2hDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBQztLQUM5QixDQUFDO0lBRUYsSUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUM7SUFp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