{"version":3,"file":"compiler.mjs","sources":["../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/directive_matching.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/schema/dom_security_schema.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/core.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/compiler_facade_interface.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/digest.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/output_ast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/constant_pool.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_identifiers.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/source_map.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/abstract_emitter.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_factory.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/expression_parser/ast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/tags.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_ast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/i18n_ast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/serializer.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/xml_helper.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/xmb.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/i18n/util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/injectable_compiler_2.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/chars.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/parse_util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/abstract_js_emitter.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/output_jit_trusted_types.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/output_jit.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_injector_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_jit.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_module_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_pipe_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/api.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/shadow_css.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/enums.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/operations.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/ops/shared.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/traits.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/ops/update.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/expression.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/handle.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/ops/create.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/ops/host.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/ir/src/variable.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/compilation.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/any_cast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/apply_i18n_expressions.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/attach_source_locations.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/util/elements.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/attribute_extraction.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/util/attributes.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/binding_specialization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/chaining.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/collapse_singleton_interpolations.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/conditionals.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/conversion.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/const_collection.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/convert_animations.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/convert_i18n_bindings.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/create_i18n_contexts.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/deduplicate_text_bindings.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/defer_configs.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/defer_resolve_targets.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/empty_elements.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/expand_safe_reads.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/extract_i18n_messages.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/generate_advance.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/generate_local_let_references.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/generate_projection_def.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/generate_variables.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/has_const_expression_collection.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/host_style_property_parsing.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/output/map_util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/i18n/icu_serializer.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/ast.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/entities.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/lexer.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/html_whitespaces.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/expression_parser/lexer.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/expression_parser/parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/expression_parser/serializer.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/namespaces.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/schema/element_schema_registry.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/schema/dom_element_schema_registry.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/html_tags.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/placeholder.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/i18n_parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/schema/trusted_types_sinks.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/i18n/meta.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/i18n/get_msg_utils.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/i18n/localize_utils.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/i18n_const_collection.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/i18n_text_extraction.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/local_refs.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/namespace.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/parse_extracted_styles.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/naming.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/next_context_merging.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/ng_container.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/nonbindable.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/ordering.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/phase_remove_content_selectors.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/pipe_creation.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/pipe_variadic.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/propagate_i18n_blocks.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/pure_function_extraction.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/pure_literal_structures.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/regular_expression_optimization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/instruction.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/reify.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/remove_empty_bindings.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/remove_i18n_contexts.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/remove_illegal_let_references.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/remove_unused_i18n_attrs.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_contexts.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_defer_deps_fns.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_dollar_event.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_i18n_attr_sanitizers.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_names.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/resolve_sanitizers.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/save_restore_view.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/slot_allocation.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/store_let_optimization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/strip_nonrequired_parentheses.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/style_binding_specialization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/temporary_variables.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/track_fn_optimization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/track_variables.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/transform_two_way_binding_set.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/var_counting.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/variable_optimization.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/wrap_icus.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/generate_arrow_functions.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/phases/control_directives.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/emit.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template/pipeline/src/ingest.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/config.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/query_generation.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/html_parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template_parser/binding_parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/style_url_resolver.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/template_parser/template_preparser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_control_flow.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_deferred_triggers.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_deferred_blocks.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_template_transform.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/template.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/combined_visitor.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/t2_binder.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/resource_loader.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/jit_compiler_facade.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/config.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/extractor_merger.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/xml_tags.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/ml_parser/xml_parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/xliff.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/xliff2.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/serializers/xtb.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/translation_bundle.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/i18n_html_parser.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/i18n/message_bundle.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/property_mapping.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_class_metadata_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/class_metadata.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/util.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/directive.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/component.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/factory.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/injectable.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/injector.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/ng_module.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/partial/pipe.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_class_debug_info_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/r3_hmr_compiler.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/render3/view/t2_api.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/version.ts","../../../../../k8-fastbuild-ST-fdfa778d11ba/bin/packages/compiler/src/compiler.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nconst _SELECTOR_REGEXP = new RegExp(\n  '(\\\\:not\\\\()|' + // 1: \":not(\"\n    '(([\\\\.\\\\#]?)[-\\\\w]+)|' + // 2: \"tag\"; 3: \".\"/\"#\";\n    // \"-\" should appear first in the regexp below as FF31 parses \"[.-\\w]\" as a range\n    // 4: attribute; 5: attribute_string; 6: attribute_value\n    '(?:\\\\[([-.\\\\w*\\\\\\\\$]+)(?:=([\"\\']?)([^\\\\]\"\\']*)\\\\5)?\\\\])|' + // \"[name]\", \"[name=value]\",\n    // \"[name=\"value\"]\",\n    // \"[name='value']\"\n    '(\\\\))|' + // 7: \")\"\n    '(\\\\s*,\\\\s*)', // 8: \",\"\n  'g',\n);\n\n/**\n * These offsets should match the match-groups in `_SELECTOR_REGEXP` offsets.\n */\nconst enum SelectorRegexp {\n  ALL = 0, // The whole match\n  NOT = 1,\n  TAG = 2,\n  PREFIX = 3,\n  ATTRIBUTE = 4,\n  ATTRIBUTE_STRING = 5,\n  ATTRIBUTE_VALUE = 6,\n  NOT_END = 7,\n  SEPARATOR = 8,\n}\n/**\n * A css selector contains an element name,\n * css classes and attribute/value pairs with the purpose\n * of selecting subsets out of them.\n */\nexport class CssSelector {\n  element: string | null = null;\n  classNames: string[] = [];\n  /**\n   * The selectors are encoded in pairs where:\n   * - even locations are attribute names\n   * - odd locations are attribute values.\n   *\n   * Example:\n   * Selector: `[key1=value1][key2]` would parse to:\n   * ```\n   * ['key1', 'value1', 'key2', '']\n   * ```\n   */\n  attrs: string[] = [];\n  notSelectors: CssSelector[] = [];\n\n  static parse(selector: string): CssSelector[] {\n    const results: CssSelector[] = [];\n    const _addResult = (res: CssSelector[], cssSel: CssSelector) => {\n      if (\n        cssSel.notSelectors.length > 0 &&\n        !cssSel.element &&\n        cssSel.classNames.length == 0 &&\n        cssSel.attrs.length == 0\n      ) {\n        cssSel.element = '*';\n      }\n      res.push(cssSel);\n    };\n    let cssSelector = new CssSelector();\n    let match: string[] | null;\n    let current = cssSelector;\n    let inNot = false;\n    _SELECTOR_REGEXP.lastIndex = 0;\n    while ((match = _SELECTOR_REGEXP.exec(selector))) {\n      if (match[SelectorRegexp.NOT]) {\n        if (inNot) {\n          throw new Error('Nesting :not in a selector is not allowed');\n        }\n        inNot = true;\n        current = new CssSelector();\n        cssSelector.notSelectors.push(current);\n      }\n      const tag = match[SelectorRegexp.TAG];\n      if (tag) {\n        const prefix = match[SelectorRegexp.PREFIX];\n        if (prefix === '#') {\n          // #hash\n          current.addAttribute('id', tag.slice(1));\n        } else if (prefix === '.') {\n          // Class\n          current.addClassName(tag.slice(1));\n        } else {\n          // Element\n          current.setElement(tag);\n        }\n      }\n      const attribute = match[SelectorRegexp.ATTRIBUTE];\n\n      if (attribute) {\n        current.addAttribute(\n          current.unescapeAttribute(attribute),\n          match[SelectorRegexp.ATTRIBUTE_VALUE],\n        );\n      }\n      if (match[SelectorRegexp.NOT_END]) {\n        inNot = false;\n        current = cssSelector;\n      }\n      if (match[SelectorRegexp.SEPARATOR]) {\n        if (inNot) {\n          throw new Error('Multiple selectors in :not are not supported');\n        }\n        _addResult(results, cssSelector);\n        cssSelector = current = new CssSelector();\n      }\n    }\n    _addResult(results, cssSelector);\n    return results;\n  }\n\n  /**\n   * Unescape `\\$` sequences from the CSS attribute selector.\n   *\n   * This is needed because `$` can have a special meaning in CSS selectors,\n   * but we might want to match an attribute that contains `$`.\n   * [MDN web link for more\n   * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).\n   * @param attr the attribute to unescape.\n   * @returns the unescaped string.\n   */\n  unescapeAttribute(attr: string): string {\n    let result = '';\n    let escaping = false;\n    for (let i = 0; i < attr.length; i++) {\n      const char = attr.charAt(i);\n      if (char === '\\\\') {\n        escaping = true;\n        continue;\n      }\n      if (char === '$' && !escaping) {\n        throw new Error(\n          `Error in attribute selector \"${attr}\". ` +\n            `Unescaped \"$\" is not supported. Please escape with \"\\\\$\".`,\n        );\n      }\n      escaping = false;\n      result += char;\n    }\n    return result;\n  }\n\n  /**\n   * Escape `$` sequences from the CSS attribute selector.\n   *\n   * This is needed because `$` can have a special meaning in CSS selectors,\n   * with this method we are escaping `$` with `\\$'.\n   * [MDN web link for more\n   * info](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).\n   * @param attr the attribute to escape.\n   * @returns the escaped string.\n   */\n  escapeAttribute(attr: string): string {\n    return attr.replace(/\\\\/g, '\\\\\\\\').replace(/\\$/g, '\\\\$');\n  }\n\n  isElementSelector(): boolean {\n    return (\n      this.hasElementSelector() &&\n      this.classNames.length == 0 &&\n      this.attrs.length == 0 &&\n      this.notSelectors.length === 0\n    );\n  }\n\n  hasElementSelector(): boolean {\n    return !!this.element;\n  }\n\n  setElement(element: string | null = null) {\n    this.element = element;\n  }\n\n  getAttrs(): string[] {\n    const result: string[] = [];\n    if (this.classNames.length > 0) {\n      result.push('class', this.classNames.join(' '));\n    }\n    return result.concat(this.attrs);\n  }\n\n  addAttribute(name: string, value: string = '') {\n    this.attrs.push(name, (value && value.toLowerCase()) || '');\n  }\n\n  addClassName(name: string) {\n    this.classNames.push(name.toLowerCase());\n  }\n\n  toString(): string {\n    let res: string = this.element || '';\n    if (this.classNames) {\n      this.classNames.forEach((klass) => (res += `.${klass}`));\n    }\n    if (this.attrs) {\n      for (let i = 0; i < this.attrs.length; i += 2) {\n        const name = this.escapeAttribute(this.attrs[i]);\n        const value = this.attrs[i + 1];\n        res += `[${name}${value ? '=' + value : ''}]`;\n      }\n    }\n    this.notSelectors.forEach((notSelector) => (res += `:not(${notSelector})`));\n    return res;\n  }\n}\n\n/**\n * Reads a list of CssSelectors and allows to calculate which ones\n * are contained in a given CssSelector.\n */\nexport class SelectorMatcher<T = any> {\n  static createNotMatcher(notSelectors: CssSelector[]): SelectorMatcher<null> {\n    const notMatcher = new SelectorMatcher<null>();\n    notMatcher.addSelectables(notSelectors, null);\n    return notMatcher;\n  }\n\n  private _elementMap = new Map<string, SelectorContext<T>[]>();\n  private _elementPartialMap = new Map<string, SelectorMatcher<T>>();\n  private _classMap = new Map<string, SelectorContext<T>[]>();\n  private _classPartialMap = new Map<string, SelectorMatcher<T>>();\n  private _attrValueMap = new Map<string, Map<string, SelectorContext<T>[]>>();\n  private _attrValuePartialMap = new Map<string, Map<string, SelectorMatcher<T>>>();\n  private _listContexts: SelectorListContext[] = [];\n\n  addSelectables(cssSelectors: CssSelector[], callbackCtxt?: T) {\n    let listContext: SelectorListContext = null!;\n    if (cssSelectors.length > 1) {\n      listContext = new SelectorListContext(cssSelectors);\n      this._listContexts.push(listContext);\n    }\n    for (let i = 0; i < cssSelectors.length; i++) {\n      this._addSelectable(cssSelectors[i], callbackCtxt as T, listContext);\n    }\n  }\n\n  /**\n   * Add an object that can be found later on by calling `match`.\n   * @param cssSelector A css selector\n   * @param callbackCtxt An opaque object that will be given to the callback of the `match` function\n   */\n  private _addSelectable(\n    cssSelector: CssSelector,\n    callbackCtxt: T,\n    listContext: SelectorListContext,\n  ) {\n    let matcher: SelectorMatcher<T> = this;\n    const element = cssSelector.element;\n    const classNames = cssSelector.classNames;\n    const attrs = cssSelector.attrs;\n    const selectable = new SelectorContext(cssSelector, callbackCtxt, listContext);\n\n    if (element) {\n      const isTerminal = attrs.length === 0 && classNames.length === 0;\n      if (isTerminal) {\n        this._addTerminal(matcher._elementMap, element, selectable);\n      } else {\n        matcher = this._addPartial(matcher._elementPartialMap, element);\n      }\n    }\n\n    if (classNames) {\n      for (let i = 0; i < classNames.length; i++) {\n        const isTerminal = attrs.length === 0 && i === classNames.length - 1;\n        const className = classNames[i];\n        if (isTerminal) {\n          this._addTerminal(matcher._classMap, className, selectable);\n        } else {\n          matcher = this._addPartial(matcher._classPartialMap, className);\n        }\n      }\n    }\n\n    if (attrs) {\n      for (let i = 0; i < attrs.length; i += 2) {\n        const isTerminal = i === attrs.length - 2;\n        const name = attrs[i];\n        const value = attrs[i + 1];\n        if (isTerminal) {\n          const terminalMap = matcher._attrValueMap;\n          let terminalValuesMap = terminalMap.get(name);\n          if (!terminalValuesMap) {\n            terminalValuesMap = new Map<string, SelectorContext<T>[]>();\n            terminalMap.set(name, terminalValuesMap);\n          }\n          this._addTerminal(terminalValuesMap, value, selectable);\n        } else {\n          const partialMap = matcher._attrValuePartialMap;\n          let partialValuesMap = partialMap.get(name);\n          if (!partialValuesMap) {\n            partialValuesMap = new Map<string, SelectorMatcher<T>>();\n            partialMap.set(name, partialValuesMap);\n          }\n          matcher = this._addPartial(partialValuesMap, value);\n        }\n      }\n    }\n  }\n\n  private _addTerminal(\n    map: Map<string, SelectorContext<T>[]>,\n    name: string,\n    selectable: SelectorContext<T>,\n  ) {\n    let terminalList = map.get(name);\n    if (!terminalList) {\n      terminalList = [];\n      map.set(name, terminalList);\n    }\n    terminalList.push(selectable);\n  }\n\n  private _addPartial(map: Map<string, SelectorMatcher<T>>, name: string): SelectorMatcher<T> {\n    let matcher = map.get(name);\n    if (!matcher) {\n      matcher = new SelectorMatcher<T>();\n      map.set(name, matcher);\n    }\n    return matcher;\n  }\n\n  /**\n   * Find the objects that have been added via `addSelectable`\n   * whose css selector is contained in the given css selector.\n   * @param cssSelector A css selector\n   * @param matchedCallback This callback will be called with the object handed into `addSelectable`\n   * @return boolean true if a match was found\n   */\n  match(\n    cssSelector: CssSelector,\n    matchedCallback: ((c: CssSelector, a: T) => void) | null,\n  ): boolean {\n    let result = false;\n    const element = cssSelector.element!;\n    const classNames = cssSelector.classNames;\n    const attrs = cssSelector.attrs;\n\n    for (let i = 0; i < this._listContexts.length; i++) {\n      this._listContexts[i].alreadyMatched = false;\n    }\n\n    result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;\n    result =\n      this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || result;\n\n    if (classNames) {\n      for (let i = 0; i < classNames.length; i++) {\n        const className = classNames[i];\n        result =\n          this._matchTerminal(this._classMap, className, cssSelector, matchedCallback) || result;\n        result =\n          this._matchPartial(this._classPartialMap, className, cssSelector, matchedCallback) ||\n          result;\n      }\n    }\n\n    if (attrs) {\n      for (let i = 0; i < attrs.length; i += 2) {\n        const name = attrs[i];\n        const value = attrs[i + 1];\n\n        const terminalValuesMap = this._attrValueMap.get(name)!;\n        if (value) {\n          result =\n            this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result;\n        }\n        result =\n          this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result;\n\n        const partialValuesMap = this._attrValuePartialMap.get(name)!;\n        if (value) {\n          result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result;\n        }\n        result =\n          this._matchPartial(partialValuesMap, value, cssSelector, matchedCallback) || result;\n      }\n    }\n    return result;\n  }\n\n  /** @internal */\n  _matchTerminal(\n    map: Map<string, SelectorContext<T>[]>,\n    name: string,\n    cssSelector: CssSelector,\n    matchedCallback: ((c: CssSelector, a: any) => void) | null,\n  ): boolean {\n    if (!map || typeof name !== 'string') {\n      return false;\n    }\n\n    let selectables: SelectorContext<T>[] = map.get(name) || [];\n    const starSelectables: SelectorContext<T>[] = map.get('*')!;\n    if (starSelectables) {\n      selectables = selectables.concat(starSelectables);\n    }\n    if (selectables.length === 0) {\n      return false;\n    }\n    let selectable: SelectorContext<T>;\n    let result = false;\n    for (let i = 0; i < selectables.length; i++) {\n      selectable = selectables[i];\n      result = selectable.finalize(cssSelector, matchedCallback) || result;\n    }\n    return result;\n  }\n\n  /** @internal */\n  _matchPartial(\n    map: Map<string, SelectorMatcher<T>>,\n    name: string,\n    cssSelector: CssSelector,\n    matchedCallback: ((c: CssSelector, a: any) => void) | null,\n  ): boolean {\n    if (!map || typeof name !== 'string') {\n      return false;\n    }\n\n    const nestedSelector = map.get(name);\n    if (!nestedSelector) {\n      return false;\n    }\n    // TODO(perf): get rid of recursion and measure again\n    // TODO(perf): don't pass the whole selector into the recursion,\n    // but only the not processed parts\n    return nestedSelector.match(cssSelector, matchedCallback);\n  }\n}\n\nexport class SelectorListContext {\n  alreadyMatched: boolean = false;\n\n  constructor(public selectors: CssSelector[]) {}\n}\n\n// Store context to pass back selector and context when a selector is matched\nexport class SelectorContext<T = any> {\n  notSelectors: CssSelector[];\n\n  constructor(\n    public selector: CssSelector,\n    public cbContext: T,\n    public listContext: SelectorListContext,\n  ) {\n    this.notSelectors = selector.notSelectors;\n  }\n\n  finalize(cssSelector: CssSelector, callback: ((c: CssSelector, a: T) => void) | null): boolean {\n    let result = true;\n    if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) {\n      const notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors);\n      result = !notMatcher.match(cssSelector, null);\n    }\n    if (result && callback && (!this.listContext || !this.listContext.alreadyMatched)) {\n      if (this.listContext) {\n        this.listContext.alreadyMatched = true;\n      }\n      callback(this.selector, this.cbContext);\n    }\n    return result;\n  }\n}\n\nexport class SelectorlessMatcher<T = unknown> {\n  constructor(private registry: Map<string, T[]>) {}\n\n  match(name: string): T[] {\n    return this.registry.has(name) ? this.registry.get(name)! : [];\n  }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property\n * like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly\n * handled.\n *\n * See DomSanitizer for more details on security in Angular applications.\n *\n * @publicApi\n */\nexport enum SecurityContext {\n  NONE = 0,\n  HTML = 1,\n  STYLE = 2,\n  SCRIPT = 3,\n  URL = 4,\n  RESOURCE_URL = 5,\n  ATTRIBUTE_NO_BINDING = 6,\n}\n\n// =================================================================================================\n// =================================================================================================\n// =========== S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P  ===========\n// =================================================================================================\n// =================================================================================================\n//\n//        DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!\n//\n// =================================================================================================\n\n/**\n *  Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'.\n */\nlet _SECURITY_SCHEMA!: {[k: string]: SecurityContext};\nconst SVG_NAMESPACE = 'svg';\nconst MATH_ML_NAMESPACE = 'math';\n\n/**\n * @remarks Keep is a copy of DOM Security Schema.\n * @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)\n */\nexport function SECURITY_SCHEMA(): {[k: string]: SecurityContext} {\n  if (!_SECURITY_SCHEMA) {\n    _SECURITY_SCHEMA = {};\n    // Case is insignificant below, all element and attribute names are lower-cased for lookup.\n\n    registerContext(SecurityContext.HTML, /** Namespace */ undefined, [\n      ['iframe', ['srcdoc']],\n      ['*', ['innerHTML', 'outerHTML']],\n    ]);\n    registerContext(SecurityContext.STYLE, /** Namespace */ undefined, [['*', ['style']]]);\n    // NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.\n    registerContext(SecurityContext.URL, /** Namespace */ undefined, [\n      ['*', ['formAction']],\n      ['area', ['href']],\n      ['a', ['href', 'xlink:href']],\n      ['form', ['action']],\n\n      // The below two items are safe and should be removed but they require a G3 clean-up as a small number of tests fail.\n      ['img', ['src']],\n      ['video', ['src']],\n    ]);\n\n    registerContext(SecurityContext.URL, MATH_ML_NAMESPACE, [\n      // MathML namespace\n      // https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1\n      ['annotation', ['href', 'xlink:href']],\n      ['annotation-xml', ['href', 'xlink:href']],\n      ['maction', ['href', 'xlink:href']],\n      ['malignmark', ['href', 'xlink:href']],\n      ['math', ['href', 'xlink:href']],\n      ['mroot', ['href', 'xlink:href']],\n      ['msqrt', ['href', 'xlink:href']],\n      ['merror', ['href', 'xlink:href']],\n      ['mfrac', ['href', 'xlink:href']],\n      ['mglyph', ['href', 'xlink:href']],\n      ['msub', ['href', 'xlink:href']],\n      ['msup', ['href', 'xlink:href']],\n      ['msubsup', ['href', 'xlink:href']],\n      ['mmultiscripts', ['href', 'xlink:href']],\n      ['mprescripts', ['href', 'xlink:href']],\n      ['mi', ['href', 'xlink:href']],\n      ['mn', ['href', 'xlink:href']],\n      ['mo', ['href', 'xlink:href']],\n      ['mpadded', ['href', 'xlink:href']],\n      ['mphantom', ['href', 'xlink:href']],\n      ['mrow', ['href', 'xlink:href']],\n      ['ms', ['href', 'xlink:href']],\n      ['mspace', ['href', 'xlink:href']],\n      ['mstyle', ['href', 'xlink:href']],\n      ['mtable', ['href', 'xlink:href']],\n      ['mtd', ['href', 'xlink:href']],\n      ['mtr', ['href', 'xlink:href']],\n      ['mtext', ['href', 'xlink:href']],\n      ['mover', ['href', 'xlink:href']],\n      ['munder', ['href', 'xlink:href']],\n      ['munderover', ['href', 'xlink:href']],\n      ['semantics', ['href', 'xlink:href']],\n      ['none', ['href', 'xlink:href']],\n    ]);\n\n    registerContext(SecurityContext.RESOURCE_URL, /** Namespace */ undefined, [\n      ['base', ['href']],\n      ['embed', ['src']],\n      ['frame', ['src']],\n      ['iframe', ['src']],\n      ['link', ['href']],\n      ['object', ['codebase', 'data']],\n    ]);\n\n    registerContext(SecurityContext.URL, SVG_NAMESPACE, [['a', ['href', 'xlink:href']]]);\n    // Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts\n    // The `unknown` elements refer to cases when we need to validate the input/binding in a directive (host bindings)\n    // and the directive can be applied to multiple different elements (with different tag names). In this case we generate\n    // a special instruction that an attribute might potentially be security-sensitive and defer the actual security check\n    // to runtime, when we apply that directive to a concrete elements, thus we can check the combination of tag+attribute\n    // against the set that requires sanitization.\n    // These are unsafe as `attributeName` can be `href` or `xlink:href`\n    // See: http://b/463880509#comment7\n    registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, SVG_NAMESPACE, [\n      ['animate', ['attributeName', 'values', 'to', 'from']],\n      ['set', ['to', 'attributeName']],\n      ['animateMotion', ['attributeName']],\n      ['animateTransform', ['attributeName']],\n    ]);\n\n    registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, /** Namespace */ undefined, [\n      [\n        'unknown',\n        [\n          'attributeName',\n          'values',\n          'to',\n          'from',\n          'sandbox',\n          'allow',\n          'allowFullscreen',\n          'referrerPolicy',\n          'csp',\n          'fetchPriority',\n        ],\n      ],\n      ['iframe', ['sandbox', 'allow', 'allowFullscreen', 'referrerPolicy', 'csp', 'fetchPriority']],\n    ]);\n  }\n\n  return _SECURITY_SCHEMA;\n}\n\nfunction registerContext(\n  ctx: SecurityContext,\n  namespace: string | undefined,\n  specs: readonly [tagName: string, attributeNames: readonly string[]][],\n): void {\n  for (const [element, attributeNames] of specs) {\n    let tagName =\n      namespace && element !== '*' && element !== 'unknown' ? `:${namespace}:${element}` : element;\n    tagName = tagName.toLowerCase();\n\n    for (const attr of attributeNames) {\n      _SECURITY_SCHEMA[`${tagName}|${attr.toLowerCase()}`] = ctx;\n    }\n  }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n// Attention:\n// This file duplicates types and values from @angular/core\n// so that we are able to make @angular/compiler independent of @angular/core.\n// This is important to prevent a build cycle, as @angular/core needs to\n// be compiled with the compiler.\n\nimport {CssSelector} from './directive_matching';\n\n// Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not\n// explicitly set.\nexport const emitDistinctChangesOnlyDefaultValue = true;\n\nexport enum ViewEncapsulation {\n  Emulated = 0,\n  // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.\n  None = 2,\n  ShadowDom = 3,\n  ExperimentalIsolatedShadowDom = 4,\n}\n\nexport enum ChangeDetectionStrategy {\n  OnPush = 0,\n  Default = 1,\n  // tslint:disable-next-line:no-duplicate-enum-values\n  Eager = 1,\n}\n\nexport interface Input {\n  alias?: string;\n  required?: boolean;\n  transform?: (value: any) => any;\n  // Note: This field is marked as `internal` in `@angular/core`, but in the compiler\n  // we rely on it for JIT processing at runtime.\n  isSignal: boolean;\n}\n\n/** Flags describing an input for a directive. */\nexport enum InputFlags {\n  None = 0,\n  SignalBased = 1 << 0,\n  HasDecoratorInputTransform = 1 << 1,\n}\n\nexport interface Output {\n  alias?: string;\n}\n\nexport interface HostBinding {\n  hostPropertyName?: string;\n}\n\nexport interface HostListener {\n  eventName?: string;\n  args?: string[];\n}\n\nexport interface SchemaMetadata {\n  name: string;\n}\n\nexport const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = {\n  name: 'custom-elements',\n};\n\nexport const NO_ERRORS_SCHEMA: SchemaMetadata = {\n  name: 'no-errors-schema',\n};\n\nexport interface Type extends Function {\n  new (...args: any[]): any;\n}\nexport const Type = Function;\n\n/**\n * Injection flags for DI.\n */\nexport const enum InjectFlags {\n  Default = 0,\n\n  /**\n   * Specifies that an injector should retrieve a dependency from any injector until reaching the\n   * host element of the current component. (Only used with Element Injector)\n   */\n  Host = 1 << 0,\n  /** Don't descend into ancestors of the node requesting injection. */\n  Self = 1 << 1,\n  /** Skip the node that is requesting injection. */\n  SkipSelf = 1 << 2,\n  /** Inject `defaultValue` instead if token not found. */\n  Optional = 1 << 3,\n  /**\n   * This token is being injected into a pipe.\n   * @internal\n   */\n  ForPipe = 1 << 4,\n}\n\nexport enum MissingTranslationStrategy {\n  Error = 0,\n  Warning = 1,\n  Ignore = 2,\n}\n\n/**\n * Flags used to generate R3-style CSS Selectors. They are pasted from\n * core/src/render3/projection.ts because they cannot be referenced directly.\n */\nexport const enum SelectorFlags {\n  /** Indicates this is the beginning of a new negative selector */\n  NOT = 0b0001,\n\n  /** Mode for matching attributes */\n  ATTRIBUTE = 0b0010,\n\n  /** Mode for matching tag names */\n  ELEMENT = 0b0100,\n\n  /** Mode for matching class names */\n  CLASS = 0b1000,\n}\n\n// These are a copy the CSS types from core/src/render3/interfaces/projection.ts\n// They are duplicated here as they cannot be directly referenced from core.\nexport type R3CssSelector = (string | SelectorFlags)[];\nexport type R3CssSelectorList = R3CssSelector[];\n\nfunction parserSelectorToSimpleSelector(selector: CssSelector): R3CssSelector {\n  const classes =\n    selector.classNames && selector.classNames.length\n      ? [SelectorFlags.CLASS, ...selector.classNames]\n      : [];\n  const elementName = selector.element && selector.element !== '*' ? selector.element : '';\n  return [elementName, ...selector.attrs, ...classes];\n}\n\nfunction parserSelectorToNegativeSelector(selector: CssSelector): R3CssSelector {\n  const classes =\n    selector.classNames && selector.classNames.length\n      ? [SelectorFlags.CLASS, ...selector.classNames]\n      : [];\n\n  if (selector.element) {\n    return [\n      SelectorFlags.NOT | SelectorFlags.ELEMENT,\n      selector.element,\n      ...selector.attrs,\n      ...classes,\n    ];\n  } else if (selector.attrs.length) {\n    return [SelectorFlags.NOT | SelectorFlags.ATTRIBUTE, ...selector.attrs, ...classes];\n  } else {\n    return selector.classNames && selector.classNames.length\n      ? [SelectorFlags.NOT | SelectorFlags.CLASS, ...selector.classNames]\n      : [];\n  }\n}\n\nfunction parserSelectorToR3Selector(selector: CssSelector): R3CssSelector {\n  const positive = parserSelectorToSimpleSelector(selector);\n\n  const negative: R3CssSelectorList =\n    selector.notSelectors && selector.notSelectors.length\n      ? selector.notSelectors.map((notSelector) => parserSelectorToNegativeSelector(notSelector))\n      : [];\n\n  return positive.concat(...negative);\n}\n\nexport function parseSelectorToR3Selector(selector: string | null): R3CssSelectorList {\n  return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : [];\n}\n\n// Pasted from render3/interfaces/definition since it cannot be referenced directly\n/**\n * Flags passed into template functions to determine which blocks (i.e. creation, update)\n * should be executed.\n *\n * Typically, a template runs both the creation block and the update block on initialization and\n * subsequent runs only execute the update block. However, dynamically created views require that\n * the creation block be executed separately from the update block (for backwards compat).\n */\nexport const enum RenderFlags {\n  /* Whether to run the creation block (e.g. create elements and directives) */\n  Create = 0b01,\n\n  /* Whether to run the update block (e.g. refresh bindings) */\n  Update = 0b10,\n}\n\n// Pasted from render3/interfaces/node.ts\n/**\n * A set of marker values to be used in the attributes arrays. These markers indicate that some\n * items are not regular attributes and the processing should be adapted accordingly.\n */\nexport const enum AttributeMarker {\n  /**\n   * Marker indicates that the following 3 values in the attributes array are:\n   * namespaceUri, attributeName, attributeValue\n   * in that order.\n   */\n  NamespaceURI = 0,\n\n  /**\n   * Signals class declaration.\n   *\n   * Each value following `Classes` designates a class name to include on the element.\n   * ## Example:\n   *\n   * Given:\n   * ```html\n   * <div class=\"foo bar baz\">...</div>\n   * ```\n   *\n   * the generated code is:\n   * ```ts\n   * var _c1 = [AttributeMarker.Classes, 'foo', 'bar', 'baz'];\n   * ```\n   */\n  Classes = 1,\n\n  /**\n   * Signals style declaration.\n   *\n   * Each pair of values following `Styles` designates a style name and value to include on the\n   * element.\n   * ## Example:\n   *\n   * Given:\n   * ```html\n   * <div style=\"width:100px; height:200px; color:red\">...</div>\n   * ```\n   *\n   * the generated code is:\n   * ```ts\n   * var _c1 = [AttributeMarker.Styles, 'width', '100px', 'height'. '200px', 'color', 'red'];\n   * ```\n   */\n  Styles = 2,\n\n  /**\n   * Signals that the following attribute names were extracted from input or output bindings.\n   *\n   * For example, given the following HTML:\n   *\n   * ```html\n   * <div moo=\"car\" [foo]=\"exp\" (bar)=\"doSth()\">\n   * ```\n   *\n   * the generated code is:\n   *\n   * ```ts\n   * var _c1 = ['moo', 'car', AttributeMarker.Bindings, 'foo', 'bar'];\n   * ```\n   */\n  Bindings = 3,\n\n  /**\n   * Signals that the following attribute names were hoisted from an inline-template declaration.\n   *\n   * For example, given the following HTML:\n   *\n   * ```html\n   * <div *ngFor=\"let value of values; trackBy:trackBy\" dirA [dirB]=\"value\">\n   * ```\n   *\n   * the generated code for the `template()` instruction would include:\n   *\n   * ```\n   * ['dirA', '', AttributeMarker.Bindings, 'dirB', AttributeMarker.Template, 'ngFor', 'ngForOf',\n   * 'ngForTrackBy', 'let-value']\n   * ```\n   *\n   * while the generated code for the `element()` instruction inside the template function would\n   * include:\n   *\n   * ```\n   * ['dirA', '', AttributeMarker.Bindings, 'dirB']\n   * ```\n   */\n  Template = 4,\n\n  /**\n   * Signals that the following attribute is `ngProjectAs` and its value is a parsed `CssSelector`.\n   *\n   * For example, given the following HTML:\n   *\n   * ```html\n   * <h1 attr=\"value\" ngProjectAs=\"[title]\">\n   * ```\n   *\n   * the generated code for the `element()` instruction would include:\n   *\n   * ```\n   * ['attr', 'value', AttributeMarker.ProjectAs, ['', 'title', '']]\n   * ```\n   */\n  ProjectAs = 5,\n\n  /**\n   * Signals that the following attribute will be translated by runtime i18n\n   *\n   * For example, given the following HTML:\n   *\n   * ```html\n   * <div moo=\"car\" foo=\"value\" i18n-foo [bar]=\"binding\" i18n-bar>\n   * ```\n   *\n   * the generated code is:\n   *\n   * ```ts\n   * var _c1 = ['moo', 'car', AttributeMarker.I18n, 'foo', 'bar'];\n   * ```\n   */\n  I18n = 6,\n}\n\nexport {SecurityContext} from './schema/dom_security_schema';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * A set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow\n * for late binding of `@angular/compiler` for JIT purposes.\n *\n * This file has two copies. Please ensure that they are in sync:\n *  - packages/compiler/src/compiler_facade_interface.ts          (main)\n *  - packages/core/src/compiler/compiler_facade_interface.ts     (replica)\n *\n * Please ensure that the two files are in sync using this command:\n * ```shell\n * cp packages/compiler/src/compiler_facade_interface.ts \\\n *    packages/core/src/compiler/compiler_facade_interface.ts\n * ```\n */\n\nexport interface ExportedCompilerFacade {\n  ɵcompilerFacade: CompilerFacade;\n}\n\nexport interface CompilerFacade {\n  compilePipe(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3PipeMetadataFacade,\n  ): any;\n  compilePipeDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    declaration: R3DeclarePipeFacade,\n  ): any;\n  compileInjectable(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3InjectableMetadataFacade,\n  ): any;\n  compileInjectableDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3DeclareInjectableFacade,\n  ): any;\n  compileInjector(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3InjectorMetadataFacade,\n  ): any;\n  compileInjectorDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    declaration: R3DeclareInjectorFacade,\n  ): any;\n  compileNgModule(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3NgModuleMetadataFacade,\n  ): any;\n  compileNgModuleDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    declaration: R3DeclareNgModuleFacade,\n  ): any;\n  compileDirective(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3DirectiveMetadataFacade,\n  ): any;\n  compileDirectiveDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    declaration: R3DeclareDirectiveFacade,\n  ): any;\n  compileComponent(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3ComponentMetadataFacade,\n  ): any;\n  compileComponentDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    declaration: R3DeclareComponentFacade,\n  ): any;\n  compileFactory(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3FactoryDefMetadataFacade,\n  ): any;\n  compileFactoryDeclaration(\n    angularCoreEnv: CoreEnvironment,\n    sourceMapUrl: string,\n    meta: R3DeclareFactoryFacade,\n  ): any;\n\n  createParseSourceSpan(kind: string, typeName: string, sourceUrl: string): ParseSourceSpan;\n\n  FactoryTarget: typeof FactoryTarget;\n  // Note that we do not use `{new(): ResourceLoader}` here because\n  // the resource loader class is abstract and not constructable.\n  ResourceLoader: Function & {prototype: ResourceLoader};\n}\n\nexport interface CoreEnvironment {\n  [name: string]: unknown;\n}\n\nexport type ResourceLoader = {\n  get(url: string): Promise<string> | string;\n};\n\nexport type Provider = unknown;\nexport type Type = Function;\nexport type OpaqueValue = unknown;\n\nexport enum FactoryTarget {\n  Directive = 0,\n  Component = 1,\n  Injectable = 2,\n  Pipe = 3,\n  NgModule = 4,\n}\n\nexport interface R3DependencyMetadataFacade {\n  token: OpaqueValue;\n  attribute: string | null;\n  host: boolean;\n  optional: boolean;\n  self: boolean;\n  skipSelf: boolean;\n}\n\nexport interface R3DeclareDependencyMetadataFacade {\n  token: OpaqueValue;\n  attribute?: boolean;\n  host?: boolean;\n  optional?: boolean;\n  self?: boolean;\n  skipSelf?: boolean;\n}\n\nexport interface R3PipeMetadataFacade {\n  name: string;\n  type: Type;\n  pipeName: string | null;\n  pure: boolean;\n  isStandalone: boolean;\n}\n\nexport interface R3InjectableMetadataFacade {\n  name: string;\n  type: Type;\n  typeArgumentCount: number;\n  providedIn?: Type | 'root' | 'platform' | 'any' | null;\n  useClass?: OpaqueValue;\n  useFactory?: OpaqueValue;\n  useExisting?: OpaqueValue;\n  useValue?: OpaqueValue;\n  deps?: R3DependencyMetadataFacade[];\n}\n\nexport interface R3NgModuleMetadataFacade {\n  type: Type;\n  bootstrap: Function[];\n  declarations: Function[];\n  imports: Function[];\n  exports: Function[];\n  schemas: {name: string}[] | null;\n  id: string | null;\n}\n\nexport interface R3InjectorMetadataFacade {\n  name: string;\n  type: Type;\n  providers: Provider[];\n  imports: OpaqueValue[];\n}\n\nexport interface R3HostDirectiveMetadataFacade {\n  directive: Type;\n  inputs?: string[];\n  outputs?: string[];\n}\n\nexport interface R3DirectiveMetadataFacade {\n  name: string;\n  type: Type;\n  typeSourceSpan: ParseSourceSpan;\n  selector: string | null;\n  queries: R3QueryMetadataFacade[];\n  host: {[key: string]: string};\n  propMetadata: {[key: string]: OpaqueValue[]};\n  lifecycle: {usesOnChanges: boolean};\n  inputs: (string | {name: string; alias?: string; required?: boolean})[];\n  outputs: string[];\n  usesInheritance: boolean;\n  controlCreate: {passThroughInput: string | null} | null;\n  exportAs: string[] | null;\n  providers: Provider[] | null;\n  viewQueries: R3QueryMetadataFacade[];\n  isStandalone: boolean;\n  hostDirectives: R3HostDirectiveMetadataFacade[] | null;\n  isSignal: boolean;\n}\n\nexport interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {\n  template: string;\n  preserveWhitespaces: boolean;\n  animations: OpaqueValue[] | undefined;\n  declarations: R3TemplateDependencyFacade[];\n  styles: string[];\n  encapsulation: ViewEncapsulation;\n  viewProviders: Provider[] | null;\n  changeDetection?: ChangeDetectionStrategy;\n  hasDirectiveDependencies: boolean;\n}\n\n// TODO(legacy-partial-output-inputs): Remove in v18.\n// https://github.com/angular/angular/blob/d4b423690210872b5c32a322a6090beda30b05a3/packages/core/src/compiler/compiler_facade_interface.ts#L197-L199\nexport type LegacyInputPartialMapping =\n  | string\n  | [bindingPropertyName: string, classPropertyName: string, transformFunction?: Function];\n\nexport interface R3DeclareDirectiveFacade {\n  selector?: string;\n  type: Type;\n  version: string;\n  inputs?: {\n    [fieldName: string]:\n      | {\n          classPropertyName: string;\n          publicName: string;\n          isSignal: boolean;\n          isRequired: boolean;\n          transformFunction: Function | null;\n        }\n      | LegacyInputPartialMapping;\n  };\n  outputs?: {[classPropertyName: string]: string};\n  host?: {\n    attributes?: {[key: string]: OpaqueValue};\n    listeners?: {[key: string]: string};\n    properties?: {[key: string]: string};\n    classAttribute?: string;\n    styleAttribute?: string;\n  };\n  queries?: R3DeclareQueryMetadataFacade[];\n  viewQueries?: R3DeclareQueryMetadataFacade[];\n  providers?: OpaqueValue;\n  exportAs?: string[];\n  usesInheritance?: boolean;\n  usesOnChanges?: boolean;\n  controlCreate?: {passThroughInput: string | null};\n  isStandalone?: boolean;\n  isSignal?: boolean;\n  hostDirectives?: R3HostDirectiveMetadataFacade[] | null;\n}\n\nexport interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {\n  template: string;\n  isInline?: boolean;\n  styles?: string[];\n\n  // Post-standalone libraries use a unified dependencies field.\n  dependencies?: R3DeclareTemplateDependencyFacade[];\n\n  // Pre-standalone libraries have separate component/directive/pipe fields:\n  components?: R3DeclareDirectiveDependencyFacade[];\n  directives?: R3DeclareDirectiveDependencyFacade[];\n  pipes?: {[pipeName: string]: OpaqueValue | (() => OpaqueValue)};\n\n  deferBlockDependencies?: (() => Promise<Type> | null)[];\n  viewProviders?: OpaqueValue;\n  animations?: OpaqueValue;\n  changeDetection?: ChangeDetectionStrategy;\n  encapsulation?: ViewEncapsulation;\n  preserveWhitespaces?: boolean;\n}\n\nexport type R3DeclareTemplateDependencyFacade = {\n  kind: string;\n} & (\n  | R3DeclareDirectiveDependencyFacade\n  | R3DeclarePipeDependencyFacade\n  | R3DeclareNgModuleDependencyFacade\n);\n\nexport interface R3DeclareDirectiveDependencyFacade {\n  kind?: 'directive' | 'component';\n  selector: string;\n  type: OpaqueValue | (() => OpaqueValue);\n  inputs?: string[];\n  outputs?: string[];\n  exportAs?: string[];\n}\n\nexport interface R3DeclarePipeDependencyFacade {\n  kind?: 'pipe';\n  name: string;\n  type: OpaqueValue | (() => OpaqueValue);\n}\n\nexport interface R3DeclareNgModuleDependencyFacade {\n  kind: 'ngmodule';\n  type: OpaqueValue | (() => OpaqueValue);\n}\n\nexport enum R3TemplateDependencyKind {\n  Directive = 0,\n  Pipe = 1,\n  NgModule = 2,\n}\n\nexport interface R3TemplateDependencyFacade {\n  kind: R3TemplateDependencyKind;\n  type: OpaqueValue | (() => OpaqueValue);\n}\nexport interface R3FactoryDefMetadataFacade {\n  name: string;\n  type: Type;\n  typeArgumentCount: number;\n  deps: R3DependencyMetadataFacade[] | null;\n  target: FactoryTarget;\n}\n\nexport interface R3DeclareFactoryFacade {\n  type: Type;\n  deps: R3DeclareDependencyMetadataFacade[] | 'invalid' | null;\n  target: FactoryTarget;\n}\n\nexport interface R3DeclareInjectableFacade {\n  type: Type;\n  providedIn?: Type | 'root' | 'platform' | 'any' | null;\n  useClass?: OpaqueValue;\n  useFactory?: OpaqueValue;\n  useExisting?: OpaqueValue;\n  useValue?: OpaqueValue;\n  deps?: R3DeclareDependencyMetadataFacade[];\n}\n\nexport enum ViewEncapsulation {\n  Emulated = 0,\n  // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.\n  None = 2,\n  ShadowDom = 3,\n  ExperimentalIsolatedShadowDom = 4,\n}\n\nexport type ChangeDetectionStrategy = number;\n\nexport interface R3QueryMetadataFacade {\n  propertyName: string;\n  first: boolean;\n  predicate: OpaqueValue | string[];\n  descendants: boolean;\n  emitDistinctChangesOnly: boolean;\n  read: OpaqueValue | null;\n  static: boolean;\n  isSignal: boolean;\n}\n\nexport interface R3DeclareQueryMetadataFacade {\n  propertyName: string;\n  first?: boolean;\n  predicate: OpaqueValue | string[];\n  descendants?: boolean;\n  read?: OpaqueValue;\n  static?: boolean;\n  emitDistinctChangesOnly?: boolean;\n  isSignal?: boolean;\n}\n\nexport interface R3DeclareInjectorFacade {\n  type: Type;\n  imports?: OpaqueValue[];\n  providers?: OpaqueValue[];\n}\n\nexport interface R3DeclareNgModuleFacade {\n  type: Type;\n  bootstrap?: OpaqueValue[] | (() => OpaqueValue[]);\n  declarations?: OpaqueValue[] | (() => OpaqueValue[]);\n  imports?: OpaqueValue[] | (() => OpaqueValue[]);\n  exports?: OpaqueValue[] | (() => OpaqueValue[]);\n  schemas?: OpaqueValue[];\n  id?: OpaqueValue;\n}\n\nexport interface R3DeclarePipeFacade {\n  type: Type;\n  version: string;\n  name: string;\n  pure?: boolean;\n  isStandalone?: boolean;\n}\n\nexport interface ParseSourceSpan {\n  start: any;\n  end: any;\n  details: any;\n  fullStart: any;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {Byte} from '../util';\n\nimport * as i18n from './i18n_ast';\n\n/**\n * A lazily created TextEncoder instance for converting strings into UTF-8 bytes\n */\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Return the message id or compute it using the XLIFF1 digest.\n */\nexport function digest(message: i18n.Message): string {\n  return message.id || computeDigest(message);\n}\n\n/**\n * Compute the message id using the XLIFF1 digest.\n */\nexport function computeDigest(message: i18n.Message): string {\n  return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);\n}\n\n/**\n * Return the message id or compute it using the XLIFF2/XMB/$localize digest.\n */\nexport function decimalDigest(message: i18n.Message): string {\n  return message.id || computeDecimalDigest(message);\n}\n\n/**\n * Compute the message id using the XLIFF2/XMB/$localize digest.\n */\nexport function computeDecimalDigest(message: i18n.Message): string {\n  const visitor = new _SerializerIgnoreIcuExpVisitor();\n  const parts = message.nodes.map((a) => a.visit(visitor, null));\n  return computeMsgId(parts.join(''), message.meaning);\n}\n\n/**\n * Serialize the i18n ast to something xml-like in order to generate an UID.\n *\n * The visitor is also used in the i18n parser tests\n *\n * @internal\n */\nclass _SerializerVisitor implements i18n.Visitor {\n  visitText(text: i18n.Text, context: any): any {\n    return text.value;\n  }\n\n  visitContainer(container: i18n.Container, context: any): any {\n    return `[${container.children.map((child) => child.visit(this)).join(', ')}]`;\n  }\n\n  visitIcu(icu: i18n.Icu, context: any): any {\n    const strCases = Object.keys(icu.cases).map(\n      (k: string) => `${k} {${icu.cases[k].visit(this)}}`,\n    );\n    return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;\n  }\n\n  visitTagPlaceholder(ph: i18n.TagPlaceholder, context: any): any {\n    return ph.isVoid\n      ? `<ph tag name=\"${ph.startName}\"/>`\n      : `<ph tag name=\"${ph.startName}\">${ph.children\n          .map((child) => child.visit(this))\n          .join(', ')}</ph name=\"${ph.closeName}\">`;\n  }\n\n  visitPlaceholder(ph: i18n.Placeholder, context: any): any {\n    return ph.value ? `<ph name=\"${ph.name}\">${ph.value}</ph>` : `<ph name=\"${ph.name}\"/>`;\n  }\n\n  visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any {\n    return `<ph icu name=\"${ph.name}\">${ph.value.visit(this)}</ph>`;\n  }\n\n  visitBlockPlaceholder(ph: i18n.BlockPlaceholder, context: any): any {\n    return `<ph block name=\"${ph.startName}\">${ph.children\n      .map((child) => child.visit(this))\n      .join(', ')}</ph name=\"${ph.closeName}\">`;\n  }\n}\n\nconst serializerVisitor = new _SerializerVisitor();\n\nexport function serializeNodes(nodes: i18n.Node[]): string[] {\n  return nodes.map((a) => a.visit(serializerVisitor, null));\n}\n\n/**\n * Serialize the i18n ast to something xml-like in order to generate an UID.\n *\n * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.\n *\n * @internal\n */\nclass _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {\n  override visitIcu(icu: i18n.Icu): string {\n    let strCases = Object.keys(icu.cases).map((k: string) => `${k} {${icu.cases[k].visit(this)}}`);\n    // Do not take the expression into account\n    return `{${icu.type}, ${strCases.join(', ')}}`;\n  }\n}\n\n/**\n * Compute the SHA1 of the given string\n *\n * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n *\n * WARNING: this function has not been designed not tested with security in mind.\n *          DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.\n */\nexport function sha1(str: string): string {\n  textEncoder ??= new TextEncoder();\n  const utf8 = [...textEncoder.encode(str)];\n  const words32 = bytesToWords32(utf8, Endian.Big);\n  const len = utf8.length * 8;\n\n  const w = new Uint32Array(80);\n  let a = 0x67452301,\n    b = 0xefcdab89,\n    c = 0x98badcfe,\n    d = 0x10325476,\n    e = 0xc3d2e1f0;\n\n  words32[len >> 5] |= 0x80 << (24 - (len % 32));\n  words32[(((len + 64) >> 9) << 4) + 15] = len;\n\n  for (let i = 0; i < words32.length; i += 16) {\n    const h0 = a,\n      h1 = b,\n      h2 = c,\n      h3 = d,\n      h4 = e;\n\n    for (let j = 0; j < 80; j++) {\n      if (j < 16) {\n        w[j] = words32[i + j];\n      } else {\n        w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);\n      }\n\n      const fkVal = fk(j, b, c, d);\n      const f = fkVal[0];\n      const k = fkVal[1];\n      const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);\n      e = d;\n      d = c;\n      c = rol32(b, 30);\n      b = a;\n      a = temp;\n    }\n    a = add32(a, h0);\n    b = add32(b, h1);\n    c = add32(c, h2);\n    d = add32(d, h3);\n    e = add32(e, h4);\n  }\n\n  // Convert the output parts to a 160-bit hexadecimal string\n  return toHexU32(a) + toHexU32(b) + toHexU32(c) + toHexU32(d) + toHexU32(e);\n}\n\n/**\n * Convert and format a number as a string representing a 32-bit unsigned hexadecimal number.\n * @param value The value to format as a string.\n * @returns A hexadecimal string representing the value.\n */\nfunction toHexU32(value: number): string {\n  // unsigned right shift of zero ensures an unsigned 32-bit number\n  return (value >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction fk(index: number, b: number, c: number, d: number): [number, number] {\n  if (index < 20) {\n    return [(b & c) | (~b & d), 0x5a827999];\n  }\n\n  if (index < 40) {\n    return [b ^ c ^ d, 0x6ed9eba1];\n  }\n\n  if (index < 60) {\n    return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];\n  }\n\n  return [b ^ c ^ d, 0xca62c1d6];\n}\n\n/**\n * Compute the fingerprint of the given string\n *\n * The output is 64 bit number encoded as a decimal string\n *\n * based on:\n * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java\n */\nexport function fingerprint(str: string): bigint {\n  textEncoder ??= new TextEncoder();\n  const utf8 = textEncoder.encode(str);\n  const view = new DataView(utf8.buffer, utf8.byteOffset, utf8.byteLength);\n\n  let hi = hash32(view, utf8.length, 0);\n  let lo = hash32(view, utf8.length, 102072);\n\n  if (hi == 0 && (lo == 0 || lo == 1)) {\n    hi = hi ^ 0x130f9bef;\n    lo = lo ^ -0x6b5f56d8;\n  }\n\n  return (BigInt.asUintN(32, BigInt(hi)) << BigInt(32)) | BigInt.asUintN(32, BigInt(lo));\n}\n\nexport function computeMsgId(msg: string, meaning: string = ''): string {\n  let msgFingerprint = fingerprint(msg);\n\n  if (meaning) {\n    // Rotate the 64-bit message fingerprint one bit to the left and then add the meaning\n    // fingerprint.\n    msgFingerprint =\n      BigInt.asUintN(64, msgFingerprint << BigInt(1)) |\n      ((msgFingerprint >> BigInt(63)) & BigInt(1));\n    msgFingerprint += fingerprint(meaning);\n  }\n\n  return BigInt.asUintN(63, msgFingerprint).toString();\n}\n\nfunction hash32(view: DataView, length: number, c: number): number {\n  let a = 0x9e3779b9,\n    b = 0x9e3779b9;\n  let index = 0;\n\n  const end = length - 12;\n  for (; index <= end; index += 12) {\n    a += view.getUint32(index, true);\n    b += view.getUint32(index + 4, true);\n    c += view.getUint32(index + 8, true);\n    const res = mix(a, b, c);\n    ((a = res[0]), (b = res[1]), (c = res[2]));\n  }\n\n  const remainder = length - index;\n\n  // the first byte of c is reserved for the length\n  c += length;\n\n  if (remainder >= 4) {\n    a += view.getUint32(index, true);\n    index += 4;\n\n    if (remainder >= 8) {\n      b += view.getUint32(index, true);\n      index += 4;\n\n      // Partial 32-bit word for c\n      if (remainder >= 9) {\n        c += view.getUint8(index++) << 8;\n      }\n      if (remainder >= 10) {\n        c += view.getUint8(index++) << 16;\n      }\n      if (remainder === 11) {\n        c += view.getUint8(index++) << 24;\n      }\n    } else {\n      // Partial 32-bit word for b\n      if (remainder >= 5) {\n        b += view.getUint8(index++);\n      }\n      if (remainder >= 6) {\n        b += view.getUint8(index++) << 8;\n      }\n      if (remainder === 7) {\n        b += view.getUint8(index++) << 16;\n      }\n    }\n  } else {\n    // Partial 32-bit word for a\n    if (remainder >= 1) {\n      a += view.getUint8(index++);\n    }\n    if (remainder >= 2) {\n      a += view.getUint8(index++) << 8;\n    }\n    if (remainder === 3) {\n      a += view.getUint8(index++) << 16;\n    }\n  }\n\n  return mix(a, b, c)[2];\n}\n\nfunction mix(a: number, b: number, c: number): [number, number, number] {\n  a -= b;\n  a -= c;\n  a ^= c >>> 13;\n  b -= c;\n  b -= a;\n  b ^= a << 8;\n  c -= a;\n  c -= b;\n  c ^= b >>> 13;\n  a -= b;\n  a -= c;\n  a ^= c >>> 12;\n  b -= c;\n  b -= a;\n  b ^= a << 16;\n  c -= a;\n  c -= b;\n  c ^= b >>> 5;\n  a -= b;\n  a -= c;\n  a ^= c >>> 3;\n  b -= c;\n  b -= a;\n  b ^= a << 10;\n  c -= a;\n  c -= b;\n  c ^= b >>> 15;\n  return [a, b, c];\n}\n\n// Utils\n\nenum Endian {\n  Little,\n  Big,\n}\n\nfunction add32(a: number, b: number): number {\n  return add32to64(a, b)[1];\n}\n\nfunction add32to64(a: number, b: number): [number, number] {\n  const low = (a & 0xffff) + (b & 0xffff);\n  const high = (a >>> 16) + (b >>> 16) + (low >>> 16);\n  return [high >>> 16, (high << 16) | (low & 0xffff)];\n}\n\n// Rotate a 32b number left `count` position\nfunction rol32(a: number, count: number): number {\n  return (a << count) | (a >>> (32 - count));\n}\n\nfunction bytesToWords32(bytes: Byte[], endian: Endian): number[] {\n  const size = (bytes.length + 3) >>> 2;\n  const words32 = [];\n\n  for (let i = 0; i < size; i++) {\n    words32[i] = wordAt(bytes, i * 4, endian);\n  }\n\n  return words32;\n}\n\nfunction byteAt(bytes: Byte[], index: number): Byte {\n  return index >= bytes.length ? 0 : bytes[index];\n}\n\nfunction wordAt(bytes: Byte[], index: number, endian: Endian): number {\n  let word = 0;\n  if (endian === Endian.Big) {\n    for (let i = 0; i < 4; i++) {\n      word += byteAt(bytes, index + i) << (24 - 8 * i);\n    }\n  } else {\n    for (let i = 0; i < 4; i++) {\n      word += byteAt(bytes, index + i) << (8 * i);\n    }\n  }\n  return word;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {computeMsgId} from '../i18n/digest';\nimport {Message} from '../i18n/i18n_ast';\nimport {ParseSourceSpan} from '../parse_util';\nimport type {I18nMeta} from '../render3/view/i18n/meta';\n\n//// Types\nexport enum TypeModifier {\n  None = 0,\n  Const = 1 << 0,\n}\n\nexport abstract class Type {\n  constructor(public modifiers: TypeModifier = TypeModifier.None) {}\n  abstract visitType(visitor: TypeVisitor, context: any): any;\n\n  hasModifier(modifier: TypeModifier): boolean {\n    return (this.modifiers & modifier) !== 0;\n  }\n}\n\nexport enum BuiltinTypeName {\n  Dynamic,\n  Bool,\n  String,\n  Int,\n  Number,\n  Function,\n  Inferred,\n  None,\n}\n\nexport class BuiltinType extends Type {\n  constructor(\n    public name: BuiltinTypeName,\n    modifiers?: TypeModifier,\n  ) {\n    super(modifiers);\n  }\n  override visitType(visitor: TypeVisitor, context: any): any {\n    return visitor.visitBuiltinType(this, context);\n  }\n}\n\nexport class ExpressionType extends Type {\n  constructor(\n    public value: Expression,\n    modifiers?: TypeModifier,\n    public typeParams: Type[] | null = null,\n  ) {\n    super(modifiers);\n  }\n  override visitType(visitor: TypeVisitor, context: any): any {\n    return visitor.visitExpressionType(this, context);\n  }\n}\n\nexport class ArrayType extends Type {\n  constructor(\n    public of: Type,\n    modifiers?: TypeModifier,\n  ) {\n    super(modifiers);\n  }\n  override visitType(visitor: TypeVisitor, context: any): any {\n    return visitor.visitArrayType(this, context);\n  }\n}\n\nexport class MapType extends Type {\n  public valueType: Type | null;\n  constructor(valueType: Type | null | undefined, modifiers?: TypeModifier) {\n    super(modifiers);\n    this.valueType = valueType || null;\n  }\n  override visitType(visitor: TypeVisitor, context: any): any {\n    return visitor.visitMapType(this, context);\n  }\n}\n\nexport class TransplantedType<T> extends Type {\n  constructor(\n    readonly type: T,\n    modifiers?: TypeModifier,\n  ) {\n    super(modifiers);\n  }\n  override visitType(visitor: TypeVisitor, context: any): any {\n    return visitor.visitTransplantedType(this, context);\n  }\n}\n\nexport const DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic);\nexport const INFERRED_TYPE = new BuiltinType(BuiltinTypeName.Inferred);\nexport const BOOL_TYPE = new BuiltinType(BuiltinTypeName.Bool);\nexport const INT_TYPE = new BuiltinType(BuiltinTypeName.Int);\nexport const NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number);\nexport const STRING_TYPE = new BuiltinType(BuiltinTypeName.String);\nexport const FUNCTION_TYPE = new BuiltinType(BuiltinTypeName.Function);\nexport const NONE_TYPE = new BuiltinType(BuiltinTypeName.None);\n\nexport interface TypeVisitor {\n  visitBuiltinType(type: BuiltinType, context: any): any;\n  visitExpressionType(type: ExpressionType, context: any): any;\n  visitArrayType(type: ArrayType, context: any): any;\n  visitMapType(type: MapType, context: any): any;\n  visitTransplantedType(type: TransplantedType<unknown>, context: any): any;\n}\n\n///// Expressions\n\nexport enum UnaryOperator {\n  Minus,\n  Plus,\n}\n\nexport enum BinaryOperator {\n  Equals,\n  NotEquals,\n  Assign,\n  Identical,\n  NotIdentical,\n  Minus,\n  Plus,\n  Divide,\n  Multiply,\n  Modulo,\n  And,\n  Or,\n  BitwiseOr,\n  BitwiseAnd,\n  Lower,\n  LowerEquals,\n  Bigger,\n  BiggerEquals,\n  NullishCoalesce,\n  Exponentiation,\n  In,\n  InstanceOf,\n  AdditionAssignment,\n  SubtractionAssignment,\n  MultiplicationAssignment,\n  DivisionAssignment,\n  RemainderAssignment,\n  ExponentiationAssignment,\n  AndAssignment,\n  OrAssignment,\n  NullishCoalesceAssignment,\n}\n\nexport function nullSafeIsEquivalent<T extends {isEquivalent(other: T): boolean}>(\n  base: T | null,\n  other: T | null,\n) {\n  if (base == null || other == null) {\n    return base == other;\n  }\n  return base.isEquivalent(other);\n}\n\nfunction areAllEquivalentPredicate<T>(\n  base: T[],\n  other: T[],\n  equivalentPredicate: (baseElement: T, otherElement: T) => boolean,\n) {\n  const len = base.length;\n  if (len !== other.length) {\n    return false;\n  }\n  for (let i = 0; i < len; i++) {\n    if (!equivalentPredicate(base[i], other[i])) {\n      return false;\n    }\n  }\n  return true;\n}\n\nexport function areAllEquivalent<T extends {isEquivalent(other: T): boolean}>(\n  base: T[],\n  other: T[],\n) {\n  return areAllEquivalentPredicate(base, other, (baseElement: T, otherElement: T) =>\n    baseElement.isEquivalent(otherElement),\n  );\n}\n\nexport abstract class Expression {\n  public type: Type | null;\n  public sourceSpan: ParseSourceSpan | null;\n\n  constructor(type: Type | null | undefined, sourceSpan?: ParseSourceSpan | null) {\n    this.type = type || null;\n    this.sourceSpan = sourceSpan || null;\n  }\n\n  abstract visitExpression(visitor: ExpressionVisitor, context: any): any;\n\n  /**\n   * Calculates whether this expression produces the same value as the given expression.\n   * Note: We don't check Types nor ParseSourceSpans nor function arguments.\n   */\n  abstract isEquivalent(e: Expression): boolean;\n\n  /**\n   * Return true if the expression is constant.\n   */\n  abstract isConstant(): boolean;\n\n  abstract clone(): Expression;\n\n  prop(name: string, sourceSpan?: ParseSourceSpan | null): ReadPropExpr {\n    return new ReadPropExpr(this, name, null, sourceSpan);\n  }\n\n  key(index: Expression, type?: Type | null, sourceSpan?: ParseSourceSpan | null): ReadKeyExpr {\n    return new ReadKeyExpr(this, index, type, sourceSpan);\n  }\n\n  callFn(\n    params: Expression[],\n    sourceSpan?: ParseSourceSpan | null,\n    pure?: boolean,\n  ): InvokeFunctionExpr {\n    return new InvokeFunctionExpr(this, params, null, sourceSpan, pure);\n  }\n\n  instantiate(\n    params: Expression[],\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ): InstantiateExpr {\n    return new InstantiateExpr(this, params, type, sourceSpan);\n  }\n\n  conditional(\n    trueCase: Expression,\n    falseCase: Expression | null = null,\n    sourceSpan?: ParseSourceSpan | null,\n  ): ConditionalExpr {\n    return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan);\n  }\n\n  equals(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Equals, this, rhs, null, sourceSpan);\n  }\n  notEquals(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.NotEquals, this, rhs, null, sourceSpan);\n  }\n  identical(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Identical, this, rhs, null, sourceSpan);\n  }\n  notIdentical(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.NotIdentical, this, rhs, null, sourceSpan);\n  }\n  minus(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Minus, this, rhs, null, sourceSpan);\n  }\n  plus(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Plus, this, rhs, null, sourceSpan);\n  }\n  divide(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Divide, this, rhs, null, sourceSpan);\n  }\n  multiply(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Multiply, this, rhs, null, sourceSpan);\n  }\n  modulo(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Modulo, this, rhs, null, sourceSpan);\n  }\n  power(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Exponentiation, this, rhs, null, sourceSpan);\n  }\n  and(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.And, this, rhs, null, sourceSpan);\n  }\n  bitwiseOr(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.BitwiseOr, this, rhs, null, sourceSpan);\n  }\n  bitwiseAnd(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.BitwiseAnd, this, rhs, null, sourceSpan);\n  }\n  or(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Or, this, rhs, null, sourceSpan);\n  }\n  lower(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Lower, this, rhs, null, sourceSpan);\n  }\n  lowerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.LowerEquals, this, rhs, null, sourceSpan);\n  }\n  bigger(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Bigger, this, rhs, null, sourceSpan);\n  }\n  biggerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.BiggerEquals, this, rhs, null, sourceSpan);\n  }\n  isBlank(sourceSpan?: ParseSourceSpan | null): Expression {\n    // Note: We use equals by purpose here to compare to null and undefined in JS.\n    // We use the typed null to allow strictNullChecks to narrow types.\n    return this.equals(TYPED_NULL_EXPR, sourceSpan);\n  }\n  nullishCoalesce(rhs: Expression, sourceSpan?: ParseSourceSpan | null): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.NullishCoalesce, this, rhs, null, sourceSpan);\n  }\n\n  toStmt(): Statement {\n    return new ExpressionStatement(this, null);\n  }\n}\n\nexport class ReadVarExpr extends Expression {\n  constructor(\n    public name: string,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof ReadVarExpr && this.name === e.name;\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitReadVarExpr(this, context);\n  }\n\n  override clone(): ReadVarExpr {\n    return new ReadVarExpr(this.name, this.type, this.sourceSpan);\n  }\n\n  set(value: Expression): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(BinaryOperator.Assign, this, value, null, this.sourceSpan);\n  }\n}\n\nexport class TypeofExpr extends Expression {\n  constructor(\n    public expr: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any) {\n    return visitor.visitTypeofExpr(this, context);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof TypeofExpr && e.expr.isEquivalent(this.expr);\n  }\n\n  override isConstant(): boolean {\n    return this.expr.isConstant();\n  }\n\n  override clone(): TypeofExpr {\n    return new TypeofExpr(this.expr.clone());\n  }\n}\n\nexport class VoidExpr extends Expression {\n  constructor(\n    public expr: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any) {\n    return visitor.visitVoidExpr(this, context);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof VoidExpr && e.expr.isEquivalent(this.expr);\n  }\n\n  override isConstant(): boolean {\n    return this.expr.isConstant();\n  }\n\n  override clone(): VoidExpr {\n    return new VoidExpr(this.expr.clone());\n  }\n}\n\nexport class WrappedNodeExpr<T> extends Expression {\n  constructor(\n    public node: T,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof WrappedNodeExpr && this.node === e.node;\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitWrappedNodeExpr(this, context);\n  }\n\n  override clone(): WrappedNodeExpr<T> {\n    return new WrappedNodeExpr(this.node, this.type, this.sourceSpan);\n  }\n}\n\nexport class InvokeFunctionExpr extends Expression {\n  constructor(\n    public fn: Expression,\n    public args: Expression[],\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n    public pure = false,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  // An alias for fn, which allows other logic to handle calls and property reads together.\n  get receiver(): Expression {\n    return this.fn;\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof InvokeFunctionExpr &&\n      this.fn.isEquivalent(e.fn) &&\n      areAllEquivalent(this.args, e.args) &&\n      this.pure === e.pure\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitInvokeFunctionExpr(this, context);\n  }\n\n  override clone(): InvokeFunctionExpr {\n    return new InvokeFunctionExpr(\n      this.fn.clone(),\n      this.args.map((arg) => arg.clone()),\n      this.type,\n      this.sourceSpan,\n      this.pure,\n    );\n  }\n}\n\nexport class TaggedTemplateLiteralExpr extends Expression {\n  constructor(\n    public tag: Expression,\n    public template: TemplateLiteralExpr,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof TaggedTemplateLiteralExpr &&\n      this.tag.isEquivalent(e.tag) &&\n      this.template.isEquivalent(e.template)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitTaggedTemplateLiteralExpr(this, context);\n  }\n\n  override clone(): TaggedTemplateLiteralExpr {\n    return new TaggedTemplateLiteralExpr(\n      this.tag.clone(),\n      this.template.clone(),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n}\n\nexport class InstantiateExpr extends Expression {\n  constructor(\n    public classExpr: Expression,\n    public args: Expression[],\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof InstantiateExpr &&\n      this.classExpr.isEquivalent(e.classExpr) &&\n      areAllEquivalent(this.args, e.args)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitInstantiateExpr(this, context);\n  }\n\n  override clone(): InstantiateExpr {\n    return new InstantiateExpr(\n      this.classExpr.clone(),\n      this.args.map((arg) => arg.clone()),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n}\n\nexport class RegularExpressionLiteralExpr extends Expression {\n  constructor(\n    public body: string,\n    public flags: string | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(null, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof RegularExpressionLiteralExpr && this.body === e.body && this.flags === e.flags\n    );\n  }\n\n  override isConstant() {\n    return true;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitRegularExpressionLiteral(this, context);\n  }\n\n  override clone(): RegularExpressionLiteralExpr {\n    return new RegularExpressionLiteralExpr(this.body, this.flags, this.sourceSpan);\n  }\n}\n\nexport class LiteralExpr extends Expression {\n  constructor(\n    public value: number | string | boolean | null | undefined,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof LiteralExpr && this.value === e.value;\n  }\n\n  override isConstant() {\n    return true;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitLiteralExpr(this, context);\n  }\n\n  override clone(): LiteralExpr {\n    return new LiteralExpr(this.value, this.type, this.sourceSpan);\n  }\n}\n\nexport class TemplateLiteralExpr extends Expression {\n  constructor(\n    public elements: TemplateLiteralElementExpr[],\n    public expressions: Expression[],\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(null, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof TemplateLiteralExpr &&\n      areAllEquivalentPredicate(this.elements, e.elements, (a, b) => a.text === b.text) &&\n      areAllEquivalent(this.expressions, e.expressions)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitTemplateLiteralExpr(this, context);\n  }\n\n  override clone(): TemplateLiteralExpr {\n    return new TemplateLiteralExpr(\n      this.elements.map((el) => el.clone()),\n      this.expressions.map((expr) => expr.clone()),\n    );\n  }\n}\nexport class TemplateLiteralElementExpr extends Expression {\n  readonly rawText: string;\n\n  constructor(\n    readonly text: string,\n    sourceSpan?: ParseSourceSpan | null,\n    rawText?: string,\n  ) {\n    super(STRING_TYPE, sourceSpan);\n\n    // If `rawText` is not provided, \"fake\" the raw string by escaping the following sequences:\n    // - \"\\\" would otherwise indicate that the next character is a control character.\n    // - \"`\" and \"${\" are template string control sequences that would otherwise prematurely\n    // indicate the end of the template literal element.\n    // Note that we can't rely on the `sourceSpan` here, because it may be incorrect (see\n    // https://github.com/angular/angular/pull/60267#discussion_r1986402524).\n    this.rawText = rawText ?? escapeForTemplateLiteral(escapeSlashes(text));\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any) {\n    return visitor.visitTemplateLiteralElementExpr(this, context);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof TemplateLiteralElementExpr && e.text === this.text && e.rawText === this.rawText\n    );\n  }\n\n  override isConstant(): boolean {\n    return true;\n  }\n\n  override clone(): TemplateLiteralElementExpr {\n    return new TemplateLiteralElementExpr(this.text, this.sourceSpan, this.rawText);\n  }\n}\n\nexport class LiteralPiece {\n  constructor(\n    public text: string,\n    public sourceSpan: ParseSourceSpan,\n  ) {}\n}\nexport class PlaceholderPiece {\n  /**\n   * Create a new instance of a `PlaceholderPiece`.\n   *\n   * @param text the name of this placeholder (e.g. `PH_1`).\n   * @param sourceSpan the location of this placeholder in its localized message the source code.\n   * @param associatedMessage reference to another message that this placeholder is associated with.\n   * The `associatedMessage` is mainly used to provide a relationship to an ICU message that has\n   * been extracted out from the message containing the placeholder.\n   */\n  constructor(\n    public text: string,\n    public sourceSpan: ParseSourceSpan,\n    public associatedMessage?: Message,\n  ) {}\n}\n\nexport type MessagePiece = LiteralPiece | PlaceholderPiece;\n\nconst MEANING_SEPARATOR = '|';\nconst ID_SEPARATOR = '@@';\nconst LEGACY_ID_INDICATOR = '␟';\n\nexport class LocalizedString extends Expression {\n  constructor(\n    readonly metaBlock: I18nMeta,\n    readonly messageParts: LiteralPiece[],\n    readonly placeHolderNames: PlaceholderPiece[],\n    readonly expressions: Expression[],\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(STRING_TYPE, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    // return e instanceof LocalizedString && this.message === e.message;\n    return false;\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitLocalizedString(this, context);\n  }\n\n  override clone(): LocalizedString {\n    return new LocalizedString(\n      this.metaBlock,\n      this.messageParts,\n      this.placeHolderNames,\n      this.expressions.map((expr) => expr.clone()),\n      this.sourceSpan,\n    );\n  }\n\n  /**\n   * Serialize the given `meta` and `messagePart` into \"cooked\" and \"raw\" strings that can be used\n   * in a `$localize` tagged string. The format of the metadata is the same as that parsed by\n   * `parseI18nMeta()`.\n   *\n   * @param meta The metadata to serialize\n   * @param messagePart The first part of the tagged string\n   */\n  serializeI18nHead(): CookedRawString {\n    let metaBlock = this.metaBlock.description || '';\n    if (this.metaBlock.meaning) {\n      metaBlock = `${this.metaBlock.meaning}${MEANING_SEPARATOR}${metaBlock}`;\n    }\n    if (this.metaBlock.customId) {\n      metaBlock = `${metaBlock}${ID_SEPARATOR}${this.metaBlock.customId}`;\n    }\n    if (this.metaBlock.legacyIds) {\n      this.metaBlock.legacyIds.forEach((legacyId) => {\n        metaBlock = `${metaBlock}${LEGACY_ID_INDICATOR}${legacyId}`;\n      });\n    }\n    return createCookedRawString(\n      metaBlock,\n      this.messageParts[0].text,\n      this.getMessagePartSourceSpan(0),\n    );\n  }\n\n  getMessagePartSourceSpan(i: number): ParseSourceSpan | null {\n    return this.messageParts[i]?.sourceSpan ?? this.sourceSpan;\n  }\n\n  getPlaceholderSourceSpan(i: number): ParseSourceSpan {\n    return (\n      this.placeHolderNames[i]?.sourceSpan ?? this.expressions[i]?.sourceSpan ?? this.sourceSpan\n    );\n  }\n\n  /**\n   * Serialize the given `placeholderName` and `messagePart` into \"cooked\" and \"raw\" strings that\n   * can be used in a `$localize` tagged string.\n   *\n   * The format is `:<placeholder-name>[@@<associated-id>]:`.\n   *\n   * The `associated-id` is the message id of the (usually an ICU) message to which this placeholder\n   * refers.\n   *\n   * @param partIndex The index of the message part to serialize.\n   */\n  serializeI18nTemplatePart(partIndex: number): CookedRawString {\n    const placeholder = this.placeHolderNames[partIndex - 1];\n    const messagePart = this.messageParts[partIndex];\n    let metaBlock = placeholder.text;\n    if (placeholder.associatedMessage?.legacyIds.length === 0) {\n      metaBlock += `${ID_SEPARATOR}${computeMsgId(\n        placeholder.associatedMessage.messageString,\n        placeholder.associatedMessage.meaning,\n      )}`;\n    }\n    return createCookedRawString(\n      metaBlock,\n      messagePart.text,\n      this.getMessagePartSourceSpan(partIndex),\n    );\n  }\n}\n\n/**\n * A structure to hold the cooked and raw strings of a template literal element, along with its\n * source-span range.\n */\nexport interface CookedRawString {\n  cooked: string;\n  raw: string;\n  range: ParseSourceSpan | null;\n}\n\nconst escapeSlashes = (str: string): string => str.replace(/\\\\/g, '\\\\\\\\');\nconst escapeStartingColon = (str: string): string => str.replace(/^:/, '\\\\:');\nconst escapeColons = (str: string): string => str.replace(/:/g, '\\\\:');\nconst escapeForTemplateLiteral = (str: string): string =>\n  str.replace(/`/g, '\\\\`').replace(/\\${/g, '$\\\\{');\n\n/**\n * Creates a `{cooked, raw}` object from the `metaBlock` and `messagePart`.\n *\n * The `raw` text must have various character sequences escaped:\n * * \"\\\" would otherwise indicate that the next character is a control character.\n * * \"`\" and \"${\" are template string control sequences that would otherwise prematurely indicate\n *   the end of a message part.\n * * \":\" inside a metablock would prematurely indicate the end of the metablock.\n * * \":\" at the start of a messagePart with no metablock would erroneously indicate the start of a\n *   metablock.\n *\n * @param metaBlock Any metadata that should be prepended to the string\n * @param messagePart The message part of the string\n */\nfunction createCookedRawString(\n  metaBlock: string,\n  messagePart: string,\n  range: ParseSourceSpan | null,\n): CookedRawString {\n  if (metaBlock === '') {\n    return {\n      cooked: messagePart,\n      raw: escapeForTemplateLiteral(escapeStartingColon(escapeSlashes(messagePart))),\n      range,\n    };\n  } else {\n    return {\n      cooked: `:${metaBlock}:${messagePart}`,\n      raw: escapeForTemplateLiteral(\n        `:${escapeColons(escapeSlashes(metaBlock))}:${escapeSlashes(messagePart)}`,\n      ),\n      range,\n    };\n  }\n}\n\nexport class ExternalExpr extends Expression {\n  constructor(\n    public value: ExternalReference,\n    type?: Type | null,\n    public typeParams: Type[] | null = null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof ExternalExpr &&\n      this.value.name === e.value.name &&\n      this.value.moduleName === e.value.moduleName\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitExternalExpr(this, context);\n  }\n\n  override clone(): ExternalExpr {\n    return new ExternalExpr(this.value, this.type, this.typeParams, this.sourceSpan);\n  }\n}\n\nexport class ExternalReference {\n  constructor(\n    public moduleName: string | null,\n    public name: string | null,\n  ) {}\n  // Note: no isEquivalent method here as we use this as an interface too.\n}\n\nexport class ConditionalExpr extends Expression {\n  public trueCase: Expression;\n\n  constructor(\n    public condition: Expression,\n    trueCase: Expression,\n    public falseCase: Expression | null = null,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type || trueCase.type, sourceSpan);\n    this.trueCase = trueCase;\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof ConditionalExpr &&\n      this.condition.isEquivalent(e.condition) &&\n      this.trueCase.isEquivalent(e.trueCase) &&\n      nullSafeIsEquivalent(this.falseCase, e.falseCase)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitConditionalExpr(this, context);\n  }\n\n  override clone(): ConditionalExpr {\n    return new ConditionalExpr(\n      this.condition.clone(),\n      this.trueCase.clone(),\n      this.falseCase?.clone(),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n}\n\nexport class DynamicImportExpr extends Expression {\n  constructor(\n    public url: string | Expression,\n    sourceSpan?: ParseSourceSpan | null,\n    public urlComment?: string,\n  ) {\n    super(null, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof DynamicImportExpr && this.url === e.url && this.urlComment === e.urlComment;\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitDynamicImportExpr(this, context);\n  }\n\n  override clone(): DynamicImportExpr {\n    return new DynamicImportExpr(\n      typeof this.url === 'string' ? this.url : this.url.clone(),\n      this.sourceSpan,\n      this.urlComment,\n    );\n  }\n}\n\nexport class NotExpr extends Expression {\n  constructor(\n    public condition: Expression,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(BOOL_TYPE, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof NotExpr && this.condition.isEquivalent(e.condition);\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitNotExpr(this, context);\n  }\n\n  override clone(): NotExpr {\n    return new NotExpr(this.condition.clone(), this.sourceSpan);\n  }\n}\n\nexport class FnParam {\n  constructor(\n    public name: string,\n    public type: Type | null = null,\n  ) {}\n\n  isEquivalent(param: FnParam): boolean {\n    return this.name === param.name;\n  }\n\n  clone(): FnParam {\n    return new FnParam(this.name, this.type);\n  }\n}\n\nexport class FunctionExpr extends Expression {\n  constructor(\n    public params: FnParam[],\n    public statements: Statement[],\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n    public name?: string | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression | Statement): boolean {\n    return (\n      (e instanceof FunctionExpr || e instanceof DeclareFunctionStmt) &&\n      areAllEquivalent(this.params, e.params) &&\n      areAllEquivalent(this.statements, e.statements)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitFunctionExpr(this, context);\n  }\n\n  toDeclStmt(name: string, modifiers?: StmtModifier): DeclareFunctionStmt {\n    return new DeclareFunctionStmt(\n      name,\n      this.params,\n      this.statements,\n      this.type,\n      modifiers,\n      this.sourceSpan,\n    );\n  }\n\n  override clone(): FunctionExpr {\n    // TODO: Should we deep clone statements?\n    return new FunctionExpr(\n      this.params.map((p) => p.clone()),\n      this.statements,\n      this.type,\n      this.sourceSpan,\n      this.name,\n    );\n  }\n}\n\nexport class ArrowFunctionExpr extends Expression {\n  // Note that `body: Expression` represents `() => expr` whereas\n  // `body: Statement[]` represents `() => { expr }`.\n\n  constructor(\n    public params: FnParam[],\n    public body: Expression | Statement[],\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    if (!(e instanceof ArrowFunctionExpr) || !areAllEquivalent(this.params, e.params)) {\n      return false;\n    }\n\n    if (this.body instanceof Expression && e.body instanceof Expression) {\n      return this.body.isEquivalent(e.body);\n    }\n\n    if (Array.isArray(this.body) && Array.isArray(e.body)) {\n      return areAllEquivalent(this.body, e.body);\n    }\n\n    return false;\n  }\n\n  override isConstant(): boolean {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any) {\n    return visitor.visitArrowFunctionExpr(this, context);\n  }\n\n  override clone(): Expression {\n    // TODO: Should we deep clone statements?\n    return new ArrowFunctionExpr(\n      this.params.map((p) => p.clone()),\n      Array.isArray(this.body) ? this.body : this.body.clone(),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n\n  toDeclStmt(name: string, modifiers?: StmtModifier): DeclareVarStmt {\n    return new DeclareVarStmt(name, this, INFERRED_TYPE, modifiers, this.sourceSpan);\n  }\n}\n\nexport class UnaryOperatorExpr extends Expression {\n  constructor(\n    public operator: UnaryOperator,\n    public expr: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n    public parens: boolean = true,\n  ) {\n    super(type || NUMBER_TYPE, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof UnaryOperatorExpr &&\n      this.operator === e.operator &&\n      this.expr.isEquivalent(e.expr)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitUnaryOperatorExpr(this, context);\n  }\n\n  override clone(): UnaryOperatorExpr {\n    return new UnaryOperatorExpr(\n      this.operator,\n      this.expr.clone(),\n      this.type,\n      this.sourceSpan,\n      this.parens,\n    );\n  }\n}\n\nexport class ParenthesizedExpr extends Expression {\n  constructor(\n    public expr: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any) {\n    return visitor.visitParenthesizedExpr(this, context);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    // TODO: should this ignore paren depth? i.e. is `(1)` equivalent to `1`?\n    return e instanceof ParenthesizedExpr && e.expr.isEquivalent(this.expr);\n  }\n\n  override isConstant(): boolean {\n    return this.expr.isConstant();\n  }\n\n  override clone(): ParenthesizedExpr {\n    return new ParenthesizedExpr(this.expr.clone());\n  }\n}\n\nexport class BinaryOperatorExpr extends Expression {\n  public lhs: Expression;\n  constructor(\n    public operator: BinaryOperator,\n    lhs: Expression,\n    public rhs: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type || lhs.type, sourceSpan);\n    this.lhs = lhs;\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof BinaryOperatorExpr &&\n      this.operator === e.operator &&\n      this.lhs.isEquivalent(e.lhs) &&\n      this.rhs.isEquivalent(e.rhs)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitBinaryOperatorExpr(this, context);\n  }\n\n  override clone(): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(\n      this.operator,\n      this.lhs.clone(),\n      this.rhs.clone(),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n\n  isAssignment(): boolean {\n    const op = this.operator;\n    return (\n      op === BinaryOperator.Assign ||\n      op === BinaryOperator.AdditionAssignment ||\n      op === BinaryOperator.SubtractionAssignment ||\n      op === BinaryOperator.MultiplicationAssignment ||\n      op === BinaryOperator.DivisionAssignment ||\n      op === BinaryOperator.RemainderAssignment ||\n      op === BinaryOperator.ExponentiationAssignment ||\n      op === BinaryOperator.AndAssignment ||\n      op === BinaryOperator.OrAssignment ||\n      op === BinaryOperator.NullishCoalesceAssignment\n    );\n  }\n}\n\nexport class ReadPropExpr extends Expression {\n  constructor(\n    public receiver: Expression,\n    public name: string,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  // An alias for name, which allows other logic to handle property reads and keyed reads together.\n  get index() {\n    return this.name;\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) && this.name === e.name\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitReadPropExpr(this, context);\n  }\n\n  set(value: Expression): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(\n      BinaryOperator.Assign,\n      this.receiver.prop(this.name),\n      value,\n      null,\n      this.sourceSpan,\n    );\n  }\n\n  override clone(): ReadPropExpr {\n    return new ReadPropExpr(this.receiver.clone(), this.name, this.type, this.sourceSpan);\n  }\n}\n\nexport class ReadKeyExpr extends Expression {\n  constructor(\n    public receiver: Expression,\n    public index: Expression,\n    type?: Type | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return (\n      e instanceof ReadKeyExpr &&\n      this.receiver.isEquivalent(e.receiver) &&\n      this.index.isEquivalent(e.index)\n    );\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitReadKeyExpr(this, context);\n  }\n\n  set(value: Expression): BinaryOperatorExpr {\n    return new BinaryOperatorExpr(\n      BinaryOperator.Assign,\n      this.receiver.key(this.index),\n      value,\n      null,\n      this.sourceSpan,\n    );\n  }\n\n  override clone(): ReadKeyExpr {\n    return new ReadKeyExpr(this.receiver.clone(), this.index.clone(), this.type, this.sourceSpan);\n  }\n}\n\nexport class LiteralArrayExpr extends Expression {\n  public entries: Expression[];\n  constructor(entries: Expression[], type?: Type | null, sourceSpan?: ParseSourceSpan | null) {\n    super(type, sourceSpan);\n    this.entries = entries;\n  }\n\n  override isConstant() {\n    return this.entries.every((e) => e.isConstant());\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries);\n  }\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitLiteralArrayExpr(this, context);\n  }\n\n  override clone(): LiteralArrayExpr {\n    return new LiteralArrayExpr(\n      this.entries.map((e) => e.clone()),\n      this.type,\n      this.sourceSpan,\n    );\n  }\n}\n\nexport class LiteralMapPropertyAssignment {\n  constructor(\n    public key: string,\n    public value: Expression,\n    public quoted: boolean,\n  ) {}\n\n  isEquivalent(e: LiteralMapPropertyAssignment): boolean {\n    return this.key === e.key && this.value.isEquivalent(e.value);\n  }\n\n  clone(): LiteralMapPropertyAssignment {\n    return new LiteralMapPropertyAssignment(this.key, this.value.clone(), this.quoted);\n  }\n\n  isConstant() {\n    return this.value.isConstant();\n  }\n}\n\nexport class LiteralMapSpreadAssignment {\n  constructor(public expression: Expression) {}\n\n  isEquivalent(e: LiteralMapSpreadAssignment): boolean {\n    return e instanceof LiteralMapSpreadAssignment && this.expression.isEquivalent(e.expression);\n  }\n\n  clone(): LiteralMapSpreadAssignment {\n    return new LiteralMapSpreadAssignment(this.expression.clone());\n  }\n\n  isConstant() {\n    return this.expression.isConstant();\n  }\n}\n\nexport type LiteralMapEntry = LiteralMapPropertyAssignment | LiteralMapSpreadAssignment;\n\nexport class LiteralMapExpr extends Expression {\n  public valueType: Type | null = null;\n  constructor(\n    public entries: LiteralMapEntry[],\n    type?: MapType | null,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(type, sourceSpan);\n    if (type) {\n      this.valueType = type.valueType;\n    }\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries);\n  }\n\n  override isConstant() {\n    return this.entries.every((e) => e.isConstant());\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitLiteralMapExpr(this, context);\n  }\n\n  override clone(): LiteralMapExpr {\n    const entriesClone = this.entries.map((entry) => entry.clone());\n    return new LiteralMapExpr(entriesClone, this.type as MapType | null, this.sourceSpan);\n  }\n}\n\nexport class CommaExpr extends Expression {\n  constructor(\n    public parts: Expression[],\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(parts[parts.length - 1].type, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts);\n  }\n\n  override isConstant() {\n    return false;\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitCommaExpr(this, context);\n  }\n\n  override clone(): CommaExpr {\n    return new CommaExpr(this.parts.map((p) => p.clone()));\n  }\n}\n\nexport class SpreadElementExpr extends Expression {\n  constructor(\n    public expression: Expression,\n    sourceSpan?: ParseSourceSpan | null,\n  ) {\n    super(null, sourceSpan);\n  }\n\n  override isEquivalent(e: Expression): boolean {\n    return e instanceof SpreadElementExpr && this.expression.isEquivalent(e.expression);\n  }\n\n  override isConstant() {\n    return this.expression.isConstant();\n  }\n\n  override visitExpression(visitor: ExpressionVisitor, context: any): any {\n    return visitor.visitSpreadElementExpr(this, context);\n  }\n\n  override clone(): SpreadElementExpr {\n    return new SpreadElementExpr(this.expression.clone(), this.sourceSpan);\n  }\n}\n\nexport interface ExpressionVisitor {\n  visitReadVarExpr(ast: ReadVarExpr, context: any): any;\n  visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: any): any;\n  visitTaggedTemplateLiteralExpr(ast: TaggedTemplateLiteralExpr, context: any): any;\n  visitTemplateLiteralExpr(ast: TemplateLiteralExpr, context: any): any;\n  visitTemplateLiteralElementExpr(ast: TemplateLiteralElementExpr, context: any): any;\n  visitInstantiateExpr(ast: InstantiateExpr, context: any): any;\n  visitLiteralExpr(ast: LiteralExpr, context: any): any;\n  visitLocalizedString(ast: LocalizedString, context: any): any;\n  visitExternalExpr(ast: ExternalExpr, context: any): any;\n  visitConditionalExpr(ast: ConditionalExpr, context: any): any;\n  visitDynamicImportExpr(ast: DynamicImportExpr, context: any): any;\n  visitNotExpr(ast: NotExpr, context: any): any;\n  visitFunctionExpr(ast: FunctionExpr, context: any): any;\n  visitUnaryOperatorExpr(ast: UnaryOperatorExpr, context: any): any;\n  visitBinaryOperatorExpr(ast: BinaryOperatorExpr, context: any): any;\n  visitReadPropExpr(ast: ReadPropExpr, context: any): any;\n  visitReadKeyExpr(ast: ReadKeyExpr, context: any): any;\n  visitLiteralArrayExpr(ast: LiteralArrayExpr, context: any): any;\n  visitLiteralMapExpr(ast: LiteralMapExpr, context: any): any;\n  visitCommaExpr(ast: CommaExpr, context: any): any;\n  visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any;\n  visitTypeofExpr(ast: TypeofExpr, context: any): any;\n  visitVoidExpr(ast: VoidExpr, context: any): any;\n  visitArrowFunctionExpr(ast: ArrowFunctionExpr, context: any): any;\n  visitParenthesizedExpr(ast: ParenthesizedExpr, context: any): any;\n  visitRegularExpressionLiteral(ast: RegularExpressionLiteralExpr, context: any): any;\n  visitSpreadElementExpr(ast: SpreadElementExpr, context: any): any;\n}\n\nexport const NULL_EXPR = new LiteralExpr(null, null, null);\nexport const TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE, null);\n\n//// Statements\nexport enum StmtModifier {\n  None = 0,\n  Final = 1 << 0,\n  Private = 1 << 1,\n  Exported = 1 << 2,\n  Static = 1 << 3,\n}\n\nexport class LeadingComment {\n  constructor(\n    public text: string,\n    public multiline: boolean,\n    public trailingNewline: boolean,\n  ) {}\n  toString() {\n    return this.multiline ? ` ${this.text} ` : this.text;\n  }\n}\nexport class JSDocComment extends LeadingComment {\n  constructor(public tags: JSDocTag[]) {\n    super('', /* multiline */ true, /* trailingNewline */ true);\n  }\n  override toString(): string {\n    return serializeTags(this.tags);\n  }\n}\n\nexport abstract class Statement {\n  constructor(\n    public modifiers: StmtModifier = StmtModifier.None,\n    public sourceSpan: ParseSourceSpan | null = null,\n    public leadingComments?: LeadingComment[],\n  ) {}\n  /**\n   * Calculates whether this statement produces the same value as the given statement.\n   * Note: We don't check Types nor ParseSourceSpans nor function arguments.\n   */\n  abstract isEquivalent(stmt: Statement): boolean;\n\n  abstract visitStatement(visitor: StatementVisitor, context: any): any;\n\n  hasModifier(modifier: StmtModifier): boolean {\n    return (this.modifiers & modifier) !== 0;\n  }\n\n  addLeadingComment(leadingComment: LeadingComment): void {\n    this.leadingComments = this.leadingComments ?? [];\n    this.leadingComments.push(leadingComment);\n  }\n}\n\nexport class DeclareVarStmt extends Statement {\n  public type: Type | null;\n  constructor(\n    public name: string,\n    public value?: Expression,\n    type?: Type | null,\n    modifiers?: StmtModifier,\n    sourceSpan?: ParseSourceSpan | null,\n    leadingComments?: LeadingComment[],\n  ) {\n    super(modifiers, sourceSpan, leadingComments);\n    this.type = type || (value && value.type) || null;\n  }\n  override isEquivalent(stmt: Statement): boolean {\n    return (\n      stmt instanceof DeclareVarStmt &&\n      this.name === stmt.name &&\n      (this.value ? !!stmt.value && this.value.isEquivalent(stmt.value) : !stmt.value)\n    );\n  }\n  override visitStatement(visitor: StatementVisitor, context: any): any {\n    return visitor.visitDeclareVarStmt(this, context);\n  }\n}\n\nexport class DeclareFunctionStmt extends Statement {\n  public type: Type | null;\n  constructor(\n    public name: string,\n    public params: FnParam[],\n    public statements: Statement[],\n    type?: Type | null,\n    modifiers?: StmtModifier,\n    sourceSpan?: ParseSourceSpan | null,\n    leadingComments?: LeadingComment[],\n  ) {\n    super(modifiers, sourceSpan, leadingComments);\n    this.type = type || null;\n  }\n  override isEquivalent(stmt: Statement): boolean {\n    return (\n      stmt instanceof DeclareFunctionStmt &&\n      areAllEquivalent(this.params, stmt.params) &&\n      areAllEquivalent(this.statements, stmt.statements)\n    );\n  }\n  override visitStatement(visitor: StatementVisitor, context: any): any {\n    return visitor.visitDeclareFunctionStmt(this, context);\n  }\n}\n\nexport class ExpressionStatement extends Statement {\n  constructor(\n    public expr: Expression,\n    sourceSpan?: ParseSourceSpan | null,\n    leadingComments?: LeadingComment[],\n  ) {\n    super(StmtModifier.None, sourceSpan, leadingComments);\n  }\n  override isEquivalent(stmt: Statement): boolean {\n    return stmt instanceof ExpressionStatement && this.expr.isEquivalent(stmt.expr);\n  }\n  override visitStatement(visitor: StatementVisitor, context: any): any {\n    return visitor.visitExpressionStmt(this, context);\n  }\n}\n\nexport class ReturnStatement extends Statement {\n  constructor(\n    public value: Expression,\n    sourceSpan: ParseSourceSpan | null = null,\n    leadingComments?: LeadingComment[],\n  ) {\n    super(StmtModifier.None, sourceSpan, leadingComments);\n  }\n  override isEquivalent(stmt: Statement): boolean {\n    return stmt instanceof ReturnStatement && this.value.isEquivalent(stmt.value);\n  }\n  override visitStatement(visitor: StatementVisitor, context: any): any {\n    return visitor.visitReturnStmt(this, context);\n  }\n}\n\nexport class IfStmt extends Statement {\n  constructor(\n    public condition: Expression,\n    public trueCase: Statement[],\n    public falseCase: Statement[] = [],\n    sourceSpan?: ParseSourceSpan | null,\n    leadingComments?: LeadingComment[],\n  ) {\n    super(StmtModifier.None, sourceSpan, leadingComments);\n  }\n  override isEquivalent(stmt: Statement): boolean {\n    return (\n      stmt instanceof IfStmt &&\n      this.condition.isEquivalent(stmt.condition) &&\n      areAllEquivalent(this.trueCase, stmt.trueCase) &&\n      areAllEquivalent(this.falseCase, stmt.falseCase)\n    );\n  }\n  override visitStatement(visitor: StatementVisitor, context: any): any {\n    return visitor.visitIfStmt(this, context);\n  }\n}\n\nexport interface StatementVisitor {\n  visitDeclareVarStmt(stmt: DeclareVarStmt, context: any): any;\n  visitDeclareFunctionStmt(stmt: DeclareFunctionStmt, context: any): any;\n  visitExpressionStmt(stmt: ExpressionStatement, context: any): any;\n  visitReturnStmt(stmt: ReturnStatement, context: any): any;\n  visitIfStmt(stmt: IfStmt, context: any): any;\n}\n\nexport class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor {\n  visitType(ast: Type, context: any): any {\n    return ast;\n  }\n  visitExpression(ast: Expression, context: any): any {\n    if (ast.type) {\n      ast.type.visitType(this, context);\n    }\n    return ast;\n  }\n  visitBuiltinType(type: BuiltinType, context: any): any {\n    return this.visitType(type, context);\n  }\n  visitExpressionType(type: ExpressionType, context: any): any {\n    type.value.visitExpression(this, context);\n    if (type.typeParams !== null) {\n      type.typeParams.forEach((param) => this.visitType(param, context));\n    }\n    return this.visitType(type, context);\n  }\n  visitArrayType(type: ArrayType, context: any): any {\n    return this.visitType(type, context);\n  }\n  visitMapType(type: MapType, context: any): any {\n    return this.visitType(type, context);\n  }\n  visitTransplantedType(type: TransplantedType<unknown>, context: any): any {\n    return type;\n  }\n  visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any {\n    return ast;\n  }\n  visitReadVarExpr(ast: ReadVarExpr, context: any): any {\n    return this.visitExpression(ast, context);\n  }\n  visitDynamicImportExpr(ast: DynamicImportExpr, context: any) {\n    return this.visitExpression(ast, context);\n  }\n  visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: any): any {\n    ast.fn.visitExpression(this, context);\n    this.visitAllExpressions(ast.args, context);\n    return this.visitExpression(ast, context);\n  }\n  visitTaggedTemplateLiteralExpr(ast: TaggedTemplateLiteralExpr, context: any): any {\n    ast.tag.visitExpression(this, context);\n    ast.template.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitInstantiateExpr(ast: InstantiateExpr, context: any): any {\n    ast.classExpr.visitExpression(this, context);\n    this.visitAllExpressions(ast.args, context);\n    return this.visitExpression(ast, context);\n  }\n  visitLiteralExpr(ast: LiteralExpr, context: any): any {\n    return this.visitExpression(ast, context);\n  }\n  visitRegularExpressionLiteral(ast: RegularExpressionLiteralExpr, context: any): any {\n    return this.visitExpression(ast, context);\n  }\n  visitLocalizedString(ast: LocalizedString, context: any): any {\n    return this.visitExpression(ast, context);\n  }\n  visitExternalExpr(ast: ExternalExpr, context: any): any {\n    if (ast.typeParams) {\n      ast.typeParams.forEach((type) => type.visitType(this, context));\n    }\n    return this.visitExpression(ast, context);\n  }\n  visitConditionalExpr(ast: ConditionalExpr, context: any): any {\n    ast.condition.visitExpression(this, context);\n    ast.trueCase.visitExpression(this, context);\n    ast.falseCase!.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitNotExpr(ast: NotExpr, context: any): any {\n    ast.condition.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitFunctionExpr(ast: FunctionExpr, context: any): any {\n    this.visitAllStatements(ast.statements, context);\n    return this.visitExpression(ast, context);\n  }\n  visitArrowFunctionExpr(ast: ArrowFunctionExpr, context: any): any {\n    if (Array.isArray(ast.body)) {\n      this.visitAllStatements(ast.body, context);\n    } else {\n      // Note: `body.visitExpression`, rather than `this.visitExpressiont(body)`,\n      // because the latter won't recurse into the sub-expressions.\n      ast.body.visitExpression(this, context);\n    }\n\n    return this.visitExpression(ast, context);\n  }\n  visitUnaryOperatorExpr(ast: UnaryOperatorExpr, context: any): any {\n    ast.expr.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitTypeofExpr(ast: TypeofExpr, context: any): any {\n    ast.expr.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitVoidExpr(ast: VoidExpr, context: any) {\n    ast.expr.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitBinaryOperatorExpr(ast: BinaryOperatorExpr, context: any): any {\n    ast.lhs.visitExpression(this, context);\n    ast.rhs.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitReadPropExpr(ast: ReadPropExpr, context: any): any {\n    ast.receiver.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitReadKeyExpr(ast: ReadKeyExpr, context: any): any {\n    ast.receiver.visitExpression(this, context);\n    ast.index.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitLiteralArrayExpr(ast: LiteralArrayExpr, context: any): any {\n    this.visitAllExpressions(ast.entries, context);\n    return this.visitExpression(ast, context);\n  }\n  visitLiteralMapExpr(ast: LiteralMapExpr, context: any): any {\n    ast.entries.forEach((entry) => {\n      if (entry instanceof LiteralMapSpreadAssignment) {\n        entry.expression.visitExpression(this, context);\n      } else {\n        entry.value.visitExpression(this, context);\n      }\n    });\n    return this.visitExpression(ast, context);\n  }\n  visitCommaExpr(ast: CommaExpr, context: any): any {\n    this.visitAllExpressions(ast.parts, context);\n    return this.visitExpression(ast, context);\n  }\n  visitTemplateLiteralExpr(ast: TemplateLiteralExpr, context: any) {\n    this.visitAllExpressions(ast.elements, context);\n    this.visitAllExpressions(ast.expressions, context);\n    return this.visitExpression(ast, context);\n  }\n  visitTemplateLiteralElementExpr(ast: TemplateLiteralElementExpr, context: any) {\n    return this.visitExpression(ast, context);\n  }\n  visitParenthesizedExpr(ast: ParenthesizedExpr, context: any) {\n    ast.expr.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitSpreadElementExpr(ast: SpreadElementExpr, context: any): any {\n    ast.expression.visitExpression(this, context);\n    return this.visitExpression(ast, context);\n  }\n  visitAllExpressions(exprs: Expression[], context: any): void {\n    exprs.forEach((expr) => expr.visitExpression(this, context));\n  }\n\n  visitDeclareVarStmt(stmt: DeclareVarStmt, context: any): any {\n    if (stmt.value) {\n      stmt.value.visitExpression(this, context);\n    }\n    if (stmt.type) {\n      stmt.type.visitType(this, context);\n    }\n    return stmt;\n  }\n  visitDeclareFunctionStmt(stmt: DeclareFunctionStmt, context: any): any {\n    this.visitAllStatements(stmt.statements, context);\n    if (stmt.type) {\n      stmt.type.visitType(this, context);\n    }\n    return stmt;\n  }\n  visitExpressionStmt(stmt: ExpressionStatement, context: any): any {\n    stmt.expr.visitExpression(this, context);\n    return stmt;\n  }\n  visitReturnStmt(stmt: ReturnStatement, context: any): any {\n    stmt.value.visitExpression(this, context);\n    return stmt;\n  }\n  visitIfStmt(stmt: IfStmt, context: any): any {\n    stmt.condition.visitExpression(this, context);\n    this.visitAllStatements(stmt.trueCase, context);\n    this.visitAllStatements(stmt.falseCase, context);\n    return stmt;\n  }\n  visitAllStatements(stmts: Statement[], context: any): void {\n    stmts.forEach((stmt) => stmt.visitStatement(this, context));\n  }\n}\n\nexport function leadingComment(\n  text: string,\n  multiline: boolean = false,\n  trailingNewline: boolean = true,\n): LeadingComment {\n  return new LeadingComment(text, multiline, trailingNewline);\n}\n\nexport function jsDocComment(tags: JSDocTag[] = []): JSDocComment {\n  return new JSDocComment(tags);\n}\n\nexport function variable(\n  name: string,\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n): ReadVarExpr {\n  return new ReadVarExpr(name, type, sourceSpan);\n}\n\nexport function importExpr(\n  id: ExternalReference,\n  typeParams: Type[] | null = null,\n  sourceSpan?: ParseSourceSpan | null,\n): ExternalExpr {\n  return new ExternalExpr(id, null, typeParams, sourceSpan);\n}\n\nexport function importType(\n  id: ExternalReference,\n  typeParams?: Type[] | null,\n  typeModifiers?: TypeModifier,\n): ExpressionType | null {\n  return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null;\n}\n\nexport function expressionType(\n  expr: Expression,\n  typeModifiers?: TypeModifier,\n  typeParams?: Type[] | null,\n): ExpressionType {\n  return new ExpressionType(expr, typeModifiers, typeParams);\n}\n\nexport function transplantedType<T>(type: T, typeModifiers?: TypeModifier): TransplantedType<T> {\n  return new TransplantedType(type, typeModifiers);\n}\n\nexport function typeofExpr(expr: Expression) {\n  return new TypeofExpr(expr);\n}\n\nexport function literalArr(\n  values: Expression[],\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n): LiteralArrayExpr {\n  return new LiteralArrayExpr(values, type, sourceSpan);\n}\n\nexport function literalMap(\n  values: {key: string; quoted: boolean; value: Expression}[],\n  type: MapType | null = null,\n): LiteralMapExpr {\n  return new LiteralMapExpr(\n    values.map((e) => new LiteralMapPropertyAssignment(e.key, e.value, e.quoted)),\n    type,\n    null,\n  );\n}\n\nexport function unary(\n  operator: UnaryOperator,\n  expr: Expression,\n  type?: Type,\n  sourceSpan?: ParseSourceSpan | null,\n): UnaryOperatorExpr {\n  return new UnaryOperatorExpr(operator, expr, type, sourceSpan);\n}\n\nexport function not(expr: Expression, sourceSpan?: ParseSourceSpan | null): NotExpr {\n  return new NotExpr(expr, sourceSpan);\n}\n\nexport function fn(\n  params: FnParam[],\n  body: Statement[],\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n  name?: string | null,\n): FunctionExpr {\n  return new FunctionExpr(params, body, type, sourceSpan, name);\n}\n\nexport function arrowFn(\n  params: FnParam[],\n  body: Expression | Statement[],\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n) {\n  return new ArrowFunctionExpr(params, body, type, sourceSpan);\n}\n\nexport function ifStmt(\n  condition: Expression,\n  thenClause: Statement[],\n  elseClause?: Statement[],\n  sourceSpan?: ParseSourceSpan,\n  leadingComments?: LeadingComment[],\n) {\n  return new IfStmt(condition, thenClause, elseClause, sourceSpan, leadingComments);\n}\n\nexport function taggedTemplate(\n  tag: Expression,\n  template: TemplateLiteralExpr,\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n): TaggedTemplateLiteralExpr {\n  return new TaggedTemplateLiteralExpr(tag, template, type, sourceSpan);\n}\n\nexport function literal(\n  value: any,\n  type?: Type | null,\n  sourceSpan?: ParseSourceSpan | null,\n): LiteralExpr {\n  return new LiteralExpr(value, type, sourceSpan);\n}\n\nexport function localizedString(\n  metaBlock: I18nMeta,\n  messageParts: LiteralPiece[],\n  placeholderNames: PlaceholderPiece[],\n  expressions: Expression[],\n  sourceSpan?: ParseSourceSpan | null,\n): LocalizedString {\n  return new LocalizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan);\n}\n\nexport function isNull(exp: Expression): boolean {\n  return exp instanceof LiteralExpr && exp.value === null;\n}\n\n// The list of JSDoc tags that we currently support. Extend it if needed.\nexport const enum JSDocTagName {\n  Desc = 'desc',\n  Id = 'id',\n  Meaning = 'meaning',\n  Suppress = 'suppress',\n}\n\n/*\n * TypeScript has an API for JSDoc already, but it's not exposed.\n * https://github.com/Microsoft/TypeScript/issues/7393\n * For now we create types that are similar to theirs so that migrating\n * to their API will be easier. See e.g. `ts.JSDocTag` and `ts.JSDocComment`.\n */\nexport type JSDocTag =\n  | {\n      // `tagName` is e.g. \"param\" in an `@param` declaration\n      tagName: JSDocTagName | string;\n      // Any remaining text on the tag, e.g. the description\n      text?: string;\n    }\n  | {\n      // no `tagName` for plain text documentation that occurs before any `@param` lines\n      tagName?: undefined;\n      text: string;\n    };\n\n/*\n * Serializes a `Tag` into a string.\n * Returns a string like \" @foo {bar} baz\" (note the leading whitespace before `@foo`).\n */\nfunction tagToString(tag: JSDocTag): string {\n  let out = '';\n  if (tag.tagName) {\n    out += ` @${tag.tagName}`;\n  }\n  if (tag.text) {\n    if (tag.text.match(/\\/\\*|\\*\\//)) {\n      throw new Error('JSDoc text cannot contain \"/*\" and \"*/\"');\n    }\n    out += ' ' + tag.text.replace(/@/g, '\\\\@');\n  }\n  return out;\n}\n\nfunction serializeTags(tags: JSDocTag[]): string {\n  if (tags.length === 0) return '';\n\n  if (tags.length === 1 && tags[0].tagName && !tags[0].text) {\n    // The JSDOC comment is a single simple tag: e.g `/** @tagname */`.\n    return `*${tagToString(tags[0])} `;\n  }\n\n  let out = '*\\n';\n  for (const tag of tags) {\n    out += ' *';\n    // If the tagToString is multi-line, insert \" * \" prefixes on lines.\n    out += tagToString(tag).replace(/\\n/g, '\\n * ');\n    out += '\\n';\n  }\n  out += ' ';\n  return out;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport * as o from './output/output_ast';\n\nconst CONSTANT_PREFIX = '_c';\n\n/**\n * Context to use when producing a key.\n *\n * This ensures we see the constant not the reference variable when producing\n * a key.\n */\nconst KEY_CONTEXT = {};\n\n/**\n * Generally all primitive values are excluded from the `ConstantPool`, but there is an exclusion\n * for strings that reach a certain length threshold. This constant defines the length threshold for\n * strings.\n */\nconst POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS = 50;\n\n/**\n * A node that is a place-holder that allows the node to be replaced when the actual\n * node is known.\n *\n * This allows the constant pool to change an expression from a direct reference to\n * a constant to a shared constant. It returns a fix-up node that is later allowed to\n * change the referenced expression.\n */\nclass FixupExpression extends o.Expression {\n  private original: o.Expression;\n\n  shared = false;\n\n  constructor(public resolved: o.Expression) {\n    super(resolved.type);\n    this.original = resolved;\n  }\n\n  override visitExpression(visitor: o.ExpressionVisitor, context: any): any {\n    if (context === KEY_CONTEXT) {\n      // When producing a key we want to traverse the constant not the\n      // variable used to refer to it.\n      return this.original.visitExpression(visitor, context);\n    } else {\n      return this.resolved.visitExpression(visitor, context);\n    }\n  }\n\n  override isEquivalent(e: o.Expression): boolean {\n    return e instanceof FixupExpression && this.resolved.isEquivalent(e.resolved);\n  }\n\n  override isConstant() {\n    return true;\n  }\n\n  override clone(): FixupExpression {\n    throw new Error(`Not supported.`);\n  }\n\n  fixup(expression: o.Expression) {\n    this.resolved = expression;\n    this.shared = true;\n  }\n}\n\n/**\n * A constant pool allows a code emitter to share constant in an output context.\n *\n * The constant pool also supports sharing access to ivy definitions references.\n */\nexport class ConstantPool {\n  statements: o.Statement[] = [];\n  private literals = new Map<string, FixupExpression>();\n  private literalFactories = new Map<string, o.Expression>();\n  private sharedConstants = new Map<string, o.Expression>();\n\n  /**\n   * Constant pool also tracks claimed names from {@link uniqueName}.\n   * This is useful to avoid collisions if variables are intended to be\n   * named a certain way- but may conflict. We wouldn't want to always suffix\n   * them with unique numbers.\n   */\n  private _claimedNames = new Map<string, number>();\n\n  private nextNameIndex = 0;\n\n  constructor(private readonly isClosureCompilerEnabled: boolean = false) {}\n\n  getConstLiteral(literal: o.Expression, forceShared?: boolean): o.Expression {\n    if (\n      (literal instanceof o.LiteralExpr && !isLongStringLiteral(literal)) ||\n      literal instanceof FixupExpression\n    ) {\n      // Do no put simple literals into the constant pool or try to produce a constant for a\n      // reference to a constant.\n      return literal;\n    }\n    const key = GenericKeyFn.INSTANCE.keyOf(literal);\n    let fixup = this.literals.get(key);\n    let newValue = false;\n    if (!fixup) {\n      fixup = new FixupExpression(literal);\n      this.literals.set(key, fixup);\n      newValue = true;\n    }\n\n    if ((!newValue && !fixup.shared) || (newValue && forceShared)) {\n      // Replace the expression with a variable\n      const name = this.freshName();\n      let value: o.Expression;\n      let usage: o.Expression;\n      if (this.isClosureCompilerEnabled && isLongStringLiteral(literal)) {\n        // For string literals, Closure will **always** inline the string at\n        // **all** usages, duplicating it each time. For large strings, this\n        // unnecessarily bloats bundle size. To work around this restriction, we\n        // wrap the string in a function, and call that function for each usage.\n        // This tricks Closure into using inline logic for functions instead of\n        // string literals. Function calls are only inlined if the body is small\n        // enough to be worth it. By doing this, very large strings will be\n        // shared across multiple usages, rather than duplicating the string at\n        // each usage site.\n        //\n        // const myStr = function() { return \"very very very long string\"; };\n        // const usage1 = myStr();\n        // const usage2 = myStr();\n        value = new o.FunctionExpr(\n          [], // Params.\n          [\n            // Statements.\n            new o.ReturnStatement(literal),\n          ],\n        );\n        usage = o.variable(name).callFn([]);\n      } else {\n        // Just declare and use the variable directly, without a function call\n        // indirection. This saves a few bytes and avoids an unnecessary call.\n        value = literal;\n        usage = o.variable(name);\n      }\n\n      this.statements.push(\n        new o.DeclareVarStmt(name, value, o.INFERRED_TYPE, o.StmtModifier.Final),\n      );\n      fixup.fixup(usage);\n    }\n\n    return fixup;\n  }\n\n  getSharedConstant(def: SharedConstantDefinition, expr: o.Expression): o.Expression {\n    const key = def.keyOf(expr);\n    if (!this.sharedConstants.has(key)) {\n      const id = this.freshName();\n      this.sharedConstants.set(key, o.variable(id));\n      this.statements.push(def.toSharedConstantDeclaration(id, expr));\n    }\n    return this.sharedConstants.get(key)!;\n  }\n\n  // TODO: useUniqueName(false) is necessary for naming compatibility with\n  // TemplateDefinitionBuilder, but should be removed once Template Pipeline is the default.\n  getSharedFunctionReference(\n    fn: o.Expression,\n    prefix: string,\n    useUniqueName: boolean = true,\n  ): o.Expression {\n    const isArrow = fn instanceof o.ArrowFunctionExpr;\n\n    for (const current of this.statements) {\n      // Arrow functions are saved as variables so we check if the\n      // value of the variable is the same as the arrow function.\n      if (isArrow && current instanceof o.DeclareVarStmt && current.value?.isEquivalent(fn)) {\n        return o.variable(current.name);\n      }\n\n      // Function declarations are saved as function statements\n      // so we compare them directly to the passed-in function.\n      if (\n        !isArrow &&\n        current instanceof o.DeclareFunctionStmt &&\n        fn instanceof o.FunctionExpr &&\n        fn.isEquivalent(current)\n      ) {\n        return o.variable(current.name);\n      }\n    }\n\n    // Otherwise declare the function.\n    const name = useUniqueName ? this.uniqueName(prefix) : prefix;\n    this.statements.push(\n      fn instanceof o.FunctionExpr\n        ? fn.toDeclStmt(name, o.StmtModifier.Final)\n        : new o.DeclareVarStmt(name, fn, o.INFERRED_TYPE, o.StmtModifier.Final, fn.sourceSpan),\n    );\n    return o.variable(name);\n  }\n\n  /**\n   * Produce a unique name in the context of this pool.\n   *\n   * The name might be unique among different prefixes if any of the prefixes end in\n   * a digit so the prefix should be a constant string (not based on user input) and\n   * must not end in a digit.\n   */\n  uniqueName(name: string, alwaysIncludeSuffix = true): string {\n    const count = this._claimedNames.get(name) ?? 0;\n    const result = count === 0 && !alwaysIncludeSuffix ? `${name}` : `${name}${count}`;\n\n    this._claimedNames.set(name, count + 1);\n    return result;\n  }\n\n  private freshName(): string {\n    return this.uniqueName(CONSTANT_PREFIX);\n  }\n}\n\nexport interface ExpressionKeyFn {\n  keyOf(expr: o.Expression): string;\n}\n\nexport interface SharedConstantDefinition extends ExpressionKeyFn {\n  toSharedConstantDeclaration(declName: string, keyExpr: o.Expression): o.Statement;\n}\n\nexport class GenericKeyFn implements ExpressionKeyFn {\n  static readonly INSTANCE = new GenericKeyFn();\n\n  keyOf(expr: o.Expression): string {\n    if (expr instanceof o.LiteralExpr && typeof expr.value === 'string') {\n      return `\"${expr.value}\"`;\n    } else if (expr instanceof o.LiteralExpr) {\n      return String(expr.value);\n    } else if (expr instanceof o.RegularExpressionLiteralExpr) {\n      return `/${expr.body}/${expr.flags ?? ''}`;\n    } else if (expr instanceof o.LiteralArrayExpr) {\n      const entries: string[] = [];\n      for (const entry of expr.entries) {\n        entries.push(this.keyOf(entry));\n      }\n      return `[${entries.join(',')}]`;\n    } else if (expr instanceof o.LiteralMapExpr) {\n      const entries: string[] = [];\n      for (const entry of expr.entries) {\n        if (entry instanceof o.LiteralMapSpreadAssignment) {\n          entries.push('...' + this.keyOf(entry.expression));\n        } else {\n          let key = entry.key;\n          if (entry.quoted) {\n            key = `\"${key}\"`;\n          }\n          entries.push(key + ':' + this.keyOf(entry.value));\n        }\n      }\n      return `{${entries.join(',')}}`;\n    } else if (expr instanceof o.ExternalExpr) {\n      return `import(\"${expr.value.moduleName}\", ${expr.value.name})`;\n    } else if (expr instanceof o.ReadVarExpr) {\n      return `read(${expr.name})`;\n    } else if (expr instanceof o.TypeofExpr) {\n      return `typeof(${this.keyOf(expr.expr)})`;\n    } else if (expr instanceof o.SpreadElementExpr) {\n      return `...${this.keyOf(expr.expression)}`;\n    } else {\n      throw new Error(\n        `${this.constructor.name} does not handle expressions of type ${expr.constructor.name}`,\n      );\n    }\n  }\n}\n\nfunction isLongStringLiteral(expr: o.Expression): boolean {\n  return (\n    expr instanceof o.LiteralExpr &&\n    typeof expr.value === 'string' &&\n    expr.value.length >= POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS\n  );\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport * as o from '../output/output_ast';\n\nconst CORE = '@angular/core';\n\nexport class Identifiers {\n  static core: o.ExternalReference = {name: null, moduleName: CORE};\n\n  static namespaceHTML: o.ExternalReference = {name: 'ɵɵnamespaceHTML', moduleName: CORE};\n\n  static namespaceMathML: o.ExternalReference = {name: 'ɵɵnamespaceMathML', moduleName: CORE};\n\n  static namespaceSVG: o.ExternalReference = {name: 'ɵɵnamespaceSVG', moduleName: CORE};\n\n  static element: o.ExternalReference = {name: 'ɵɵelement', moduleName: CORE};\n\n  static elementStart: o.ExternalReference = {name: 'ɵɵelementStart', moduleName: CORE};\n\n  static elementEnd: o.ExternalReference = {name: 'ɵɵelementEnd', moduleName: CORE};\n\n  static domElement: o.ExternalReference = {name: 'ɵɵdomElement', moduleName: CORE};\n  static domElementStart: o.ExternalReference = {name: 'ɵɵdomElementStart', moduleName: CORE};\n  static domElementEnd: o.ExternalReference = {name: 'ɵɵdomElementEnd', moduleName: CORE};\n  static domElementContainer: o.ExternalReference = {\n    name: 'ɵɵdomElementContainer',\n    moduleName: CORE,\n  };\n  static domElementContainerStart: o.ExternalReference = {\n    name: 'ɵɵdomElementContainerStart',\n    moduleName: CORE,\n  };\n  static domElementContainerEnd: o.ExternalReference = {\n    name: 'ɵɵdomElementContainerEnd',\n    moduleName: CORE,\n  };\n  static domTemplate: o.ExternalReference = {name: 'ɵɵdomTemplate', moduleName: CORE};\n  static domListener: o.ExternalReference = {name: 'ɵɵdomListener', moduleName: CORE};\n\n  static advance: o.ExternalReference = {name: 'ɵɵadvance', moduleName: CORE};\n\n  static syntheticHostProperty: o.ExternalReference = {\n    name: 'ɵɵsyntheticHostProperty',\n    moduleName: CORE,\n  };\n\n  static syntheticHostListener: o.ExternalReference = {\n    name: 'ɵɵsyntheticHostListener',\n    moduleName: CORE,\n  };\n\n  static attribute: o.ExternalReference = {name: 'ɵɵattribute', moduleName: CORE};\n\n  static classProp: o.ExternalReference = {name: 'ɵɵclassProp', moduleName: CORE};\n\n  static elementContainerStart: o.ExternalReference = {\n    name: 'ɵɵelementContainerStart',\n    moduleName: CORE,\n  };\n\n  static elementContainerEnd: o.ExternalReference = {\n    name: 'ɵɵelementContainerEnd',\n    moduleName: CORE,\n  };\n\n  static elementContainer: o.ExternalReference = {name: 'ɵɵelementContainer', moduleName: CORE};\n\n  static styleMap: o.ExternalReference = {name: 'ɵɵstyleMap', moduleName: CORE};\n\n  static classMap: o.ExternalReference = {name: 'ɵɵclassMap', moduleName: CORE};\n\n  static styleProp: o.ExternalReference = {name: 'ɵɵstyleProp', moduleName: CORE};\n\n  static interpolate: o.ExternalReference = {\n    name: 'ɵɵinterpolate',\n    moduleName: CORE,\n  };\n  static interpolate1: o.ExternalReference = {\n    name: 'ɵɵinterpolate1',\n    moduleName: CORE,\n  };\n  static interpolate2: o.ExternalReference = {\n    name: 'ɵɵinterpolate2',\n    moduleName: CORE,\n  };\n  static interpolate3: o.ExternalReference = {\n    name: 'ɵɵinterpolate3',\n    moduleName: CORE,\n  };\n  static interpolate4: o.ExternalReference = {\n    name: 'ɵɵinterpolate4',\n    moduleName: CORE,\n  };\n  static interpolate5: o.ExternalReference = {\n    name: 'ɵɵinterpolate5',\n    moduleName: CORE,\n  };\n  static interpolate6: o.ExternalReference = {\n    name: 'ɵɵinterpolate6',\n    moduleName: CORE,\n  };\n  static interpolate7: o.ExternalReference = {\n    name: 'ɵɵinterpolate7',\n    moduleName: CORE,\n  };\n  static interpolate8: o.ExternalReference = {\n    name: 'ɵɵinterpolate8',\n    moduleName: CORE,\n  };\n  static interpolateV: o.ExternalReference = {\n    name: 'ɵɵinterpolateV',\n    moduleName: CORE,\n  };\n\n  static nextContext: o.ExternalReference = {name: 'ɵɵnextContext', moduleName: CORE};\n\n  static resetView: o.ExternalReference = {name: 'ɵɵresetView', moduleName: CORE};\n\n  static templateCreate: o.ExternalReference = {name: 'ɵɵtemplate', moduleName: CORE};\n\n  static defer: o.ExternalReference = {name: 'ɵɵdefer', moduleName: CORE};\n  static deferWhen: o.ExternalReference = {name: 'ɵɵdeferWhen', moduleName: CORE};\n  static deferOnIdle: o.ExternalReference = {name: 'ɵɵdeferOnIdle', moduleName: CORE};\n  static deferOnImmediate: o.ExternalReference = {name: 'ɵɵdeferOnImmediate', moduleName: CORE};\n  static deferOnTimer: o.ExternalReference = {name: 'ɵɵdeferOnTimer', moduleName: CORE};\n  static deferOnHover: o.ExternalReference = {name: 'ɵɵdeferOnHover', moduleName: CORE};\n  static deferOnInteraction: o.ExternalReference = {name: 'ɵɵdeferOnInteraction', moduleName: CORE};\n  static deferOnViewport: o.ExternalReference = {name: 'ɵɵdeferOnViewport', moduleName: CORE};\n  static deferPrefetchWhen: o.ExternalReference = {name: 'ɵɵdeferPrefetchWhen', moduleName: CORE};\n  static deferPrefetchOnIdle: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnIdle',\n    moduleName: CORE,\n  };\n  static deferPrefetchOnImmediate: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnImmediate',\n    moduleName: CORE,\n  };\n  static deferPrefetchOnTimer: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnTimer',\n    moduleName: CORE,\n  };\n  static deferPrefetchOnHover: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnHover',\n    moduleName: CORE,\n  };\n  static deferPrefetchOnInteraction: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnInteraction',\n    moduleName: CORE,\n  };\n  static deferPrefetchOnViewport: o.ExternalReference = {\n    name: 'ɵɵdeferPrefetchOnViewport',\n    moduleName: CORE,\n  };\n  static deferHydrateWhen: o.ExternalReference = {name: 'ɵɵdeferHydrateWhen', moduleName: CORE};\n  static deferHydrateNever: o.ExternalReference = {name: 'ɵɵdeferHydrateNever', moduleName: CORE};\n  static deferHydrateOnIdle: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnIdle',\n    moduleName: CORE,\n  };\n  static deferHydrateOnImmediate: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnImmediate',\n    moduleName: CORE,\n  };\n  static deferHydrateOnTimer: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnTimer',\n    moduleName: CORE,\n  };\n  static deferHydrateOnHover: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnHover',\n    moduleName: CORE,\n  };\n  static deferHydrateOnInteraction: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnInteraction',\n    moduleName: CORE,\n  };\n  static deferHydrateOnViewport: o.ExternalReference = {\n    name: 'ɵɵdeferHydrateOnViewport',\n    moduleName: CORE,\n  };\n  static deferEnableTimerScheduling: o.ExternalReference = {\n    name: 'ɵɵdeferEnableTimerScheduling',\n    moduleName: CORE,\n  };\n\n  static conditionalCreate: o.ExternalReference = {name: 'ɵɵconditionalCreate', moduleName: CORE};\n  static conditionalBranchCreate: o.ExternalReference = {\n    name: 'ɵɵconditionalBranchCreate',\n    moduleName: CORE,\n  };\n  static conditional: o.ExternalReference = {name: 'ɵɵconditional', moduleName: CORE};\n  static repeater: o.ExternalReference = {name: 'ɵɵrepeater', moduleName: CORE};\n  static repeaterCreate: o.ExternalReference = {name: 'ɵɵrepeaterCreate', moduleName: CORE};\n  static repeaterTrackByIndex: o.ExternalReference = {\n    name: 'ɵɵrepeaterTrackByIndex',\n    moduleName: CORE,\n  };\n  static repeaterTrackByIdentity: o.ExternalReference = {\n    name: 'ɵɵrepeaterTrackByIdentity',\n    moduleName: CORE,\n  };\n  static componentInstance: o.ExternalReference = {name: 'ɵɵcomponentInstance', moduleName: CORE};\n\n  static text: o.ExternalReference = {name: 'ɵɵtext', moduleName: CORE};\n\n  static enableBindings: o.ExternalReference = {name: 'ɵɵenableBindings', moduleName: CORE};\n\n  static disableBindings: o.ExternalReference = {name: 'ɵɵdisableBindings', moduleName: CORE};\n\n  static getCurrentView: o.ExternalReference = {name: 'ɵɵgetCurrentView', moduleName: CORE};\n\n  static textInterpolate: o.ExternalReference = {name: 'ɵɵtextInterpolate', moduleName: CORE};\n  static textInterpolate1: o.ExternalReference = {name: 'ɵɵtextInterpolate1', moduleName: CORE};\n  static textInterpolate2: o.ExternalReference = {name: 'ɵɵtextInterpolate2', moduleName: CORE};\n  static textInterpolate3: o.ExternalReference = {name: 'ɵɵtextInterpolate3', moduleName: CORE};\n  static textInterpolate4: o.ExternalReference = {name: 'ɵɵtextInterpolate4', moduleName: CORE};\n  static textInterpolate5: o.ExternalReference = {name: 'ɵɵtextInterpolate5', moduleName: CORE};\n  static textInterpolate6: o.ExternalReference = {name: 'ɵɵtextInterpolate6', moduleName: CORE};\n  static textInterpolate7: o.ExternalReference = {name: 'ɵɵtextInterpolate7', moduleName: CORE};\n  static textInterpolate8: o.ExternalReference = {name: 'ɵɵtextInterpolate8', moduleName: CORE};\n  static textInterpolateV: o.ExternalReference = {name: 'ɵɵtextInterpolateV', moduleName: CORE};\n\n  static restoreView: o.ExternalReference = {name: 'ɵɵrestoreView', moduleName: CORE};\n\n  static pureFunction0: o.ExternalReference = {name: 'ɵɵpureFunction0', moduleName: CORE};\n  static pureFunction1: o.ExternalReference = {name: 'ɵɵpureFunction1', moduleName: CORE};\n  static pureFunction2: o.ExternalReference = {name: 'ɵɵpureFunction2', moduleName: CORE};\n  static pureFunction3: o.ExternalReference = {name: 'ɵɵpureFunction3', moduleName: CORE};\n  static pureFunction4: o.ExternalReference = {name: 'ɵɵpureFunction4', moduleName: CORE};\n  static pureFunction5: o.ExternalReference = {name: 'ɵɵpureFunction5', moduleName: CORE};\n  static pureFunction6: o.ExternalReference = {name: 'ɵɵpureFunction6', moduleName: CORE};\n  static pureFunction7: o.ExternalReference = {name: 'ɵɵpureFunction7', moduleName: CORE};\n  static pureFunction8: o.ExternalReference = {name: 'ɵɵpureFunction8', moduleName: CORE};\n  static pureFunctionV: o.ExternalReference = {name: 'ɵɵpureFunctionV', moduleName: CORE};\n\n  static pipeBind1: o.ExternalReference = {name: 'ɵɵpipeBind1', moduleName: CORE};\n  static pipeBind2: o.ExternalReference = {name: 'ɵɵpipeBind2', moduleName: CORE};\n  static pipeBind3: o.ExternalReference = {name: 'ɵɵpipeBind3', moduleName: CORE};\n  static pipeBind4: o.ExternalReference = {name: 'ɵɵpipeBind4', moduleName: CORE};\n  static pipeBindV: o.ExternalReference = {name: 'ɵɵpipeBindV', moduleName: CORE};\n\n  static domProperty: o.ExternalReference = {name: 'ɵɵdomProperty', moduleName: CORE};\n\n  static ariaProperty: o.ExternalReference = {name: 'ɵɵariaProperty', moduleName: CORE};\n  static property: o.ExternalReference = {name: 'ɵɵproperty', moduleName: CORE};\n\n  static control: o.ExternalReference = {name: 'ɵɵcontrol', moduleName: CORE};\n  static controlCreate: o.ExternalReference = {name: 'ɵɵcontrolCreate', moduleName: CORE};\n\n  static animationEnterListener: o.ExternalReference = {\n    name: 'ɵɵanimateEnterListener',\n    moduleName: CORE,\n  };\n  static animationLeaveListener: o.ExternalReference = {\n    name: 'ɵɵanimateLeaveListener',\n    moduleName: CORE,\n  };\n  static animationEnter: o.ExternalReference = {name: 'ɵɵanimateEnter', moduleName: CORE};\n  static animationLeave: o.ExternalReference = {name: 'ɵɵanimateLeave', moduleName: CORE};\n\n  static i18n: o.ExternalReference = {name: 'ɵɵi18n', moduleName: CORE};\n  static i18nAttributes: o.ExternalReference = {name: 'ɵɵi18nAttributes', moduleName: CORE};\n  static i18nExp: o.ExternalReference = {name: 'ɵɵi18nExp', moduleName: CORE};\n  static i18nStart: o.ExternalReference = {name: 'ɵɵi18nStart', moduleName: CORE};\n  static i18nEnd: o.ExternalReference = {name: 'ɵɵi18nEnd', moduleName: CORE};\n  static i18nApply: o.ExternalReference = {name: 'ɵɵi18nApply', moduleName: CORE};\n  static i18nPostprocess: o.ExternalReference = {name: 'ɵɵi18nPostprocess', moduleName: CORE};\n\n  static pipe: o.ExternalReference = {name: 'ɵɵpipe', moduleName: CORE};\n\n  static projection: o.ExternalReference = {name: 'ɵɵprojection', moduleName: CORE};\n  static projectionDef: o.ExternalReference = {name: 'ɵɵprojectionDef', moduleName: CORE};\n\n  static reference: o.ExternalReference = {name: 'ɵɵreference', moduleName: CORE};\n\n  static inject: o.ExternalReference = {name: 'ɵɵinject', moduleName: CORE};\n\n  static injectAttribute: o.ExternalReference = {name: 'ɵɵinjectAttribute', moduleName: CORE};\n\n  static directiveInject: o.ExternalReference = {name: 'ɵɵdirectiveInject', moduleName: CORE};\n  static invalidFactory: o.ExternalReference = {name: 'ɵɵinvalidFactory', moduleName: CORE};\n  static invalidFactoryDep: o.ExternalReference = {name: 'ɵɵinvalidFactoryDep', moduleName: CORE};\n\n  static templateRefExtractor: o.ExternalReference = {\n    name: 'ɵɵtemplateRefExtractor',\n    moduleName: CORE,\n  };\n\n  static forwardRef: o.ExternalReference = {name: 'forwardRef', moduleName: CORE};\n  static resolveForwardRef: o.ExternalReference = {name: 'resolveForwardRef', moduleName: CORE};\n\n  static replaceMetadata: o.ExternalReference = {name: 'ɵɵreplaceMetadata', moduleName: CORE};\n  static getReplaceMetadataURL: o.ExternalReference = {\n    name: 'ɵɵgetReplaceMetadataURL',\n    moduleName: CORE,\n  };\n\n  static ɵɵdefineInjectable: o.ExternalReference = {name: 'ɵɵdefineInjectable', moduleName: CORE};\n  static declareInjectable: o.ExternalReference = {name: 'ɵɵngDeclareInjectable', moduleName: CORE};\n  static InjectableDeclaration: o.ExternalReference = {\n    name: 'ɵɵInjectableDeclaration',\n    moduleName: CORE,\n  };\n\n  static resolveWindow: o.ExternalReference = {name: 'ɵɵresolveWindow', moduleName: CORE};\n  static resolveDocument: o.ExternalReference = {name: 'ɵɵresolveDocument', moduleName: CORE};\n  static resolveBody: o.ExternalReference = {name: 'ɵɵresolveBody', moduleName: CORE};\n\n  static getComponentDepsFactory: o.ExternalReference = {\n    name: 'ɵɵgetComponentDepsFactory',\n    moduleName: CORE,\n  };\n\n  static defineComponent: o.ExternalReference = {name: 'ɵɵdefineComponent', moduleName: CORE};\n  static declareComponent: o.ExternalReference = {name: 'ɵɵngDeclareComponent', moduleName: CORE};\n\n  static setComponentScope: o.ExternalReference = {name: 'ɵɵsetComponentScope', moduleName: CORE};\n\n  static ChangeDetectionStrategy: o.ExternalReference = {\n    name: 'ChangeDetectionStrategy',\n    moduleName: CORE,\n  };\n  static ViewEncapsulation: o.ExternalReference = {\n    name: 'ViewEncapsulation',\n    moduleName: CORE,\n  };\n\n  static ComponentDeclaration: o.ExternalReference = {\n    name: 'ɵɵComponentDeclaration',\n    moduleName: CORE,\n  };\n\n  static FactoryDeclaration: o.ExternalReference = {\n    name: 'ɵɵFactoryDeclaration',\n    moduleName: CORE,\n  };\n  static declareFactory: o.ExternalReference = {name: 'ɵɵngDeclareFactory', moduleName: CORE};\n  static FactoryTarget: o.ExternalReference = {name: 'ɵɵFactoryTarget', moduleName: CORE};\n\n  static defineDirective: o.ExternalReference = {name: 'ɵɵdefineDirective', moduleName: CORE};\n  static declareDirective: o.ExternalReference = {name: 'ɵɵngDeclareDirective', moduleName: CORE};\n\n  static DirectiveDeclaration: o.ExternalReference = {\n    name: 'ɵɵDirectiveDeclaration',\n    moduleName: CORE,\n  };\n\n  static InjectorDef: o.ExternalReference = {name: 'ɵɵInjectorDef', moduleName: CORE};\n  static InjectorDeclaration: o.ExternalReference = {\n    name: 'ɵɵInjectorDeclaration',\n    moduleName: CORE,\n  };\n\n  static defineInjector: o.ExternalReference = {name: 'ɵɵdefineInjector', moduleName: CORE};\n  static declareInjector: o.ExternalReference = {name: 'ɵɵngDeclareInjector', moduleName: CORE};\n\n  static NgModuleDeclaration: o.ExternalReference = {\n    name: 'ɵɵNgModuleDeclaration',\n    moduleName: CORE,\n  };\n\n  static ModuleWithProviders: o.ExternalReference = {\n    name: 'ModuleWithProviders',\n    moduleName: CORE,\n  };\n\n  static defineNgModule: o.ExternalReference = {name: 'ɵɵdefineNgModule', moduleName: CORE};\n  static declareNgModule: o.ExternalReference = {name: 'ɵɵngDeclareNgModule', moduleName: CORE};\n  static setNgModuleScope: o.ExternalReference = {name: 'ɵɵsetNgModuleScope', moduleName: CORE};\n  static registerNgModuleType: o.ExternalReference = {\n    name: 'ɵɵregisterNgModuleType',\n    moduleName: CORE,\n  };\n\n  static PipeDeclaration: o.ExternalReference = {name: 'ɵɵPipeDeclaration', moduleName: CORE};\n\n  static definePipe: o.ExternalReference = {name: 'ɵɵdefinePipe', moduleName: CORE};\n  static declarePipe: o.ExternalReference = {name: 'ɵɵngDeclarePipe', moduleName: CORE};\n\n  static declareClassMetadata: o.ExternalReference = {\n    name: 'ɵɵngDeclareClassMetadata',\n    moduleName: CORE,\n  };\n  static declareClassMetadataAsync: o.ExternalReference = {\n    name: 'ɵɵngDeclareClassMetadataAsync',\n    moduleName: CORE,\n  };\n  static setClassMetadata: o.ExternalReference = {name: 'ɵsetClassMetadata', moduleName: CORE};\n  static setClassMetadataAsync: o.ExternalReference = {\n    name: 'ɵsetClassMetadataAsync',\n    moduleName: CORE,\n  };\n  static setClassDebugInfo: o.ExternalReference = {name: 'ɵsetClassDebugInfo', moduleName: CORE};\n  static queryRefresh: o.ExternalReference = {name: 'ɵɵqueryRefresh', moduleName: CORE};\n  static viewQuery: o.ExternalReference = {name: 'ɵɵviewQuery', moduleName: CORE};\n  static loadQuery: o.ExternalReference = {name: 'ɵɵloadQuery', moduleName: CORE};\n  static contentQuery: o.ExternalReference = {name: 'ɵɵcontentQuery', moduleName: CORE};\n\n  // Signal queries\n  static viewQuerySignal: o.ExternalReference = {name: 'ɵɵviewQuerySignal', moduleName: CORE};\n  static contentQuerySignal: o.ExternalReference = {name: 'ɵɵcontentQuerySignal', moduleName: CORE};\n  static queryAdvance: o.ExternalReference = {name: 'ɵɵqueryAdvance', moduleName: CORE};\n\n  // Two-way bindings\n  static twoWayProperty: o.ExternalReference = {name: 'ɵɵtwoWayProperty', moduleName: CORE};\n  static twoWayBindingSet: o.ExternalReference = {name: 'ɵɵtwoWayBindingSet', moduleName: CORE};\n  static twoWayListener: o.ExternalReference = {name: 'ɵɵtwoWayListener', moduleName: CORE};\n\n  static declareLet: o.ExternalReference = {name: 'ɵɵdeclareLet', moduleName: CORE};\n  static storeLet: o.ExternalReference = {name: 'ɵɵstoreLet', moduleName: CORE};\n  static readContextLet: o.ExternalReference = {name: 'ɵɵreadContextLet', moduleName: CORE};\n\n  static arrowFunction: o.ExternalReference = {name: 'ɵɵarrowFunction', moduleName: CORE};\n\n  static attachSourceLocations: o.ExternalReference = {\n    name: 'ɵɵattachSourceLocations',\n    moduleName: CORE,\n  };\n\n  static NgOnChangesFeature: o.ExternalReference = {name: 'ɵɵNgOnChangesFeature', moduleName: CORE};\n\n  static ControlFeature: o.ExternalReference = {\n    name: 'ɵɵControlFeature',\n    moduleName: CORE,\n  };\n\n  static InheritDefinitionFeature: o.ExternalReference = {\n    name: 'ɵɵInheritDefinitionFeature',\n    moduleName: CORE,\n  };\n\n  static ProvidersFeature: o.ExternalReference = {name: 'ɵɵProvidersFeature', moduleName: CORE};\n\n  static HostDirectivesFeature: o.ExternalReference = {\n    name: 'ɵɵHostDirectivesFeature',\n    moduleName: CORE,\n  };\n\n  static ExternalStylesFeature: o.ExternalReference = {\n    name: 'ɵɵExternalStylesFeature',\n    moduleName: CORE,\n  };\n\n  static listener: o.ExternalReference = {name: 'ɵɵlistener', moduleName: CORE};\n\n  static getInheritedFactory: o.ExternalReference = {\n    name: 'ɵɵgetInheritedFactory',\n    moduleName: CORE,\n  };\n\n  // sanitization-related functions\n  static sanitizeHtml: o.ExternalReference = {name: 'ɵɵsanitizeHtml', moduleName: CORE};\n  static sanitizeStyle: o.ExternalReference = {name: 'ɵɵsanitizeStyle', moduleName: CORE};\n  static validateAttribute: o.ExternalReference = {\n    name: 'ɵɵvalidateAttribute',\n    moduleName: CORE,\n  };\n  static sanitizeResourceUrl: o.ExternalReference = {\n    name: 'ɵɵsanitizeResourceUrl',\n    moduleName: CORE,\n  };\n  static sanitizeScript: o.ExternalReference = {name: 'ɵɵsanitizeScript', moduleName: CORE};\n  static sanitizeUrl: o.ExternalReference = {name: 'ɵɵsanitizeUrl', moduleName: CORE};\n  static sanitizeUrlOrResourceUrl: o.ExternalReference = {\n    name: 'ɵɵsanitizeUrlOrResourceUrl',\n    moduleName: CORE,\n  };\n  static trustConstantHtml: o.ExternalReference = {name: 'ɵɵtrustConstantHtml', moduleName: CORE};\n  static trustConstantResourceUrl: o.ExternalReference = {\n    name: 'ɵɵtrustConstantResourceUrl',\n    moduleName: CORE,\n  };\n\n  // Decorators\n  static inputDecorator: o.ExternalReference = {name: 'Input', moduleName: CORE};\n  static outputDecorator: o.ExternalReference = {name: 'Output', moduleName: CORE};\n  static viewChildDecorator: o.ExternalReference = {name: 'ViewChild', moduleName: CORE};\n  static viewChildrenDecorator: o.ExternalReference = {name: 'ViewChildren', moduleName: CORE};\n  static contentChildDecorator: o.ExternalReference = {name: 'ContentChild', moduleName: CORE};\n  static contentChildrenDecorator: o.ExternalReference = {\n    name: 'ContentChildren',\n    moduleName: CORE,\n  };\n\n  // type-checking\n  static InputSignalBrandWriteType = {name: 'ɵINPUT_SIGNAL_BRAND_WRITE_TYPE', moduleName: CORE};\n  static UnwrapDirectiveSignalInputs = {name: 'ɵUnwrapDirectiveSignalInputs', moduleName: CORE};\n  static unwrapWritableSignal = {name: 'ɵunwrapWritableSignal', moduleName: CORE};\n  static assertType = {name: 'ɵassertType', moduleName: CORE};\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nconst DASH_CASE_REGEXP = /-+([a-z0-9])/g;\n\nexport function dashCaseToCamelCase(input: string): string {\n  return input.replace(DASH_CASE_REGEXP, (...m: any[]) => m[1].toUpperCase());\n}\n\nexport function splitAtColon(input: string, defaultValues: (string | null)[]): (string | null)[] {\n  return _splitAt(input, ':', defaultValues);\n}\n\nexport function splitAtPeriod(input: string, defaultValues: (string | null)[]): (string | null)[] {\n  return _splitAt(input, '.', defaultValues);\n}\n\nfunction _splitAt(\n  input: string,\n  character: string,\n  defaultValues: (string | null)[],\n): (string | null)[] {\n  const characterIndex = input.indexOf(character);\n  if (characterIndex == -1) return defaultValues;\n  return [input.slice(0, characterIndex).trim(), input.slice(characterIndex + 1).trim()];\n}\n\nexport function noUndefined<T>(val: T | undefined): T {\n  return val === undefined ? null! : val;\n}\n\nexport function error(msg: string): never {\n  throw new Error(`Internal Error: ${msg}`);\n}\n\n// Escape characters that have a special meaning in Regular Expressions\nexport function escapeRegExp(s: string): string {\n  return s.replace(/([.*+?^=!:${}()|[\\]\\/\\\\])/g, '\\\\$1');\n}\n\nexport type Byte = number;\n\nexport function utf8Encode(str: string): Byte[] {\n  let encoded: Byte[] = [];\n  for (let index = 0; index < str.length; index++) {\n    let codePoint = str.charCodeAt(index);\n\n    // decode surrogate\n    // see https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n    if (codePoint >= 0xd800 && codePoint <= 0xdbff && str.length > index + 1) {\n      const low = str.charCodeAt(index + 1);\n      if (low >= 0xdc00 && low <= 0xdfff) {\n        index++;\n        codePoint = ((codePoint - 0xd800) << 10) + low - 0xdc00 + 0x10000;\n      }\n    }\n\n    if (codePoint <= 0x7f) {\n      encoded.push(codePoint);\n    } else if (codePoint <= 0x7ff) {\n      encoded.push(((codePoint >> 6) & 0x1f) | 0xc0, (codePoint & 0x3f) | 0x80);\n    } else if (codePoint <= 0xffff) {\n      encoded.push(\n        (codePoint >> 12) | 0xe0,\n        ((codePoint >> 6) & 0x3f) | 0x80,\n        (codePoint & 0x3f) | 0x80,\n      );\n    } else if (codePoint <= 0x1fffff) {\n      encoded.push(\n        ((codePoint >> 18) & 0x07) | 0xf0,\n        ((codePoint >> 12) & 0x3f) | 0x80,\n        ((codePoint >> 6) & 0x3f) | 0x80,\n        (codePoint & 0x3f) | 0x80,\n      );\n    }\n  }\n\n  return encoded;\n}\n\nexport function stringify(token: any): string {\n  if (typeof token === 'string') {\n    return token;\n  }\n\n  if (Array.isArray(token)) {\n    return `[${token.map(stringify).join(', ')}]`;\n  }\n\n  if (token == null) {\n    return '' + token;\n  }\n\n  const name = token.overriddenName || token.name;\n  if (name) {\n    return `${name}`;\n  }\n\n  if (!token.toString) {\n    return 'object';\n  }\n\n  // WARNING: do not try to `JSON.stringify(token)` here\n  // see https://github.com/angular/angular/issues/23440\n  const result = token.toString();\n\n  if (result == null) {\n    return '' + result;\n  }\n\n  const newLineIndex = result.indexOf('\\n');\n  return newLineIndex >= 0 ? result.slice(0, newLineIndex) : result;\n}\n\nexport class Version {\n  public readonly major: string;\n  public readonly minor: string;\n  public readonly patch: string;\n\n  constructor(public full: string) {\n    const splits = full.split('.');\n    this.major = splits[0];\n    this.minor = splits[1];\n    this.patch = splits.slice(2).join('.');\n  }\n}\n\nexport interface Console {\n  log(message: string): void;\n  warn(message: string): void;\n}\n\nconst _global: {[name: string]: any} = globalThis;\nexport {_global as global};\n\nconst V1_TO_18 = /^([1-9]|1[0-8])\\./;\n\nexport function getJitStandaloneDefaultForVersion(version: string): boolean {\n  if (version.startsWith('0.')) {\n    // 0.0.0 is always \"latest\", default is true.\n    return true;\n  }\n  if (V1_TO_18.test(version)) {\n    // Angular v2 - v18 default is false.\n    return false;\n  }\n\n  // All other Angular versions (v19+) default to true.\n  return true;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {utf8Encode} from '../util';\n\n// https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit\nconst VERSION = 3;\n\nconst JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';\n\ntype Segment = {\n  col0: number;\n  sourceUrl?: string;\n  sourceLine0?: number;\n  sourceCol0?: number;\n};\n\nexport type SourceMap = {\n  version: number;\n  file?: string;\n  sourceRoot: string;\n  sources: string[];\n  sourcesContent: (string | null)[];\n  mappings: string;\n};\n\nexport class SourceMapGenerator {\n  private sourcesContent: Map<string, string | null> = new Map();\n  private lines: Segment[][] = [];\n  private lastCol0: number = 0;\n  private hasMappings = false;\n\n  constructor(private file: string | null = null) {}\n\n  // The content is `null` when the content is expected to be loaded using the URL\n  addSource(url: string, content: string | null = null): this {\n    if (!this.sourcesContent.has(url)) {\n      this.sourcesContent.set(url, content);\n    }\n    return this;\n  }\n\n  addLine(): this {\n    this.lines.push([]);\n    this.lastCol0 = 0;\n    return this;\n  }\n\n  addMapping(col0: number, sourceUrl?: string, sourceLine0?: number, sourceCol0?: number): this {\n    if (!this.currentLine) {\n      throw new Error(`A line must be added before mappings can be added`);\n    }\n    if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {\n      throw new Error(`Unknown source file \"${sourceUrl}\"`);\n    }\n    if (col0 == null) {\n      throw new Error(`The column in the generated code must be provided`);\n    }\n    if (col0 < this.lastCol0) {\n      throw new Error(`Mapping should be added in output order`);\n    }\n    if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {\n      throw new Error(`The source location must be provided when a source url is provided`);\n    }\n\n    this.hasMappings = true;\n    this.lastCol0 = col0;\n    this.currentLine.push({col0, sourceUrl, sourceLine0, sourceCol0});\n    return this;\n  }\n\n  /**\n   * @internal strip this from published d.ts files due to\n   * https://github.com/microsoft/TypeScript/issues/36216\n   */\n  private get currentLine(): Segment[] | null {\n    return this.lines.slice(-1)[0];\n  }\n\n  toJSON(): SourceMap | null {\n    if (!this.hasMappings) {\n      return null;\n    }\n\n    const sourcesIndex = new Map<string, number>();\n    const sources: string[] = [];\n    const sourcesContent: (string | null)[] = [];\n\n    Array.from(this.sourcesContent.keys()).forEach((url: string, i: number) => {\n      sourcesIndex.set(url, i);\n      sources.push(url);\n      sourcesContent.push(this.sourcesContent.get(url) || null);\n    });\n\n    let mappings: string = '';\n    let lastCol0: number = 0;\n    let lastSourceIndex: number = 0;\n    let lastSourceLine0: number = 0;\n    let lastSourceCol0: number = 0;\n\n    this.lines.forEach((segments) => {\n      lastCol0 = 0;\n\n      mappings += segments\n        .map((segment) => {\n          // zero-based starting column of the line in the generated code\n          let segAsStr = toBase64VLQ(segment.col0 - lastCol0);\n          lastCol0 = segment.col0;\n\n          if (segment.sourceUrl != null) {\n            // zero-based index into the “sources” list\n            segAsStr += toBase64VLQ(sourcesIndex.get(segment.sourceUrl)! - lastSourceIndex);\n            lastSourceIndex = sourcesIndex.get(segment.sourceUrl)!;\n            // the zero-based starting line in the original source\n            segAsStr += toBase64VLQ(segment.sourceLine0! - lastSourceLine0);\n            lastSourceLine0 = segment.sourceLine0!;\n            // the zero-based starting column in the original source\n            segAsStr += toBase64VLQ(segment.sourceCol0! - lastSourceCol0);\n            lastSourceCol0 = segment.sourceCol0!;\n          }\n\n          return segAsStr;\n        })\n        .join(',');\n      mappings += ';';\n    });\n\n    mappings = mappings.slice(0, -1);\n\n    return {\n      'file': this.file || '',\n      'version': VERSION,\n      'sourceRoot': '',\n      'sources': sources,\n      'sourcesContent': sourcesContent,\n      'mappings': mappings,\n    };\n  }\n\n  toJsComment(): string {\n    return this.hasMappings\n      ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0))\n      : '';\n  }\n}\n\nexport function toBase64String(value: string): string {\n  let b64 = '';\n  const encoded = utf8Encode(value);\n  for (let i = 0; i < encoded.length; ) {\n    const i1 = encoded[i++];\n    const i2 = i < encoded.length ? encoded[i++] : null;\n    const i3 = i < encoded.length ? encoded[i++] : null;\n    b64 += toBase64Digit(i1 >> 2);\n    b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));\n    b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));\n    b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);\n  }\n\n  return b64;\n}\n\nfunction toBase64VLQ(value: number): string {\n  value = value < 0 ? (-value << 1) + 1 : value << 1;\n\n  let out = '';\n  do {\n    let digit = value & 31;\n    value = value >> 5;\n    if (value > 0) {\n      digit = digit | 32;\n    }\n    out += toBase64Digit(digit);\n  } while (value > 0);\n\n  return out;\n}\n\nconst B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nfunction toBase64Digit(value: number): string {\n  if (value < 0 || value >= 64) {\n    throw new Error(`Can only encode value in the range [0, 63]`);\n  }\n\n  return B64_DIGITS[value];\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {ParseSourceSpan} from '../parse_util';\n\nimport * as o from './output_ast';\nimport {SourceMapGenerator} from './source_map';\n\nconst _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\\\|\\n|\\r|\\$/g;\nconst _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;\nconst _INDENT_WITH = '  ';\n\nclass _EmittedLine {\n  partsLength = 0;\n  parts: string[] = [];\n  srcSpans: (ParseSourceSpan | null)[] = [];\n  constructor(public indent: number) {}\n}\n\nconst BINARY_OPERATORS = new Map([\n  [o.BinaryOperator.And, '&&'],\n  [o.BinaryOperator.Bigger, '>'],\n  [o.BinaryOperator.BiggerEquals, '>='],\n  [o.BinaryOperator.BitwiseOr, '|'],\n  [o.BinaryOperator.BitwiseAnd, '&'],\n  [o.BinaryOperator.Divide, '/'],\n  [o.BinaryOperator.Assign, '='],\n  [o.BinaryOperator.Equals, '=='],\n  [o.BinaryOperator.Identical, '==='],\n  [o.BinaryOperator.Lower, '<'],\n  [o.BinaryOperator.LowerEquals, '<='],\n  [o.BinaryOperator.Minus, '-'],\n  [o.BinaryOperator.Modulo, '%'],\n  [o.BinaryOperator.Exponentiation, '**'],\n  [o.BinaryOperator.Multiply, '*'],\n  [o.BinaryOperator.NotEquals, '!='],\n  [o.BinaryOperator.NotIdentical, '!=='],\n  [o.BinaryOperator.NullishCoalesce, '??'],\n  [o.BinaryOperator.Or, '||'],\n  [o.BinaryOperator.Plus, '+'],\n  [o.BinaryOperator.In, 'in'],\n  [o.BinaryOperator.InstanceOf, 'instanceof'],\n  [o.BinaryOperator.AdditionAssignment, '+='],\n  [o.BinaryOperator.SubtractionAssignment, '-='],\n  [o.BinaryOperator.MultiplicationAssignment, '*='],\n  [o.BinaryOperator.DivisionAssignment, '/='],\n  [o.BinaryOperator.RemainderAssignment, '%='],\n  [o.BinaryOperator.ExponentiationAssignment, '**='],\n  [o.BinaryOperator.AndAssignment, '&&='],\n  [o.BinaryOperator.OrAssignment, '||='],\n  [o.BinaryOperator.NullishCoalesceAssignment, '??='],\n]);\n\nexport class EmitterVisitorContext {\n  static createRoot(): EmitterVisitorContext {\n    return new EmitterVisitorContext(0);\n  }\n\n  private _lines: _EmittedLine[];\n\n  constructor(private _indent: number) {\n    this._lines = [new _EmittedLine(_indent)];\n  }\n\n  /**\n   * @internal strip this from published d.ts files due to\n   * https://github.com/microsoft/TypeScript/issues/36216\n   */\n  private get _currentLine(): _EmittedLine {\n    return this._lines[this._lines.length - 1];\n  }\n\n  println(from?: {sourceSpan: ParseSourceSpan | null} | null, lastPart: string = ''): void {\n    this.print(from || null, lastPart, true);\n  }\n\n  lineIsEmpty(): boolean {\n    return this._currentLine.parts.length === 0;\n  }\n\n  lineLength(): number {\n    return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;\n  }\n\n  print(from: {sourceSpan: ParseSourceSpan | null} | null, part: string, newLine: boolean = false) {\n    if (part.length > 0) {\n      this._currentLine.parts.push(part);\n      this._currentLine.partsLength += part.length;\n      this._currentLine.srcSpans.push((from && from.sourceSpan) || null);\n    }\n    if (newLine) {\n      this._lines.push(new _EmittedLine(this._indent));\n    }\n  }\n\n  removeEmptyLastLine() {\n    if (this.lineIsEmpty()) {\n      this._lines.pop();\n    }\n  }\n\n  incIndent() {\n    this._indent++;\n    if (this.lineIsEmpty()) {\n      this._currentLine.indent = this._indent;\n    }\n  }\n\n  decIndent() {\n    this._indent--;\n    if (this.lineIsEmpty()) {\n      this._currentLine.indent = this._indent;\n    }\n  }\n\n  toSource(): string {\n    return this.sourceLines\n      .map((l) => (l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : ''))\n      .join('\\n');\n  }\n\n  toSourceMapGenerator(genFilePath: string, startsAtLine: number = 0): SourceMapGenerator {\n    const map = new SourceMapGenerator(genFilePath);\n\n    let firstOffsetMapped = false;\n    const mapFirstOffsetIfNeeded = () => {\n      if (!firstOffsetMapped) {\n        // Add a single space so that tools won't try to load the file from disk.\n        // Note: We are using virtual urls like `ng:///`, so we have to\n        // provide a content here.\n        map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);\n        firstOffsetMapped = true;\n      }\n    };\n\n    for (let i = 0; i < startsAtLine; i++) {\n      map.addLine();\n      mapFirstOffsetIfNeeded();\n    }\n\n    this.sourceLines.forEach((line, lineIdx) => {\n      map.addLine();\n\n      const spans = line.srcSpans;\n      const parts = line.parts;\n      let col0 = line.indent * _INDENT_WITH.length;\n      let spanIdx = 0;\n      // skip leading parts without source spans\n      while (spanIdx < spans.length && !spans[spanIdx]) {\n        col0 += parts[spanIdx].length;\n        spanIdx++;\n      }\n      if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {\n        firstOffsetMapped = true;\n      } else {\n        mapFirstOffsetIfNeeded();\n      }\n\n      while (spanIdx < spans.length) {\n        const span = spans[spanIdx]!;\n        const source = span.start.file;\n        const sourceLine = span.start.line;\n        const sourceCol = span.start.col;\n        map\n          .addSource(source.url, source.content)\n          .addMapping(col0, source.url, sourceLine, sourceCol);\n\n        col0 += parts[spanIdx].length;\n        spanIdx++;\n\n        // assign parts without span or the same span to the previous segment\n        while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {\n          col0 += parts[spanIdx].length;\n          spanIdx++;\n        }\n      }\n    });\n\n    return map;\n  }\n\n  spanOf(line: number, column: number): ParseSourceSpan | null {\n    const emittedLine = this._lines[line];\n    if (emittedLine) {\n      let columnsLeft = column - _createIndent(emittedLine.indent).length;\n      for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {\n        const part = emittedLine.parts[partIndex];\n        if (part.length > columnsLeft) {\n          return emittedLine.srcSpans[partIndex];\n        }\n        columnsLeft -= part.length;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @internal strip this from published d.ts files due to\n   * https://github.com/microsoft/TypeScript/issues/36216\n   */\n  private get sourceLines(): _EmittedLine[] {\n    if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {\n      return this._lines.slice(0, -1);\n    }\n    return this._lines;\n  }\n}\n\nexport abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.ExpressionVisitor {\n  private lastIfCondition: o.Expression | null = null;\n\n  constructor(private _escapeDollarInStrings: boolean) {}\n\n  protected printLeadingComments(stmt: o.Statement, ctx: EmitterVisitorContext): void {\n    if (stmt.leadingComments === undefined) {\n      return;\n    }\n    for (const comment of stmt.leadingComments) {\n      if (comment instanceof o.JSDocComment) {\n        ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);\n      } else {\n        if (comment.multiline) {\n          ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);\n        } else {\n          comment.text.split('\\n').forEach((line) => {\n            ctx.println(stmt, `// ${line}`);\n          });\n        }\n      }\n    }\n  }\n\n  visitExpressionStmt(stmt: o.ExpressionStatement, ctx: EmitterVisitorContext): any {\n    this.printLeadingComments(stmt, ctx);\n    stmt.expr.visitExpression(this, ctx);\n    ctx.println(stmt, ';');\n    return null;\n  }\n\n  visitReturnStmt(stmt: o.ReturnStatement, ctx: EmitterVisitorContext): any {\n    this.printLeadingComments(stmt, ctx);\n    ctx.print(stmt, `return `);\n    stmt.value.visitExpression(this, ctx);\n    ctx.println(stmt, ';');\n    return null;\n  }\n\n  visitIfStmt(stmt: o.IfStmt, ctx: EmitterVisitorContext): any {\n    this.printLeadingComments(stmt, ctx);\n    ctx.print(stmt, `if (`);\n    this.lastIfCondition = stmt.condition; // We can skip redundant parentheses for the condition.\n    stmt.condition.visitExpression(this, ctx);\n    this.lastIfCondition = null;\n    ctx.print(stmt, `) {`);\n    const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;\n    if (stmt.trueCase.length <= 1 && !hasElseCase) {\n      ctx.print(stmt, ` `);\n      this.visitAllStatements(stmt.trueCase, ctx);\n      ctx.removeEmptyLastLine();\n      ctx.print(stmt, ` `);\n    } else {\n      ctx.println();\n      ctx.incIndent();\n      this.visitAllStatements(stmt.trueCase, ctx);\n      ctx.decIndent();\n      if (hasElseCase) {\n        ctx.println(stmt, `} else {`);\n        ctx.incIndent();\n        this.visitAllStatements(stmt.falseCase, ctx);\n        ctx.decIndent();\n      }\n    }\n    ctx.println(stmt, `}`);\n    return null;\n  }\n\n  abstract visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: EmitterVisitorContext): any;\n\n  visitInvokeFunctionExpr(expr: o.InvokeFunctionExpr, ctx: EmitterVisitorContext): any {\n    const shouldParenthesize = expr.fn instanceof o.ArrowFunctionExpr;\n\n    if (shouldParenthesize) {\n      ctx.print(expr.fn, '(');\n    }\n    expr.fn.visitExpression(this, ctx);\n    if (shouldParenthesize) {\n      ctx.print(expr.fn, ')');\n    }\n    ctx.print(expr, `(`);\n    this.visitAllExpressions(expr.args, ctx, ',');\n    ctx.print(expr, `)`);\n    return null;\n  }\n  visitTaggedTemplateLiteralExpr(\n    expr: o.TaggedTemplateLiteralExpr,\n    ctx: EmitterVisitorContext,\n  ): any {\n    expr.tag.visitExpression(this, ctx);\n    expr.template.visitExpression(this, ctx);\n    return null;\n  }\n  visitTemplateLiteralExpr(expr: o.TemplateLiteralExpr, ctx: EmitterVisitorContext) {\n    ctx.print(expr, '`');\n    for (let i = 0; i < expr.elements.length; i++) {\n      expr.elements[i].visitExpression(this, ctx);\n      const expression = i < expr.expressions.length ? expr.expressions[i] : null;\n      if (expression !== null) {\n        ctx.print(expression, '${');\n        expression.visitExpression(this, ctx);\n        ctx.print(expression, '}');\n      }\n    }\n    ctx.print(expr, '`');\n  }\n  visitTemplateLiteralElementExpr(expr: o.TemplateLiteralElementExpr, ctx: EmitterVisitorContext) {\n    ctx.print(expr, expr.rawText);\n  }\n  visitWrappedNodeExpr(ast: o.WrappedNodeExpr<any>, ctx: EmitterVisitorContext): any {\n    throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');\n  }\n  visitTypeofExpr(expr: o.TypeofExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(expr, 'typeof ');\n    expr.expr.visitExpression(this, ctx);\n  }\n  visitVoidExpr(expr: o.VoidExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(expr, 'void ');\n    expr.expr.visitExpression(this, ctx);\n  }\n  visitReadVarExpr(ast: o.ReadVarExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, ast.name);\n    return null;\n  }\n  visitInstantiateExpr(ast: o.InstantiateExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, `new `);\n    ast.classExpr.visitExpression(this, ctx);\n    ctx.print(ast, `(`);\n    this.visitAllExpressions(ast.args, ctx, ',');\n    ctx.print(ast, `)`);\n    return null;\n  }\n\n  visitLiteralExpr(ast: o.LiteralExpr, ctx: EmitterVisitorContext): any {\n    const value = ast.value;\n    if (typeof value === 'string') {\n      ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));\n    } else {\n      ctx.print(ast, `${value}`);\n    }\n    return null;\n  }\n\n  visitRegularExpressionLiteral(\n    ast: o.RegularExpressionLiteralExpr,\n    ctx: EmitterVisitorContext,\n  ): any {\n    ctx.print(ast, `/${ast.body}/${ast.flags || ''}`);\n    return null;\n  }\n\n  visitLocalizedString(ast: o.LocalizedString, ctx: EmitterVisitorContext): any {\n    const head = ast.serializeI18nHead();\n    ctx.print(ast, '$localize `' + head.raw);\n    for (let i = 1; i < ast.messageParts.length; i++) {\n      ctx.print(ast, '${');\n      ast.expressions[i - 1].visitExpression(this, ctx);\n      ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);\n    }\n    ctx.print(ast, '`');\n    return null;\n  }\n\n  abstract visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any;\n\n  visitConditionalExpr(ast: o.ConditionalExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, `(`);\n    ast.condition.visitExpression(this, ctx);\n    ctx.print(ast, '? ');\n    ast.trueCase.visitExpression(this, ctx);\n    ctx.print(ast, ': ');\n    ast.falseCase!.visitExpression(this, ctx);\n    ctx.print(ast, `)`);\n    return null;\n  }\n\n  visitDynamicImportExpr(ast: o.DynamicImportExpr, ctx: EmitterVisitorContext) {\n    ctx.print(ast, `import(${ast.url})`);\n  }\n\n  visitNotExpr(ast: o.NotExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, '!');\n    ast.condition.visitExpression(this, ctx);\n    return null;\n  }\n  abstract visitFunctionExpr(ast: o.FunctionExpr, ctx: EmitterVisitorContext): any;\n  abstract visitArrowFunctionExpr(ast: o.ArrowFunctionExpr, context: any): any;\n  abstract visitDeclareFunctionStmt(stmt: o.DeclareFunctionStmt, context: any): any;\n\n  visitUnaryOperatorExpr(ast: o.UnaryOperatorExpr, ctx: EmitterVisitorContext): any {\n    let opStr: string;\n    switch (ast.operator) {\n      case o.UnaryOperator.Plus:\n        opStr = '+';\n        break;\n      case o.UnaryOperator.Minus:\n        opStr = '-';\n        break;\n      default:\n        throw new Error(`Unknown operator ${ast.operator}`);\n    }\n    const parens = ast !== this.lastIfCondition;\n    if (parens) ctx.print(ast, `(`);\n    ctx.print(ast, opStr);\n    ast.expr.visitExpression(this, ctx);\n    if (parens) ctx.print(ast, `)`);\n    return null;\n  }\n\n  visitBinaryOperatorExpr(ast: o.BinaryOperatorExpr, ctx: EmitterVisitorContext): any {\n    const operator = BINARY_OPERATORS.get(ast.operator);\n    if (!operator) {\n      throw new Error(`Unknown operator ${ast.operator}`);\n    }\n    const parens = ast !== this.lastIfCondition;\n    if (parens) ctx.print(ast, `(`);\n    ast.lhs.visitExpression(this, ctx);\n    ctx.print(ast, ` ${operator} `);\n    ast.rhs.visitExpression(this, ctx);\n    if (parens) ctx.print(ast, `)`);\n    return null;\n  }\n\n  visitReadPropExpr(ast: o.ReadPropExpr, ctx: EmitterVisitorContext): any {\n    ast.receiver.visitExpression(this, ctx);\n    ctx.print(ast, `.`);\n    ctx.print(ast, ast.name);\n    return null;\n  }\n  visitReadKeyExpr(ast: o.ReadKeyExpr, ctx: EmitterVisitorContext): any {\n    ast.receiver.visitExpression(this, ctx);\n    ctx.print(ast, `[`);\n    ast.index.visitExpression(this, ctx);\n    ctx.print(ast, `]`);\n    return null;\n  }\n  visitLiteralArrayExpr(ast: o.LiteralArrayExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, `[`);\n    this.visitAllExpressions(ast.entries, ctx, ',');\n    ctx.print(ast, `]`);\n    return null;\n  }\n  visitLiteralMapExpr(ast: o.LiteralMapExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, `{`);\n    this.visitAllObjects(\n      (entry) => {\n        if (entry instanceof o.LiteralMapSpreadAssignment) {\n          ctx.print(ast, '...');\n          entry.expression.visitExpression(this, ctx);\n        } else {\n          ctx.print(\n            ast,\n            `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`,\n          );\n          entry.value.visitExpression(this, ctx);\n        }\n      },\n      ast.entries,\n      ctx,\n      ',',\n    );\n    ctx.print(ast, `}`);\n    return null;\n  }\n  visitCommaExpr(ast: o.CommaExpr, ctx: EmitterVisitorContext): any {\n    ctx.print(ast, '(');\n    this.visitAllExpressions(ast.parts, ctx, ',');\n    ctx.print(ast, ')');\n    return null;\n  }\n  visitParenthesizedExpr(ast: o.ParenthesizedExpr, ctx: EmitterVisitorContext): any {\n    // We parenthesize everything regardless of an explicit ParenthesizedExpr, so we can just visit\n    // the inner expression.\n    // TODO: Do we *need* to parenthesize everything?\n    ast.expr.visitExpression(this, ctx);\n  }\n  visitSpreadElementExpr(ast: o.SpreadElementExpr, ctx: EmitterVisitorContext) {\n    ctx.print(ast, '...');\n    ast.expression.visitExpression(this, ctx);\n  }\n  visitAllExpressions(\n    expressions: o.Expression[],\n    ctx: EmitterVisitorContext,\n    separator: string,\n  ): void {\n    this.visitAllObjects((expr) => expr.visitExpression(this, ctx), expressions, ctx, separator);\n  }\n\n  visitAllObjects<T>(\n    handler: (t: T) => void,\n    expressions: T[],\n    ctx: EmitterVisitorContext,\n    separator: string,\n  ): void {\n    let incrementedIndent = false;\n    for (let i = 0; i < expressions.length; i++) {\n      if (i > 0) {\n        if (ctx.lineLength() > 80) {\n          ctx.print(null, separator, true);\n          if (!incrementedIndent) {\n            // continuation are marked with double indent.\n            ctx.incIndent();\n            ctx.incIndent();\n            incrementedIndent = true;\n          }\n        } else {\n          ctx.print(null, separator, false);\n        }\n      }\n      handler(expressions[i]);\n    }\n    if (incrementedIndent) {\n      // continuation are marked with double indent.\n      ctx.decIndent();\n      ctx.decIndent();\n    }\n  }\n\n  visitAllStatements(statements: o.Statement[], ctx: EmitterVisitorContext): void {\n    statements.forEach((stmt) => stmt.visitStatement(this, ctx));\n  }\n}\n\nexport function escapeIdentifier(\n  input: string,\n  escapeDollar: boolean,\n  alwaysQuote: boolean = true,\n): any {\n  if (input == null) {\n    return null;\n  }\n  const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match: string[]) => {\n    if (match[0] == '$') {\n      return escapeDollar ? '\\\\$' : '$';\n    } else if (match[0] == '\\n') {\n      return '\\\\n';\n    } else if (match[0] == '\\r') {\n      return '\\\\r';\n    } else {\n      return `\\\\${match[0]}`;\n    }\n  });\n  const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);\n  return requiresQuotes ? `'${body}'` : body;\n}\n\nfunction _createIndent(count: number): string {\n  let res = '';\n  for (let i = 0; i < count; i++) {\n    res += _INDENT_WITH;\n  }\n  return res;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {escapeIdentifier} from '../output/abstract_emitter';\nimport * as o from '../output/output_ast';\n\nimport {Identifiers} from './r3_identifiers';\n\nexport function typeWithParameters(type: o.Expression, numParams: number): o.ExpressionType {\n  if (numParams === 0) {\n    return o.expressionType(type);\n  }\n  const params: o.Type[] = [];\n  for (let i = 0; i < numParams; i++) {\n    params.push(o.DYNAMIC_TYPE);\n  }\n  return o.expressionType(type, undefined, params);\n}\n\nexport interface R3Reference {\n  value: o.Expression;\n  type: o.Expression;\n}\n\n/**\n * Result of compilation of a render3 code unit, e.g. component, directive, pipe, etc.\n */\nexport interface R3CompiledExpression {\n  expression: o.Expression;\n  type: o.Type;\n  statements: o.Statement[];\n}\n\nconst LEGACY_ANIMATE_SYMBOL_PREFIX = '@';\nexport function prepareSyntheticPropertyName(name: string) {\n  return `${LEGACY_ANIMATE_SYMBOL_PREFIX}${name}`;\n}\n\nexport function prepareSyntheticListenerName(name: string, phase: string) {\n  return `${LEGACY_ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;\n}\n\nexport function getSafePropertyAccessString(accessor: string, name: string): string {\n  const escapedName = escapeIdentifier(name, false, false);\n  return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;\n}\n\nexport function prepareSyntheticListenerFunctionName(name: string, phase: string) {\n  return `animation_${name}_${phase}`;\n}\n\nexport function jitOnlyGuardedExpression(expr: o.Expression): o.Expression {\n  return guardedExpression('ngJitMode', expr);\n}\n\nexport function devOnlyGuardedExpression(expr: o.Expression): o.Expression {\n  return guardedExpression('ngDevMode', expr);\n}\n\nexport function guardedExpression(guard: string, expr: o.Expression): o.Expression {\n  const guardExpr = new o.ExternalExpr({name: guard, moduleName: null});\n  const guardNotDefined = new o.BinaryOperatorExpr(\n    o.BinaryOperator.Identical,\n    new o.TypeofExpr(guardExpr),\n    o.literal('undefined'),\n  );\n  const guardUndefinedOrTrue = new o.BinaryOperatorExpr(\n    o.BinaryOperator.Or,\n    guardNotDefined,\n    guardExpr,\n    /* type */ undefined,\n    /* sourceSpan */ undefined,\n  );\n  return new o.BinaryOperatorExpr(o.BinaryOperator.And, guardUndefinedOrTrue, expr);\n}\n\nexport function wrapReference(value: any): R3Reference {\n  const wrapped = new o.WrappedNodeExpr(value);\n  return {value: wrapped, type: wrapped};\n}\n\nexport function refsToArray(refs: R3Reference[], shouldForwardDeclare: boolean): o.Expression {\n  const values = o.literalArr(refs.map((ref) => ref.value));\n  return shouldForwardDeclare ? o.arrowFn([], values) : values;\n}\n\n/**\n * Describes an expression that may have been wrapped in a `forwardRef()` guard.\n *\n * This is used when describing expressions that can refer to types that may eagerly reference types\n * that have not yet been defined.\n */\nexport interface MaybeForwardRefExpression<T extends o.Expression = o.Expression> {\n  /**\n   * The unwrapped expression.\n   */\n  expression: T;\n  /**\n   * Specified whether the `expression` contains a reference to something that has not yet been\n   * defined, and whether the expression is still wrapped in a `forwardRef()` call.\n   *\n   * If this value is `ForwardRefHandling.None` then the `expression` is safe to use as-is.\n   *\n   * Otherwise the `expression` was wrapped in a call to `forwardRef()` and must not be eagerly\n   * evaluated. Instead it must be wrapped in a function closure that will be evaluated lazily to\n   * allow the definition of the expression to be evaluated first.\n   *\n   * In full AOT compilation it can be safe to unwrap the `forwardRef()` call up front if the\n   * expression will actually be evaluated lazily inside a function call after the value of\n   * `expression` has been defined.\n   *\n   * But in other cases, such as partial AOT compilation or JIT compilation the expression will be\n   * evaluated eagerly in top level code so will need to continue to be wrapped in a `forwardRef()`\n   * call.\n   *\n   */\n  forwardRef: ForwardRefHandling;\n}\n\nexport function createMayBeForwardRefExpression<T extends o.Expression>(\n  expression: T,\n  forwardRef: ForwardRefHandling,\n): MaybeForwardRefExpression<T> {\n  return {expression, forwardRef};\n}\n\n/**\n * Convert a `MaybeForwardRefExpression` to an `Expression`, possibly wrapping its expression in a\n * `forwardRef()` call.\n *\n * If `MaybeForwardRefExpression.forwardRef` is `ForwardRefHandling.Unwrapped` then the expression\n * was originally wrapped in a `forwardRef()` call to prevent the value from being eagerly evaluated\n * in the code.\n *\n * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and\n * `packages/compiler/src/jit_compiler_facade.ts` for more information.\n */\nexport function convertFromMaybeForwardRefExpression({\n  expression,\n  forwardRef,\n}: MaybeForwardRefExpression): o.Expression {\n  switch (forwardRef) {\n    case ForwardRefHandling.None:\n    case ForwardRefHandling.Wrapped:\n      return expression;\n    case ForwardRefHandling.Unwrapped:\n      return generateForwardRef(expression);\n  }\n}\n\n/**\n * Generate an expression that has the given `expr` wrapped in the following form:\n *\n * ```ts\n * forwardRef(() => expr)\n * ```\n */\nexport function generateForwardRef(expr: o.Expression): o.Expression {\n  return o.importExpr(Identifiers.forwardRef).callFn([o.arrowFn([], expr)]);\n}\n\n/**\n * Specifies how a forward ref has been handled in a MaybeForwardRefExpression\n */\nexport const enum ForwardRefHandling {\n  /** The expression was not wrapped in a `forwardRef()` call in the first place. */\n  None,\n  /** The expression is still wrapped in a `forwardRef()` call. */\n  Wrapped,\n  /** The expression was wrapped in a `forwardRef()` call but has since been unwrapped. */\n  Unwrapped,\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {FactoryTarget} from '../compiler_facade_interface';\nimport {InjectFlags} from '../core';\nimport * as o from '../output/output_ast';\nimport {Identifiers as R3} from '../render3/r3_identifiers';\n\nimport {R3CompiledExpression, R3Reference, typeWithParameters} from './util';\n\n/**\n * Metadata required by the factory generator to generate a `factory` function for a type.\n */\nexport interface R3ConstructorFactoryMetadata {\n  /**\n   * String name of the type being generated (used to name the factory function).\n   */\n  name: string;\n\n  /**\n   * An expression representing the interface type being constructed.\n   */\n  type: R3Reference;\n\n  /** Number of arguments for the `type`. */\n  typeArgumentCount: number;\n\n  /**\n   * Regardless of whether `fnOrClass` is a constructor function or a user-defined factory, it\n   * may have 0 or more parameters, which will be injected according to the `R3DependencyMetadata`\n   * for those parameters. If this is `null`, then the type's constructor is nonexistent and will\n   * be inherited from `fnOrClass` which is interpreted as the current type. If this is `'invalid'`,\n   * then one or more of the parameters wasn't resolvable and any attempt to use these deps will\n   * result in a runtime error.\n   */\n  deps: R3DependencyMetadata[] | 'invalid' | null;\n\n  /**\n   * Type of the target being created by the factory.\n   */\n  target: FactoryTarget;\n}\n\nexport enum R3FactoryDelegateType {\n  Class = 0,\n  Function = 1,\n}\n\nexport interface R3DelegatedFnOrClassMetadata extends R3ConstructorFactoryMetadata {\n  delegate: o.Expression;\n  delegateType: R3FactoryDelegateType;\n  delegateDeps: R3DependencyMetadata[];\n}\n\nexport interface R3ExpressionFactoryMetadata extends R3ConstructorFactoryMetadata {\n  expression: o.Expression;\n}\n\nexport type R3FactoryMetadata =\n  | R3ConstructorFactoryMetadata\n  | R3DelegatedFnOrClassMetadata\n  | R3ExpressionFactoryMetadata;\n\nexport interface R3DependencyMetadata {\n  /**\n   * An expression representing the token or value to be injected.\n   * Or `null` if the dependency could not be resolved - making it invalid.\n   */\n  token: o.Expression | null;\n\n  /**\n   * If an @Attribute decorator is present, this is the literal type of the attribute name, or\n   * the unknown type if no literal type is available (e.g. the attribute name is an expression).\n   * Otherwise it is null;\n   */\n  attributeNameType: o.Expression | null;\n\n  /**\n   * Whether the dependency has an @Host qualifier.\n   */\n  host: boolean;\n\n  /**\n   * Whether the dependency has an @Optional qualifier.\n   */\n  optional: boolean;\n\n  /**\n   * Whether the dependency has an @Self qualifier.\n   */\n  self: boolean;\n\n  /**\n   * Whether the dependency has an @SkipSelf qualifier.\n   */\n  skipSelf: boolean;\n}\n\n/**\n * Construct a factory function expression for the given `R3FactoryMetadata`.\n */\nexport function compileFactoryFunction(meta: R3FactoryMetadata): R3CompiledExpression {\n  const t = o.variable('__ngFactoryType__');\n  let baseFactoryVar: o.ReadVarExpr | null = null;\n\n  // The type to instantiate via constructor invocation. If there is no delegated factory, meaning\n  // this type is always created by constructor invocation, then this is the type-to-create\n  // parameter provided by the user (t) if specified, or the current type if not. If there is a\n  // delegated factory (which is used to create the current type) then this is only the type-to-\n  // create parameter (t).\n  const typeForCtor = !isDelegatedFactoryMetadata(meta)\n    ? new o.BinaryOperatorExpr(o.BinaryOperator.Or, t, meta.type.value)\n    : t;\n\n  let ctorExpr: o.Expression | null = null;\n  if (meta.deps !== null) {\n    // There is a constructor (either explicitly or implicitly defined).\n    if (meta.deps !== 'invalid') {\n      ctorExpr = new o.InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));\n    }\n  } else {\n    // There is no constructor, use the base class' factory to construct typeForCtor.\n    baseFactoryVar = o.variable(`ɵ${meta.name}_BaseFactory`);\n    ctorExpr = baseFactoryVar.callFn([typeForCtor]);\n  }\n\n  const body: o.Statement[] = [];\n  let retExpr: o.Expression | null = null;\n\n  function makeConditionalFactory(nonCtorExpr: o.Expression): o.ReadVarExpr {\n    const r = o.variable('__ngConditionalFactory__');\n    body.push(new o.DeclareVarStmt(r.name, o.NULL_EXPR, o.INFERRED_TYPE));\n    const ctorStmt =\n      ctorExpr !== null\n        ? r.set(ctorExpr).toStmt()\n        : o.importExpr(R3.invalidFactory).callFn([]).toStmt();\n    body.push(o.ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));\n    return r;\n  }\n\n  if (isDelegatedFactoryMetadata(meta)) {\n    // This type is created with a delegated factory. If a type parameter is not specified, call\n    // the factory instead.\n    const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);\n    // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.\n    const factoryExpr = new (\n      meta.delegateType === R3FactoryDelegateType.Class ? o.InstantiateExpr : o.InvokeFunctionExpr\n    )(meta.delegate, delegateArgs);\n    retExpr = makeConditionalFactory(factoryExpr);\n  } else if (isExpressionFactoryMetadata(meta)) {\n    // TODO(alxhub): decide whether to lower the value here or in the caller\n    retExpr = makeConditionalFactory(meta.expression);\n  } else {\n    retExpr = ctorExpr;\n  }\n\n  if (retExpr === null) {\n    // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.\n    body.push(o.importExpr(R3.invalidFactory).callFn([]).toStmt());\n  } else if (baseFactoryVar !== null) {\n    // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.\n    const getInheritedFactoryCall = o.importExpr(R3.getInheritedFactory).callFn([meta.type.value]);\n    // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`\n    const baseFactory = new o.BinaryOperatorExpr(\n      o.BinaryOperator.Or,\n      baseFactoryVar,\n      baseFactoryVar.set(getInheritedFactoryCall),\n    );\n    body.push(new o.ReturnStatement(baseFactory.callFn([typeForCtor])));\n  } else {\n    // This is straightforward factory, just return it.\n    body.push(new o.ReturnStatement(retExpr));\n  }\n\n  let factoryFn: o.Expression = o.fn(\n    [new o.FnParam(t.name, o.DYNAMIC_TYPE)],\n    body,\n    o.INFERRED_TYPE,\n    undefined,\n    `${meta.name}_Factory`,\n  );\n\n  if (baseFactoryVar !== null) {\n    // There is a base factory variable so wrap its declaration along with the factory function into\n    // an IIFE.\n    factoryFn = o\n      .arrowFn([], [new o.DeclareVarStmt(baseFactoryVar.name!), new o.ReturnStatement(factoryFn)])\n      .callFn([], /* sourceSpan */ undefined, /* pure */ true);\n  }\n\n  return {\n    expression: factoryFn,\n    statements: [],\n    type: createFactoryType(meta),\n  };\n}\n\nexport function createFactoryType(meta: R3FactoryMetadata) {\n  const ctorDepsType =\n    meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : o.NONE_TYPE;\n  return o.expressionType(\n    o.importExpr(R3.FactoryDeclaration, [\n      typeWithParameters(meta.type.type, meta.typeArgumentCount),\n      ctorDepsType,\n    ]),\n  );\n}\n\nfunction injectDependencies(deps: R3DependencyMetadata[], target: FactoryTarget): o.Expression[] {\n  return deps.map((dep, index) => compileInjectDependency(dep, target, index));\n}\n\nfunction compileInjectDependency(\n  dep: R3DependencyMetadata,\n  target: FactoryTarget,\n  index: number,\n): o.Expression {\n  // Interpret the dependency according to its resolved type.\n  if (dep.token === null) {\n    return o.importExpr(R3.invalidFactoryDep).callFn([o.literal(index)]);\n  } else if (dep.attributeNameType === null) {\n    // Build up the injection flags according to the metadata.\n    const flags =\n      InjectFlags.Default |\n      (dep.self ? InjectFlags.Self : 0) |\n      (dep.skipSelf ? InjectFlags.SkipSelf : 0) |\n      (dep.host ? InjectFlags.Host : 0) |\n      (dep.optional ? InjectFlags.Optional : 0) |\n      (target === FactoryTarget.Pipe ? InjectFlags.ForPipe : 0);\n\n    // If this dependency is optional or otherwise has non-default flags, then additional\n    // parameters describing how to inject the dependency must be passed to the inject function\n    // that's being used.\n    let flagsParam: o.LiteralExpr | null =\n      flags !== InjectFlags.Default || dep.optional ? o.literal(flags) : null;\n\n    // Build up the arguments to the injectFn call.\n    const injectArgs = [dep.token];\n    if (flagsParam) {\n      injectArgs.push(flagsParam);\n    }\n    const injectFn = getInjectFn(target);\n    return o.importExpr(injectFn).callFn(injectArgs);\n  } else {\n    // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`\n    // type dependency. For the generated JS we still want to use the `dep.token` value in case the\n    // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,\n    // we want to generate `ɵɵinjectAttribute(foo())`.\n    //\n    // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate\n    // typings.\n    return o.importExpr(R3.injectAttribute).callFn([dep.token]);\n  }\n}\n\nfunction createCtorDepsType(deps: R3DependencyMetadata[]): o.Type {\n  let hasTypes = false;\n  const attributeTypes = deps.map((dep) => {\n    const type = createCtorDepType(dep);\n    if (type !== null) {\n      hasTypes = true;\n      return type;\n    } else {\n      return o.literal(null);\n    }\n  });\n\n  if (hasTypes) {\n    return o.expressionType(o.literalArr(attributeTypes));\n  } else {\n    return o.NONE_TYPE;\n  }\n}\n\nfunction createCtorDepType(dep: R3DependencyMetadata): o.LiteralMapExpr | null {\n  const entries: {key: string; quoted: boolean; value: o.Expression}[] = [];\n\n  if (dep.attributeNameType !== null) {\n    entries.push({key: 'attribute', value: dep.attributeNameType, quoted: false});\n  }\n  if (dep.optional) {\n    entries.push({key: 'optional', value: o.literal(true), quoted: false});\n  }\n  if (dep.host) {\n    entries.push({key: 'host', value: o.literal(true), quoted: false});\n  }\n  if (dep.self) {\n    entries.push({key: 'self', value: o.literal(true), quoted: false});\n  }\n  if (dep.skipSelf) {\n    entries.push({key: 'skipSelf', value: o.literal(true), quoted: false});\n  }\n\n  return entries.length > 0 ? o.literalMap(entries) : null;\n}\n\nexport function isDelegatedFactoryMetadata(\n  meta: R3FactoryMetadata,\n): meta is R3DelegatedFnOrClassMetadata {\n  return (meta as any).delegateType !== undefined;\n}\n\nexport function isExpressionFactoryMetadata(\n  meta: R3FactoryMetadata,\n): meta is R3ExpressionFactoryMetadata {\n  return (meta as any).expression !== undefined;\n}\n\nfunction getInjectFn(target: FactoryTarget): o.ExternalReference {\n  switch (target) {\n    case FactoryTarget.Component:\n    case FactoryTarget.Directive:\n    case FactoryTarget.Pipe:\n      return R3.directiveInject;\n    case FactoryTarget.NgModule:\n    case FactoryTarget.Injectable:\n    default:\n      return R3.inject;\n  }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {SecurityContext} from '../core';\nimport {ParseError, ParseSourceSpan} from '../parse_util';\n\nexport class ParseSpan {\n  constructor(\n    public start: number,\n    public end: number,\n  ) {}\n  toAbsolute(absoluteOffset: number): AbsoluteSourceSpan {\n    return new AbsoluteSourceSpan(absoluteOffset + this.start, absoluteOffset + this.end);\n  }\n}\n\nexport abstract class AST {\n  constructor(\n    public span: ParseSpan,\n    /**\n     * Absolute location of the expression AST in a source code file.\n     */\n    public sourceSpan: AbsoluteSourceSpan,\n  ) {}\n\n  abstract visit(visitor: AstVisitor, context?: any): any;\n\n  toString(): string {\n    return 'AST';\n  }\n}\n\nexport abstract class ASTWithName extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public nameSpan: AbsoluteSourceSpan,\n  ) {\n    super(span, sourceSpan);\n  }\n}\n\nexport class EmptyExpr extends AST {\n  override visit(visitor: AstVisitor, context: any = null) {\n    return visitor.visitEmptyExpr?.(this, context);\n  }\n}\n\nexport class ImplicitReceiver extends AST {\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitImplicitReceiver(this, context);\n  }\n}\n\nexport class ThisReceiver extends AST {\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitThisReceiver?.(this, context);\n  }\n}\n\n/**\n * Multiple expressions separated by a semicolon.\n */\nexport class Chain extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public expressions: AST[],\n  ) {\n    super(span, sourceSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitChain(this, context);\n  }\n}\n\nexport class Conditional extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public condition: AST,\n    public trueExp: AST,\n    public falseExp: AST,\n  ) {\n    super(span, sourceSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitConditional(this, context);\n  }\n}\n\nexport class PropertyRead extends ASTWithName {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    nameSpan: AbsoluteSourceSpan,\n    public receiver: AST,\n    public name: string,\n  ) {\n    super(span, sourceSpan, nameSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitPropertyRead(this, context);\n  }\n}\n\nexport class SafePropertyRead extends ASTWithName {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    nameSpan: AbsoluteSourceSpan,\n    public receiver: AST,\n    public name: string,\n  ) {\n    super(span, sourceSpan, nameSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitSafePropertyRead(this, context);\n  }\n}\n\nexport class KeyedRead extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public receiver: AST,\n    public key: AST,\n  ) {\n    super(span, sourceSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitKeyedRead(this, context);\n  }\n}\n\nexport class SafeKeyedRead extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public receiver: AST,\n    public key: AST,\n  ) {\n    super(span, sourceSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitSafeKeyedRead(this, context);\n  }\n}\n\n/** Possible types for a pipe. */\nexport enum BindingPipeType {\n  /**\n   * Pipe is being referenced by its name, for example:\n   * `@Pipe({name: 'foo'}) class FooPipe` and `{{123 | foo}}`.\n   */\n  ReferencedByName,\n\n  /**\n   * Pipe is being referenced by its class name, for example:\n   * `@Pipe() class FooPipe` and `{{123 | FooPipe}}`.\n   */\n  ReferencedDirectly,\n}\n\nexport class BindingPipe extends ASTWithName {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public exp: AST,\n    public name: string,\n    public args: AST[],\n    readonly type: BindingPipeType,\n    nameSpan: AbsoluteSourceSpan,\n  ) {\n    super(span, sourceSpan, nameSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitPipe(this, context);\n  }\n}\n\nexport class LiteralPrimitive extends AST {\n  constructor(\n    span: ParseSpan,\n    sourceSpan: AbsoluteSourceSpan,\n    public value: string | number | boolean | null | undefined,\n  ) {\n    super(span, sourceSpan);\n  }\n  override visit(visitor: AstVisitor, context: any = null): any {\n    return visitor.visitLiteralPrimitive(this, context);\n  }\n}\n\nexport class LiteralAr