summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/vendor
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/content/widgets/vendor
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/content/widgets/vendor')
-rw-r--r--toolkit/content/widgets/vendor/lit.all.mjs4467
1 files changed, 4467 insertions, 0 deletions
diff --git a/toolkit/content/widgets/vendor/lit.all.mjs b/toolkit/content/widgets/vendor/lit.all.mjs
new file mode 100644
index 0000000000..ec542440ae
--- /dev/null
+++ b/toolkit/content/widgets/vendor/lit.all.mjs
@@ -0,0 +1,4467 @@
+/**
+ * @license
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const NODE_MODE$1 = false;
+const global$2 = window;
+/**
+ * Whether the current browser supports `adoptedStyleSheets`.
+ */
+const supportsAdoptingStyleSheets = global$2.ShadowRoot &&
+ (global$2.ShadyCSS === undefined || global$2.ShadyCSS.nativeShadow) &&
+ 'adoptedStyleSheets' in Document.prototype &&
+ 'replace' in CSSStyleSheet.prototype;
+const constructionToken = Symbol();
+const cssTagCache = new WeakMap();
+/**
+ * A container for a string of CSS text, that may be used to create a CSSStyleSheet.
+ *
+ * CSSResult is the return value of `css`-tagged template literals and
+ * `unsafeCSS()`. In order to ensure that CSSResults are only created via the
+ * `css` tag and `unsafeCSS()`, CSSResult cannot be constructed directly.
+ */
+class CSSResult {
+ constructor(cssText, strings, safeToken) {
+ // This property needs to remain unminified.
+ this['_$cssResult$'] = true;
+ if (safeToken !== constructionToken) {
+ throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.');
+ }
+ this.cssText = cssText;
+ this._strings = strings;
+ }
+ // This is a getter so that it's lazy. In practice, this means stylesheets
+ // are not created until the first element instance is made.
+ get styleSheet() {
+ // If `supportsAdoptingStyleSheets` is true then we assume CSSStyleSheet is
+ // constructable.
+ let styleSheet = this._styleSheet;
+ const strings = this._strings;
+ if (supportsAdoptingStyleSheets && styleSheet === undefined) {
+ const cacheable = strings !== undefined && strings.length === 1;
+ if (cacheable) {
+ styleSheet = cssTagCache.get(strings);
+ }
+ if (styleSheet === undefined) {
+ (this._styleSheet = styleSheet = new CSSStyleSheet()).replaceSync(this.cssText);
+ if (cacheable) {
+ cssTagCache.set(strings, styleSheet);
+ }
+ }
+ }
+ return styleSheet;
+ }
+ toString() {
+ return this.cssText;
+ }
+}
+const textFromCSSResult = (value) => {
+ // This property needs to remain unminified.
+ if (value['_$cssResult$'] === true) {
+ return value.cssText;
+ }
+ else if (typeof value === 'number') {
+ return value;
+ }
+ else {
+ throw new Error(`Value passed to 'css' function must be a 'css' function result: ` +
+ `${value}. Use 'unsafeCSS' to pass non-literal values, but take care ` +
+ `to ensure page security.`);
+ }
+};
+/**
+ * Wrap a value for interpolation in a {@linkcode css} tagged template literal.
+ *
+ * This is unsafe because untrusted CSS text can be used to phone home
+ * or exfiltrate data to an attacker controlled site. Take care to only use
+ * this with trusted input.
+ */
+const unsafeCSS = (value) => new CSSResult(typeof value === 'string' ? value : String(value), undefined, constructionToken);
+/**
+ * A template literal tag which can be used with LitElement's
+ * {@linkcode LitElement.styles} property to set element styles.
+ *
+ * For security reasons, only literal string values and number may be used in
+ * embedded expressions. To incorporate non-literal values {@linkcode unsafeCSS}
+ * may be used inside an expression.
+ */
+const css = (strings, ...values) => {
+ const cssText = strings.length === 1
+ ? strings[0]
+ : values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]);
+ return new CSSResult(cssText, strings, constructionToken);
+};
+/**
+ * Applies the given styles to a `shadowRoot`. When Shadow DOM is
+ * available but `adoptedStyleSheets` is not, styles are appended to the
+ * `shadowRoot` to [mimic spec behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets).
+ * Note, when shimming is used, any styles that are subsequently placed into
+ * the shadowRoot should be placed *before* any shimmed adopted styles. This
+ * will match spec behavior that gives adopted sheets precedence over styles in
+ * shadowRoot.
+ */
+const adoptStyles = (renderRoot, styles) => {
+ if (supportsAdoptingStyleSheets) {
+ renderRoot.adoptedStyleSheets = styles.map((s) => s instanceof CSSStyleSheet ? s : s.styleSheet);
+ }
+ else {
+ styles.forEach((s) => {
+ const style = document.createElement('style');
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const nonce = global$2['litNonce'];
+ if (nonce !== undefined) {
+ style.setAttribute('nonce', nonce);
+ }
+ style.textContent = s.cssText;
+ renderRoot.appendChild(style);
+ });
+ }
+};
+const cssResultFromStyleSheet = (sheet) => {
+ let cssText = '';
+ for (const rule of sheet.cssRules) {
+ cssText += rule.cssText;
+ }
+ return unsafeCSS(cssText);
+};
+const getCompatibleStyle = supportsAdoptingStyleSheets ||
+ (NODE_MODE$1 )
+ ? (s) => s
+ : (s) => s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s;
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+var _d$1;
+var _e;
+const global$1 = window;
+const trustedTypes$1 = global$1
+ .trustedTypes;
+// Temporary workaround for https://crbug.com/993268
+// Currently, any attribute starting with "on" is considered to be a
+// TrustedScript source. Such boolean attributes must be set to the equivalent
+// trusted emptyScript value.
+const emptyStringForBooleanAttribute$1 = trustedTypes$1
+ ? trustedTypes$1.emptyScript
+ : '';
+const polyfillSupport$2 = global$1.reactiveElementPolyfillSupport;
+/*
+ * When using Closure Compiler, JSCompiler_renameProperty(property, object) is
+ * replaced at compile time by the munged name for object[property]. We cannot
+ * alias this function, so we have to use a small shim that has the same
+ * behavior when not compiling.
+ */
+/*@__INLINE__*/
+const JSCompiler_renameProperty = (prop, _obj) => prop;
+const defaultConverter = {
+ toAttribute(value, type) {
+ switch (type) {
+ case Boolean:
+ value = value ? emptyStringForBooleanAttribute$1 : null;
+ break;
+ case Object:
+ case Array:
+ // if the value is `null` or `undefined` pass this through
+ // to allow removing/no change behavior.
+ value = value == null ? value : JSON.stringify(value);
+ break;
+ }
+ return value;
+ },
+ fromAttribute(value, type) {
+ let fromValue = value;
+ switch (type) {
+ case Boolean:
+ fromValue = value !== null;
+ break;
+ case Number:
+ fromValue = value === null ? null : Number(value);
+ break;
+ case Object:
+ case Array:
+ // Do *not* generate exception when invalid JSON is set as elements
+ // don't normally complain on being mis-configured.
+ // TODO(sorvell): Do generate exception in *dev mode*.
+ try {
+ // Assert to adhere to Bazel's "must type assert JSON parse" rule.
+ fromValue = JSON.parse(value);
+ }
+ catch (e) {
+ fromValue = null;
+ }
+ break;
+ }
+ return fromValue;
+ },
+};
+/**
+ * Change function that returns true if `value` is different from `oldValue`.
+ * This method is used as the default for a property's `hasChanged` function.
+ */
+const notEqual = (value, old) => {
+ // This ensures (old==NaN, value==NaN) always returns false
+ return old !== value && (old === old || value === value);
+};
+const defaultPropertyDeclaration = {
+ attribute: true,
+ type: String,
+ converter: defaultConverter,
+ reflect: false,
+ hasChanged: notEqual,
+};
+/**
+ * The Closure JS Compiler doesn't currently have good support for static
+ * property semantics where "this" is dynamic (e.g.
+ * https://github.com/google/closure-compiler/issues/3177 and others) so we use
+ * this hack to bypass any rewriting by the compiler.
+ */
+const finalized = 'finalized';
+/**
+ * Base element class which manages element properties and attributes. When
+ * properties change, the `update` method is asynchronously called. This method
+ * should be supplied by subclassers to render updates as desired.
+ * @noInheritDoc
+ */
+class ReactiveElement extends HTMLElement {
+ constructor() {
+ super();
+ this.__instanceProperties = new Map();
+ /**
+ * True if there is a pending update as a result of calling `requestUpdate()`.
+ * Should only be read.
+ * @category updates
+ */
+ this.isUpdatePending = false;
+ /**
+ * Is set to `true` after the first update. The element code cannot assume
+ * that `renderRoot` exists before the element `hasUpdated`.
+ * @category updates
+ */
+ this.hasUpdated = false;
+ /**
+ * Name of currently reflecting property
+ */
+ this.__reflectingProperty = null;
+ this._initialize();
+ }
+ /**
+ * Adds an initializer function to the class that is called during instance
+ * construction.
+ *
+ * This is useful for code that runs against a `ReactiveElement`
+ * subclass, such as a decorator, that needs to do work for each
+ * instance, such as setting up a `ReactiveController`.
+ *
+ * ```ts
+ * const myDecorator = (target: typeof ReactiveElement, key: string) => {
+ * target.addInitializer((instance: ReactiveElement) => {
+ * // This is run during construction of the element
+ * new MyController(instance);
+ * });
+ * }
+ * ```
+ *
+ * Decorating a field will then cause each instance to run an initializer
+ * that adds a controller:
+ *
+ * ```ts
+ * class MyElement extends LitElement {
+ * @myDecorator foo;
+ * }
+ * ```
+ *
+ * Initializers are stored per-constructor. Adding an initializer to a
+ * subclass does not add it to a superclass. Since initializers are run in
+ * constructors, initializers will run in order of the class hierarchy,
+ * starting with superclasses and progressing to the instance's class.
+ *
+ * @nocollapse
+ */
+ static addInitializer(initializer) {
+ var _a;
+ this.finalize();
+ ((_a = this._initializers) !== null && _a !== void 0 ? _a : (this._initializers = [])).push(initializer);
+ }
+ /**
+ * Returns a list of attributes corresponding to the registered properties.
+ * @nocollapse
+ * @category attributes
+ */
+ static get observedAttributes() {
+ // note: piggy backing on this to ensure we're finalized.
+ this.finalize();
+ const attributes = [];
+ // Use forEach so this works even if for/of loops are compiled to for loops
+ // expecting arrays
+ this.elementProperties.forEach((v, p) => {
+ const attr = this.__attributeNameForProperty(p, v);
+ if (attr !== undefined) {
+ this.__attributeToPropertyMap.set(attr, p);
+ attributes.push(attr);
+ }
+ });
+ return attributes;
+ }
+ /**
+ * Creates a property accessor on the element prototype if one does not exist
+ * and stores a {@linkcode PropertyDeclaration} for the property with the
+ * given options. The property setter calls the property's `hasChanged`
+ * property option or uses a strict identity check to determine whether or not
+ * to request an update.
+ *
+ * This method may be overridden to customize properties; however,
+ * when doing so, it's important to call `super.createProperty` to ensure
+ * the property is setup correctly. This method calls
+ * `getPropertyDescriptor` internally to get a descriptor to install.
+ * To customize what properties do when they are get or set, override
+ * `getPropertyDescriptor`. To customize the options for a property,
+ * implement `createProperty` like this:
+ *
+ * ```ts
+ * static createProperty(name, options) {
+ * options = Object.assign(options, {myOption: true});
+ * super.createProperty(name, options);
+ * }
+ * ```
+ *
+ * @nocollapse
+ * @category properties
+ */
+ static createProperty(name, options = defaultPropertyDeclaration) {
+ // if this is a state property, force the attribute to false.
+ if (options.state) {
+ // Cast as any since this is readonly.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ options.attribute = false;
+ }
+ // Note, since this can be called by the `@property` decorator which
+ // is called before `finalize`, we ensure finalization has been kicked off.
+ this.finalize();
+ this.elementProperties.set(name, options);
+ // Do not generate an accessor if the prototype already has one, since
+ // it would be lost otherwise and that would never be the user's intention;
+ // Instead, we expect users to call `requestUpdate` themselves from
+ // user-defined accessors. Note that if the super has an accessor we will
+ // still overwrite it
+ if (!options.noAccessor && !this.prototype.hasOwnProperty(name)) {
+ const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
+ const descriptor = this.getPropertyDescriptor(name, key, options);
+ if (descriptor !== undefined) {
+ Object.defineProperty(this.prototype, name, descriptor);
+ }
+ }
+ }
+ /**
+ * Returns a property descriptor to be defined on the given named property.
+ * If no descriptor is returned, the property will not become an accessor.
+ * For example,
+ *
+ * ```ts
+ * class MyElement extends LitElement {
+ * static getPropertyDescriptor(name, key, options) {
+ * const defaultDescriptor =
+ * super.getPropertyDescriptor(name, key, options);
+ * const setter = defaultDescriptor.set;
+ * return {
+ * get: defaultDescriptor.get,
+ * set(value) {
+ * setter.call(this, value);
+ * // custom action.
+ * },
+ * configurable: true,
+ * enumerable: true
+ * }
+ * }
+ * }
+ * ```
+ *
+ * @nocollapse
+ * @category properties
+ */
+ static getPropertyDescriptor(name, key, options) {
+ return {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ get() {
+ return this[key];
+ },
+ set(value) {
+ const oldValue = this[name];
+ this[key] = value;
+ this.requestUpdate(name, oldValue, options);
+ },
+ configurable: true,
+ enumerable: true,
+ };
+ }
+ /**
+ * Returns the property options associated with the given property.
+ * These options are defined with a `PropertyDeclaration` via the `properties`
+ * object or the `@property` decorator and are registered in
+ * `createProperty(...)`.
+ *
+ * Note, this method should be considered "final" and not overridden. To
+ * customize the options for a given property, override
+ * {@linkcode createProperty}.
+ *
+ * @nocollapse
+ * @final
+ * @category properties
+ */
+ static getPropertyOptions(name) {
+ return this.elementProperties.get(name) || defaultPropertyDeclaration;
+ }
+ /**
+ * Creates property accessors for registered properties, sets up element
+ * styling, and ensures any superclasses are also finalized. Returns true if
+ * the element was finalized.
+ * @nocollapse
+ */
+ static finalize() {
+ if (this.hasOwnProperty(finalized)) {
+ return false;
+ }
+ this[finalized] = true;
+ // finalize any superclasses
+ const superCtor = Object.getPrototypeOf(this);
+ superCtor.finalize();
+ // Create own set of initializers for this class if any exist on the
+ // superclass and copy them down. Note, for a small perf boost, avoid
+ // creating initializers unless needed.
+ if (superCtor._initializers !== undefined) {
+ this._initializers = [...superCtor._initializers];
+ }
+ this.elementProperties = new Map(superCtor.elementProperties);
+ // initialize Map populated in observedAttributes
+ this.__attributeToPropertyMap = new Map();
+ // make any properties
+ // Note, only process "own" properties since this element will inherit
+ // any properties defined on the superClass, and finalization ensures
+ // the entire prototype chain is finalized.
+ if (this.hasOwnProperty(JSCompiler_renameProperty('properties'))) {
+ const props = this.properties;
+ // support symbols in properties (IE11 does not support this)
+ const propKeys = [
+ ...Object.getOwnPropertyNames(props),
+ ...Object.getOwnPropertySymbols(props),
+ ];
+ // This for/of is ok because propKeys is an array
+ for (const p of propKeys) {
+ // note, use of `any` is due to TypeScript lack of support for symbol in
+ // index types
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ this.createProperty(p, props[p]);
+ }
+ }
+ this.elementStyles = this.finalizeStyles(this.styles);
+ return true;
+ }
+ /**
+ * Takes the styles the user supplied via the `static styles` property and
+ * returns the array of styles to apply to the element.
+ * Override this method to integrate into a style management system.
+ *
+ * Styles are deduplicated preserving the _last_ instance in the list. This
+ * is a performance optimization to avoid duplicated styles that can occur
+ * especially when composing via subclassing. The last item is kept to try
+ * to preserve the cascade order with the assumption that it's most important
+ * that last added styles override previous styles.
+ *
+ * @nocollapse
+ * @category styles
+ */
+ static finalizeStyles(styles) {
+ const elementStyles = [];
+ if (Array.isArray(styles)) {
+ // Dedupe the flattened array in reverse order to preserve the last items.
+ // Casting to Array<unknown> works around TS error that
+ // appears to come from trying to flatten a type CSSResultArray.
+ const set = new Set(styles.flat(Infinity).reverse());
+ // Then preserve original order by adding the set items in reverse order.
+ for (const s of set) {
+ elementStyles.unshift(getCompatibleStyle(s));
+ }
+ }
+ else if (styles !== undefined) {
+ elementStyles.push(getCompatibleStyle(styles));
+ }
+ return elementStyles;
+ }
+ /**
+ * Returns the property name for the given attribute `name`.
+ * @nocollapse
+ */
+ static __attributeNameForProperty(name, options) {
+ const attribute = options.attribute;
+ return attribute === false
+ ? undefined
+ : typeof attribute === 'string'
+ ? attribute
+ : typeof name === 'string'
+ ? name.toLowerCase()
+ : undefined;
+ }
+ /**
+ * Internal only override point for customizing work done when elements
+ * are constructed.
+ *
+ * @internal
+ */
+ _initialize() {
+ var _a;
+ this.__updatePromise = new Promise((res) => (this.enableUpdating = res));
+ this._$changedProperties = new Map();
+ this.__saveInstanceProperties();
+ // ensures first update will be caught by an early access of
+ // `updateComplete`
+ this.requestUpdate();
+ (_a = this.constructor._initializers) === null || _a === void 0 ? void 0 : _a.forEach((i) => i(this));
+ }
+ /**
+ * Registers a `ReactiveController` to participate in the element's reactive
+ * update cycle. The element automatically calls into any registered
+ * controllers during its lifecycle callbacks.
+ *
+ * If the element is connected when `addController()` is called, the
+ * controller's `hostConnected()` callback will be immediately called.
+ * @category controllers
+ */
+ addController(controller) {
+ var _a, _b;
+ ((_a = this.__controllers) !== null && _a !== void 0 ? _a : (this.__controllers = [])).push(controller);
+ // If a controller is added after the element has been connected,
+ // call hostConnected. Note, re-using existence of `renderRoot` here
+ // (which is set in connectedCallback) to avoid the need to track a
+ // first connected state.
+ if (this.renderRoot !== undefined && this.isConnected) {
+ (_b = controller.hostConnected) === null || _b === void 0 ? void 0 : _b.call(controller);
+ }
+ }
+ /**
+ * Removes a `ReactiveController` from the element.
+ * @category controllers
+ */
+ removeController(controller) {
+ var _a;
+ // Note, if the indexOf is -1, the >>> will flip the sign which makes the
+ // splice do nothing.
+ (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.splice(this.__controllers.indexOf(controller) >>> 0, 1);
+ }
+ /**
+ * Fixes any properties set on the instance before upgrade time.
+ * Otherwise these would shadow the accessor and break these properties.
+ * The properties are stored in a Map which is played back after the
+ * constructor runs. Note, on very old versions of Safari (<=9) or Chrome
+ * (<=41), properties created for native platform properties like (`id` or
+ * `name`) may not have default values set in the element constructor. On
+ * these browsers native properties appear on instances and therefore their
+ * default value will overwrite any element default (e.g. if the element sets
+ * this.id = 'id' in the constructor, the 'id' will become '' since this is
+ * the native platform default).
+ */
+ __saveInstanceProperties() {
+ // Use forEach so this works even if for/of loops are compiled to for loops
+ // expecting arrays
+ this.constructor.elementProperties.forEach((_v, p) => {
+ if (this.hasOwnProperty(p)) {
+ this.__instanceProperties.set(p, this[p]);
+ delete this[p];
+ }
+ });
+ }
+ /**
+ * Returns the node into which the element should render and by default
+ * creates and returns an open shadowRoot. Implement to customize where the
+ * element's DOM is rendered. For example, to render into the element's
+ * childNodes, return `this`.
+ *
+ * @return Returns a node into which to render.
+ * @category rendering
+ */
+ createRenderRoot() {
+ var _a;
+ const renderRoot = (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this.attachShadow(this.constructor.shadowRootOptions);
+ adoptStyles(renderRoot, this.constructor.elementStyles);
+ return renderRoot;
+ }
+ /**
+ * On first connection, creates the element's renderRoot, sets up
+ * element styling, and enables updating.
+ * @category lifecycle
+ */
+ connectedCallback() {
+ var _a;
+ // create renderRoot before first update.
+ if (this.renderRoot === undefined) {
+ this.renderRoot = this.createRenderRoot();
+ }
+ this.enableUpdating(true);
+ (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostConnected) === null || _a === void 0 ? void 0 : _a.call(c); });
+ }
+ /**
+ * Note, this method should be considered final and not overridden. It is
+ * overridden on the element instance with a function that triggers the first
+ * update.
+ * @category updates
+ */
+ enableUpdating(_requestedUpdate) { }
+ /**
+ * Allows for `super.disconnectedCallback()` in extensions while
+ * reserving the possibility of making non-breaking feature additions
+ * when disconnecting at some point in the future.
+ * @category lifecycle
+ */
+ disconnectedCallback() {
+ var _a;
+ (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostDisconnected) === null || _a === void 0 ? void 0 : _a.call(c); });
+ }
+ /**
+ * Synchronizes property values when attributes change.
+ *
+ * Specifically, when an attribute is set, the corresponding property is set.
+ * You should rarely need to implement this callback. If this method is
+ * overridden, `super.attributeChangedCallback(name, _old, value)` must be
+ * called.
+ *
+ * See [using the lifecycle callbacks](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks)
+ * on MDN for more information about the `attributeChangedCallback`.
+ * @category attributes
+ */
+ attributeChangedCallback(name, _old, value) {
+ this._$attributeToProperty(name, value);
+ }
+ __propertyToAttribute(name, value, options = defaultPropertyDeclaration) {
+ var _a;
+ const attr = this.constructor.__attributeNameForProperty(name, options);
+ if (attr !== undefined && options.reflect === true) {
+ const converter = ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.toAttribute) !==
+ undefined
+ ? options.converter
+ : defaultConverter;
+ const attrValue = converter.toAttribute(value, options.type);
+ // Track if the property is being reflected to avoid
+ // setting the property again via `attributeChangedCallback`. Note:
+ // 1. this takes advantage of the fact that the callback is synchronous.
+ // 2. will behave incorrectly if multiple attributes are in the reaction
+ // stack at time of calling. However, since we process attributes
+ // in `update` this should not be possible (or an extreme corner case
+ // that we'd like to discover).
+ // mark state reflecting
+ this.__reflectingProperty = name;
+ if (attrValue == null) {
+ this.removeAttribute(attr);
+ }
+ else {
+ this.setAttribute(attr, attrValue);
+ }
+ // mark state not reflecting
+ this.__reflectingProperty = null;
+ }
+ }
+ /** @internal */
+ _$attributeToProperty(name, value) {
+ var _a;
+ const ctor = this.constructor;
+ // Note, hint this as an `AttributeMap` so closure clearly understands
+ // the type; it has issues with tracking types through statics
+ const propName = ctor.__attributeToPropertyMap.get(name);
+ // Use tracking info to avoid reflecting a property value to an attribute
+ // if it was just set because the attribute changed.
+ if (propName !== undefined && this.__reflectingProperty !== propName) {
+ const options = ctor.getPropertyOptions(propName);
+ const converter = typeof options.converter === 'function'
+ ? { fromAttribute: options.converter }
+ : ((_a = options.converter) === null || _a === void 0 ? void 0 : _a.fromAttribute) !== undefined
+ ? options.converter
+ : defaultConverter;
+ // mark state reflecting
+ this.__reflectingProperty = propName;
+ this[propName] = converter.fromAttribute(value, options.type
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ );
+ // mark state not reflecting
+ this.__reflectingProperty = null;
+ }
+ }
+ /**
+ * Requests an update which is processed asynchronously. This should be called
+ * when an element should update based on some state not triggered by setting
+ * a reactive property. In this case, pass no arguments. It should also be
+ * called when manually implementing a property setter. In this case, pass the
+ * property `name` and `oldValue` to ensure that any configured property
+ * options are honored.
+ *
+ * @param name name of requesting property
+ * @param oldValue old value of requesting property
+ * @param options property options to use instead of the previously
+ * configured options
+ * @category updates
+ */
+ requestUpdate(name, oldValue, options) {
+ let shouldRequestUpdate = true;
+ // If we have a property key, perform property update steps.
+ if (name !== undefined) {
+ options =
+ options ||
+ this.constructor.getPropertyOptions(name);
+ const hasChanged = options.hasChanged || notEqual;
+ if (hasChanged(this[name], oldValue)) {
+ if (!this._$changedProperties.has(name)) {
+ this._$changedProperties.set(name, oldValue);
+ }
+ // Add to reflecting properties set.
+ // Note, it's important that every change has a chance to add the
+ // property to `_reflectingProperties`. This ensures setting
+ // attribute + property reflects correctly.
+ if (options.reflect === true && this.__reflectingProperty !== name) {
+ if (this.__reflectingProperties === undefined) {
+ this.__reflectingProperties = new Map();
+ }
+ this.__reflectingProperties.set(name, options);
+ }
+ }
+ else {
+ // Abort the request if the property should not be considered changed.
+ shouldRequestUpdate = false;
+ }
+ }
+ if (!this.isUpdatePending && shouldRequestUpdate) {
+ this.__updatePromise = this.__enqueueUpdate();
+ }
+ // Note, since this no longer returns a promise, in dev mode we return a
+ // thenable which warns if it's called.
+ return undefined;
+ }
+ /**
+ * Sets up the element to asynchronously update.
+ */
+ async __enqueueUpdate() {
+ this.isUpdatePending = true;
+ try {
+ // Ensure any previous update has resolved before updating.
+ // This `await` also ensures that property changes are batched.
+ await this.__updatePromise;
+ }
+ catch (e) {
+ // Refire any previous errors async so they do not disrupt the update
+ // cycle. Errors are refired so developers have a chance to observe
+ // them, and this can be done by implementing
+ // `window.onunhandledrejection`.
+ Promise.reject(e);
+ }
+ const result = this.scheduleUpdate();
+ // If `scheduleUpdate` returns a Promise, we await it. This is done to
+ // enable coordinating updates with a scheduler. Note, the result is
+ // checked to avoid delaying an additional microtask unless we need to.
+ if (result != null) {
+ await result;
+ }
+ return !this.isUpdatePending;
+ }
+ /**
+ * Schedules an element update. You can override this method to change the
+ * timing of updates by returning a Promise. The update will await the
+ * returned Promise, and you should resolve the Promise to allow the update
+ * to proceed. If this method is overridden, `super.scheduleUpdate()`
+ * must be called.
+ *
+ * For instance, to schedule updates to occur just before the next frame:
+ *
+ * ```ts
+ * override protected async scheduleUpdate(): Promise<unknown> {
+ * await new Promise((resolve) => requestAnimationFrame(() => resolve()));
+ * super.scheduleUpdate();
+ * }
+ * ```
+ * @category updates
+ */
+ scheduleUpdate() {
+ return this.performUpdate();
+ }
+ /**
+ * Performs an element update. Note, if an exception is thrown during the
+ * update, `firstUpdated` and `updated` will not be called.
+ *
+ * Call `performUpdate()` to immediately process a pending update. This should
+ * generally not be needed, but it can be done in rare cases when you need to
+ * update synchronously.
+ *
+ * Note: To ensure `performUpdate()` synchronously completes a pending update,
+ * it should not be overridden. In LitElement 2.x it was suggested to override
+ * `performUpdate()` to also customizing update scheduling. Instead, you should now
+ * override `scheduleUpdate()`. For backwards compatibility with LitElement 2.x,
+ * scheduling updates via `performUpdate()` continues to work, but will make
+ * also calling `performUpdate()` to synchronously process updates difficult.
+ *
+ * @category updates
+ */
+ performUpdate() {
+ var _b;
+ // Abort any update if one is not pending when this is called.
+ // This can happen if `performUpdate` is called early to "flush"
+ // the update.
+ if (!this.isUpdatePending) {
+ return;
+ }
+ // create renderRoot before first update.
+ if (!this.hasUpdated) ;
+ // Mixin instance properties once, if they exist.
+ if (this.__instanceProperties) {
+ // Use forEach so this works even if for/of loops are compiled to for loops
+ // expecting arrays
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ this.__instanceProperties.forEach((v, p) => (this[p] = v));
+ this.__instanceProperties = undefined;
+ }
+ let shouldUpdate = false;
+ const changedProperties = this._$changedProperties;
+ try {
+ shouldUpdate = this.shouldUpdate(changedProperties);
+ if (shouldUpdate) {
+ this.willUpdate(changedProperties);
+ (_b = this.__controllers) === null || _b === void 0 ? void 0 : _b.forEach((c) => { var _a; return (_a = c.hostUpdate) === null || _a === void 0 ? void 0 : _a.call(c); });
+ this.update(changedProperties);
+ }
+ else {
+ this.__markUpdated();
+ }
+ }
+ catch (e) {
+ // Prevent `firstUpdated` and `updated` from running when there's an
+ // update exception.
+ shouldUpdate = false;
+ // Ensure element can accept additional updates after an exception.
+ this.__markUpdated();
+ throw e;
+ }
+ // The update is no longer considered pending and further updates are now allowed.
+ if (shouldUpdate) {
+ this._$didUpdate(changedProperties);
+ }
+ }
+ /**
+ * Invoked before `update()` to compute values needed during the update.
+ *
+ * Implement `willUpdate` to compute property values that depend on other
+ * properties and are used in the rest of the update process.
+ *
+ * ```ts
+ * willUpdate(changedProperties) {
+ * // only need to check changed properties for an expensive computation.
+ * if (changedProperties.has('firstName') || changedProperties.has('lastName')) {
+ * this.sha = computeSHA(`${this.firstName} ${this.lastName}`);
+ * }
+ * }
+ *
+ * render() {
+ * return html`SHA: ${this.sha}`;
+ * }
+ * ```
+ *
+ * @category updates
+ */
+ willUpdate(_changedProperties) { }
+ // Note, this is an override point for polyfill-support.
+ // @internal
+ _$didUpdate(changedProperties) {
+ var _a;
+ (_a = this.__controllers) === null || _a === void 0 ? void 0 : _a.forEach((c) => { var _a; return (_a = c.hostUpdated) === null || _a === void 0 ? void 0 : _a.call(c); });
+ if (!this.hasUpdated) {
+ this.hasUpdated = true;
+ this.firstUpdated(changedProperties);
+ }
+ this.updated(changedProperties);
+ }
+ __markUpdated() {
+ this._$changedProperties = new Map();
+ this.isUpdatePending = false;
+ }
+ /**
+ * Returns a Promise that resolves when the element has completed updating.
+ * The Promise value is a boolean that is `true` if the element completed the
+ * update without triggering another update. The Promise result is `false` if
+ * a property was set inside `updated()`. If the Promise is rejected, an
+ * exception was thrown during the update.
+ *
+ * To await additional asynchronous work, override the `getUpdateComplete`
+ * method. For example, it is sometimes useful to await a rendered element
+ * before fulfilling this Promise. To do this, first await
+ * `super.getUpdateComplete()`, then any subsequent state.
+ *
+ * @return A promise of a boolean that resolves to true if the update completed
+ * without triggering another update.
+ * @category updates
+ */
+ get updateComplete() {
+ return this.getUpdateComplete();
+ }
+ /**
+ * Override point for the `updateComplete` promise.
+ *
+ * It is not safe to override the `updateComplete` getter directly due to a
+ * limitation in TypeScript which means it is not possible to call a
+ * superclass getter (e.g. `super.updateComplete.then(...)`) when the target
+ * language is ES5 (https://github.com/microsoft/TypeScript/issues/338).
+ * This method should be overridden instead. For example:
+ *
+ * ```ts
+ * class MyElement extends LitElement {
+ * override async getUpdateComplete() {
+ * const result = await super.getUpdateComplete();
+ * await this._myChild.updateComplete;
+ * return result;
+ * }
+ * }
+ * ```
+ *
+ * @return A promise of a boolean that resolves to true if the update completed
+ * without triggering another update.
+ * @category updates
+ */
+ getUpdateComplete() {
+ return this.__updatePromise;
+ }
+ /**
+ * Controls whether or not `update()` should be called when the element requests
+ * an update. By default, this method always returns `true`, but this can be
+ * customized to control when to update.
+ *
+ * @param _changedProperties Map of changed properties with old values
+ * @category updates
+ */
+ shouldUpdate(_changedProperties) {
+ return true;
+ }
+ /**
+ * Updates the element. This method reflects property values to attributes.
+ * It can be overridden to render and keep updated element DOM.
+ * Setting properties inside this method will *not* trigger
+ * another update.
+ *
+ * @param _changedProperties Map of changed properties with old values
+ * @category updates
+ */
+ update(_changedProperties) {
+ if (this.__reflectingProperties !== undefined) {
+ // Use forEach so this works even if for/of loops are compiled to for
+ // loops expecting arrays
+ this.__reflectingProperties.forEach((v, k) => this.__propertyToAttribute(k, this[k], v));
+ this.__reflectingProperties = undefined;
+ }
+ this.__markUpdated();
+ }
+ /**
+ * Invoked whenever the element is updated. Implement to perform
+ * post-updating tasks via DOM APIs, for example, focusing an element.
+ *
+ * Setting properties inside this method will trigger the element to update
+ * again after this update cycle completes.
+ *
+ * @param _changedProperties Map of changed properties with old values
+ * @category updates
+ */
+ updated(_changedProperties) { }
+ /**
+ * Invoked when the element is first updated. Implement to perform one time
+ * work on the element after update.
+ *
+ * ```ts
+ * firstUpdated() {
+ * this.renderRoot.getElementById('my-text-area').focus();
+ * }
+ * ```
+ *
+ * Setting properties inside this method will trigger the element to update
+ * again after this update cycle completes.
+ *
+ * @param _changedProperties Map of changed properties with old values
+ * @category updates
+ */
+ firstUpdated(_changedProperties) { }
+}
+_e = finalized;
+/**
+ * Marks class as having finished creating properties.
+ */
+ReactiveElement[_e] = true;
+/**
+ * Memoized list of all element properties, including any superclass properties.
+ * Created lazily on user subclasses when finalizing the class.
+ * @nocollapse
+ * @category properties
+ */
+ReactiveElement.elementProperties = new Map();
+/**
+ * Memoized list of all element styles.
+ * Created lazily on user subclasses when finalizing the class.
+ * @nocollapse
+ * @category styles
+ */
+ReactiveElement.elementStyles = [];
+/**
+ * Options used when calling `attachShadow`. Set this property to customize
+ * the options for the shadowRoot; for example, to create a closed
+ * shadowRoot: `{mode: 'closed'}`.
+ *
+ * Note, these options are used in `createRenderRoot`. If this method
+ * is customized, options should be respected if possible.
+ * @nocollapse
+ * @category rendering
+ */
+ReactiveElement.shadowRootOptions = { mode: 'open' };
+// Apply polyfills if available
+polyfillSupport$2 === null || polyfillSupport$2 === void 0 ? void 0 : polyfillSupport$2({ ReactiveElement });
+// IMPORTANT: do not change the property name or the assignment expression.
+// This line will be used in regexes to search for ReactiveElement usage.
+((_d$1 = global$1.reactiveElementVersions) !== null && _d$1 !== void 0 ? _d$1 : (global$1.reactiveElementVersions = [])).push('1.5.0');
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+var _d;
+// Use window for browser builds because IE11 doesn't have globalThis.
+const global = window;
+const __moz_domParser = new DOMParser();
+const wrap$1 = (node) => node;
+const trustedTypes = global.trustedTypes;
+/**
+ * Our TrustedTypePolicy for HTML which is declared using the html template
+ * tag function.
+ *
+ * That HTML is a developer-authored constant, and is parsed with innerHTML
+ * before any untrusted expressions have been mixed in. Therefor it is
+ * considered safe by construction.
+ */
+const policy = trustedTypes
+ ? trustedTypes.createPolicy('lit-html', {
+ createHTML: (s) => s,
+ })
+ : undefined;
+// Added to an attribute name to mark the attribute as bound so we can find
+// it easily.
+const boundAttributeSuffix = '$lit$';
+// This marker is used in many syntactic positions in HTML, so it must be
+// a valid element name and attribute name. We don't support dynamic names (yet)
+// but this at least ensures that the parse tree is closer to the template
+// intention.
+const marker = `lit$${String(Math.random()).slice(9)}$`;
+// String used to tell if a comment is a marker comment
+const markerMatch = '?' + marker;
+// Text used to insert a comment marker node. We use processing instruction
+// syntax because it's slightly smaller, but parses as a comment node.
+const nodeMarker = `<${markerMatch}>`;
+const d = document;
+// Creates a dynamic marker. We never have to search for these in the DOM.
+const createMarker$1 = (v = '') => d.createComment(v);
+const isPrimitive$1 = (value) => value === null || (typeof value != 'object' && typeof value != 'function');
+const isArray = Array.isArray;
+const isIterable = (value) => isArray(value) ||
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ typeof (value === null || value === void 0 ? void 0 : value[Symbol.iterator]) === 'function';
+const SPACE_CHAR = `[ \t\n\f\r]`;
+const ATTR_VALUE_CHAR = `[^ \t\n\f\r"'\`<>=]`;
+const NAME_CHAR = `[^\\s"'>=/]`;
+// These regexes represent the five parsing states that we care about in the
+// Template's HTML scanner. They match the *end* of the state they're named
+// after.
+// Depending on the match, we transition to a new state. If there's no match,
+// we stay in the same state.
+// Note that the regexes are stateful. We utilize lastIndex and sync it
+// across the multiple regexes used. In addition to the five regexes below
+// we also dynamically create a regex to find the matching end tags for raw
+// text elements.
+/**
+ * End of text is: `<` followed by:
+ * (comment start) or (tag) or (dynamic tag binding)
+ */
+const textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g;
+const COMMENT_START = 1;
+const TAG_NAME = 2;
+const DYNAMIC_TAG_NAME = 3;
+const commentEndRegex = /-->/g;
+/**
+ * Comments not started with <!--, like </{, can be ended by a single `>`
+ */
+const comment2EndRegex = />/g;
+/**
+ * The tagEnd regex matches the end of the "inside an opening" tag syntax
+ * position. It either matches a `>`, an attribute-like sequence, or the end
+ * of the string after a space (attribute-name position ending).
+ *
+ * See attributes in the HTML spec:
+ * https://www.w3.org/TR/html5/syntax.html#elements-attributes
+ *
+ * " \t\n\f\r" are HTML space characters:
+ * https://infra.spec.whatwg.org/#ascii-whitespace
+ *
+ * So an attribute is:
+ * * The name: any character except a whitespace character, ("), ('), ">",
+ * "=", or "/". Note: this is different from the HTML spec which also excludes control characters.
+ * * Followed by zero or more space characters
+ * * Followed by "="
+ * * Followed by zero or more space characters
+ * * Followed by:
+ * * Any character except space, ('), ("), "<", ">", "=", (`), or
+ * * (") then any non-("), or
+ * * (') then any non-(')
+ */
+const tagEndRegex = new RegExp(`>|${SPACE_CHAR}(?:(${NAME_CHAR}+)(${SPACE_CHAR}*=${SPACE_CHAR}*(?:${ATTR_VALUE_CHAR}|("|')|))|$)`, 'g');
+const ENTIRE_MATCH = 0;
+const ATTRIBUTE_NAME = 1;
+const SPACES_AND_EQUALS = 2;
+const QUOTE_CHAR = 3;
+const singleQuoteAttrEndRegex = /'/g;
+const doubleQuoteAttrEndRegex = /"/g;
+/**
+ * Matches the raw text elements.
+ *
+ * Comments are not parsed within raw text elements, so we need to search their
+ * text content for marker strings.
+ */
+const rawTextElement = /^(?:script|style|textarea|title)$/i;
+/** TemplateResult types */
+const HTML_RESULT$1 = 1;
+const SVG_RESULT$1 = 2;
+// TemplatePart types
+// IMPORTANT: these must match the values in PartType
+const ATTRIBUTE_PART = 1;
+const CHILD_PART = 2;
+const PROPERTY_PART = 3;
+const BOOLEAN_ATTRIBUTE_PART = 4;
+const EVENT_PART = 5;
+const ELEMENT_PART = 6;
+const COMMENT_PART = 7;
+/**
+ * Generates a template literal tag function that returns a TemplateResult with
+ * the given result type.
+ */
+const tag = (type) => (strings, ...values) => {
+ return {
+ // This property needs to remain unminified.
+ ['_$litType$']: type,
+ strings,
+ values,
+ };
+};
+/**
+ * Interprets a template literal as an HTML template that can efficiently
+ * render to and update a container.
+ *
+ * ```ts
+ * const header = (title: string) => html`<h1>${title}</h1>`;
+ * ```
+ *
+ * The `html` tag returns a description of the DOM to render as a value. It is
+ * lazy, meaning no work is done until the template is rendered. When rendering,
+ * if a template comes from the same expression as a previously rendered result,
+ * it's efficiently updated instead of replaced.
+ */
+const html$1 = tag(HTML_RESULT$1);
+/**
+ * Interprets a template literal as an SVG fragment that can efficiently
+ * render to and update a container.
+ *
+ * ```ts
+ * const rect = svg`<rect width="10" height="10"></rect>`;
+ *
+ * const myImage = html`
+ * <svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
+ * ${rect}
+ * </svg>`;
+ * ```
+ *
+ * The `svg` *tag function* should only be used for SVG fragments, or elements
+ * that would be contained **inside** an `<svg>` HTML element. A common error is
+ * placing an `<svg>` *element* in a template tagged with the `svg` tag
+ * function. The `<svg>` element is an HTML element and should be used within a
+ * template tagged with the {@linkcode html} tag function.
+ *
+ * In LitElement usage, it's invalid to return an SVG fragment from the
+ * `render()` method, as the SVG fragment will be contained within the element's
+ * shadow root and thus cannot be used within an `<svg>` HTML element.
+ */
+const svg$1 = tag(SVG_RESULT$1);
+/**
+ * A sentinel value that signals that a value was handled by a directive and
+ * should not be written to the DOM.
+ */
+const noChange = Symbol.for('lit-noChange');
+/**
+ * A sentinel value that signals a ChildPart to fully clear its content.
+ *
+ * ```ts
+ * const button = html`${
+ * user.isAdmin
+ * ? html`<button>DELETE</button>`
+ * : nothing
+ * }`;
+ * ```
+ *
+ * Prefer using `nothing` over other falsy values as it provides a consistent
+ * behavior between various expression binding contexts.
+ *
+ * In child expressions, `undefined`, `null`, `''`, and `nothing` all behave the
+ * same and render no nodes. In attribute expressions, `nothing` _removes_ the
+ * attribute, while `undefined` and `null` will render an empty string. In
+ * property expressions `nothing` becomes `undefined`.
+ */
+const nothing = Symbol.for('lit-nothing');
+/**
+ * The cache of prepared templates, keyed by the tagged TemplateStringsArray
+ * and _not_ accounting for the specific template tag used. This means that
+ * template tags cannot be dynamic - the must statically be one of html, svg,
+ * or attr. This restriction simplifies the cache lookup, which is on the hot
+ * path for rendering.
+ */
+const templateCache = new WeakMap();
+const walker = d.createTreeWalker(d, 129 /* NodeFilter.SHOW_{ELEMENT|COMMENT} */, null, false);
+/**
+ * Returns an HTML string for the given TemplateStringsArray and result type
+ * (HTML or SVG), along with the case-sensitive bound attribute names in
+ * template order. The HTML contains comment markers denoting the `ChildPart`s
+ * and suffixes on bound attributes denoting the `AttributeParts`.
+ *
+ * @param strings template strings array
+ * @param type HTML or SVG
+ * @return Array containing `[html, attrNames]` (array returned for terseness,
+ * to avoid object fields since this code is shared with non-minified SSR
+ * code)
+ */
+const getTemplateHtml = (strings, type) => {
+ // Insert makers into the template HTML to represent the position of
+ // bindings. The following code scans the template strings to determine the
+ // syntactic position of the bindings. They can be in text position, where
+ // we insert an HTML comment, attribute value position, where we insert a
+ // sentinel string and re-write the attribute name, or inside a tag where
+ // we insert the sentinel string.
+ const l = strings.length - 1;
+ // Stores the case-sensitive bound attribute names in the order of their
+ // parts. ElementParts are also reflected in this array as undefined
+ // rather than a string, to disambiguate from attribute bindings.
+ const attrNames = [];
+ let html = type === SVG_RESULT$1 ? '<svg>' : '';
+ // When we're inside a raw text tag (not it's text content), the regex
+ // will still be tagRegex so we can find attributes, but will switch to
+ // this regex when the tag ends.
+ let rawTextEndRegex;
+ // The current parsing state, represented as a reference to one of the
+ // regexes
+ let regex = textEndRegex;
+ for (let i = 0; i < l; i++) {
+ const s = strings[i];
+ // The index of the end of the last attribute name. When this is
+ // positive at end of a string, it means we're in an attribute value
+ // position and need to rewrite the attribute name.
+ // We also use a special value of -2 to indicate that we encountered
+ // the end of a string in attribute name position.
+ let attrNameEndIndex = -1;
+ let attrName;
+ let lastIndex = 0;
+ let match;
+ // The conditions in this loop handle the current parse state, and the
+ // assignments to the `regex` variable are the state transitions.
+ while (lastIndex < s.length) {
+ // Make sure we start searching from where we previously left off
+ regex.lastIndex = lastIndex;
+ match = regex.exec(s);
+ if (match === null) {
+ break;
+ }
+ lastIndex = regex.lastIndex;
+ if (regex === textEndRegex) {
+ if (match[COMMENT_START] === '!--') {
+ regex = commentEndRegex;
+ }
+ else if (match[COMMENT_START] !== undefined) {
+ // We started a weird comment, like </{
+ regex = comment2EndRegex;
+ }
+ else if (match[TAG_NAME] !== undefined) {
+ if (rawTextElement.test(match[TAG_NAME])) {
+ // Record if we encounter a raw-text element. We'll switch to
+ // this regex at the end of the tag.
+ rawTextEndRegex = new RegExp(`</${match[TAG_NAME]}`, 'g');
+ }
+ regex = tagEndRegex;
+ }
+ else if (match[DYNAMIC_TAG_NAME] !== undefined) {
+ regex = tagEndRegex;
+ }
+ }
+ else if (regex === tagEndRegex) {
+ if (match[ENTIRE_MATCH] === '>') {
+ // End of a tag. If we had started a raw-text element, use that
+ // regex
+ regex = rawTextEndRegex !== null && rawTextEndRegex !== void 0 ? rawTextEndRegex : textEndRegex;
+ // We may be ending an unquoted attribute value, so make sure we
+ // clear any pending attrNameEndIndex
+ attrNameEndIndex = -1;
+ }
+ else if (match[ATTRIBUTE_NAME] === undefined) {
+ // Attribute name position
+ attrNameEndIndex = -2;
+ }
+ else {
+ attrNameEndIndex = regex.lastIndex - match[SPACES_AND_EQUALS].length;
+ attrName = match[ATTRIBUTE_NAME];
+ regex =
+ match[QUOTE_CHAR] === undefined
+ ? tagEndRegex
+ : match[QUOTE_CHAR] === '"'
+ ? doubleQuoteAttrEndRegex
+ : singleQuoteAttrEndRegex;
+ }
+ }
+ else if (regex === doubleQuoteAttrEndRegex ||
+ regex === singleQuoteAttrEndRegex) {
+ regex = tagEndRegex;
+ }
+ else if (regex === commentEndRegex || regex === comment2EndRegex) {
+ regex = textEndRegex;
+ }
+ else {
+ // Not one of the five state regexes, so it must be the dynamically
+ // created raw text regex and we're at the close of that element.
+ regex = tagEndRegex;
+ rawTextEndRegex = undefined;
+ }
+ }
+ // We have four cases:
+ // 1. We're in text position, and not in a raw text element
+ // (regex === textEndRegex): insert a comment marker.
+ // 2. We have a non-negative attrNameEndIndex which means we need to
+ // rewrite the attribute name to add a bound attribute suffix.
+ // 3. We're at the non-first binding in a multi-binding attribute, use a
+ // plain marker.
+ // 4. We're somewhere else inside the tag. If we're in attribute name
+ // position (attrNameEndIndex === -2), add a sequential suffix to
+ // generate a unique attribute name.
+ // Detect a binding next to self-closing tag end and insert a space to
+ // separate the marker from the tag end:
+ const end = regex === tagEndRegex && strings[i + 1].startsWith('/>') ? ' ' : '';
+ html +=
+ regex === textEndRegex
+ ? s + nodeMarker
+ : attrNameEndIndex >= 0
+ ? (attrNames.push(attrName),
+ s.slice(0, attrNameEndIndex) +
+ boundAttributeSuffix +
+ s.slice(attrNameEndIndex)) +
+ marker +
+ end
+ : s +
+ marker +
+ (attrNameEndIndex === -2 ? (attrNames.push(undefined), i) : end);
+ }
+ const htmlResult = html + (strings[l] || '<?>') + (type === SVG_RESULT$1 ? '</svg>' : '');
+ // A security check to prevent spoofing of Lit template results.
+ // In the future, we may be able to replace this with Array.isTemplateObject,
+ // though we might need to make that check inside of the html and svg
+ // functions, because precompiled templates don't come in as
+ // TemplateStringArray objects.
+ if (!Array.isArray(strings) || !strings.hasOwnProperty('raw')) {
+ let message = 'invalid template strings array';
+ throw new Error(message);
+ }
+ // Returned as an array for terseness
+ return [
+ policy !== undefined
+ ? policy.createHTML(htmlResult)
+ : htmlResult,
+ attrNames,
+ ];
+};
+class Template {
+ constructor(
+ // This property needs to remain unminified.
+ { strings, ['_$litType$']: type }, options) {
+ /** @internal */
+ this.parts = [];
+ let node;
+ let nodeIndex = 0;
+ let attrNameIndex = 0;
+ const partCount = strings.length - 1;
+ const parts = this.parts;
+ // Create template element
+ const [html, attrNames] = getTemplateHtml(strings, type);
+ this.el = Template.createElement(html, options);
+ walker.currentNode = this.el.content;
+ // Reparent SVG nodes into template root
+ if (type === SVG_RESULT$1) {
+ const content = this.el.content;
+ const svgElement = content.firstChild;
+ svgElement.remove();
+ content.append(...svgElement.childNodes);
+ }
+ // Walk the template to find binding markers and create TemplateParts
+ while ((node = walker.nextNode()) !== null && parts.length < partCount) {
+ if (node.nodeType === 1) {
+ // TODO (justinfagnani): for attempted dynamic tag names, we don't
+ // increment the bindingIndex, and it'll be off by 1 in the element
+ // and off by two after it.
+ if (node.hasAttributes()) {
+ // We defer removing bound attributes because on IE we might not be
+ // iterating attributes in their template order, and would sometimes
+ // remove an attribute that we still need to create a part for.
+ const attrsToRemove = [];
+ for (const name of node.getAttributeNames()) {
+ // `name` is the name of the attribute we're iterating over, but not
+ // _neccessarily_ the name of the attribute we will create a part
+ // for. They can be different in browsers that don't iterate on
+ // attributes in source order. In that case the attrNames array
+ // contains the attribute name we'll process next. We only need the
+ // attribute name here to know if we should process a bound attribute
+ // on this element.
+ if (name.endsWith(boundAttributeSuffix) ||
+ name.startsWith(marker)) {
+ const realName = attrNames[attrNameIndex++];
+ attrsToRemove.push(name);
+ if (realName !== undefined) {
+ // Lowercase for case-sensitive SVG attributes like viewBox
+ const value = node.getAttribute(realName.toLowerCase() + boundAttributeSuffix);
+ const statics = value.split(marker);
+ const m = /([.?@])?(.*)/.exec(realName);
+ parts.push({
+ type: ATTRIBUTE_PART,
+ index: nodeIndex,
+ name: m[2],
+ strings: statics,
+ ctor: m[1] === '.'
+ ? PropertyPart
+ : m[1] === '?'
+ ? BooleanAttributePart
+ : m[1] === '@'
+ ? EventPart
+ : AttributePart,
+ });
+ }
+ else {
+ parts.push({
+ type: ELEMENT_PART,
+ index: nodeIndex,
+ });
+ }
+ }
+ }
+ for (const name of attrsToRemove) {
+ node.removeAttribute(name);
+ }
+ }
+ // TODO (justinfagnani): benchmark the regex against testing for each
+ // of the 3 raw text element names.
+ if (rawTextElement.test(node.tagName)) {
+ // For raw text elements we need to split the text content on
+ // markers, create a Text node for each segment, and create
+ // a TemplatePart for each marker.
+ const strings = node.textContent.split(marker);
+ const lastIndex = strings.length - 1;
+ if (lastIndex > 0) {
+ node.textContent = trustedTypes
+ ? trustedTypes.emptyScript
+ : '';
+ // Generate a new text node for each literal section
+ // These nodes are also used as the markers for node parts
+ // We can't use empty text nodes as markers because they're
+ // normalized when cloning in IE (could simplify when
+ // IE is no longer supported)
+ for (let i = 0; i < lastIndex; i++) {
+ node.append(strings[i], createMarker$1());
+ // Walk past the marker node we just added
+ walker.nextNode();
+ parts.push({ type: CHILD_PART, index: ++nodeIndex });
+ }
+ // Note because this marker is added after the walker's current
+ // node, it will be walked to in the outer loop (and ignored), so
+ // we don't need to adjust nodeIndex here
+ node.append(strings[lastIndex], createMarker$1());
+ }
+ }
+ }
+ else if (node.nodeType === 8) {
+ const data = node.data;
+ if (data === markerMatch) {
+ parts.push({ type: CHILD_PART, index: nodeIndex });
+ }
+ else {
+ let i = -1;
+ while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
+ // Comment node has a binding marker inside, make an inactive part
+ // The binding won't work, but subsequent bindings will
+ parts.push({ type: COMMENT_PART, index: nodeIndex });
+ // Move to the end of the match
+ i += marker.length - 1;
+ }
+ }
+ }
+ nodeIndex++;
+ }
+ }
+ // Overridden via `litHtmlPolyfillSupport` to provide platform support.
+ /** @nocollapse */
+ static createElement(html, _options) {
+ const doc = __moz_domParser.parseFromString(`<template>${html}</template>`, 'text/html');
+ return document.importNode(doc.querySelector('template'), true);
+ }
+}
+function resolveDirective(part, value, parent = part, attributeIndex) {
+ var _a, _b, _c;
+ var _d;
+ // Bail early if the value is explicitly noChange. Note, this means any
+ // nested directive is still attached and is not run.
+ if (value === noChange) {
+ return value;
+ }
+ let currentDirective = attributeIndex !== undefined
+ ? (_a = parent.__directives) === null || _a === void 0 ? void 0 : _a[attributeIndex]
+ : parent.__directive;
+ const nextDirectiveConstructor = isPrimitive$1(value)
+ ? undefined
+ : // This property needs to remain unminified.
+ value['_$litDirective$'];
+ if ((currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective.constructor) !== nextDirectiveConstructor) {
+ // This property needs to remain unminified.
+ (_b = currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective['_$notifyDirectiveConnectionChanged']) === null || _b === void 0 ? void 0 : _b.call(currentDirective, false);
+ if (nextDirectiveConstructor === undefined) {
+ currentDirective = undefined;
+ }
+ else {
+ currentDirective = new nextDirectiveConstructor(part);
+ currentDirective._$initialize(part, parent, attributeIndex);
+ }
+ if (attributeIndex !== undefined) {
+ ((_c = (_d = parent).__directives) !== null && _c !== void 0 ? _c : (_d.__directives = []))[attributeIndex] =
+ currentDirective;
+ }
+ else {
+ parent.__directive = currentDirective;
+ }
+ }
+ if (currentDirective !== undefined) {
+ value = resolveDirective(part, currentDirective._$resolve(part, value.values), currentDirective, attributeIndex);
+ }
+ return value;
+}
+/**
+ * An updateable instance of a Template. Holds references to the Parts used to
+ * update the template instance.
+ */
+class TemplateInstance {
+ constructor(template, parent) {
+ /** @internal */
+ this._parts = [];
+ /** @internal */
+ this._$disconnectableChildren = undefined;
+ this._$template = template;
+ this._$parent = parent;
+ }
+ // Called by ChildPart parentNode getter
+ get parentNode() {
+ return this._$parent.parentNode;
+ }
+ // See comment in Disconnectable interface for why this is a getter
+ get _$isConnected() {
+ return this._$parent._$isConnected;
+ }
+ // This method is separate from the constructor because we need to return a
+ // DocumentFragment and we don't want to hold onto it with an instance field.
+ _clone(options) {
+ var _a;
+ const { el: { content }, parts: parts, } = this._$template;
+ const fragment = ((_a = options === null || options === void 0 ? void 0 : options.creationScope) !== null && _a !== void 0 ? _a : d).importNode(content, true);
+ walker.currentNode = fragment;
+ let node = walker.nextNode();
+ let nodeIndex = 0;
+ let partIndex = 0;
+ let templatePart = parts[0];
+ while (templatePart !== undefined) {
+ if (nodeIndex === templatePart.index) {
+ let part;
+ if (templatePart.type === CHILD_PART) {
+ part = new ChildPart$1(node, node.nextSibling, this, options);
+ }
+ else if (templatePart.type === ATTRIBUTE_PART) {
+ part = new templatePart.ctor(node, templatePart.name, templatePart.strings, this, options);
+ }
+ else if (templatePart.type === ELEMENT_PART) {
+ part = new ElementPart(node, this, options);
+ }
+ this._parts.push(part);
+ templatePart = parts[++partIndex];
+ }
+ if (nodeIndex !== (templatePart === null || templatePart === void 0 ? void 0 : templatePart.index)) {
+ node = walker.nextNode();
+ nodeIndex++;
+ }
+ }
+ return fragment;
+ }
+ _update(values) {
+ let i = 0;
+ for (const part of this._parts) {
+ if (part !== undefined) {
+ if (part.strings !== undefined) {
+ part._$setValue(values, part, i);
+ // The number of values the part consumes is part.strings.length - 1
+ // since values are in between template spans. We increment i by 1
+ // later in the loop, so increment it by part.strings.length - 2 here
+ i += part.strings.length - 2;
+ }
+ else {
+ part._$setValue(values[i]);
+ }
+ }
+ i++;
+ }
+ }
+}
+class ChildPart$1 {
+ constructor(startNode, endNode, parent, options) {
+ var _a;
+ this.type = CHILD_PART;
+ this._$committedValue = nothing;
+ // The following fields will be patched onto ChildParts when required by
+ // AsyncDirective
+ /** @internal */
+ this._$disconnectableChildren = undefined;
+ this._$startNode = startNode;
+ this._$endNode = endNode;
+ this._$parent = parent;
+ this.options = options;
+ // Note __isConnected is only ever accessed on RootParts (i.e. when there is
+ // no _$parent); the value on a non-root-part is "don't care", but checking
+ // for parent would be more code
+ this.__isConnected = (_a = options === null || options === void 0 ? void 0 : options.isConnected) !== null && _a !== void 0 ? _a : true;
+ }
+ // See comment in Disconnectable interface for why this is a getter
+ get _$isConnected() {
+ var _a, _b;
+ // ChildParts that are not at the root should always be created with a
+ // parent; only RootChildNode's won't, so they return the local isConnected
+ // state
+ return (_b = (_a = this._$parent) === null || _a === void 0 ? void 0 : _a._$isConnected) !== null && _b !== void 0 ? _b : this.__isConnected;
+ }
+ /**
+ * The parent node into which the part renders its content.
+ *
+ * A ChildPart's content consists of a range of adjacent child nodes of
+ * `.parentNode`, possibly bordered by 'marker nodes' (`.startNode` and
+ * `.endNode`).
+ *
+ * - If both `.startNode` and `.endNode` are non-null, then the part's content
+ * consists of all siblings between `.startNode` and `.endNode`, exclusively.
+ *
+ * - If `.startNode` is non-null but `.endNode` is null, then the part's
+ * content consists of all siblings following `.startNode`, up to and
+ * including the last child of `.parentNode`. If `.endNode` is non-null, then
+ * `.startNode` will always be non-null.
+ *
+ * - If both `.endNode` and `.startNode` are null, then the part's content
+ * consists of all child nodes of `.parentNode`.
+ */
+ get parentNode() {
+ let parentNode = wrap$1(this._$startNode).parentNode;
+ const parent = this._$parent;
+ if (parent !== undefined &&
+ parentNode.nodeType === 11 /* Node.DOCUMENT_FRAGMENT */) {
+ // If the parentNode is a DocumentFragment, it may be because the DOM is
+ // still in the cloned fragment during initial render; if so, get the real
+ // parentNode the part will be committed into by asking the parent.
+ parentNode = parent.parentNode;
+ }
+ return parentNode;
+ }
+ /**
+ * The part's leading marker node, if any. See `.parentNode` for more
+ * information.
+ */
+ get startNode() {
+ return this._$startNode;
+ }
+ /**
+ * The part's trailing marker node, if any. See `.parentNode` for more
+ * information.
+ */
+ get endNode() {
+ return this._$endNode;
+ }
+ _$setValue(value, directiveParent = this) {
+ value = resolveDirective(this, value, directiveParent);
+ if (isPrimitive$1(value)) {
+ // Non-rendering child values. It's important that these do not render
+ // empty text nodes to avoid issues with preventing default <slot>
+ // fallback content.
+ if (value === nothing || value == null || value === '') {
+ if (this._$committedValue !== nothing) {
+ this._$clear();
+ }
+ this._$committedValue = nothing;
+ }
+ else if (value !== this._$committedValue && value !== noChange) {
+ this._commitText(value);
+ }
+ // This property needs to remain unminified.
+ }
+ else if (value['_$litType$'] !== undefined) {
+ this._commitTemplateResult(value);
+ }
+ else if (value.nodeType !== undefined) {
+ this._commitNode(value);
+ }
+ else if (isIterable(value)) {
+ this._commitIterable(value);
+ }
+ else {
+ // Fallback, will render the string representation
+ this._commitText(value);
+ }
+ }
+ _insert(node, ref = this._$endNode) {
+ return wrap$1(wrap$1(this._$startNode).parentNode).insertBefore(node, ref);
+ }
+ _commitNode(value) {
+ if (this._$committedValue !== value) {
+ this._$clear();
+ this._$committedValue = this._insert(value);
+ }
+ }
+ _commitText(value) {
+ // If the committed value is a primitive it means we called _commitText on
+ // the previous render, and we know that this._$startNode.nextSibling is a
+ // Text node. We can now just replace the text content (.data) of the node.
+ if (this._$committedValue !== nothing &&
+ isPrimitive$1(this._$committedValue)) {
+ const node = wrap$1(this._$startNode).nextSibling;
+ node.data = value;
+ }
+ else {
+ {
+ this._commitNode(d.createTextNode(value));
+ }
+ }
+ this._$committedValue = value;
+ }
+ _commitTemplateResult(result) {
+ var _a;
+ // This property needs to remain unminified.
+ const { values, ['_$litType$']: type } = result;
+ // If $litType$ is a number, result is a plain TemplateResult and we get
+ // the template from the template cache. If not, result is a
+ // CompiledTemplateResult and _$litType$ is a CompiledTemplate and we need
+ // to create the <template> element the first time we see it.
+ const template = typeof type === 'number'
+ ? this._$getTemplate(result)
+ : (type.el === undefined &&
+ (type.el = Template.createElement(type.h, this.options)),
+ type);
+ if (((_a = this._$committedValue) === null || _a === void 0 ? void 0 : _a._$template) === template) {
+ this._$committedValue._update(values);
+ }
+ else {
+ const instance = new TemplateInstance(template, this);
+ const fragment = instance._clone(this.options);
+ instance._update(values);
+ this._commitNode(fragment);
+ this._$committedValue = instance;
+ }
+ }
+ // Overridden via `litHtmlPolyfillSupport` to provide platform support.
+ /** @internal */
+ _$getTemplate(result) {
+ let template = templateCache.get(result.strings);
+ if (template === undefined) {
+ templateCache.set(result.strings, (template = new Template(result)));
+ }
+ return template;
+ }
+ _commitIterable(value) {
+ // For an Iterable, we create a new InstancePart per item, then set its
+ // value to the item. This is a little bit of overhead for every item in
+ // an Iterable, but it lets us recurse easily and efficiently update Arrays
+ // of TemplateResults that will be commonly returned from expressions like:
+ // array.map((i) => html`${i}`), by reusing existing TemplateInstances.
+ // If value is an array, then the previous render was of an
+ // iterable and value will contain the ChildParts from the previous
+ // render. If value is not an array, clear this part and make a new
+ // array for ChildParts.
+ if (!isArray(this._$committedValue)) {
+ this._$committedValue = [];
+ this._$clear();
+ }
+ // Lets us keep track of how many items we stamped so we can clear leftover
+ // items from a previous render
+ const itemParts = this._$committedValue;
+ let partIndex = 0;
+ let itemPart;
+ for (const item of value) {
+ if (partIndex === itemParts.length) {
+ // If no existing part, create a new one
+ // TODO (justinfagnani): test perf impact of always creating two parts
+ // instead of sharing parts between nodes
+ // https://github.com/lit/lit/issues/1266
+ itemParts.push((itemPart = new ChildPart$1(this._insert(createMarker$1()), this._insert(createMarker$1()), this, this.options)));
+ }
+ else {
+ // Reuse an existing part
+ itemPart = itemParts[partIndex];
+ }
+ itemPart._$setValue(item);
+ partIndex++;
+ }
+ if (partIndex < itemParts.length) {
+ // itemParts always have end nodes
+ this._$clear(itemPart && wrap$1(itemPart._$endNode).nextSibling, partIndex);
+ // Truncate the parts array so _value reflects the current state
+ itemParts.length = partIndex;
+ }
+ }
+ /**
+ * Removes the nodes contained within this Part from the DOM.
+ *
+ * @param start Start node to clear from, for clearing a subset of the part's
+ * DOM (used when truncating iterables)
+ * @param from When `start` is specified, the index within the iterable from
+ * which ChildParts are being removed, used for disconnecting directives in
+ * those Parts.
+ *
+ * @internal
+ */
+ _$clear(start = wrap$1(this._$startNode).nextSibling, from) {
+ var _a;
+ (_a = this._$notifyConnectionChanged) === null || _a === void 0 ? void 0 : _a.call(this, false, true, from);
+ while (start && start !== this._$endNode) {
+ const n = wrap$1(start).nextSibling;
+ wrap$1(start).remove();
+ start = n;
+ }
+ }
+ /**
+ * Implementation of RootPart's `isConnected`. Note that this metod
+ * should only be called on `RootPart`s (the `ChildPart` returned from a
+ * top-level `render()` call). It has no effect on non-root ChildParts.
+ * @param isConnected Whether to set
+ * @internal
+ */
+ setConnected(isConnected) {
+ var _a;
+ if (this._$parent === undefined) {
+ this.__isConnected = isConnected;
+ (_a = this._$notifyConnectionChanged) === null || _a === void 0 ? void 0 : _a.call(this, isConnected);
+ }
+ }
+}
+class AttributePart {
+ constructor(element, name, strings, parent, options) {
+ this.type = ATTRIBUTE_PART;
+ /** @internal */
+ this._$committedValue = nothing;
+ /** @internal */
+ this._$disconnectableChildren = undefined;
+ this.element = element;
+ this.name = name;
+ this._$parent = parent;
+ this.options = options;
+ if (strings.length > 2 || strings[0] !== '' || strings[1] !== '') {
+ this._$committedValue = new Array(strings.length - 1).fill(new String());
+ this.strings = strings;
+ }
+ else {
+ this._$committedValue = nothing;
+ }
+ }
+ get tagName() {
+ return this.element.tagName;
+ }
+ // See comment in Disconnectable interface for why this is a getter
+ get _$isConnected() {
+ return this._$parent._$isConnected;
+ }
+ /**
+ * Sets the value of this part by resolving the value from possibly multiple
+ * values and static strings and committing it to the DOM.
+ * If this part is single-valued, `this._strings` will be undefined, and the
+ * method will be called with a single value argument. If this part is
+ * multi-value, `this._strings` will be defined, and the method is called
+ * with the value array of the part's owning TemplateInstance, and an offset
+ * into the value array from which the values should be read.
+ * This method is overloaded this way to eliminate short-lived array slices
+ * of the template instance values, and allow a fast-path for single-valued
+ * parts.
+ *
+ * @param value The part value, or an array of values for multi-valued parts
+ * @param valueIndex the index to start reading values from. `undefined` for
+ * single-valued parts
+ * @param noCommit causes the part to not commit its value to the DOM. Used
+ * in hydration to prime attribute parts with their first-rendered value,
+ * but not set the attribute, and in SSR to no-op the DOM operation and
+ * capture the value for serialization.
+ *
+ * @internal
+ */
+ _$setValue(value, directiveParent = this, valueIndex, noCommit) {
+ const strings = this.strings;
+ // Whether any of the values has changed, for dirty-checking
+ let change = false;
+ if (strings === undefined) {
+ // Single-value binding case
+ value = resolveDirective(this, value, directiveParent, 0);
+ change =
+ !isPrimitive$1(value) ||
+ (value !== this._$committedValue && value !== noChange);
+ if (change) {
+ this._$committedValue = value;
+ }
+ }
+ else {
+ // Interpolation case
+ const values = value;
+ value = strings[0];
+ let i, v;
+ for (i = 0; i < strings.length - 1; i++) {
+ v = resolveDirective(this, values[valueIndex + i], directiveParent, i);
+ if (v === noChange) {
+ // If the user-provided value is `noChange`, use the previous value
+ v = this._$committedValue[i];
+ }
+ change || (change = !isPrimitive$1(v) || v !== this._$committedValue[i]);
+ if (v === nothing) {
+ value = nothing;
+ }
+ else if (value !== nothing) {
+ value += (v !== null && v !== void 0 ? v : '') + strings[i + 1];
+ }
+ // We always record each value, even if one is `nothing`, for future
+ // change detection.
+ this._$committedValue[i] = v;
+ }
+ }
+ if (change && !noCommit) {
+ this._commitValue(value);
+ }
+ }
+ /** @internal */
+ _commitValue(value) {
+ if (value === nothing) {
+ wrap$1(this.element).removeAttribute(this.name);
+ }
+ else {
+ wrap$1(this.element).setAttribute(this.name, (value !== null && value !== void 0 ? value : ''));
+ }
+ }
+}
+class PropertyPart extends AttributePart {
+ constructor() {
+ super(...arguments);
+ this.type = PROPERTY_PART;
+ }
+ /** @internal */
+ _commitValue(value) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ this.element[this.name] = value === nothing ? undefined : value;
+ }
+}
+// Temporary workaround for https://crbug.com/993268
+// Currently, any attribute starting with "on" is considered to be a
+// TrustedScript source. Such boolean attributes must be set to the equivalent
+// trusted emptyScript value.
+const emptyStringForBooleanAttribute = trustedTypes
+ ? trustedTypes.emptyScript
+ : '';
+class BooleanAttributePart extends AttributePart {
+ constructor() {
+ super(...arguments);
+ this.type = BOOLEAN_ATTRIBUTE_PART;
+ }
+ /** @internal */
+ _commitValue(value) {
+ if (value && value !== nothing) {
+ wrap$1(this.element).setAttribute(this.name, emptyStringForBooleanAttribute);
+ }
+ else {
+ wrap$1(this.element).removeAttribute(this.name);
+ }
+ }
+}
+class EventPart extends AttributePart {
+ constructor(element, name, strings, parent, options) {
+ super(element, name, strings, parent, options);
+ this.type = EVENT_PART;
+ }
+ // EventPart does not use the base _$setValue/_resolveValue implementation
+ // since the dirty checking is more complex
+ /** @internal */
+ _$setValue(newListener, directiveParent = this) {
+ var _a;
+ newListener =
+ (_a = resolveDirective(this, newListener, directiveParent, 0)) !== null && _a !== void 0 ? _a : nothing;
+ if (newListener === noChange) {
+ return;
+ }
+ const oldListener = this._$committedValue;
+ // If the new value is nothing or any options change we have to remove the
+ // part as a listener.
+ const shouldRemoveListener = (newListener === nothing && oldListener !== nothing) ||
+ newListener.capture !==
+ oldListener.capture ||
+ newListener.once !==
+ oldListener.once ||
+ newListener.passive !==
+ oldListener.passive;
+ // If the new value is not nothing and we removed the listener, we have
+ // to add the part as a listener.
+ const shouldAddListener = newListener !== nothing &&
+ (oldListener === nothing || shouldRemoveListener);
+ if (shouldRemoveListener) {
+ this.element.removeEventListener(this.name, this, oldListener);
+ }
+ if (shouldAddListener) {
+ // Beware: IE11 and Chrome 41 don't like using the listener as the
+ // options object. Figure out how to deal w/ this in IE11 - maybe
+ // patch addEventListener?
+ this.element.addEventListener(this.name, this, newListener);
+ }
+ this._$committedValue = newListener;
+ }
+ handleEvent(event) {
+ var _a, _b;
+ if (typeof this._$committedValue === 'function') {
+ this._$committedValue.call((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.host) !== null && _b !== void 0 ? _b : this.element, event);
+ }
+ else {
+ this._$committedValue.handleEvent(event);
+ }
+ }
+}
+class ElementPart {
+ constructor(element, parent, options) {
+ this.element = element;
+ this.type = ELEMENT_PART;
+ /** @internal */
+ this._$disconnectableChildren = undefined;
+ this._$parent = parent;
+ this.options = options;
+ }
+ // See comment in Disconnectable interface for why this is a getter
+ get _$isConnected() {
+ return this._$parent._$isConnected;
+ }
+ _$setValue(value) {
+ resolveDirective(this, value);
+ }
+}
+/**
+ * END USERS SHOULD NOT RELY ON THIS OBJECT.
+ *
+ * Private exports for use by other Lit packages, not intended for use by
+ * external users.
+ *
+ * We currently do not make a mangled rollup build of the lit-ssr code. In order
+ * to keep a number of (otherwise private) top-level exports mangled in the
+ * client side code, we export a _$LH object containing those members (or
+ * helper methods for accessing private fields of those members), and then
+ * re-export them for use in lit-ssr. This keeps lit-ssr agnostic to whether the
+ * client-side code is being used in `dev` mode or `prod` mode.
+ *
+ * This has a unique name, to disambiguate it from private exports in
+ * lit-element, which re-exports all of lit-html.
+ *
+ * @private
+ */
+const _$LH = {
+ // Used in lit-ssr
+ _boundAttributeSuffix: boundAttributeSuffix,
+ _marker: marker,
+ _markerMatch: markerMatch,
+ _HTML_RESULT: HTML_RESULT$1,
+ _getTemplateHtml: getTemplateHtml,
+ // Used in hydrate
+ _TemplateInstance: TemplateInstance,
+ _isIterable: isIterable,
+ _resolveDirective: resolveDirective,
+ // Used in tests and private-ssr-support
+ _ChildPart: ChildPart$1,
+ _AttributePart: AttributePart,
+ _BooleanAttributePart: BooleanAttributePart,
+ _EventPart: EventPart,
+ _PropertyPart: PropertyPart,
+ _ElementPart: ElementPart,
+};
+// Apply polyfills if available
+const polyfillSupport$1 = global.litHtmlPolyfillSupport;
+polyfillSupport$1 === null || polyfillSupport$1 === void 0 ? void 0 : polyfillSupport$1(Template, ChildPart$1);
+// IMPORTANT: do not change the property name or the assignment expression.
+// This line will be used in regexes to search for lit-html usage.
+((_d = global.litHtmlVersions) !== null && _d !== void 0 ? _d : (global.litHtmlVersions = [])).push('2.5.0');
+/**
+ * Renders a value, usually a lit-html TemplateResult, to the container.
+ *
+ * This example renders the text "Hello, Zoe!" inside a paragraph tag, appending
+ * it to the container `document.body`.
+ *
+ * ```js
+ * import {html, render} from 'lit';
+ *
+ * const name = "Zoe";
+ * render(html`<p>Hello, ${name}!</p>`, document.body);
+ * ```
+ *
+ * @param value Any [renderable
+ * value](https://lit.dev/docs/templates/expressions/#child-expressions),
+ * typically a {@linkcode TemplateResult} created by evaluating a template tag
+ * like {@linkcode html} or {@linkcode svg}.
+ * @param container A DOM container to render to. The first render will append
+ * the rendered value to the container, and subsequent renders will
+ * efficiently update the rendered value if the same result type was
+ * previously rendered there.
+ * @param options See {@linkcode RenderOptions} for options documentation.
+ * @see
+ * {@link https://lit.dev/docs/libraries/standalone-templates/#rendering-lit-html-templates| Rendering Lit HTML Templates}
+ */
+const render = (value, container, options) => {
+ var _a, _b;
+ const partOwnerNode = (_a = options === null || options === void 0 ? void 0 : options.renderBefore) !== null && _a !== void 0 ? _a : container;
+ // This property needs to remain unminified.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ let part = partOwnerNode['_$litPart$'];
+ if (part === undefined) {
+ const endNode = (_b = options === null || options === void 0 ? void 0 : options.renderBefore) !== null && _b !== void 0 ? _b : null;
+ // This property needs to remain unminified.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ partOwnerNode['_$litPart$'] = part = new ChildPart$1(container.insertBefore(createMarker$1(), endNode), endNode, undefined, options !== null && options !== void 0 ? options : {});
+ }
+ part._$setValue(value);
+ return part;
+};
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+var _b, _c;
+// For backwards compatibility export ReactiveElement as UpdatingElement. Note,
+// IE transpilation requires exporting like this.
+const UpdatingElement = ReactiveElement;
+/**
+ * Base element class that manages element properties and attributes, and
+ * renders a lit-html template.
+ *
+ * To define a component, subclass `LitElement` and implement a
+ * `render` method to provide the component's template. Define properties
+ * using the {@linkcode LitElement.properties properties} property or the
+ * {@linkcode property} decorator.
+ */
+class LitElement extends ReactiveElement {
+ constructor() {
+ super(...arguments);
+ /**
+ * @category rendering
+ */
+ this.renderOptions = { host: this };
+ this.__childPart = undefined;
+ }
+ /**
+ * @category rendering
+ */
+ createRenderRoot() {
+ var _a;
+ var _b;
+ const renderRoot = super.createRenderRoot();
+ // When adoptedStyleSheets are shimmed, they are inserted into the
+ // shadowRoot by createRenderRoot. Adjust the renderBefore node so that
+ // any styles in Lit content render before adoptedStyleSheets. This is
+ // important so that adoptedStyleSheets have precedence over styles in
+ // the shadowRoot.
+ (_a = (_b = this.renderOptions).renderBefore) !== null && _a !== void 0 ? _a : (_b.renderBefore = renderRoot.firstChild);
+ return renderRoot;
+ }
+ /**
+ * Updates the element. This method reflects property values to attributes
+ * and calls `render` to render DOM via lit-html. Setting properties inside
+ * this method will *not* trigger another update.
+ * @param changedProperties Map of changed properties with old values
+ * @category updates
+ */
+ update(changedProperties) {
+ // Setting properties in `render` should not trigger an update. Since
+ // updates are allowed after super.update, it's important to call `render`
+ // before that.
+ const value = this.render();
+ if (!this.hasUpdated) {
+ this.renderOptions.isConnected = this.isConnected;
+ }
+ super.update(changedProperties);
+ this.__childPart = render(value, this.renderRoot, this.renderOptions);
+ }
+ /**
+ * Invoked when the component is added to the document's DOM.
+ *
+ * In `connectedCallback()` you should setup tasks that should only occur when
+ * the element is connected to the document. The most common of these is
+ * adding event listeners to nodes external to the element, like a keydown
+ * event handler added to the window.
+ *
+ * ```ts
+ * connectedCallback() {
+ * super.connectedCallback();
+ * addEventListener('keydown', this._handleKeydown);
+ * }
+ * ```
+ *
+ * Typically, anything done in `connectedCallback()` should be undone when the
+ * element is disconnected, in `disconnectedCallback()`.
+ *
+ * @category lifecycle
+ */
+ connectedCallback() {
+ var _a;
+ super.connectedCallback();
+ (_a = this.__childPart) === null || _a === void 0 ? void 0 : _a.setConnected(true);
+ }
+ /**
+ * Invoked when the component is removed from the document's DOM.
+ *
+ * This callback is the main signal to the element that it may no longer be
+ * used. `disconnectedCallback()` should ensure that nothing is holding a
+ * reference to the element (such as event listeners added to nodes external
+ * to the element), so that it is free to be garbage collected.
+ *
+ * ```ts
+ * disconnectedCallback() {
+ * super.disconnectedCallback();
+ * window.removeEventListener('keydown', this._handleKeydown);
+ * }
+ * ```
+ *
+ * An element may be re-connected after being disconnected.
+ *
+ * @category lifecycle
+ */
+ disconnectedCallback() {
+ var _a;
+ super.disconnectedCallback();
+ (_a = this.__childPart) === null || _a === void 0 ? void 0 : _a.setConnected(false);
+ }
+ /**
+ * Invoked on each update to perform rendering tasks. This method may return
+ * any value renderable by lit-html's `ChildPart` - typically a
+ * `TemplateResult`. Setting properties inside this method will *not* trigger
+ * the element to update.
+ * @category rendering
+ */
+ render() {
+ return noChange;
+ }
+}
+/**
+ * Ensure this class is marked as `finalized` as an optimization ensuring
+ * it will not needlessly try to `finalize`.
+ *
+ * Note this property name is a string to prevent breaking Closure JS Compiler
+ * optimizations. See @lit/reactive-element for more information.
+ */
+LitElement['finalized'] = true;
+// This property needs to remain unminified.
+LitElement['_$litElement$'] = true;
+// Install hydration if available
+(_b = globalThis.litElementHydrateSupport) === null || _b === void 0 ? void 0 : _b.call(globalThis, { LitElement });
+// Apply polyfills if available
+const polyfillSupport = globalThis.litElementPolyfillSupport;
+polyfillSupport === null || polyfillSupport === void 0 ? void 0 : polyfillSupport({ LitElement });
+/**
+ * END USERS SHOULD NOT RELY ON THIS OBJECT.
+ *
+ * Private exports for use by other Lit packages, not intended for use by
+ * external users.
+ *
+ * We currently do not make a mangled rollup build of the lit-ssr code. In order
+ * to keep a number of (otherwise private) top-level exports mangled in the
+ * client side code, we export a _$LE object containing those members (or
+ * helper methods for accessing private fields of those members), and then
+ * re-export them for use in lit-ssr. This keeps lit-ssr agnostic to whether the
+ * client-side code is being used in `dev` mode or `prod` mode.
+ *
+ * This has a unique name, to disambiguate it from private exports in
+ * lit-html, since this module re-exports all of lit-html.
+ *
+ * @private
+ */
+const _$LE = {
+ _$attributeToProperty: (el, name, value) => {
+ // eslint-disable-next-line
+ el._$attributeToProperty(name, value);
+ },
+ // eslint-disable-next-line
+ _$changedProperties: (el) => el._$changedProperties,
+};
+// IMPORTANT: do not change the property name or the assignment expression.
+// This line will be used in regexes to search for LitElement usage.
+((_c = globalThis.litElementVersions) !== null && _c !== void 0 ? _c : (globalThis.litElementVersions = [])).push('3.2.2');
+
+/**
+ * @license
+ * Copyright 2022 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * @fileoverview
+ *
+ * This file exports a boolean const whose value will depend on what environment
+ * the module is being imported from.
+ */
+const NODE_MODE = false;
+/**
+ * A boolean that will be `true` in server environments like Node, and `false`
+ * in browser environments. Note that your server environment or toolchain must
+ * support the `"node"` export condition for this to be `true`.
+ *
+ * This can be used when authoring components to change behavior based on
+ * whether or not the component is executing in an SSR context.
+ */
+const isServer = NODE_MODE;
+
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const { _ChildPart: ChildPart } = _$LH;
+const wrap = (node) => node;
+/**
+ * Tests if a value is a primitive value.
+ *
+ * See https://tc39.github.io/ecma262/#sec-typeof-operator
+ */
+const isPrimitive = (value) => value === null || (typeof value != 'object' && typeof value != 'function');
+const TemplateResultType = {
+ HTML: 1,
+ SVG: 2,
+};
+/**
+ * Tests if a value is a TemplateResult.
+ */
+const isTemplateResult = (value, type) => type === undefined
+ ? // This property needs to remain unminified.
+ (value === null || value === void 0 ? void 0 : value['_$litType$']) !== undefined
+ : (value === null || value === void 0 ? void 0 : value['_$litType$']) === type;
+/**
+ * Tests if a value is a DirectiveResult.
+ */
+const isDirectiveResult = (value) =>
+// This property needs to remain unminified.
+(value === null || value === void 0 ? void 0 : value['_$litDirective$']) !== undefined;
+/**
+ * Retrieves the Directive class for a DirectiveResult
+ */
+const getDirectiveClass = (value) =>
+// This property needs to remain unminified.
+value === null || value === void 0 ? void 0 : value['_$litDirective$'];
+/**
+ * Tests whether a part has only a single-expression with no strings to
+ * interpolate between.
+ *
+ * Only AttributePart and PropertyPart can have multiple expressions.
+ * Multi-expression parts have a `strings` property and single-expression
+ * parts do not.
+ */
+const isSingleExpression = (part) => part.strings === undefined;
+const createMarker = () => document.createComment('');
+/**
+ * Inserts a ChildPart into the given container ChildPart's DOM, either at the
+ * end of the container ChildPart, or before the optional `refPart`.
+ *
+ * This does not add the part to the containerPart's committed value. That must
+ * be done by callers.
+ *
+ * @param containerPart Part within which to add the new ChildPart
+ * @param refPart Part before which to add the new ChildPart; when omitted the
+ * part added to the end of the `containerPart`
+ * @param part Part to insert, or undefined to create a new part
+ */
+const insertPart = (containerPart, refPart, part) => {
+ var _a;
+ const container = wrap(containerPart._$startNode).parentNode;
+ const refNode = refPart === undefined ? containerPart._$endNode : refPart._$startNode;
+ if (part === undefined) {
+ const startNode = wrap(container).insertBefore(createMarker(), refNode);
+ const endNode = wrap(container).insertBefore(createMarker(), refNode);
+ part = new ChildPart(startNode, endNode, containerPart, containerPart.options);
+ }
+ else {
+ const endNode = wrap(part._$endNode).nextSibling;
+ const oldParent = part._$parent;
+ const parentChanged = oldParent !== containerPart;
+ if (parentChanged) {
+ (_a = part._$reparentDisconnectables) === null || _a === void 0 ? void 0 : _a.call(part, containerPart);
+ // Note that although `_$reparentDisconnectables` updates the part's
+ // `_$parent` reference after unlinking from its current parent, that
+ // method only exists if Disconnectables are present, so we need to
+ // unconditionally set it here
+ part._$parent = containerPart;
+ // Since the _$isConnected getter is somewhat costly, only
+ // read it once we know the subtree has directives that need
+ // to be notified
+ let newConnectionState;
+ if (part._$notifyConnectionChanged !== undefined &&
+ (newConnectionState = containerPart._$isConnected) !==
+ oldParent._$isConnected) {
+ part._$notifyConnectionChanged(newConnectionState);
+ }
+ }
+ if (endNode !== refNode || parentChanged) {
+ let start = part._$startNode;
+ while (start !== endNode) {
+ const n = wrap(start).nextSibling;
+ wrap(container).insertBefore(start, refNode);
+ start = n;
+ }
+ }
+ }
+ return part;
+};
+/**
+ * Sets the value of a Part.
+ *
+ * Note that this should only be used to set/update the value of user-created
+ * parts (i.e. those created using `insertPart`); it should not be used
+ * by directives to set the value of the directive's container part. Directives
+ * should return a value from `update`/`render` to update their part state.
+ *
+ * For directives that require setting their part value asynchronously, they
+ * should extend `AsyncDirective` and call `this.setValue()`.
+ *
+ * @param part Part to set
+ * @param value Value to set
+ * @param index For `AttributePart`s, the index to set
+ * @param directiveParent Used internally; should not be set by user
+ */
+const setChildPartValue = (part, value, directiveParent = part) => {
+ part._$setValue(value, directiveParent);
+ return part;
+};
+// A sentinal value that can never appear as a part value except when set by
+// live(). Used to force a dirty-check to fail and cause a re-render.
+const RESET_VALUE = {};
+/**
+ * Sets the committed value of a ChildPart directly without triggering the
+ * commit stage of the part.
+ *
+ * This is useful in cases where a directive needs to update the part such
+ * that the next update detects a value change or not. When value is omitted,
+ * the next update will be guaranteed to be detected as a change.
+ *
+ * @param part
+ * @param value
+ */
+const setCommittedValue = (part, value = RESET_VALUE) => (part._$committedValue = value);
+/**
+ * Returns the committed value of a ChildPart.
+ *
+ * The committed value is used for change detection and efficient updates of
+ * the part. It can differ from the value set by the template or directive in
+ * cases where the template value is transformed before being commited.
+ *
+ * - `TemplateResult`s are committed as a `TemplateInstance`
+ * - Iterables are committed as `Array<ChildPart>`
+ * - All other types are committed as the template value or value returned or
+ * set by a directive.
+ *
+ * @param part
+ */
+const getCommittedValue = (part) => part._$committedValue;
+/**
+ * Removes a ChildPart from the DOM, including any of its content.
+ *
+ * @param part The Part to remove
+ */
+const removePart = (part) => {
+ var _a;
+ (_a = part._$notifyConnectionChanged) === null || _a === void 0 ? void 0 : _a.call(part, false, true);
+ let start = part._$startNode;
+ const end = wrap(part._$endNode).nextSibling;
+ while (start !== end) {
+ const n = wrap(start).nextSibling;
+ wrap(start).remove();
+ start = n;
+ }
+};
+const clearPart = (part) => {
+ part._$clear();
+};
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const PartType = {
+ ATTRIBUTE: 1,
+ CHILD: 2,
+ PROPERTY: 3,
+ BOOLEAN_ATTRIBUTE: 4,
+ EVENT: 5,
+ ELEMENT: 6,
+};
+/**
+ * Creates a user-facing directive function from a Directive class. This
+ * function has the same parameters as the directive's render() method.
+ */
+const directive = (c) => (...values) => ({
+ // This property needs to remain unminified.
+ ['_$litDirective$']: c,
+ values,
+});
+/**
+ * Base class for creating custom directives. Users should extend this class,
+ * implement `render` and/or `update`, and then pass their subclass to
+ * `directive`.
+ */
+class Directive {
+ constructor(_partInfo) { }
+ // See comment in Disconnectable interface for why this is a getter
+ get _$isConnected() {
+ return this._$parent._$isConnected;
+ }
+ /** @internal */
+ _$initialize(part, parent, attributeIndex) {
+ this.__part = part;
+ this._$parent = parent;
+ this.__attributeIndex = attributeIndex;
+ }
+ /** @internal */
+ _$resolve(part, props) {
+ return this.update(part, props);
+ }
+ update(_part, props) {
+ return this.render(...props);
+ }
+}
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * Recursively walks down the tree of Parts/TemplateInstances/Directives to set
+ * the connected state of directives and run `disconnected`/ `reconnected`
+ * callbacks.
+ *
+ * @return True if there were children to disconnect; false otherwise
+ */
+const notifyChildrenConnectedChanged = (parent, isConnected) => {
+ var _a, _b;
+ const children = parent._$disconnectableChildren;
+ if (children === undefined) {
+ return false;
+ }
+ for (const obj of children) {
+ // The existence of `_$notifyDirectiveConnectionChanged` is used as a "brand" to
+ // disambiguate AsyncDirectives from other DisconnectableChildren
+ // (as opposed to using an instanceof check to know when to call it); the
+ // redundancy of "Directive" in the API name is to avoid conflicting with
+ // `_$notifyConnectionChanged`, which exists `ChildParts` which are also in
+ // this list
+ // Disconnect Directive (and any nested directives contained within)
+ // This property needs to remain unminified.
+ (_b = (_a = obj)['_$notifyDirectiveConnectionChanged']) === null || _b === void 0 ? void 0 : _b.call(_a, isConnected, false);
+ // Disconnect Part/TemplateInstance
+ notifyChildrenConnectedChanged(obj, isConnected);
+ }
+ return true;
+};
+/**
+ * Removes the given child from its parent list of disconnectable children, and
+ * if the parent list becomes empty as a result, removes the parent from its
+ * parent, and so forth up the tree when that causes subsequent parent lists to
+ * become empty.
+ */
+const removeDisconnectableFromParent = (obj) => {
+ let parent, children;
+ do {
+ if ((parent = obj._$parent) === undefined) {
+ break;
+ }
+ children = parent._$disconnectableChildren;
+ children.delete(obj);
+ obj = parent;
+ } while ((children === null || children === void 0 ? void 0 : children.size) === 0);
+};
+const addDisconnectableToParent = (obj) => {
+ // Climb the parent tree, creating a sparse tree of children needing
+ // disconnection
+ for (let parent; (parent = obj._$parent); obj = parent) {
+ let children = parent._$disconnectableChildren;
+ if (children === undefined) {
+ parent._$disconnectableChildren = children = new Set();
+ }
+ else if (children.has(obj)) {
+ // Once we've reached a parent that already contains this child, we
+ // can short-circuit
+ break;
+ }
+ children.add(obj);
+ installDisconnectAPI(parent);
+ }
+};
+/**
+ * Changes the parent reference of the ChildPart, and updates the sparse tree of
+ * Disconnectable children accordingly.
+ *
+ * Note, this method will be patched onto ChildPart instances and called from
+ * the core code when parts are moved between different parents.
+ */
+function reparentDisconnectables(newParent) {
+ if (this._$disconnectableChildren !== undefined) {
+ removeDisconnectableFromParent(this);
+ this._$parent = newParent;
+ addDisconnectableToParent(this);
+ }
+ else {
+ this._$parent = newParent;
+ }
+}
+/**
+ * Sets the connected state on any directives contained within the committed
+ * value of this part (i.e. within a TemplateInstance or iterable of
+ * ChildParts) and runs their `disconnected`/`reconnected`s, as well as within
+ * any directives stored on the ChildPart (when `valueOnly` is false).
+ *
+ * `isClearingValue` should be passed as `true` on a top-level part that is
+ * clearing itself, and not as a result of recursively disconnecting directives
+ * as part of a `clear` operation higher up the tree. This both ensures that any
+ * directive on this ChildPart that produced a value that caused the clear
+ * operation is not disconnected, and also serves as a performance optimization
+ * to avoid needless bookkeeping when a subtree is going away; when clearing a
+ * subtree, only the top-most part need to remove itself from the parent.
+ *
+ * `fromPartIndex` is passed only in the case of a partial `_clear` running as a
+ * result of truncating an iterable.
+ *
+ * Note, this method will be patched onto ChildPart instances and called from the
+ * core code when parts are cleared or the connection state is changed by the
+ * user.
+ */
+function notifyChildPartConnectedChanged(isConnected, isClearingValue = false, fromPartIndex = 0) {
+ const value = this._$committedValue;
+ const children = this._$disconnectableChildren;
+ if (children === undefined || children.size === 0) {
+ return;
+ }
+ if (isClearingValue) {
+ if (Array.isArray(value)) {
+ // Iterable case: Any ChildParts created by the iterable should be
+ // disconnected and removed from this ChildPart's disconnectable
+ // children (starting at `fromPartIndex` in the case of truncation)
+ for (let i = fromPartIndex; i < value.length; i++) {
+ notifyChildrenConnectedChanged(value[i], false);
+ removeDisconnectableFromParent(value[i]);
+ }
+ }
+ else if (value != null) {
+ // TemplateInstance case: If the value has disconnectable children (will
+ // only be in the case that it is a TemplateInstance), we disconnect it
+ // and remove it from this ChildPart's disconnectable children
+ notifyChildrenConnectedChanged(value, false);
+ removeDisconnectableFromParent(value);
+ }
+ }
+ else {
+ notifyChildrenConnectedChanged(this, isConnected);
+ }
+}
+/**
+ * Patches disconnection API onto ChildParts.
+ */
+const installDisconnectAPI = (obj) => {
+ var _a, _b;
+ var _c, _d;
+ if (obj.type == PartType.CHILD) {
+ (_a = (_c = obj)._$notifyConnectionChanged) !== null && _a !== void 0 ? _a : (_c._$notifyConnectionChanged = notifyChildPartConnectedChanged);
+ (_b = (_d = obj)._$reparentDisconnectables) !== null && _b !== void 0 ? _b : (_d._$reparentDisconnectables = reparentDisconnectables);
+ }
+};
+/**
+ * An abstract `Directive` base class whose `disconnected` method will be
+ * called when the part containing the directive is cleared as a result of
+ * re-rendering, or when the user calls `part.setConnected(false)` on
+ * a part that was previously rendered containing the directive (as happens
+ * when e.g. a LitElement disconnects from the DOM).
+ *
+ * If `part.setConnected(true)` is subsequently called on a
+ * containing part, the directive's `reconnected` method will be called prior
+ * to its next `update`/`render` callbacks. When implementing `disconnected`,
+ * `reconnected` should also be implemented to be compatible with reconnection.
+ *
+ * Note that updates may occur while the directive is disconnected. As such,
+ * directives should generally check the `this.isConnected` flag during
+ * render/update to determine whether it is safe to subscribe to resources
+ * that may prevent garbage collection.
+ */
+class AsyncDirective extends Directive {
+ constructor() {
+ super(...arguments);
+ // @internal
+ this._$disconnectableChildren = undefined;
+ }
+ /**
+ * Initialize the part with internal fields
+ * @param part
+ * @param parent
+ * @param attributeIndex
+ */
+ _$initialize(part, parent, attributeIndex) {
+ super._$initialize(part, parent, attributeIndex);
+ addDisconnectableToParent(this);
+ this.isConnected = part._$isConnected;
+ }
+ // This property needs to remain unminified.
+ /**
+ * Called from the core code when a directive is going away from a part (in
+ * which case `shouldRemoveFromParent` should be true), and from the
+ * `setChildrenConnected` helper function when recursively changing the
+ * connection state of a tree (in which case `shouldRemoveFromParent` should
+ * be false).
+ *
+ * @param isConnected
+ * @param isClearingDirective - True when the directive itself is being
+ * removed; false when the tree is being disconnected
+ * @internal
+ */
+ ['_$notifyDirectiveConnectionChanged'](isConnected, isClearingDirective = true) {
+ var _a, _b;
+ if (isConnected !== this.isConnected) {
+ this.isConnected = isConnected;
+ if (isConnected) {
+ (_a = this.reconnected) === null || _a === void 0 ? void 0 : _a.call(this);
+ }
+ else {
+ (_b = this.disconnected) === null || _b === void 0 ? void 0 : _b.call(this);
+ }
+ }
+ if (isClearingDirective) {
+ notifyChildrenConnectedChanged(this, isConnected);
+ removeDisconnectableFromParent(this);
+ }
+ }
+ /**
+ * Sets the value of the directive's Part outside the normal `update`/`render`
+ * lifecycle of a directive.
+ *
+ * This method should not be called synchronously from a directive's `update`
+ * or `render`.
+ *
+ * @param directive The directive to update
+ * @param value The value to set
+ */
+ setValue(value) {
+ if (isSingleExpression(this.__part)) {
+ this.__part._$setValue(value, this);
+ }
+ else {
+ const newValues = [...this.__part._$committedValue];
+ newValues[this.__attributeIndex] = value;
+ this.__part._$setValue(newValues, this, 0);
+ }
+ }
+ /**
+ * User callbacks for implementing logic to release any resources/subscriptions
+ * that may have been retained by this directive. Since directives may also be
+ * re-connected, `reconnected` should also be implemented to restore the
+ * working state of the directive prior to the next render.
+ */
+ disconnected() { }
+ reconnected() { }
+}
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+// Note, this module is not included in package exports so that it's private to
+// our first-party directives. If it ends up being useful, we can open it up and
+// export it.
+/**
+ * Helper to iterate an AsyncIterable in its own closure.
+ * @param iterable The iterable to iterate
+ * @param callback The callback to call for each value. If the callback returns
+ * `false`, the loop will be broken.
+ */
+const forAwaitOf = async (iterable, callback) => {
+ for await (const v of iterable) {
+ if ((await callback(v)) === false) {
+ return;
+ }
+ }
+};
+/**
+ * Holds a reference to an instance that can be disconnected and reconnected,
+ * so that a closure over the ref (e.g. in a then function to a promise) does
+ * not strongly hold a ref to the instance. Approximates a WeakRef but must
+ * be manually connected & disconnected to the backing instance.
+ */
+class PseudoWeakRef {
+ constructor(ref) {
+ this._ref = ref;
+ }
+ /**
+ * Disassociates the ref with the backing instance.
+ */
+ disconnect() {
+ this._ref = undefined;
+ }
+ /**
+ * Reassociates the ref with the backing instance.
+ */
+ reconnect(ref) {
+ this._ref = ref;
+ }
+ /**
+ * Retrieves the backing instance (will be undefined when disconnected)
+ */
+ deref() {
+ return this._ref;
+ }
+}
+/**
+ * A helper to pause and resume waiting on a condition in an async function
+ */
+class Pauser {
+ constructor() {
+ this._promise = undefined;
+ this._resolve = undefined;
+ }
+ /**
+ * When paused, returns a promise to be awaited; when unpaused, returns
+ * undefined. Note that in the microtask between the pauser being resumed
+ * an an await of this promise resolving, the pauser could be paused again,
+ * hence callers should check the promise in a loop when awaiting.
+ * @returns A promise to be awaited when paused or undefined
+ */
+ get() {
+ return this._promise;
+ }
+ /**
+ * Creates a promise to be awaited
+ */
+ pause() {
+ var _a;
+ (_a = this._promise) !== null && _a !== void 0 ? _a : (this._promise = new Promise((resolve) => (this._resolve = resolve)));
+ }
+ /**
+ * Resolves the promise which may be awaited
+ */
+ resume() {
+ var _a;
+ (_a = this._resolve) === null || _a === void 0 ? void 0 : _a.call(this);
+ this._promise = this._resolve = undefined;
+ }
+}
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class AsyncReplaceDirective extends AsyncDirective {
+ constructor() {
+ super(...arguments);
+ this.__weakThis = new PseudoWeakRef(this);
+ this.__pauser = new Pauser();
+ }
+ // @ts-expect-error value not used, but we want a nice parameter for docs
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ render(value, _mapper) {
+ return noChange;
+ }
+ update(_part, [value, mapper]) {
+ // If our initial render occurs while disconnected, ensure that the pauser
+ // and weakThis are in the disconnected state
+ if (!this.isConnected) {
+ this.disconnected();
+ }
+ // If we've already set up this particular iterable, we don't need
+ // to do anything.
+ if (value === this.__value) {
+ return;
+ }
+ this.__value = value;
+ let i = 0;
+ const { __weakThis: weakThis, __pauser: pauser } = this;
+ // Note, the callback avoids closing over `this` so that the directive
+ // can be gc'ed before the promise resolves; instead `this` is retrieved
+ // from `weakThis`, which can break the hard reference in the closure when
+ // the directive disconnects
+ forAwaitOf(value, async (v) => {
+ // The while loop here handles the case that the connection state
+ // thrashes, causing the pauser to resume and then get re-paused
+ while (pauser.get()) {
+ await pauser.get();
+ }
+ // If the callback gets here and there is no `this`, it means that the
+ // directive has been disconnected and garbage collected and we don't
+ // need to do anything else
+ const _this = weakThis.deref();
+ if (_this !== undefined) {
+ // Check to make sure that value is the still the current value of
+ // the part, and if not bail because a new value owns this part
+ if (_this.__value !== value) {
+ return false;
+ }
+ // As a convenience, because functional-programming-style
+ // transforms of iterables and async iterables requires a library,
+ // we accept a mapper function. This is especially convenient for
+ // rendering a template for each item.
+ if (mapper !== undefined) {
+ v = mapper(v, i);
+ }
+ _this.commitValue(v, i);
+ i++;
+ }
+ return true;
+ });
+ return noChange;
+ }
+ // Override point for AsyncAppend to append rather than replace
+ commitValue(value, _index) {
+ this.setValue(value);
+ }
+ disconnected() {
+ this.__weakThis.disconnect();
+ this.__pauser.pause();
+ }
+ reconnected() {
+ this.__weakThis.reconnect(this);
+ this.__pauser.resume();
+ }
+}
+/**
+ * A directive that renders the items of an async iterable[1], replacing
+ * previous values with new values, so that only one value is ever rendered
+ * at a time. This directive may be used in any expression type.
+ *
+ * Async iterables are objects with a `[Symbol.asyncIterator]` method, which
+ * returns an iterator who's `next()` method returns a Promise. When a new
+ * value is available, the Promise resolves and the value is rendered to the
+ * Part controlled by the directive. If another value other than this
+ * directive has been set on the Part, the iterable will no longer be listened
+ * to and new values won't be written to the Part.
+ *
+ * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of
+ *
+ * @param value An async iterable
+ * @param mapper An optional function that maps from (value, index) to another
+ * value. Useful for generating templates for each item in the iterable.
+ */
+const asyncReplace = directive(AsyncReplaceDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class AsyncAppendDirective extends AsyncReplaceDirective {
+ // Override AsyncReplace to narrow the allowed part type to ChildPart only
+ constructor(partInfo) {
+ super(partInfo);
+ if (partInfo.type !== PartType.CHILD) {
+ throw new Error('asyncAppend can only be used in child expressions');
+ }
+ }
+ // Override AsyncReplace to save the part since we need to append into it
+ update(part, params) {
+ this.__childPart = part;
+ return super.update(part, params);
+ }
+ // Override AsyncReplace to append rather than replace
+ commitValue(value, index) {
+ // When we get the first value, clear the part. This lets the
+ // previous value display until we can replace it.
+ if (index === 0) {
+ clearPart(this.__childPart);
+ }
+ // Create and insert a new part and set its value to the next value
+ const newPart = insertPart(this.__childPart);
+ setChildPartValue(newPart, value);
+ }
+}
+/**
+ * A directive that renders the items of an async iterable[1], appending new
+ * values after previous values, similar to the built-in support for iterables.
+ * This directive is usable only in child expressions.
+ *
+ * Async iterables are objects with a [Symbol.asyncIterator] method, which
+ * returns an iterator who's `next()` method returns a Promise. When a new
+ * value is available, the Promise resolves and the value is appended to the
+ * Part controlled by the directive. If another value other than this
+ * directive has been set on the Part, the iterable will no longer be listened
+ * to and new values won't be written to the Part.
+ *
+ * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of
+ *
+ * @param value An async iterable
+ * @param mapper An optional function that maps from (value, index) to another
+ * value. Useful for generating templates for each item in the iterable.
+ */
+const asyncAppend = directive(AsyncAppendDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class CacheDirective extends Directive {
+ constructor(partInfo) {
+ super(partInfo);
+ this._templateCache = new WeakMap();
+ }
+ render(v) {
+ // Return an array of the value to induce lit-html to create a ChildPart
+ // for the value that we can move into the cache.
+ return [v];
+ }
+ update(containerPart, [v]) {
+ // If the previous value is a TemplateResult and the new value is not,
+ // or is a different Template as the previous value, move the child part
+ // into the cache.
+ if (isTemplateResult(this._value) &&
+ (!isTemplateResult(v) || this._value.strings !== v.strings)) {
+ // This is always an array because we return [v] in render()
+ const partValue = getCommittedValue(containerPart);
+ const childPart = partValue.pop();
+ let cachedContainerPart = this._templateCache.get(this._value.strings);
+ if (cachedContainerPart === undefined) {
+ const fragment = document.createDocumentFragment();
+ cachedContainerPart = render(nothing, fragment);
+ cachedContainerPart.setConnected(false);
+ this._templateCache.set(this._value.strings, cachedContainerPart);
+ }
+ // Move into cache
+ setCommittedValue(cachedContainerPart, [childPart]);
+ insertPart(cachedContainerPart, undefined, childPart);
+ }
+ // If the new value is a TemplateResult and the previous value is not,
+ // or is a different Template as the previous value, restore the child
+ // part from the cache.
+ if (isTemplateResult(v)) {
+ if (!isTemplateResult(this._value) || this._value.strings !== v.strings) {
+ const cachedContainerPart = this._templateCache.get(v.strings);
+ if (cachedContainerPart !== undefined) {
+ // Move the cached part back into the container part value
+ const partValue = getCommittedValue(cachedContainerPart);
+ const cachedPart = partValue.pop();
+ // Move cached part back into DOM
+ clearPart(containerPart);
+ insertPart(containerPart, undefined, cachedPart);
+ setCommittedValue(containerPart, [cachedPart]);
+ }
+ }
+ this._value = v;
+ }
+ else {
+ this._value = undefined;
+ }
+ return this.render(v);
+ }
+}
+/**
+ * Enables fast switching between multiple templates by caching the DOM nodes
+ * and TemplateInstances produced by the templates.
+ *
+ * Example:
+ *
+ * ```js
+ * let checked = false;
+ *
+ * html`
+ * ${cache(checked ? html`input is checked` : html`input is not checked`)}
+ * `
+ * ```
+ */
+const cache = directive(CacheDirective);
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * Chooses and evaluates a template function from a list based on matching
+ * the given `value` to a case.
+ *
+ * Cases are structured as `[caseValue, func]`. `value` is matched to
+ * `caseValue` by strict equality. The first match is selected. Case values
+ * can be of any type including primitives, objects, and symbols.
+ *
+ * This is similar to a switch statement, but as an expression and without
+ * fallthrough.
+ *
+ * @example
+ *
+ * ```ts
+ * render() {
+ * return html`
+ * ${choose(this.section, [
+ * ['home', () => html`<h1>Home</h1>`],
+ * ['about', () => html`<h1>About</h1>`]
+ * ],
+ * () => html`<h1>Error</h1>`)}
+ * `;
+ * }
+ * ```
+ */
+const choose = (value, cases, defaultCase) => {
+ for (const c of cases) {
+ const caseValue = c[0];
+ if (caseValue === value) {
+ const fn = c[1];
+ return fn();
+ }
+ }
+ return defaultCase === null || defaultCase === void 0 ? void 0 : defaultCase();
+};
+
+/**
+ * @license
+ * Copyright 2018 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class ClassMapDirective extends Directive {
+ constructor(partInfo) {
+ var _a;
+ super(partInfo);
+ if (partInfo.type !== PartType.ATTRIBUTE ||
+ partInfo.name !== 'class' ||
+ ((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) {
+ throw new Error('`classMap()` can only be used in the `class` attribute ' +
+ 'and must be the only part in the attribute.');
+ }
+ }
+ render(classInfo) {
+ // Add spaces to ensure separation from static classes
+ return (' ' +
+ Object.keys(classInfo)
+ .filter((key) => classInfo[key])
+ .join(' ') +
+ ' ');
+ }
+ update(part, [classInfo]) {
+ var _a, _b;
+ // Remember dynamic classes on the first render
+ if (this._previousClasses === undefined) {
+ this._previousClasses = new Set();
+ if (part.strings !== undefined) {
+ this._staticClasses = new Set(part.strings
+ .join(' ')
+ .split(/\s/)
+ .filter((s) => s !== ''));
+ }
+ for (const name in classInfo) {
+ if (classInfo[name] && !((_a = this._staticClasses) === null || _a === void 0 ? void 0 : _a.has(name))) {
+ this._previousClasses.add(name);
+ }
+ }
+ return this.render(classInfo);
+ }
+ const classList = part.element.classList;
+ // Remove old classes that no longer apply
+ // We use forEach() instead of for-of so that we don't require down-level
+ // iteration.
+ this._previousClasses.forEach((name) => {
+ if (!(name in classInfo)) {
+ classList.remove(name);
+ this._previousClasses.delete(name);
+ }
+ });
+ // Add or remove classes based on their classMap value
+ for (const name in classInfo) {
+ // We explicitly want a loose truthy check of `value` because it seems
+ // more convenient that '' and 0 are skipped.
+ const value = !!classInfo[name];
+ if (value !== this._previousClasses.has(name) &&
+ !((_b = this._staticClasses) === null || _b === void 0 ? void 0 : _b.has(name))) {
+ if (value) {
+ classList.add(name);
+ this._previousClasses.add(name);
+ }
+ else {
+ classList.remove(name);
+ this._previousClasses.delete(name);
+ }
+ }
+ }
+ return noChange;
+ }
+}
+/**
+ * A directive that applies dynamic CSS classes.
+ *
+ * This must be used in the `class` attribute and must be the only part used in
+ * the attribute. It takes each property in the `classInfo` argument and adds
+ * the property name to the element's `classList` if the property value is
+ * truthy; if the property value is falsey, the property name is removed from
+ * the element's `class`.
+ *
+ * For example `{foo: bar}` applies the class `foo` if the value of `bar` is
+ * truthy.
+ *
+ * @param classInfo
+ */
+const classMap = directive(ClassMapDirective);
+
+/**
+ * @license
+ * Copyright 2018 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+// A sentinal that indicates guard() hasn't rendered anything yet
+const initialValue = {};
+class GuardDirective extends Directive {
+ constructor() {
+ super(...arguments);
+ this._previousValue = initialValue;
+ }
+ render(_value, f) {
+ return f();
+ }
+ update(_part, [value, f]) {
+ if (Array.isArray(value)) {
+ // Dirty-check arrays by item
+ if (Array.isArray(this._previousValue) &&
+ this._previousValue.length === value.length &&
+ value.every((v, i) => v === this._previousValue[i])) {
+ return noChange;
+ }
+ }
+ else if (this._previousValue === value) {
+ // Dirty-check non-arrays by identity
+ return noChange;
+ }
+ // Copy the value if it's an array so that if it's mutated we don't forget
+ // what the previous values were.
+ this._previousValue = Array.isArray(value) ? Array.from(value) : value;
+ const r = this.render(value, f);
+ return r;
+ }
+}
+/**
+ * Prevents re-render of a template function until a single value or an array of
+ * values changes.
+ *
+ * Values are checked against previous values with strict equality (`===`), and
+ * so the check won't detect nested property changes inside objects or arrays.
+ * Arrays values have each item checked against the previous value at the same
+ * index with strict equality. Nested arrays are also checked only by strict
+ * equality.
+ *
+ * Example:
+ *
+ * ```js
+ * html`
+ * <div>
+ * ${guard([user.id, company.id], () => html`...`)}
+ * </div>
+ * `
+ * ```
+ *
+ * In this case, the template only rerenders if either `user.id` or `company.id`
+ * changes.
+ *
+ * guard() is useful with immutable data patterns, by preventing expensive work
+ * until data updates.
+ *
+ * Example:
+ *
+ * ```js
+ * html`
+ * <div>
+ * ${guard([immutableItems], () => immutableItems.map(i => html`${i}`))}
+ * </div>
+ * `
+ * ```
+ *
+ * In this case, items are mapped over only when the array reference changes.
+ *
+ * @param value the value to check before re-rendering
+ * @param f the template function
+ */
+const guard = directive(GuardDirective);
+
+/**
+ * @license
+ * Copyright 2018 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * For AttributeParts, sets the attribute if the value is defined and removes
+ * the attribute if the value is undefined.
+ *
+ * For other part types, this directive is a no-op.
+ */
+const ifDefined = (value) => value !== null && value !== void 0 ? value : nothing;
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+function* join(items, joiner) {
+ const isFunction = typeof joiner === 'function';
+ if (items !== undefined) {
+ let i = -1;
+ for (const value of items) {
+ if (i > -1) {
+ yield isFunction ? joiner(i) : joiner;
+ }
+ i++;
+ yield value;
+ }
+ }
+}
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class Keyed extends Directive {
+ constructor() {
+ super(...arguments);
+ this.key = nothing;
+ }
+ render(k, v) {
+ this.key = k;
+ return v;
+ }
+ update(part, [k, v]) {
+ if (k !== this.key) {
+ // Clear the part before returning a value. The one-arg form of
+ // setCommittedValue sets the value to a sentinel which forces a
+ // commit the next render.
+ setCommittedValue(part);
+ this.key = k;
+ }
+ return v;
+ }
+}
+/**
+ * Associates a renderable value with a unique key. When the key changes, the
+ * previous DOM is removed and disposed before rendering the next value, even
+ * if the value - such as a template - is the same.
+ *
+ * This is useful for forcing re-renders of stateful components, or working
+ * with code that expects new data to generate new HTML elements, such as some
+ * animation techniques.
+ */
+const keyed = directive(Keyed);
+
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class LiveDirective extends Directive {
+ constructor(partInfo) {
+ super(partInfo);
+ if (!(partInfo.type === PartType.PROPERTY ||
+ partInfo.type === PartType.ATTRIBUTE ||
+ partInfo.type === PartType.BOOLEAN_ATTRIBUTE)) {
+ throw new Error('The `live` directive is not allowed on child or event bindings');
+ }
+ if (!isSingleExpression(partInfo)) {
+ throw new Error('`live` bindings can only contain a single expression');
+ }
+ }
+ render(value) {
+ return value;
+ }
+ update(part, [value]) {
+ if (value === noChange || value === nothing) {
+ return value;
+ }
+ const element = part.element;
+ const name = part.name;
+ if (part.type === PartType.PROPERTY) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ if (value === element[name]) {
+ return noChange;
+ }
+ }
+ else if (part.type === PartType.BOOLEAN_ATTRIBUTE) {
+ if (!!value === element.hasAttribute(name)) {
+ return noChange;
+ }
+ }
+ else if (part.type === PartType.ATTRIBUTE) {
+ if (element.getAttribute(name) === String(value)) {
+ return noChange;
+ }
+ }
+ // Resets the part's value, causing its dirty-check to fail so that it
+ // always sets the value.
+ setCommittedValue(part);
+ return value;
+ }
+}
+/**
+ * Checks binding values against live DOM values, instead of previously bound
+ * values, when determining whether to update the value.
+ *
+ * This is useful for cases where the DOM value may change from outside of
+ * lit-html, such as with a binding to an `<input>` element's `value` property,
+ * a content editable elements text, or to a custom element that changes it's
+ * own properties or attributes.
+ *
+ * In these cases if the DOM value changes, but the value set through lit-html
+ * bindings hasn't, lit-html won't know to update the DOM value and will leave
+ * it alone. If this is not what you want--if you want to overwrite the DOM
+ * value with the bound value no matter what--use the `live()` directive:
+ *
+ * ```js
+ * html`<input .value=${live(x)}>`
+ * ```
+ *
+ * `live()` performs a strict equality check against the live DOM value, and if
+ * the new value is equal to the live value, does nothing. This means that
+ * `live()` should not be used when the binding will cause a type conversion. If
+ * you use `live()` with an attribute binding, make sure that only strings are
+ * passed in, or the binding will update every render.
+ */
+const live = directive(LiveDirective);
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * Returns an iterable containing the result of calling `f(value)` on each
+ * value in `items`.
+ *
+ * @example
+ *
+ * ```ts
+ * render() {
+ * return html`
+ * <ul>
+ * ${map(items, (i) => html`<li>${i}</li>`)}
+ * </ul>
+ * `;
+ * }
+ * ```
+ */
+function* map(items, f) {
+ if (items !== undefined) {
+ let i = 0;
+ for (const value of items) {
+ yield f(value, i++);
+ }
+ }
+}
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+function* range(startOrEnd, end, step = 1) {
+ const start = end === undefined ? 0 : startOrEnd;
+ end !== null && end !== void 0 ? end : (end = startOrEnd);
+ for (let i = start; step > 0 ? i < end : end < i; i += step) {
+ yield i;
+ }
+}
+
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * Creates a new Ref object, which is container for a reference to an element.
+ */
+const createRef = () => new Ref();
+/**
+ * An object that holds a ref value.
+ */
+class Ref {
+}
+// When callbacks are used for refs, this map tracks the last value the callback
+// was called with, for ensuring a directive doesn't clear the ref if the ref
+// has already been rendered to a new spot. It is double-keyed on both the
+// context (`options.host`) and the callback, since we auto-bind class methods
+// to `options.host`.
+const lastElementForContextAndCallback = new WeakMap();
+class RefDirective extends AsyncDirective {
+ render(_ref) {
+ return nothing;
+ }
+ update(part, [ref]) {
+ var _a;
+ const refChanged = ref !== this._ref;
+ if (refChanged && this._ref !== undefined) {
+ // The ref passed to the directive has changed;
+ // unset the previous ref's value
+ this._updateRefValue(undefined);
+ }
+ if (refChanged || this._lastElementForRef !== this._element) {
+ // We either got a new ref or this is the first render;
+ // store the ref/element & update the ref value
+ this._ref = ref;
+ this._context = (_a = part.options) === null || _a === void 0 ? void 0 : _a.host;
+ this._updateRefValue((this._element = part.element));
+ }
+ return nothing;
+ }
+ _updateRefValue(element) {
+ var _a;
+ if (typeof this._ref === 'function') {
+ // If the current ref was called with a previous value, call with
+ // `undefined`; We do this to ensure callbacks are called in a consistent
+ // way regardless of whether a ref might be moving up in the tree (in
+ // which case it would otherwise be called with the new value before the
+ // previous one unsets it) and down in the tree (where it would be unset
+ // before being set). Note that element lookup is keyed by
+ // both the context and the callback, since we allow passing unbound
+ // functions that are called on options.host, and we want to treat
+ // these as unique "instances" of a function.
+ const context = (_a = this._context) !== null && _a !== void 0 ? _a : globalThis;
+ let lastElementForCallback = lastElementForContextAndCallback.get(context);
+ if (lastElementForCallback === undefined) {
+ lastElementForCallback = new WeakMap();
+ lastElementForContextAndCallback.set(context, lastElementForCallback);
+ }
+ if (lastElementForCallback.get(this._ref) !== undefined) {
+ this._ref.call(this._context, undefined);
+ }
+ lastElementForCallback.set(this._ref, element);
+ // Call the ref with the new element value
+ if (element !== undefined) {
+ this._ref.call(this._context, element);
+ }
+ }
+ else {
+ this._ref.value = element;
+ }
+ }
+ get _lastElementForRef() {
+ var _a, _b, _c;
+ return typeof this._ref === 'function'
+ ? (_b = lastElementForContextAndCallback
+ .get((_a = this._context) !== null && _a !== void 0 ? _a : globalThis)) === null || _b === void 0 ? void 0 : _b.get(this._ref)
+ : (_c = this._ref) === null || _c === void 0 ? void 0 : _c.value;
+ }
+ disconnected() {
+ // Only clear the box if our element is still the one in it (i.e. another
+ // directive instance hasn't rendered its element to it before us); that
+ // only happens in the event of the directive being cleared (not via manual
+ // disconnection)
+ if (this._lastElementForRef === this._element) {
+ this._updateRefValue(undefined);
+ }
+ }
+ reconnected() {
+ // If we were manually disconnected, we can safely put our element back in
+ // the box, since no rendering could have occurred to change its state
+ this._updateRefValue(this._element);
+ }
+}
+/**
+ * Sets the value of a Ref object or calls a ref callback with the element it's
+ * bound to.
+ *
+ * A Ref object acts as a container for a reference to an element. A ref
+ * callback is a function that takes an element as its only argument.
+ *
+ * The ref directive sets the value of the Ref object or calls the ref callback
+ * during rendering, if the referenced element changed.
+ *
+ * Note: If a ref callback is rendered to a different element position or is
+ * removed in a subsequent render, it will first be called with `undefined`,
+ * followed by another call with the new element it was rendered to (if any).
+ *
+ * ```js
+ * // Using Ref object
+ * const inputRef = createRef();
+ * render(html`<input ${ref(inputRef)}>`, container);
+ * inputRef.value.focus();
+ *
+ * // Using callback
+ * const callback = (inputElement) => inputElement.focus();
+ * render(html`<input ${ref(callback)}>`, container);
+ * ```
+ */
+const ref = directive(RefDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+// Helper for generating a map of array item to its index over a subset
+// of an array (used to lazily generate `newKeyToIndexMap` and
+// `oldKeyToIndexMap`)
+const generateMap = (list, start, end) => {
+ const map = new Map();
+ for (let i = start; i <= end; i++) {
+ map.set(list[i], i);
+ }
+ return map;
+};
+class RepeatDirective extends Directive {
+ constructor(partInfo) {
+ super(partInfo);
+ if (partInfo.type !== PartType.CHILD) {
+ throw new Error('repeat() can only be used in text expressions');
+ }
+ }
+ _getValuesAndKeys(items, keyFnOrTemplate, template) {
+ let keyFn;
+ if (template === undefined) {
+ template = keyFnOrTemplate;
+ }
+ else if (keyFnOrTemplate !== undefined) {
+ keyFn = keyFnOrTemplate;
+ }
+ const keys = [];
+ const values = [];
+ let index = 0;
+ for (const item of items) {
+ keys[index] = keyFn ? keyFn(item, index) : index;
+ values[index] = template(item, index);
+ index++;
+ }
+ return {
+ values,
+ keys,
+ };
+ }
+ render(items, keyFnOrTemplate, template) {
+ return this._getValuesAndKeys(items, keyFnOrTemplate, template).values;
+ }
+ update(containerPart, [items, keyFnOrTemplate, template]) {
+ var _a;
+ // Old part & key lists are retrieved from the last update (which may
+ // be primed by hydration)
+ const oldParts = getCommittedValue(containerPart);
+ const { values: newValues, keys: newKeys } = this._getValuesAndKeys(items, keyFnOrTemplate, template);
+ // We check that oldParts, the committed value, is an Array as an
+ // indicator that the previous value came from a repeat() call. If
+ // oldParts is not an Array then this is the first render and we return
+ // an array for lit-html's array handling to render, and remember the
+ // keys.
+ if (!Array.isArray(oldParts)) {
+ this._itemKeys = newKeys;
+ return newValues;
+ }
+ // In SSR hydration it's possible for oldParts to be an arrray but for us
+ // to not have item keys because the update() hasn't run yet. We set the
+ // keys to an empty array. This will cause all oldKey/newKey comparisons
+ // to fail and execution to fall to the last nested brach below which
+ // reuses the oldPart.
+ const oldKeys = ((_a = this._itemKeys) !== null && _a !== void 0 ? _a : (this._itemKeys = []));
+ // New part list will be built up as we go (either reused from
+ // old parts or created for new keys in this update). This is
+ // saved in the above cache at the end of the update.
+ const newParts = [];
+ // Maps from key to index for current and previous update; these
+ // are generated lazily only when needed as a performance
+ // optimization, since they are only required for multiple
+ // non-contiguous changes in the list, which are less common.
+ let newKeyToIndexMap;
+ let oldKeyToIndexMap;
+ // Head and tail pointers to old parts and new values
+ let oldHead = 0;
+ let oldTail = oldParts.length - 1;
+ let newHead = 0;
+ let newTail = newValues.length - 1;
+ // Overview of O(n) reconciliation algorithm (general approach
+ // based on ideas found in ivi, vue, snabbdom, etc.):
+ //
+ // * We start with the list of old parts and new values (and
+ // arrays of their respective keys), head/tail pointers into
+ // each, and we build up the new list of parts by updating
+ // (and when needed, moving) old parts or creating new ones.
+ // The initial scenario might look like this (for brevity of
+ // the diagrams, the numbers in the array reflect keys
+ // associated with the old parts or new values, although keys
+ // and parts/values are actually stored in parallel arrays
+ // indexed using the same head/tail pointers):
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, 2, 3, 4, 5, 6]
+ // newParts: [ , , , , , , ]
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] <- reflects the user's new
+ // item order
+ // newHead ^ ^ newTail
+ //
+ // * Iterate old & new lists from both sides, updating,
+ // swapping, or removing parts at the head/tail locations
+ // until neither head nor tail can move.
+ //
+ // * Example below: keys at head pointers match, so update old
+ // part 0 in-place (no need to move it) and record part 0 in
+ // the `newParts` list. The last thing we do is advance the
+ // `oldHead` and `newHead` pointers (will be reflected in the
+ // next diagram).
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, 2, 3, 4, 5, 6]
+ // newParts: [0, , , , , , ] <- heads matched: update 0
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldHead
+ // & newHead
+ // newHead ^ ^ newTail
+ //
+ // * Example below: head pointers don't match, but tail
+ // pointers do, so update part 6 in place (no need to move
+ // it), and record part 6 in the `newParts` list. Last,
+ // advance the `oldTail` and `oldHead` pointers.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, 2, 3, 4, 5, 6]
+ // newParts: [0, , , , , , 6] <- tails matched: update 6
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldTail
+ // & newTail
+ // newHead ^ ^ newTail
+ //
+ // * If neither head nor tail match; next check if one of the
+ // old head/tail items was removed. We first need to generate
+ // the reverse map of new keys to index (`newKeyToIndexMap`),
+ // which is done once lazily as a performance optimization,
+ // since we only hit this case if multiple non-contiguous
+ // changes were made. Note that for contiguous removal
+ // anywhere in the list, the head and tails would advance
+ // from either end and pass each other before we get to this
+ // case and removals would be handled in the final while loop
+ // without needing to generate the map.
+ //
+ // * Example below: The key at `oldTail` was removed (no longer
+ // in the `newKeyToIndexMap`), so remove that part from the
+ // DOM and advance just the `oldTail` pointer.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, 2, 3, 4, 5, 6]
+ // newParts: [0, , , , , , 6] <- 5 not in new map: remove
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] 5 and advance oldTail
+ // newHead ^ ^ newTail
+ //
+ // * Once head and tail cannot move, any mismatches are due to
+ // either new or moved items; if a new key is in the previous
+ // "old key to old index" map, move the old part to the new
+ // location, otherwise create and insert a new part. Note
+ // that when moving an old part we null its position in the
+ // oldParts array if it lies between the head and tail so we
+ // know to skip it when the pointers get there.
+ //
+ // * Example below: neither head nor tail match, and neither
+ // were removed; so find the `newHead` key in the
+ // `oldKeyToIndexMap`, and move that old part's DOM into the
+ // next head position (before `oldParts[oldHead]`). Last,
+ // null the part in the `oldPart` array since it was
+ // somewhere in the remaining oldParts still to be scanned
+ // (between the head and tail pointers) so that we know to
+ // skip that old part on future iterations.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, -, 3, 4, 5, 6]
+ // newParts: [0, 2, , , , , 6] <- stuck: update & move 2
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] into place and advance
+ // newHead
+ // newHead ^ ^ newTail
+ //
+ // * Note that for moves/insertions like the one above, a part
+ // inserted at the head pointer is inserted before the
+ // current `oldParts[oldHead]`, and a part inserted at the
+ // tail pointer is inserted before `newParts[newTail+1]`. The
+ // seeming asymmetry lies in the fact that new parts are
+ // moved into place outside in, so to the right of the head
+ // pointer are old parts, and to the right of the tail
+ // pointer are new parts.
+ //
+ // * We always restart back from the top of the algorithm,
+ // allowing matching and simple updates in place to
+ // continue...
+ //
+ // * Example below: the head pointers once again match, so
+ // simply update part 1 and record it in the `newParts`
+ // array. Last, advance both head pointers.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, -, 3, 4, 5, 6]
+ // newParts: [0, 2, 1, , , , 6] <- heads matched: update 1
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance both oldHead
+ // & newHead
+ // newHead ^ ^ newTail
+ //
+ // * As mentioned above, items that were moved as a result of
+ // being stuck (the final else clause in the code below) are
+ // marked with null, so we always advance old pointers over
+ // these so we're comparing the next actual old value on
+ // either end.
+ //
+ // * Example below: `oldHead` is null (already placed in
+ // newParts), so advance `oldHead`.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, -, 3, 4, 5, 6] <- old head already used:
+ // newParts: [0, 2, 1, , , , 6] advance oldHead
+ // newKeys: [0, 2, 1, 4, 3, 7, 6]
+ // newHead ^ ^ newTail
+ //
+ // * Note it's not critical to mark old parts as null when they
+ // are moved from head to tail or tail to head, since they
+ // will be outside the pointer range and never visited again.
+ //
+ // * Example below: Here the old tail key matches the new head
+ // key, so the part at the `oldTail` position and move its
+ // DOM to the new head position (before `oldParts[oldHead]`).
+ // Last, advance `oldTail` and `newHead` pointers.
+ //
+ // oldHead v v oldTail
+ // oldKeys: [0, 1, -, 3, 4, 5, 6]
+ // newParts: [0, 2, 1, 4, , , 6] <- old tail matches new
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] head: update & move 4,
+ // advance oldTail & newHead
+ // newHead ^ ^ newTail
+ //
+ // * Example below: Old and new head keys match, so update the
+ // old head part in place, and advance the `oldHead` and
+ // `newHead` pointers.
+ //
+ // oldHead v oldTail
+ // oldKeys: [0, 1, -, 3, 4, 5, 6]
+ // newParts: [0, 2, 1, 4, 3, ,6] <- heads match: update 3
+ // newKeys: [0, 2, 1, 4, 3, 7, 6] and advance oldHead &
+ // newHead
+ // newHead ^ ^ newTail
+ //
+ // * Once the new or old pointers move past each other then all
+ // we have left is additions (if old list exhausted) or
+ // removals (if new list exhausted). Those are handled in the
+ // final while loops at the end.
+ //
+ // * Example below: `oldHead` exceeded `oldTail`, so we're done
+ // with the main loop. Create the remaining part and insert
+ // it at the new head position, and the update is complete.
+ //
+ // (oldHead > oldTail)
+ // oldKeys: [0, 1, -, 3, 4, 5, 6]
+ // newParts: [0, 2, 1, 4, 3, 7 ,6] <- create and insert 7
+ // newKeys: [0, 2, 1, 4, 3, 7, 6]
+ // newHead ^ newTail
+ //
+ // * Note that the order of the if/else clauses is not
+ // important to the algorithm, as long as the null checks
+ // come first (to ensure we're always working on valid old
+ // parts) and that the final else clause comes last (since
+ // that's where the expensive moves occur). The order of
+ // remaining clauses is is just a simple guess at which cases
+ // will be most common.
+ //
+ // * Note, we could calculate the longest
+ // increasing subsequence (LIS) of old items in new position,
+ // and only move those not in the LIS set. However that costs
+ // O(nlogn) time and adds a bit more code, and only helps
+ // make rare types of mutations require fewer moves. The
+ // above handles removes, adds, reversal, swaps, and single
+ // moves of contiguous items in linear time, in the minimum
+ // number of moves. As the number of multiple moves where LIS
+ // might help approaches a random shuffle, the LIS
+ // optimization becomes less helpful, so it seems not worth
+ // the code at this point. Could reconsider if a compelling
+ // case arises.
+ while (oldHead <= oldTail && newHead <= newTail) {
+ if (oldParts[oldHead] === null) {
+ // `null` means old part at head has already been used
+ // below; skip
+ oldHead++;
+ }
+ else if (oldParts[oldTail] === null) {
+ // `null` means old part at tail has already been used
+ // below; skip
+ oldTail--;
+ }
+ else if (oldKeys[oldHead] === newKeys[newHead]) {
+ // Old head matches new head; update in place
+ newParts[newHead] = setChildPartValue(oldParts[oldHead], newValues[newHead]);
+ oldHead++;
+ newHead++;
+ }
+ else if (oldKeys[oldTail] === newKeys[newTail]) {
+ // Old tail matches new tail; update in place
+ newParts[newTail] = setChildPartValue(oldParts[oldTail], newValues[newTail]);
+ oldTail--;
+ newTail--;
+ }
+ else if (oldKeys[oldHead] === newKeys[newTail]) {
+ // Old head matches new tail; update and move to new tail
+ newParts[newTail] = setChildPartValue(oldParts[oldHead], newValues[newTail]);
+ insertPart(containerPart, newParts[newTail + 1], oldParts[oldHead]);
+ oldHead++;
+ newTail--;
+ }
+ else if (oldKeys[oldTail] === newKeys[newHead]) {
+ // Old tail matches new head; update and move to new head
+ newParts[newHead] = setChildPartValue(oldParts[oldTail], newValues[newHead]);
+ insertPart(containerPart, oldParts[oldHead], oldParts[oldTail]);
+ oldTail--;
+ newHead++;
+ }
+ else {
+ if (newKeyToIndexMap === undefined) {
+ // Lazily generate key-to-index maps, used for removals &
+ // moves below
+ newKeyToIndexMap = generateMap(newKeys, newHead, newTail);
+ oldKeyToIndexMap = generateMap(oldKeys, oldHead, oldTail);
+ }
+ if (!newKeyToIndexMap.has(oldKeys[oldHead])) {
+ // Old head is no longer in new list; remove
+ removePart(oldParts[oldHead]);
+ oldHead++;
+ }
+ else if (!newKeyToIndexMap.has(oldKeys[oldTail])) {
+ // Old tail is no longer in new list; remove
+ removePart(oldParts[oldTail]);
+ oldTail--;
+ }
+ else {
+ // Any mismatches at this point are due to additions or
+ // moves; see if we have an old part we can reuse and move
+ // into place
+ const oldIndex = oldKeyToIndexMap.get(newKeys[newHead]);
+ const oldPart = oldIndex !== undefined ? oldParts[oldIndex] : null;
+ if (oldPart === null) {
+ // No old part for this value; create a new one and
+ // insert it
+ const newPart = insertPart(containerPart, oldParts[oldHead]);
+ setChildPartValue(newPart, newValues[newHead]);
+ newParts[newHead] = newPart;
+ }
+ else {
+ // Reuse old part
+ newParts[newHead] = setChildPartValue(oldPart, newValues[newHead]);
+ insertPart(containerPart, oldParts[oldHead], oldPart);
+ // This marks the old part as having been used, so that
+ // it will be skipped in the first two checks above
+ oldParts[oldIndex] = null;
+ }
+ newHead++;
+ }
+ }
+ }
+ // Add parts for any remaining new values
+ while (newHead <= newTail) {
+ // For all remaining additions, we insert before last new
+ // tail, since old pointers are no longer valid
+ const newPart = insertPart(containerPart, newParts[newTail + 1]);
+ setChildPartValue(newPart, newValues[newHead]);
+ newParts[newHead++] = newPart;
+ }
+ // Remove any remaining unused old parts
+ while (oldHead <= oldTail) {
+ const oldPart = oldParts[oldHead++];
+ if (oldPart !== null) {
+ removePart(oldPart);
+ }
+ }
+ // Save order of new parts for next round
+ this._itemKeys = newKeys;
+ // Directly set part value, bypassing it's dirty-checking
+ setCommittedValue(containerPart, newParts);
+ return noChange;
+ }
+}
+/**
+ * A directive that repeats a series of values (usually `TemplateResults`)
+ * generated from an iterable, and updates those items efficiently when the
+ * iterable changes based on user-provided `keys` associated with each item.
+ *
+ * Note that if a `keyFn` is provided, strict key-to-DOM mapping is maintained,
+ * meaning previous DOM for a given key is moved into the new position if
+ * needed, and DOM will never be reused with values for different keys (new DOM
+ * will always be created for new keys). This is generally the most efficient
+ * way to use `repeat` since it performs minimum unnecessary work for insertions
+ * and removals.
+ *
+ * The `keyFn` takes two parameters, the item and its index, and returns a unique key value.
+ *
+ * ```js
+ * html`
+ * <ol>
+ * ${repeat(this.items, (item) => item.id, (item, index) => {
+ * return html`<li>${index}: ${item.name}</li>`;
+ * })}
+ * </ol>
+ * `
+ * ```
+ *
+ * **Important**: If providing a `keyFn`, keys *must* be unique for all items in a
+ * given call to `repeat`. The behavior when two or more items have the same key
+ * is undefined.
+ *
+ * If no `keyFn` is provided, this directive will perform similar to mapping
+ * items to values, and DOM will be reused against potentially different items.
+ */
+const repeat = directive(RepeatDirective);
+
+/**
+ * @license
+ * Copyright 2018 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class StyleMapDirective extends Directive {
+ constructor(partInfo) {
+ var _a;
+ super(partInfo);
+ if (partInfo.type !== PartType.ATTRIBUTE ||
+ partInfo.name !== 'style' ||
+ ((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) {
+ throw new Error('The `styleMap` directive must be used in the `style` attribute ' +
+ 'and must be the only part in the attribute.');
+ }
+ }
+ render(styleInfo) {
+ return Object.keys(styleInfo).reduce((style, prop) => {
+ return style + prop.slice(0, 0);
+ }, '');
+ }
+ update(part, [styleInfo]) {
+ const { style } = part.element;
+ if (this._previousStyleProperties === undefined) {
+ this._previousStyleProperties = new Set();
+ }
+ // Remove old properties that no longer exist in styleInfo
+ // We use forEach() instead of for-of so that re don't require down-level
+ // iteration.
+ this._previousStyleProperties.forEach((name) => {
+ // If the name isn't in styleInfo or it's null/undefined
+ if (styleInfo[name] == null) {
+ this._previousStyleProperties.delete(name);
+ if (name.includes('-')) {
+ style.removeProperty(name);
+ }
+ else {
+ // Note reset using empty string (vs null) as IE11 does not always
+ // reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ style[name] = '';
+ }
+ }
+ });
+ // Add or update properties
+ for (const name in styleInfo) {
+ const value = styleInfo[name];
+ if (value != null) {
+ this._previousStyleProperties.add(name);
+ if (name.includes('-')) {
+ style.setProperty(name, value);
+ }
+ else {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ style[name] = value;
+ }
+ }
+ }
+ return noChange;
+ }
+}
+/**
+ * A directive that applies CSS properties to an element.
+ *
+ * `styleMap` can only be used in the `style` attribute and must be the only
+ * expression in the attribute. It takes the property names in the
+ * {@link StyleInfo styleInfo} object and adds the property values as CSS
+ * properties. Property names with dashes (`-`) are assumed to be valid CSS
+ * property names and set on the element's style object using `setProperty()`.
+ * Names without dashes are assumed to be camelCased JavaScript property names
+ * and set on the element's style object using property assignment, allowing the
+ * style object to translate JavaScript-style names to CSS property names.
+ *
+ * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size':
+ * '0'})` sets the `background-color`, `border-top` and `--size` properties.
+ *
+ * @param styleInfo
+ * @see {@link https://lit.dev/docs/templates/directives/#stylemap styleMap code samples on Lit.dev}
+ */
+const styleMap = directive(StyleMapDirective);
+
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+class TemplateContentDirective extends Directive {
+ constructor(partInfo) {
+ super(partInfo);
+ if (partInfo.type !== PartType.CHILD) {
+ throw new Error('templateContent can only be used in child bindings');
+ }
+ }
+ render(template) {
+ if (this._previousTemplate === template) {
+ return noChange;
+ }
+ this._previousTemplate = template;
+ return document.importNode(template.content, true);
+ }
+}
+/**
+ * Renders the content of a template element as HTML.
+ *
+ * Note, the template should be developer controlled and not user controlled.
+ * Rendering a user-controlled template with this directive
+ * could lead to cross-site-scripting vulnerabilities.
+ */
+const templateContent = directive(TemplateContentDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const HTML_RESULT = 1;
+class UnsafeHTMLDirective extends Directive {
+ constructor(partInfo) {
+ super(partInfo);
+ this._value = nothing;
+ if (partInfo.type !== PartType.CHILD) {
+ throw new Error(`${this.constructor.directiveName}() can only be used in child bindings`);
+ }
+ }
+ render(value) {
+ if (value === nothing || value == null) {
+ this._templateResult = undefined;
+ return (this._value = value);
+ }
+ if (value === noChange) {
+ return value;
+ }
+ if (typeof value != 'string') {
+ throw new Error(`${this.constructor.directiveName}() called with a non-string value`);
+ }
+ if (value === this._value) {
+ return this._templateResult;
+ }
+ this._value = value;
+ const strings = [value];
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ strings.raw = strings;
+ // WARNING: impersonating a TemplateResult like this is extremely
+ // dangerous. Third-party directives should not do this.
+ return (this._templateResult = {
+ // Cast to a known set of integers that satisfy ResultType so that we
+ // don't have to export ResultType and possibly encourage this pattern.
+ // This property needs to remain unminified.
+ ['_$litType$']: this.constructor
+ .resultType,
+ strings,
+ values: [],
+ });
+ }
+}
+UnsafeHTMLDirective.directiveName = 'unsafeHTML';
+UnsafeHTMLDirective.resultType = HTML_RESULT;
+/**
+ * Renders the result as HTML, rather than text.
+ *
+ * The values `undefined`, `null`, and `nothing`, will all result in no content
+ * (empty string) being rendered.
+ *
+ * Note, this is unsafe to use with any user-provided input that hasn't been
+ * sanitized or escaped, as it may lead to cross-site-scripting
+ * vulnerabilities.
+ */
+const unsafeHTML = directive(UnsafeHTMLDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const SVG_RESULT = 2;
+class UnsafeSVGDirective extends UnsafeHTMLDirective {
+}
+UnsafeSVGDirective.directiveName = 'unsafeSVG';
+UnsafeSVGDirective.resultType = SVG_RESULT;
+/**
+ * Renders the result as SVG, rather than text.
+ *
+ * The values `undefined`, `null`, and `nothing`, will all result in no content
+ * (empty string) being rendered.
+ *
+ * Note, this is unsafe to use with any user-provided input that hasn't been
+ * sanitized or escaped, as it may lead to cross-site-scripting
+ * vulnerabilities.
+ */
+const unsafeSVG = directive(UnsafeSVGDirective);
+
+/**
+ * @license
+ * Copyright 2017 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+const isPromise = (x) => {
+ return !isPrimitive(x) && typeof x.then === 'function';
+};
+// Effectively infinity, but a SMI.
+const _infinity = 0x3fffffff;
+class UntilDirective extends AsyncDirective {
+ constructor() {
+ super(...arguments);
+ this.__lastRenderedIndex = _infinity;
+ this.__values = [];
+ this.__weakThis = new PseudoWeakRef(this);
+ this.__pauser = new Pauser();
+ }
+ render(...args) {
+ var _a;
+ return (_a = args.find((x) => !isPromise(x))) !== null && _a !== void 0 ? _a : noChange;
+ }
+ update(_part, args) {
+ const previousValues = this.__values;
+ let previousLength = previousValues.length;
+ this.__values = args;
+ const weakThis = this.__weakThis;
+ const pauser = this.__pauser;
+ // If our initial render occurs while disconnected, ensure that the pauser
+ // and weakThis are in the disconnected state
+ if (!this.isConnected) {
+ this.disconnected();
+ }
+ for (let i = 0; i < args.length; i++) {
+ // If we've rendered a higher-priority value already, stop.
+ if (i > this.__lastRenderedIndex) {
+ break;
+ }
+ const value = args[i];
+ // Render non-Promise values immediately
+ if (!isPromise(value)) {
+ this.__lastRenderedIndex = i;
+ // Since a lower-priority value will never overwrite a higher-priority
+ // synchronous value, we can stop processing now.
+ return value;
+ }
+ // If this is a Promise we've already handled, skip it.
+ if (i < previousLength && value === previousValues[i]) {
+ continue;
+ }
+ // We have a Promise that we haven't seen before, so priorities may have
+ // changed. Forget what we rendered before.
+ this.__lastRenderedIndex = _infinity;
+ previousLength = 0;
+ // Note, the callback avoids closing over `this` so that the directive
+ // can be gc'ed before the promise resolves; instead `this` is retrieved
+ // from `weakThis`, which can break the hard reference in the closure when
+ // the directive disconnects
+ Promise.resolve(value).then(async (result) => {
+ // If we're disconnected, wait until we're (maybe) reconnected
+ // The while loop here handles the case that the connection state
+ // thrashes, causing the pauser to resume and then get re-paused
+ while (pauser.get()) {
+ await pauser.get();
+ }
+ // If the callback gets here and there is no `this`, it means that the
+ // directive has been disconnected and garbage collected and we don't
+ // need to do anything else
+ const _this = weakThis.deref();
+ if (_this !== undefined) {
+ const index = _this.__values.indexOf(value);
+ // If state.values doesn't contain the value, we've re-rendered without
+ // the value, so don't render it. Then, only render if the value is
+ // higher-priority than what's already been rendered.
+ if (index > -1 && index < _this.__lastRenderedIndex) {
+ _this.__lastRenderedIndex = index;
+ _this.setValue(result);
+ }
+ }
+ });
+ }
+ return noChange;
+ }
+ disconnected() {
+ this.__weakThis.disconnect();
+ this.__pauser.pause();
+ }
+ reconnected() {
+ this.__weakThis.reconnect(this);
+ this.__pauser.resume();
+ }
+}
+/**
+ * Renders one of a series of values, including Promises, to a Part.
+ *
+ * Values are rendered in priority order, with the first argument having the
+ * highest priority and the last argument having the lowest priority. If a
+ * value is a Promise, low-priority values will be rendered until it resolves.
+ *
+ * The priority of values can be used to create placeholder content for async
+ * data. For example, a Promise with pending content can be the first,
+ * highest-priority, argument, and a non_promise loading indicator template can
+ * be used as the second, lower-priority, argument. The loading indicator will
+ * render immediately, and the primary content will render when the Promise
+ * resolves.
+ *
+ * Example:
+ *
+ * ```js
+ * const content = fetch('./content.txt').then(r => r.text());
+ * html`${until(content, html`<span>Loading...</span>`)}`
+ * ```
+ */
+const until = directive(UntilDirective);
+/**
+ * The type of the class that powers this directive. Necessary for naming the
+ * directive's return type.
+ */
+// export type {UntilDirective};
+
+/**
+ * @license
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+function when(condition, trueCase, falseCase) {
+ return condition ? trueCase() : falseCase === null || falseCase === void 0 ? void 0 : falseCase();
+}
+
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/**
+ * Prevents JSON injection attacks.
+ *
+ * The goals of this brand:
+ * 1) fast to check
+ * 2) code is small on the wire
+ * 3) multiple versions of Lit in a single page will all produce mutually
+ * interoperable StaticValues
+ * 4) normal JSON.parse (without an unusual reviver) can not produce a
+ * StaticValue
+ *
+ * Symbols satisfy (1), (2), and (4). We use Symbol.for to satisfy (3), but
+ * we don't care about the key, so we break ties via (2) and use the empty
+ * string.
+ */
+const brand = Symbol.for('');
+/** Safely extracts the string part of a StaticValue. */
+const unwrapStaticValue = (value) => {
+ if ((value === null || value === void 0 ? void 0 : value.r) !== brand) {
+ return undefined;
+ }
+ return value === null || value === void 0 ? void 0 : value['_$litStatic$'];
+};
+/**
+ * Wraps a string so that it behaves like part of the static template
+ * strings instead of a dynamic value.
+ *
+ * Users must take care to ensure that adding the static string to the template
+ * results in well-formed HTML, or else templates may break unexpectedly.
+ *
+ * Note that this function is unsafe to use on untrusted content, as it will be
+ * directly parsed into HTML. Do not pass user input to this function
+ * without sanitizing it.
+ *
+ * Static values can be changed, but they will cause a complete re-render
+ * since they effectively create a new template.
+ */
+const unsafeStatic = (value) => ({
+ ['_$litStatic$']: value,
+ r: brand,
+});
+const textFromStatic = (value) => {
+ if (value['_$litStatic$'] !== undefined) {
+ return value['_$litStatic$'];
+ }
+ else {
+ throw new Error(`Value passed to 'literal' function must be a 'literal' result: ${value}. Use 'unsafeStatic' to pass non-literal values, but
+ take care to ensure page security.`);
+ }
+};
+/**
+ * Tags a string literal so that it behaves like part of the static template
+ * strings instead of a dynamic value.
+ *
+ * The only values that may be used in template expressions are other tagged
+ * `literal` results or `unsafeStatic` values (note that untrusted content
+ * should never be passed to `unsafeStatic`).
+ *
+ * Users must take care to ensure that adding the static string to the template
+ * results in well-formed HTML, or else templates may break unexpectedly.
+ *
+ * Static values can be changed, but they will cause a complete re-render since
+ * they effectively create a new template.
+ */
+const literal = (strings, ...values) => ({
+ ['_$litStatic$']: values.reduce((acc, v, idx) => acc + textFromStatic(v) + strings[idx + 1], strings[0]),
+ r: brand,
+});
+const stringsCache = new Map();
+/**
+ * Wraps a lit-html template tag (`html` or `svg`) to add static value support.
+ */
+const withStatic = (coreTag) => (strings, ...values) => {
+ const l = values.length;
+ let staticValue;
+ let dynamicValue;
+ const staticStrings = [];
+ const dynamicValues = [];
+ let i = 0;
+ let hasStatics = false;
+ let s;
+ while (i < l) {
+ s = strings[i];
+ // Collect any unsafeStatic values, and their following template strings
+ // so that we treat a run of template strings and unsafe static values as
+ // a single template string.
+ while (i < l &&
+ ((dynamicValue = values[i]),
+ (staticValue = unwrapStaticValue(dynamicValue))) !== undefined) {
+ s += staticValue + strings[++i];
+ hasStatics = true;
+ }
+ dynamicValues.push(dynamicValue);
+ staticStrings.push(s);
+ i++;
+ }
+ // If the last value isn't static (which would have consumed the last
+ // string), then we need to add the last string.
+ if (i === l) {
+ staticStrings.push(strings[l]);
+ }
+ if (hasStatics) {
+ const key = staticStrings.join('$$lit$$');
+ strings = stringsCache.get(key);
+ if (strings === undefined) {
+ // Beware: in general this pattern is unsafe, and doing so may bypass
+ // lit's security checks and allow an attacker to execute arbitrary
+ // code and inject arbitrary content.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ staticStrings.raw = staticStrings;
+ stringsCache.set(key, (strings = staticStrings));
+ }
+ values = dynamicValues;
+ }
+ return coreTag(strings, ...values);
+};
+/**
+ * Interprets a template literal as an HTML template that can efficiently
+ * render to and update a container.
+ *
+ * Includes static value support from `lit-html/static.js`.
+ */
+const html = withStatic(html$1);
+/**
+ * Interprets a template literal as an SVG template that can efficiently
+ * render to and update a container.
+ *
+ * Includes static value support from `lit-html/static.js`.
+ */
+const svg = withStatic(svg$1);
+
+export { AsyncDirective, AsyncReplaceDirective, CSSResult, Directive, LitElement, PartType, ReactiveElement, TemplateResultType, UnsafeHTMLDirective, UntilDirective, UpdatingElement, _$LE, _$LH, adoptStyles, asyncAppend, asyncReplace, cache, choose, classMap, clearPart, createRef, css, defaultConverter, directive, getCommittedValue, getCompatibleStyle, getDirectiveClass, guard, html$1 as html, ifDefined, insertPart, isDirectiveResult, isPrimitive, isServer, isSingleExpression, isTemplateResult, join, keyed, literal, live, map, noChange, notEqual, nothing, range, ref, removePart, render, repeat, setChildPartValue, setCommittedValue, html as staticHtml, svg as staticSvg, styleMap, supportsAdoptingStyleSheets, svg$1 as svg, templateContent, unsafeCSS, unsafeHTML, unsafeSVG, unsafeStatic, until, when, withStatic };