mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-11-04 08:29:52 +00:00 
			
		
		
		
	Compare commits
	
		
			18 Commits
		
	
	
		
			button-hea
			...
			copilot/ad
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					1ab3b155d6 | ||
| 
						 | 
					72fe6f1e94 | ||
| 
						 | 
					faf6cb6333 | ||
| 
						 | 
					a2e1e6362b | ||
| 
						 | 
					3212ab6f3b | ||
| 
						 | 
					3d27daad80 | ||
| 
						 | 
					b679f1ce60 | ||
| 
						 | 
					6b0a5d783b | ||
| 
						 | 
					23e2f94d11 | ||
| 
						 | 
					c250777858 | ||
| 
						 | 
					c35d0da9bd | ||
| 
						 | 
					794aa45a2b | ||
| 
						 | 
					d0b85d0c0b | ||
| 
						 | 
					23b6a3a1a9 | ||
| 
						 | 
					43a23e6cdd | ||
| 
						 | 
					aa4dd1cf29 | ||
| 
						 | 
					0ae55c39cc | ||
| 
						 | 
					0bfacacc9e | 
							
								
								
									
										6
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							@@ -36,14 +36,14 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      # Initializes the CodeQL tools for scanning.
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
 | 
			
		||||
        uses: github/codeql-action/init@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
 | 
			
		||||
        with:
 | 
			
		||||
          languages: ${{ matrix.language }}
 | 
			
		||||
 | 
			
		||||
      # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
 | 
			
		||||
      # If this step fails, then you should remove it and run the build manually (see below)
 | 
			
		||||
      - name: Autobuild
 | 
			
		||||
        uses: github/codeql-action/autobuild@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
 | 
			
		||||
        uses: github/codeql-action/autobuild@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
 | 
			
		||||
 | 
			
		||||
      # ℹ️ Command-line programs to run using the OS shell.
 | 
			
		||||
      # 📚 https://git.io/JvXDl
 | 
			
		||||
@@ -57,4 +57,4 @@ jobs:
 | 
			
		||||
      #   make release
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
 | 
			
		||||
        uses: github/codeql-action/analyze@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # v4.30.8
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/release.yaml
									
									
									
									
										vendored
									
									
								
							@@ -55,7 +55,7 @@ jobs:
 | 
			
		||||
          script/release
 | 
			
		||||
 | 
			
		||||
      - name: Upload release assets
 | 
			
		||||
        uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 # v2.3.4
 | 
			
		||||
        uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
 | 
			
		||||
        with:
 | 
			
		||||
          files: |
 | 
			
		||||
            dist/*.whl
 | 
			
		||||
@@ -108,7 +108,7 @@ jobs:
 | 
			
		||||
      - name: Tar folder
 | 
			
		||||
        run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist .
 | 
			
		||||
      - name: Upload release asset
 | 
			
		||||
        uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 # v2.3.4
 | 
			
		||||
        uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
 | 
			
		||||
        with:
 | 
			
		||||
          files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz
 | 
			
		||||
 | 
			
		||||
@@ -137,6 +137,6 @@ jobs:
 | 
			
		||||
      - name: Tar folder
 | 
			
		||||
        run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build .
 | 
			
		||||
      - name: Upload release asset
 | 
			
		||||
        uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 # v2.3.4
 | 
			
		||||
        uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
 | 
			
		||||
        with:
 | 
			
		||||
          files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,9 @@ class HassioIngressView extends LitElement {
 | 
			
		||||
      </hass-subpage>`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return html`${this.narrow || this.hass.dockedSidebar === "always_hidden"
 | 
			
		||||
    return html`${this._addon.webui_ha_aware
 | 
			
		||||
      ? iframe
 | 
			
		||||
      : this.narrow || this.hass.dockedSidebar === "always_hidden"
 | 
			
		||||
        ? html`<div class="header">
 | 
			
		||||
              <ha-icon-button
 | 
			
		||||
                .label=${this.hass.localize("ui.sidebar.sidebar_toggle")}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								package.json
									
									
									
									
									
								
							@@ -34,18 +34,18 @@
 | 
			
		||||
    "@codemirror/legacy-modes": "6.5.2",
 | 
			
		||||
    "@codemirror/search": "6.5.11",
 | 
			
		||||
    "@codemirror/state": "6.5.2",
 | 
			
		||||
    "@codemirror/view": "6.38.4",
 | 
			
		||||
    "@codemirror/view": "6.38.5",
 | 
			
		||||
    "@date-fns/tz": "1.4.1",
 | 
			
		||||
    "@egjs/hammerjs": "2.0.17",
 | 
			
		||||
    "@formatjs/intl-datetimeformat": "6.18.1",
 | 
			
		||||
    "@formatjs/intl-displaynames": "6.8.12",
 | 
			
		||||
    "@formatjs/intl-durationformat": "0.7.5",
 | 
			
		||||
    "@formatjs/intl-datetimeformat": "6.18.2",
 | 
			
		||||
    "@formatjs/intl-displaynames": "6.8.13",
 | 
			
		||||
    "@formatjs/intl-durationformat": "0.7.6",
 | 
			
		||||
    "@formatjs/intl-getcanonicallocales": "2.5.6",
 | 
			
		||||
    "@formatjs/intl-listformat": "7.7.12",
 | 
			
		||||
    "@formatjs/intl-locale": "4.2.12",
 | 
			
		||||
    "@formatjs/intl-numberformat": "8.15.5",
 | 
			
		||||
    "@formatjs/intl-pluralrules": "5.4.5",
 | 
			
		||||
    "@formatjs/intl-relativetimeformat": "11.4.12",
 | 
			
		||||
    "@formatjs/intl-listformat": "7.7.13",
 | 
			
		||||
    "@formatjs/intl-locale": "4.2.13",
 | 
			
		||||
    "@formatjs/intl-numberformat": "8.15.6",
 | 
			
		||||
    "@formatjs/intl-pluralrules": "5.4.6",
 | 
			
		||||
    "@formatjs/intl-relativetimeformat": "11.4.13",
 | 
			
		||||
    "@fullcalendar/core": "6.1.19",
 | 
			
		||||
    "@fullcalendar/daygrid": "6.1.19",
 | 
			
		||||
    "@fullcalendar/interaction": "6.1.19",
 | 
			
		||||
@@ -99,7 +99,7 @@
 | 
			
		||||
    "barcode-detector": "3.0.6",
 | 
			
		||||
    "color-name": "2.0.2",
 | 
			
		||||
    "comlink": "4.4.2",
 | 
			
		||||
    "core-js": "3.45.1",
 | 
			
		||||
    "core-js": "3.46.0",
 | 
			
		||||
    "cropperjs": "1.6.2",
 | 
			
		||||
    "culori": "4.0.2",
 | 
			
		||||
    "date-fns": "4.1.0",
 | 
			
		||||
@@ -114,7 +114,7 @@
 | 
			
		||||
    "hls.js": "1.6.13",
 | 
			
		||||
    "home-assistant-js-websocket": "9.5.0",
 | 
			
		||||
    "idb-keyval": "6.2.2",
 | 
			
		||||
    "intl-messageformat": "10.7.17",
 | 
			
		||||
    "intl-messageformat": "10.7.18",
 | 
			
		||||
    "js-yaml": "4.1.0",
 | 
			
		||||
    "leaflet": "1.9.4",
 | 
			
		||||
    "leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
 | 
			
		||||
@@ -122,7 +122,7 @@
 | 
			
		||||
    "lit": "3.3.1",
 | 
			
		||||
    "lit-html": "3.3.1",
 | 
			
		||||
    "luxon": "3.7.2",
 | 
			
		||||
    "marked": "16.3.0",
 | 
			
		||||
    "marked": "16.4.0",
 | 
			
		||||
    "memoize-one": "6.0.0",
 | 
			
		||||
    "node-vibrant": "4.0.3",
 | 
			
		||||
    "object-hash": "3.0.0",
 | 
			
		||||
@@ -135,7 +135,7 @@
 | 
			
		||||
    "stacktrace-js": "2.0.2",
 | 
			
		||||
    "superstruct": "2.0.2",
 | 
			
		||||
    "tinykeys": "3.0.0",
 | 
			
		||||
    "ua-parser-js": "2.0.5",
 | 
			
		||||
    "ua-parser-js": "2.0.6",
 | 
			
		||||
    "vue": "2.7.16",
 | 
			
		||||
    "vue2-daterange-picker": "0.6.8",
 | 
			
		||||
    "weekstart": "2.0.0",
 | 
			
		||||
@@ -152,7 +152,7 @@
 | 
			
		||||
    "@babel/helper-define-polyfill-provider": "0.6.5",
 | 
			
		||||
    "@babel/plugin-transform-runtime": "7.28.3",
 | 
			
		||||
    "@babel/preset-env": "7.28.3",
 | 
			
		||||
    "@bundle-stats/plugin-webpack-filter": "4.21.4",
 | 
			
		||||
    "@bundle-stats/plugin-webpack-filter": "4.21.5",
 | 
			
		||||
    "@lokalise/node-api": "15.3.0",
 | 
			
		||||
    "@octokit/auth-oauth-device": "8.0.2",
 | 
			
		||||
    "@octokit/plugin-retry": "8.0.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -112,6 +112,7 @@ export interface HassioAddonDetails extends HassioAddonInfo {
 | 
			
		||||
  translations: Record<string, AddonTranslations>;
 | 
			
		||||
  watchdog: null | boolean;
 | 
			
		||||
  webui: null | string;
 | 
			
		||||
  webui_ha_aware: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface HassioAddonsInfo {
 | 
			
		||||
 
 | 
			
		||||
@@ -167,15 +167,12 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return html`<ha-md-button-menu positioning="popover">
 | 
			
		||||
      <ha-button
 | 
			
		||||
      <ha-icon-button
 | 
			
		||||
        slot="trigger"
 | 
			
		||||
        appearance="plain"
 | 
			
		||||
        variant="neutral"
 | 
			
		||||
        size="small"
 | 
			
		||||
        title=${this.hass.localize(`ui.card.media_player.source`)}
 | 
			
		||||
        .title=${this.hass.localize(`ui.card.media_player.source`)}
 | 
			
		||||
        .path=${mdiLoginVariant}
 | 
			
		||||
      >
 | 
			
		||||
        <ha-svg-icon .path=${mdiLoginVariant}></ha-svg-icon>
 | 
			
		||||
      </ha-button>
 | 
			
		||||
      </ha-icon-button>
 | 
			
		||||
      ${this.stateObj.attributes.source_list!.map(
 | 
			
		||||
        (source) =>
 | 
			
		||||
          html`<ha-md-menu-item
 | 
			
		||||
@@ -203,15 +200,12 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return html`<ha-md-button-menu positioning="popover">
 | 
			
		||||
      <ha-button
 | 
			
		||||
      <ha-icon-button
 | 
			
		||||
        slot="trigger"
 | 
			
		||||
        appearance="plain"
 | 
			
		||||
        variant="neutral"
 | 
			
		||||
        size="small"
 | 
			
		||||
        title=${this.hass.localize(`ui.card.media_player.sound_mode`)}
 | 
			
		||||
        .title=${this.hass.localize(`ui.card.media_player.sound_mode`)}
 | 
			
		||||
        .path=${mdiMusicNoteEighth}
 | 
			
		||||
      >
 | 
			
		||||
        <ha-svg-icon .path=${mdiMusicNoteEighth}></ha-svg-icon>
 | 
			
		||||
      </ha-button>
 | 
			
		||||
      </ha-icon-button>
 | 
			
		||||
      ${this.stateObj.attributes.sound_mode_list!.map(
 | 
			
		||||
        (soundMode) =>
 | 
			
		||||
          html`<ha-md-menu-item
 | 
			
		||||
@@ -237,21 +231,17 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
    const groupMembers = this.stateObj.attributes.group_members;
 | 
			
		||||
    const hasMultipleMembers = groupMembers && groupMembers?.length > 1;
 | 
			
		||||
 | 
			
		||||
    return html`<ha-button
 | 
			
		||||
      class="grouping"
 | 
			
		||||
    return html`<ha-icon-button
 | 
			
		||||
      @click=${this._showGroupMediaPlayers}
 | 
			
		||||
      appearance="plain"
 | 
			
		||||
      variant="neutral"
 | 
			
		||||
      size="small"
 | 
			
		||||
      title=${this.hass.localize("ui.card.media_player.join")}
 | 
			
		||||
      .title=${this.hass.localize("ui.card.media_player.join")}
 | 
			
		||||
    >
 | 
			
		||||
      <div>
 | 
			
		||||
      <div class="grouping">
 | 
			
		||||
        <ha-svg-icon .path=${mdiSpeakerMultiple}></ha-svg-icon>
 | 
			
		||||
        ${hasMultipleMembers
 | 
			
		||||
          ? html`<span class="badge">${groupMembers?.length || 4}</span>`
 | 
			
		||||
          : nothing}
 | 
			
		||||
      </div>
 | 
			
		||||
    </ha-button>`;
 | 
			
		||||
    </ha-icon-button>`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected _renderEmptyCover(title: string, icon?: string) {
 | 
			
		||||
@@ -414,48 +404,39 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
          ${!isUnavailableState(stateObj.state) &&
 | 
			
		||||
          supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA)
 | 
			
		||||
            ? html`
 | 
			
		||||
                <ha-button
 | 
			
		||||
                <ha-icon-button
 | 
			
		||||
                  @click=${this._showBrowseMedia}
 | 
			
		||||
                  appearance="plain"
 | 
			
		||||
                  variant="neutral"
 | 
			
		||||
                  size="small"
 | 
			
		||||
                  title=${this.hass.localize(
 | 
			
		||||
                  .title=${this.hass.localize(
 | 
			
		||||
                    "ui.card.media_player.browse_media"
 | 
			
		||||
                  )}
 | 
			
		||||
                  .path=${mdiPlayBoxMultiple}
 | 
			
		||||
                >
 | 
			
		||||
                  <ha-svg-icon .path=${mdiPlayBoxMultiple}></ha-svg-icon>
 | 
			
		||||
                </ha-button>
 | 
			
		||||
                </ha-icon-button>
 | 
			
		||||
              `
 | 
			
		||||
            : nothing}
 | 
			
		||||
          ${this._renderGrouping()} ${this._renderSourceControl()}
 | 
			
		||||
          ${this._renderSoundMode()}
 | 
			
		||||
          ${turnOn
 | 
			
		||||
            ? html`<ha-button
 | 
			
		||||
            ? html`<ha-icon-button
 | 
			
		||||
                action=${turnOn.action}
 | 
			
		||||
                @click=${this._handleClick}
 | 
			
		||||
                appearance="plain"
 | 
			
		||||
                variant="neutral"
 | 
			
		||||
                size="small"
 | 
			
		||||
                title=${this.hass.localize(
 | 
			
		||||
                .title=${this.hass.localize(
 | 
			
		||||
                  `ui.card.media_player.${turnOn.action}`
 | 
			
		||||
                )}
 | 
			
		||||
                .path=${turnOn.icon}
 | 
			
		||||
              >
 | 
			
		||||
                <ha-svg-icon .path=${turnOn.icon}></ha-svg-icon>
 | 
			
		||||
              </ha-button>`
 | 
			
		||||
              </ha-icon-button>`
 | 
			
		||||
            : nothing}
 | 
			
		||||
          ${turnOff
 | 
			
		||||
            ? html`<ha-button
 | 
			
		||||
            ? html`<ha-icon-button
 | 
			
		||||
                action=${turnOff.action}
 | 
			
		||||
                @click=${this._handleClick}
 | 
			
		||||
                appearance="plain"
 | 
			
		||||
                variant="neutral"
 | 
			
		||||
                size="small"
 | 
			
		||||
                title=${this.hass.localize(
 | 
			
		||||
                .title=${this.hass.localize(
 | 
			
		||||
                  `ui.card.media_player.${turnOff.action}`
 | 
			
		||||
                )}
 | 
			
		||||
                .path=${turnOff.icon}
 | 
			
		||||
              >
 | 
			
		||||
                <ha-svg-icon .path=${turnOff.icon}></ha-svg-icon>
 | 
			
		||||
              </ha-button>`
 | 
			
		||||
              </ha-icon-button>`
 | 
			
		||||
            : nothing}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
@@ -579,7 +560,7 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
      font-size: var(--ha-font-size-xs);
 | 
			
		||||
      background-color: var(--primary-color);
 | 
			
		||||
      padding: 0 4px;
 | 
			
		||||
      color: var(--primary-text-color);
 | 
			
		||||
      color: var(--text-primary-color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .position-bar {
 | 
			
		||||
@@ -616,15 +597,15 @@ class MoreInfoMediaPlayer extends LitElement {
 | 
			
		||||
      justify-content: space-around;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .controls-row ha-button {
 | 
			
		||||
      width: 32px;
 | 
			
		||||
    .controls-row ha-icon-button {
 | 
			
		||||
      color: var(--secondary-text-color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .controls-row ha-svg-icon {
 | 
			
		||||
      color: var(--ha-color-on-neutral-quiet);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .grouping::part(label) {
 | 
			
		||||
    .grouping {
 | 
			
		||||
      position: relative;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ import type { PropertyValues } from "lit";
 | 
			
		||||
import { LitElement, css, html, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import { cache } from "lit/directives/cache";
 | 
			
		||||
import { join } from "lit/directives/join";
 | 
			
		||||
import { keyed } from "lit/directives/keyed";
 | 
			
		||||
import { dynamicElement } from "../../common/dom/dynamic-element-directive";
 | 
			
		||||
import { fireEvent } from "../../common/dom/fire_event";
 | 
			
		||||
@@ -33,6 +32,7 @@ import {
 | 
			
		||||
} from "../../common/entity/context/get_entity_context";
 | 
			
		||||
import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event";
 | 
			
		||||
import { navigate } from "../../common/navigate";
 | 
			
		||||
import { computeRTL } from "../../common/util/compute_rtl";
 | 
			
		||||
import "../../components/ha-button-menu";
 | 
			
		||||
import "../../components/ha-dialog";
 | 
			
		||||
import "../../components/ha-dialog-header";
 | 
			
		||||
@@ -361,6 +361,8 @@ export class MoreInfoDialog extends LitElement {
 | 
			
		||||
    );
 | 
			
		||||
    const title = this._childView?.viewTitle || breadcrumb.pop() || entityId;
 | 
			
		||||
 | 
			
		||||
    const isRTL = computeRTL(this.hass);
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      <ha-dialog
 | 
			
		||||
        open
 | 
			
		||||
@@ -394,17 +396,13 @@ export class MoreInfoDialog extends LitElement {
 | 
			
		||||
            ${breadcrumb.length > 0
 | 
			
		||||
              ? !__DEMO__ && isAdmin
 | 
			
		||||
                ? html`
 | 
			
		||||
                    <button
 | 
			
		||||
                      class="breadcrumb"
 | 
			
		||||
                      @click=${this._breadcrumbClick}
 | 
			
		||||
                      aria-label=${breadcrumb.join(" > ")}
 | 
			
		||||
                    >
 | 
			
		||||
                      ${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
 | 
			
		||||
                    <button class="breadcrumb" @click=${this._breadcrumbClick}>
 | 
			
		||||
                      ${breadcrumb.join(isRTL ? " ◂ " : " ▸ ")}
 | 
			
		||||
                    </button>
 | 
			
		||||
                  `
 | 
			
		||||
                : html`
 | 
			
		||||
                    <p class="breadcrumb">
 | 
			
		||||
                      ${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
 | 
			
		||||
                      ${breadcrumb.join(isRTL ? " ◂ " : " ▸ ")}
 | 
			
		||||
                    </p>
 | 
			
		||||
                  `
 | 
			
		||||
              : nothing}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,11 @@
 | 
			
		||||
import { mdiCalendarSync, mdiClose, mdiGestureTap } from "@mdi/js";
 | 
			
		||||
import { mdiCalendarSync, mdiGestureTap } from "@mdi/js";
 | 
			
		||||
import type { CSSResultGroup } from "lit";
 | 
			
		||||
import { LitElement, css, html, nothing } from "lit";
 | 
			
		||||
import { customElement, property, query, state } from "lit/decorators";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import { fireEvent } from "../../../../common/dom/fire_event";
 | 
			
		||||
import "../../../../components/ha-dialog-header";
 | 
			
		||||
import "../../../../components/ha-icon-button";
 | 
			
		||||
import "../../../../components/ha-icon-next";
 | 
			
		||||
import "../../../../components/ha-md-dialog";
 | 
			
		||||
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
 | 
			
		||||
import "../../../../components/ha-md-list";
 | 
			
		||||
import "../../../../components/ha-wa-dialog";
 | 
			
		||||
import "../../../../components/ha-md-list-item";
 | 
			
		||||
import "../../../../components/ha-svg-icon";
 | 
			
		||||
import type { HassDialog } from "../../../../dialogs/make-dialog-manager";
 | 
			
		||||
@@ -24,48 +21,38 @@ class DialogNewBackup extends LitElement implements HassDialog {
 | 
			
		||||
 | 
			
		||||
  @state() private _params?: NewBackupDialogParams;
 | 
			
		||||
 | 
			
		||||
  @query("ha-md-dialog") private _dialog?: HaMdDialog;
 | 
			
		||||
 | 
			
		||||
  public showDialog(params: NewBackupDialogParams): void {
 | 
			
		||||
    this._opened = true;
 | 
			
		||||
    this._params = params;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public closeDialog() {
 | 
			
		||||
    this._dialog?.close();
 | 
			
		||||
    this._opened = false;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _dialogClosed() {
 | 
			
		||||
    if (this._params!.cancel) {
 | 
			
		||||
      this._params!.cancel();
 | 
			
		||||
    if (this._params?.cancel) {
 | 
			
		||||
      this._params.cancel();
 | 
			
		||||
    }
 | 
			
		||||
    if (this._opened) {
 | 
			
		||||
      fireEvent(this, "dialog-closed", { dialog: this.localName });
 | 
			
		||||
    }
 | 
			
		||||
    this._opened = false;
 | 
			
		||||
    this._params = undefined;
 | 
			
		||||
    fireEvent(this, "dialog-closed", { dialog: this.localName });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected render() {
 | 
			
		||||
    if (!this._opened || !this._params) {
 | 
			
		||||
    if (!this._params) {
 | 
			
		||||
      return nothing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      <ha-md-dialog open @closed=${this._dialogClosed}>
 | 
			
		||||
        <ha-dialog-header slot="headline">
 | 
			
		||||
          <ha-icon-button
 | 
			
		||||
            slot="navigationIcon"
 | 
			
		||||
            @click=${this.closeDialog}
 | 
			
		||||
            .label=${this.hass.localize("ui.common.close")}
 | 
			
		||||
            .path=${mdiClose}
 | 
			
		||||
          ></ha-icon-button>
 | 
			
		||||
          <span slot="title">
 | 
			
		||||
            ${this.hass.localize("ui.panel.config.backup.dialogs.new.title")}
 | 
			
		||||
          </span>
 | 
			
		||||
        </ha-dialog-header>
 | 
			
		||||
        <div slot="content">
 | 
			
		||||
      <ha-wa-dialog
 | 
			
		||||
        .hass=${this.hass}
 | 
			
		||||
        .open=${this._opened}
 | 
			
		||||
        header-title=${this.hass.localize(
 | 
			
		||||
          "ui.panel.config.backup.dialogs.new.title"
 | 
			
		||||
        )}
 | 
			
		||||
        @closed=${this._dialogClosed}
 | 
			
		||||
      >
 | 
			
		||||
        <ha-md-list
 | 
			
		||||
          innerRole="listbox"
 | 
			
		||||
          itemRoles="option"
 | 
			
		||||
@@ -73,7 +60,6 @@ class DialogNewBackup extends LitElement implements HassDialog {
 | 
			
		||||
            "ui.panel.config.backup.dialogs.new.options"
 | 
			
		||||
          )}
 | 
			
		||||
          rootTabbable
 | 
			
		||||
            dialogInitialFocus
 | 
			
		||||
        >
 | 
			
		||||
          <ha-md-list-item
 | 
			
		||||
            @click=${this._automatic}
 | 
			
		||||
@@ -108,8 +94,7 @@ class DialogNewBackup extends LitElement implements HassDialog {
 | 
			
		||||
            <ha-icon-next slot="end"></ha-icon-next>
 | 
			
		||||
          </ha-md-list-item>
 | 
			
		||||
        </ha-md-list>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ha-md-dialog>
 | 
			
		||||
      </ha-wa-dialog>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -128,24 +113,13 @@ class DialogNewBackup extends LitElement implements HassDialog {
 | 
			
		||||
      haStyle,
 | 
			
		||||
      haStyleDialog,
 | 
			
		||||
      css`
 | 
			
		||||
        ha-md-dialog {
 | 
			
		||||
        ha-wa-dialog {
 | 
			
		||||
          --dialog-content-padding: 0;
 | 
			
		||||
          max-width: 500px;
 | 
			
		||||
        }
 | 
			
		||||
        @media all and (max-width: 450px), all and (max-height: 500px) {
 | 
			
		||||
          ha-md-dialog {
 | 
			
		||||
            max-width: none;
 | 
			
		||||
          }
 | 
			
		||||
          div[slot="content"] {
 | 
			
		||||
            margin-top: 0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ha-md-list {
 | 
			
		||||
          background: none;
 | 
			
		||||
        }
 | 
			
		||||
        ha-md-list-item {
 | 
			
		||||
        }
 | 
			
		||||
        ha-icon-next {
 | 
			
		||||
          width: 24px;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -128,11 +128,10 @@ class ZHAAddDevicesPage extends LitElement {
 | 
			
		||||
                              this.hass,
 | 
			
		||||
                              "/integrations/zha#adding-devices"
 | 
			
		||||
                            )}
 | 
			
		||||
                          >
 | 
			
		||||
                            ${this.hass.localize(
 | 
			
		||||
                            >${this.hass.localize(
 | 
			
		||||
                              "ui.panel.config.zha.add_device_page.pairing_mode_link"
 | 
			
		||||
                            )}
 | 
			
		||||
                          </a>
 | 
			
		||||
                            )}</a
 | 
			
		||||
                          >
 | 
			
		||||
                        `,
 | 
			
		||||
                      }
 | 
			
		||||
                    )}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
import "../heading-badges/hui-entity-heading-badge";
 | 
			
		||||
import "../heading-badges/hui-button-heading-badge";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  createLovelaceElement,
 | 
			
		||||
@@ -7,7 +6,7 @@ import {
 | 
			
		||||
} from "./create-element-base";
 | 
			
		||||
import type { LovelaceHeadingBadgeConfig } from "../heading-badges/types";
 | 
			
		||||
 | 
			
		||||
const ALWAYS_LOADED_TYPES = new Set(["error", "entity", "button"]);
 | 
			
		||||
const ALWAYS_LOADED_TYPES = new Set(["error", "entity"]);
 | 
			
		||||
 | 
			
		||||
export const createHeadingBadgeElement = (config: LovelaceHeadingBadgeConfig) =>
 | 
			
		||||
  createLovelaceElement(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,238 +0,0 @@
 | 
			
		||||
import { mdiEye, mdiGestureTap, mdiTextShort } from "@mdi/js";
 | 
			
		||||
import { css, html, LitElement, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import memoizeOne from "memoize-one";
 | 
			
		||||
import { any, array, assert, object, optional, string } from "superstruct";
 | 
			
		||||
import { fireEvent } from "../../../../common/dom/fire_event";
 | 
			
		||||
import "../../../../components/ha-expansion-panel";
 | 
			
		||||
import "../../../../components/ha-form/ha-form";
 | 
			
		||||
import type {
 | 
			
		||||
  HaFormSchema,
 | 
			
		||||
  SchemaUnion,
 | 
			
		||||
} from "../../../../components/ha-form/types";
 | 
			
		||||
import type { HomeAssistant } from "../../../../types";
 | 
			
		||||
import type { Condition } from "../../common/validate-condition";
 | 
			
		||||
import type { UiAction } from "../../components/hui-action-editor";
 | 
			
		||||
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
 | 
			
		||||
import type { LovelaceGenericElementEditor } from "../../types";
 | 
			
		||||
import "../conditions/ha-card-conditions-editor";
 | 
			
		||||
import { configElementStyle } from "../config-elements/config-elements-style";
 | 
			
		||||
import { actionConfigStruct } from "../structs/action-struct";
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_CONFIG: Partial<ButtonHeadingBadgeConfig> = {
 | 
			
		||||
  type: "button",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const entityConfigStruct = object({
 | 
			
		||||
  type: optional(string()),
 | 
			
		||||
  text: optional(string()),
 | 
			
		||||
  icon: optional(string()),
 | 
			
		||||
  tap_action: optional(actionConfigStruct),
 | 
			
		||||
  hold_action: optional(actionConfigStruct),
 | 
			
		||||
  double_tap_action: optional(actionConfigStruct),
 | 
			
		||||
  visibility: optional(array(any())),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ALLOWED_ACTIONS: UiAction[] = [
 | 
			
		||||
  "navigate",
 | 
			
		||||
  "url",
 | 
			
		||||
  "assist",
 | 
			
		||||
  "call-service",
 | 
			
		||||
  "none",
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@customElement("hui-heading-button-editor")
 | 
			
		||||
export class HuiHeadingButtonEditor
 | 
			
		||||
  extends LitElement
 | 
			
		||||
  implements LovelaceGenericElementEditor
 | 
			
		||||
{
 | 
			
		||||
  @property({ attribute: false }) public hass?: HomeAssistant;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public preview = false;
 | 
			
		||||
 | 
			
		||||
  @state() private _config?: ButtonHeadingBadgeConfig;
 | 
			
		||||
 | 
			
		||||
  public setConfig(config: ButtonHeadingBadgeConfig): void {
 | 
			
		||||
    assert(config, entityConfigStruct);
 | 
			
		||||
    this._config = {
 | 
			
		||||
      ...DEFAULT_CONFIG,
 | 
			
		||||
      ...config,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _schema = memoizeOne(
 | 
			
		||||
    () =>
 | 
			
		||||
      [
 | 
			
		||||
        {
 | 
			
		||||
          name: "content",
 | 
			
		||||
          type: "expandable",
 | 
			
		||||
          flatten: true,
 | 
			
		||||
          iconPath: mdiTextShort,
 | 
			
		||||
          schema: [
 | 
			
		||||
            {
 | 
			
		||||
              name: "",
 | 
			
		||||
              type: "grid",
 | 
			
		||||
              schema: [
 | 
			
		||||
                {
 | 
			
		||||
                  name: "text",
 | 
			
		||||
                  selector: {
 | 
			
		||||
                    text: {},
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                  name: "icon",
 | 
			
		||||
                  selector: { icon: {} },
 | 
			
		||||
                  context: { icon_entity: "entity" },
 | 
			
		||||
                },
 | 
			
		||||
              ],
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "interactions",
 | 
			
		||||
          type: "expandable",
 | 
			
		||||
          flatten: true,
 | 
			
		||||
          iconPath: mdiGestureTap,
 | 
			
		||||
          schema: [
 | 
			
		||||
            {
 | 
			
		||||
              name: "tap_action",
 | 
			
		||||
              selector: {
 | 
			
		||||
                ui_action: {
 | 
			
		||||
                  default_action: "none",
 | 
			
		||||
                  actions: ALLOWED_ACTIONS,
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              name: "",
 | 
			
		||||
              type: "optional_actions",
 | 
			
		||||
              flatten: true,
 | 
			
		||||
              schema: (["hold_action", "double_tap_action"] as const).map(
 | 
			
		||||
                (action) => ({
 | 
			
		||||
                  name: action,
 | 
			
		||||
                  selector: {
 | 
			
		||||
                    ui_action: {
 | 
			
		||||
                      default_action: "none" as const,
 | 
			
		||||
                      actions: ALLOWED_ACTIONS,
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                })
 | 
			
		||||
              ),
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
      ] as const satisfies readonly HaFormSchema[]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  protected render() {
 | 
			
		||||
    if (!this.hass || !this._config) {
 | 
			
		||||
      return nothing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const schema = this._schema();
 | 
			
		||||
 | 
			
		||||
    const conditions = this._config.visibility ?? [];
 | 
			
		||||
    return html`
 | 
			
		||||
      <ha-form
 | 
			
		||||
        .hass=${this.hass}
 | 
			
		||||
        .data=${this._config}
 | 
			
		||||
        .schema=${schema}
 | 
			
		||||
        .computeLabel=${this._computeLabelCallback}
 | 
			
		||||
        @value-changed=${this._valueChanged}
 | 
			
		||||
      ></ha-form>
 | 
			
		||||
      <ha-expansion-panel outlined>
 | 
			
		||||
        <ha-svg-icon slot="leading-icon" .path=${mdiEye}></ha-svg-icon>
 | 
			
		||||
        <h3 slot="header">
 | 
			
		||||
          ${this.hass!.localize(
 | 
			
		||||
            "ui.panel.lovelace.editor.card.heading.entity_config.visibility"
 | 
			
		||||
          )}
 | 
			
		||||
        </h3>
 | 
			
		||||
        <div class="content">
 | 
			
		||||
          <p class="intro">
 | 
			
		||||
            ${this.hass.localize(
 | 
			
		||||
              "ui.panel.lovelace.editor.card.heading.entity_config.visibility_explanation"
 | 
			
		||||
            )}
 | 
			
		||||
          </p>
 | 
			
		||||
          <ha-card-conditions-editor
 | 
			
		||||
            .hass=${this.hass}
 | 
			
		||||
            .conditions=${conditions}
 | 
			
		||||
            @value-changed=${this._conditionChanged}
 | 
			
		||||
          >
 | 
			
		||||
          </ha-card-conditions-editor>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ha-expansion-panel>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _valueChanged(ev: CustomEvent): void {
 | 
			
		||||
    ev.stopPropagation();
 | 
			
		||||
    if (!this._config || !this.hass) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const config = { ...ev.detail.value } as FormData;
 | 
			
		||||
 | 
			
		||||
    fireEvent(this, "config-changed", { config });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _conditionChanged(ev: CustomEvent): void {
 | 
			
		||||
    ev.stopPropagation();
 | 
			
		||||
    if (!this._config || !this.hass) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const conditions = ev.detail.value as Condition[];
 | 
			
		||||
 | 
			
		||||
    const newConfig: ButtonHeadingBadgeConfig = {
 | 
			
		||||
      ...this._config,
 | 
			
		||||
      visibility: conditions,
 | 
			
		||||
    };
 | 
			
		||||
    if (newConfig.visibility?.length === 0) {
 | 
			
		||||
      delete newConfig.visibility;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fireEvent(this, "config-changed", { config: newConfig });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _computeLabelCallback = (
 | 
			
		||||
    schema: SchemaUnion<ReturnType<typeof this._schema>>
 | 
			
		||||
  ) => {
 | 
			
		||||
    switch (schema.name) {
 | 
			
		||||
      case "text":
 | 
			
		||||
        return this.hass!.localize(
 | 
			
		||||
          `ui.panel.lovelace.editor.card.heading.button_config.${schema.name}`
 | 
			
		||||
        );
 | 
			
		||||
      default:
 | 
			
		||||
        return this.hass!.localize(
 | 
			
		||||
          `ui.panel.lovelace.editor.card.generic.${schema.name}`
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static get styles() {
 | 
			
		||||
    return [
 | 
			
		||||
      configElementStyle,
 | 
			
		||||
      css`
 | 
			
		||||
        .container {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          flex-direction: column;
 | 
			
		||||
        }
 | 
			
		||||
        ha-form {
 | 
			
		||||
          display: block;
 | 
			
		||||
          margin-bottom: 24px;
 | 
			
		||||
        }
 | 
			
		||||
        .intro {
 | 
			
		||||
          margin: 0;
 | 
			
		||||
          color: var(--secondary-text-color);
 | 
			
		||||
          margin-bottom: 8px;
 | 
			
		||||
        }
 | 
			
		||||
      `,
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare global {
 | 
			
		||||
  interface HTMLElementTagNameMap {
 | 
			
		||||
    "hui-heading-button-editor": HuiHeadingButtonEditor;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
import { LitElement, css, html, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import "../../../components/ha-state-icon";
 | 
			
		||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
 | 
			
		||||
import "../../../state-display/state-display";
 | 
			
		||||
import type { HomeAssistant } from "../../../types";
 | 
			
		||||
import { actionHandler } from "../common/directives/action-handler-directive";
 | 
			
		||||
import { handleAction } from "../common/handle-action";
 | 
			
		||||
import { hasAction } from "../common/has-action";
 | 
			
		||||
import { DEFAULT_CONFIG } from "../editor/heading-badge-editor/hui-entity-heading-badge-editor";
 | 
			
		||||
import type {
 | 
			
		||||
  LovelaceHeadingBadge,
 | 
			
		||||
  LovelaceHeadingBadgeEditor,
 | 
			
		||||
} from "../types";
 | 
			
		||||
import type { ButtonHeadingBadgeConfig } from "./types";
 | 
			
		||||
 | 
			
		||||
const DEFAULT_ACTIONS: Pick<
 | 
			
		||||
  ButtonHeadingBadgeConfig,
 | 
			
		||||
  "tap_action" | "hold_action" | "double_tap_action"
 | 
			
		||||
> = {
 | 
			
		||||
  tap_action: { action: "none" },
 | 
			
		||||
  hold_action: { action: "none" },
 | 
			
		||||
  double_tap_action: { action: "none" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@customElement("hui-button-heading-badge")
 | 
			
		||||
export class HuiButtonHeadingBadge
 | 
			
		||||
  extends LitElement
 | 
			
		||||
  implements LovelaceHeadingBadge
 | 
			
		||||
{
 | 
			
		||||
  public static async getConfigElement(): Promise<LovelaceHeadingBadgeEditor> {
 | 
			
		||||
    await import(
 | 
			
		||||
      "../editor/heading-badge-editor/hui-button-heading-badge-editor"
 | 
			
		||||
    );
 | 
			
		||||
    return document.createElement("hui-heading-button-editor");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public hass?: HomeAssistant;
 | 
			
		||||
 | 
			
		||||
  @state() private _config?: ButtonHeadingBadgeConfig;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public preview = false;
 | 
			
		||||
 | 
			
		||||
  public setConfig(config): void {
 | 
			
		||||
    this._config = {
 | 
			
		||||
      ...DEFAULT_CONFIG,
 | 
			
		||||
      ...DEFAULT_ACTIONS,
 | 
			
		||||
      ...config,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get hasAction() {
 | 
			
		||||
    return (
 | 
			
		||||
      hasAction(this._config?.tap_action) ||
 | 
			
		||||
      hasAction(this._config?.hold_action) ||
 | 
			
		||||
      hasAction(this._config?.double_tap_action)
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _handleAction(ev: ActionHandlerEvent) {
 | 
			
		||||
    handleAction(this, this.hass!, this._config!, ev.detail.action!);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected render() {
 | 
			
		||||
    if (!this.hass || !this._config) {
 | 
			
		||||
      return nothing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const config = this._config;
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      <ha-button
 | 
			
		||||
        @action=${this._handleAction}
 | 
			
		||||
        .actionHandler=${actionHandler({
 | 
			
		||||
          hasHold: hasAction(this._config!.hold_action),
 | 
			
		||||
          hasDoubleClick: hasAction(this._config!.double_tap_action),
 | 
			
		||||
        })}
 | 
			
		||||
      >
 | 
			
		||||
        <ha-icon .icon=${config.icon}></ha-icon>
 | 
			
		||||
        ${this._config.text}
 | 
			
		||||
      </ha-button>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static styles = css`
 | 
			
		||||
    [role="button"] {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
    }
 | 
			
		||||
  `;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare global {
 | 
			
		||||
  interface HTMLElementTagNameMap {
 | 
			
		||||
    "hui-button-heading-badge": HuiButtonHeadingBadge;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,12 +26,3 @@ export interface EntityHeadingBadgeConfig extends LovelaceHeadingBadgeConfig {
 | 
			
		||||
  hold_action?: ActionConfig;
 | 
			
		||||
  double_tap_action?: ActionConfig;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ButtonHeadingBadgeConfig extends LovelaceHeadingBadgeConfig {
 | 
			
		||||
  type?: "button";
 | 
			
		||||
  icon: string;
 | 
			
		||||
  text?: string;
 | 
			
		||||
  tap_action: ActionConfig;
 | 
			
		||||
  hold_action?: ActionConfig;
 | 
			
		||||
  double_tap_action?: ActionConfig;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import { isComponentLoaded } from "../../../../common/config/is_component_loaded
 | 
			
		||||
import { generateEntityFilter } from "../../../../common/entity/entity_filter";
 | 
			
		||||
import type { AreaRegistryEntry } from "../../../../data/area_registry";
 | 
			
		||||
import { getEnergyPreferences } from "../../../../data/energy";
 | 
			
		||||
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
 | 
			
		||||
import type {
 | 
			
		||||
  LovelaceSectionConfig,
 | 
			
		||||
  LovelaceSectionRawConfig,
 | 
			
		||||
@@ -15,11 +16,11 @@ import type {
 | 
			
		||||
  AreaCardConfig,
 | 
			
		||||
  HomeSummaryCard,
 | 
			
		||||
  MarkdownCardConfig,
 | 
			
		||||
  TileCardConfig,
 | 
			
		||||
  WeatherForecastCardConfig,
 | 
			
		||||
} from "../../cards/types";
 | 
			
		||||
import { getAreas } from "../areas/helpers/areas-strategy-helper";
 | 
			
		||||
import { getAreas, getFloors } from "../areas/helpers/areas-strategy-helper";
 | 
			
		||||
import type { CommonControlSectionStrategyConfig } from "../usage_prediction/common-controls-section-strategy";
 | 
			
		||||
import { getHomeStructure } from "./helpers/home-structure";
 | 
			
		||||
 | 
			
		||||
export interface HomeMainViewStrategyConfig {
 | 
			
		||||
  type: "home-main";
 | 
			
		||||
@@ -59,25 +60,67 @@ export class HomeMainViewStrategy extends ReactiveElement {
 | 
			
		||||
    hass: HomeAssistant
 | 
			
		||||
  ): Promise<LovelaceViewConfig> {
 | 
			
		||||
    const areas = getAreas(hass.areas);
 | 
			
		||||
    const floors = getFloors(hass.floors);
 | 
			
		||||
 | 
			
		||||
    const areasSection: LovelaceSectionConfig = {
 | 
			
		||||
      type: "grid",
 | 
			
		||||
      column_span: 2,
 | 
			
		||||
      cards: [
 | 
			
		||||
        {
 | 
			
		||||
          type: "heading",
 | 
			
		||||
          heading_style: "title",
 | 
			
		||||
          heading: hass.localize("ui.panel.lovelace.strategy.home.areas"),
 | 
			
		||||
        },
 | 
			
		||||
        ...areas.map<AreaCardConfig>((area) =>
 | 
			
		||||
          computeAreaCard(area.area_id, hass)
 | 
			
		||||
        ),
 | 
			
		||||
      ],
 | 
			
		||||
    };
 | 
			
		||||
    const home = getHomeStructure(floors, areas);
 | 
			
		||||
 | 
			
		||||
    const floorCount = home.floors.length + (home.areas.length ? 1 : 0);
 | 
			
		||||
 | 
			
		||||
    // Allow between 2 and 3 columns (the max should be set to define the width of the header)
 | 
			
		||||
    const maxColumns = 2;
 | 
			
		||||
 | 
			
		||||
    const floorsSections: LovelaceSectionConfig[] = [];
 | 
			
		||||
    for (const floorStructure of home.floors) {
 | 
			
		||||
      const floorId = floorStructure.id;
 | 
			
		||||
      const areaIds = floorStructure.areas;
 | 
			
		||||
      const floor = hass.floors[floorId];
 | 
			
		||||
 | 
			
		||||
      const cards: LovelaceCardConfig[] = [];
 | 
			
		||||
      for (const areaId of areaIds) {
 | 
			
		||||
        cards.push(computeAreaCard(areaId, hass));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (cards.length) {
 | 
			
		||||
        floorsSections.push({
 | 
			
		||||
          type: "grid",
 | 
			
		||||
          column_span: maxColumns,
 | 
			
		||||
          cards: [
 | 
			
		||||
            {
 | 
			
		||||
              type: "heading",
 | 
			
		||||
              heading:
 | 
			
		||||
                floorCount > 1
 | 
			
		||||
                  ? floor.name
 | 
			
		||||
                  : hass.localize("ui.panel.lovelace.strategy.home.areas"),
 | 
			
		||||
              heading_style: "title",
 | 
			
		||||
            },
 | 
			
		||||
            ...cards,
 | 
			
		||||
          ],
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (home.areas.length) {
 | 
			
		||||
      const cards: LovelaceCardConfig[] = [];
 | 
			
		||||
      for (const areaId of home.areas) {
 | 
			
		||||
        cards.push(computeAreaCard(areaId, hass));
 | 
			
		||||
      }
 | 
			
		||||
      floorsSections.push({
 | 
			
		||||
        type: "grid",
 | 
			
		||||
        column_span: maxColumns,
 | 
			
		||||
        cards: [
 | 
			
		||||
          {
 | 
			
		||||
            type: "heading",
 | 
			
		||||
            heading:
 | 
			
		||||
              floorCount > 1
 | 
			
		||||
                ? hass.localize("ui.panel.lovelace.strategy.home.other_areas")
 | 
			
		||||
                : hass.localize("ui.panel.lovelace.strategy.home.areas"),
 | 
			
		||||
            heading_style: "title",
 | 
			
		||||
          },
 | 
			
		||||
          ...cards,
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const favoriteSection: LovelaceSectionConfig = {
 | 
			
		||||
      type: "grid",
 | 
			
		||||
      column_span: maxColumns,
 | 
			
		||||
@@ -87,31 +130,14 @@ export class HomeMainViewStrategy extends ReactiveElement {
 | 
			
		||||
    const favoriteEntities = (config.favorite_entities || []).filter(
 | 
			
		||||
      (entityId) => hass.states[entityId] !== undefined
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (favoriteEntities.length > 0) {
 | 
			
		||||
      favoriteSection.cards!.push(
 | 
			
		||||
        {
 | 
			
		||||
          type: "heading",
 | 
			
		||||
          heading: "",
 | 
			
		||||
          heading_style: "subtitle",
 | 
			
		||||
        },
 | 
			
		||||
        ...favoriteEntities.map(
 | 
			
		||||
          (entityId) =>
 | 
			
		||||
            ({
 | 
			
		||||
              type: "tile",
 | 
			
		||||
              entity: entityId,
 | 
			
		||||
              show_entity_picture: true,
 | 
			
		||||
            }) as TileCardConfig
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    const maxCommonControls = Math.max(8, favoriteEntities.length);
 | 
			
		||||
 | 
			
		||||
    const commonControlsSection = {
 | 
			
		||||
      strategy: {
 | 
			
		||||
        type: "common-controls",
 | 
			
		||||
        title: hass.localize("ui.panel.lovelace.strategy.home.common_controls"),
 | 
			
		||||
        limit: 4,
 | 
			
		||||
        exclude_entities: favoriteEntities,
 | 
			
		||||
        limit: maxCommonControls,
 | 
			
		||||
        include_entities: favoriteEntities,
 | 
			
		||||
        hide_empty: true,
 | 
			
		||||
      } satisfies CommonControlSectionStrategyConfig,
 | 
			
		||||
      column_span: maxColumns,
 | 
			
		||||
@@ -234,7 +260,7 @@ export class HomeMainViewStrategy extends ReactiveElement {
 | 
			
		||||
        favoriteSection.cards && favoriteSection,
 | 
			
		||||
        commonControlsSection,
 | 
			
		||||
        summarySection,
 | 
			
		||||
        areasSection,
 | 
			
		||||
        ...floorsSections,
 | 
			
		||||
        widgetSection.cards && widgetSection,
 | 
			
		||||
      ] satisfies (LovelaceSectionRawConfig | undefined)[]
 | 
			
		||||
    ).filter(Boolean) as LovelaceSectionRawConfig[];
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ export interface CommonControlSectionStrategyConfig {
 | 
			
		||||
  icon?: string;
 | 
			
		||||
  limit?: number;
 | 
			
		||||
  exclude_entities?: string[];
 | 
			
		||||
  include_entities?: string[];
 | 
			
		||||
  hide_empty?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -52,12 +53,23 @@ export class CommonControlsSectionStrategy extends ReactiveElement {
 | 
			
		||||
      (entity) => entity in hass.states
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (config.exclude_entities) {
 | 
			
		||||
    if (config.exclude_entities?.length) {
 | 
			
		||||
      predictedEntities = predictedEntities.filter(
 | 
			
		||||
        (entity) => !config.exclude_entities!.includes(entity)
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.include_entities?.length) {
 | 
			
		||||
      // Remove included entities from predicted list to avoid duplicates
 | 
			
		||||
      predictedEntities = predictedEntities.filter(
 | 
			
		||||
        (entity) => !config.include_entities!.includes(entity)
 | 
			
		||||
      );
 | 
			
		||||
      // Add included entities to the start of the list
 | 
			
		||||
      predictedEntities.unshift(
 | 
			
		||||
        ...config.include_entities!.filter((entity) => entity in hass.states)
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const limit = config.limit ?? DEFAULT_LIMIT;
 | 
			
		||||
    predictedEntities = predictedEntities.slice(0, limit);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,11 @@ export class HuiDialogWebBrowserPlayMedia extends LitElement {
 | 
			
		||||
 | 
			
		||||
  public closeDialog() {
 | 
			
		||||
    this._params = undefined;
 | 
			
		||||
    const img = this.renderRoot.querySelector("img");
 | 
			
		||||
    if (img) {
 | 
			
		||||
      // Unload streaming images so the connection can be closed
 | 
			
		||||
      img.src = "";
 | 
			
		||||
    }
 | 
			
		||||
    fireEvent(this, "dialog-closed", { dialog: this.localName });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7766,9 +7766,6 @@
 | 
			
		||||
                  "state": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements_options::state%]"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              "button_config": {
 | 
			
		||||
                "text": "Text"
 | 
			
		||||
              },
 | 
			
		||||
              "default_heading": "Kitchen"
 | 
			
		||||
            },
 | 
			
		||||
            "map": {
 | 
			
		||||
@@ -7939,7 +7936,7 @@
 | 
			
		||||
              "hide_completed": "Hide completed items",
 | 
			
		||||
              "hide_create": "Hide 'Add item' field",
 | 
			
		||||
              "hide_section_headers": "Hide section headers",
 | 
			
		||||
              "hide_section_headers_helper": "Removes the 'Active' and 'Completed' sections with the overflow menus.",
 | 
			
		||||
              "hide_section_headers_helper": "Removes the 'Active' and 'Completed' section headers and their overflow menus.",
 | 
			
		||||
              "display_order": "Display order",
 | 
			
		||||
              "item_tap_action": "Item tap behavior",
 | 
			
		||||
              "actions": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										210
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										210
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -1206,14 +1206,14 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@bundle-stats/plugin-webpack-filter@npm:4.21.4":
 | 
			
		||||
  version: 4.21.4
 | 
			
		||||
  resolution: "@bundle-stats/plugin-webpack-filter@npm:4.21.4"
 | 
			
		||||
"@bundle-stats/plugin-webpack-filter@npm:4.21.5":
 | 
			
		||||
  version: 4.21.5
 | 
			
		||||
  resolution: "@bundle-stats/plugin-webpack-filter@npm:4.21.5"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tslib: "npm:2.8.1"
 | 
			
		||||
  peerDependencies:
 | 
			
		||||
    core-js: ^3.0.0
 | 
			
		||||
  checksum: 10/67e589755ce6702c92db3e9ca6158d0cbdce5a0c1d92508fae61c0424720121e81c6884efd86392f4906db871e4ba6f97111a55976571cdb79720a47149c027b
 | 
			
		||||
  checksum: 10/a24e4fb0efdd671e8d21116045a22500494198feb451981d40db732cd890b90b7bad9a9f1d7909c8db9a1069f4c6226ae35939b4d865be437ea8e19b989ebcf1
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -1284,15 +1284,15 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@codemirror/view@npm:6.38.4, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
 | 
			
		||||
  version: 6.38.4
 | 
			
		||||
  resolution: "@codemirror/view@npm:6.38.4"
 | 
			
		||||
"@codemirror/view@npm:6.38.5, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0":
 | 
			
		||||
  version: 6.38.5
 | 
			
		||||
  resolution: "@codemirror/view@npm:6.38.5"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@codemirror/state": "npm:^6.5.0"
 | 
			
		||||
    crelt: "npm:^1.0.6"
 | 
			
		||||
    style-mod: "npm:^4.1.0"
 | 
			
		||||
    w3c-keyname: "npm:^2.2.4"
 | 
			
		||||
  checksum: 10/86b3894e9e7c2113aabb1db8684d0520378339c194fa56a688fc26cd7d40336bb9df1f5f19f68309d95f14b80ecf0b70c0ffe5e43f2ec11c4bab18f2d5ee4494
 | 
			
		||||
  checksum: 10/2335b593770042eb3adfe369073432b07cd2d15f1e230ae4dc7be7a7b8edd74e57c13e59b92a11e7e5d59ae030aabf7f55478dfec1cf2a2fe3a1ef3f091676a4
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -1698,15 +1698,15 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/ecma402-abstract@npm:2.3.5":
 | 
			
		||||
  version: 2.3.5
 | 
			
		||||
  resolution: "@formatjs/ecma402-abstract@npm:2.3.5"
 | 
			
		||||
"@formatjs/ecma402-abstract@npm:2.3.6":
 | 
			
		||||
  version: 2.3.6
 | 
			
		||||
  resolution: "@formatjs/ecma402-abstract@npm:2.3.6"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/fast-memoize": "npm:2.2.7"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    decimal.js: "npm:^10.4.3"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/254651057170836237dc4f0fbb372157f97133c4dcee414007e0cdb5b589baf0546c2f6337d117b988ee0a4f0a4d8247780aaa9e96b410c568495f162c40dc50
 | 
			
		||||
  checksum: 10/30b1b5cd6b62ba46245f934429936592df5500bc1b089dc92dd49c826757b873dd92c305dcfe370701e4df6b057bf007782113abb9b65db550d73be4961718bc
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -1719,68 +1719,68 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/icu-messageformat-parser@npm:2.11.3":
 | 
			
		||||
  version: 2.11.3
 | 
			
		||||
  resolution: "@formatjs/icu-messageformat-parser@npm:2.11.3"
 | 
			
		||||
"@formatjs/icu-messageformat-parser@npm:2.11.4":
 | 
			
		||||
  version: 2.11.4
 | 
			
		||||
  resolution: "@formatjs/icu-messageformat-parser@npm:2.11.4"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/icu-skeleton-parser": "npm:1.8.15"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/icu-skeleton-parser": "npm:1.8.16"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/339f5ff5ea7417e2db7f01bd41340f78fd5a8e56a66e723272d21ce7ab4b265dcb45748cdca76eac7137e2b5e6767986812b471e011b4602cf7afbc6da57fb98
 | 
			
		||||
  checksum: 10/2acb100c06c2ade666d72787fb9f9795b1ace41e8e73bfadc2b1a7b8562e81f655e484f0f33d8c39473aa17bf0ad96fb2228871806a9b3dc4f5f876754a0de3a
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/icu-skeleton-parser@npm:1.8.15":
 | 
			
		||||
  version: 1.8.15
 | 
			
		||||
  resolution: "@formatjs/icu-skeleton-parser@npm:1.8.15"
 | 
			
		||||
"@formatjs/icu-skeleton-parser@npm:1.8.16":
 | 
			
		||||
  version: 1.8.16
 | 
			
		||||
  resolution: "@formatjs/icu-skeleton-parser@npm:1.8.16"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/19825abc1a5eef0288456c08420d06f3da8256fbe81db0b9ead48cacc94954d748c8068988e26d184d38fca2e50c191ecda5a10ff3935529c3134b8d80db0538
 | 
			
		||||
  checksum: 10/428001e5bed81889b276a2356a1393157af91dc59220b765a1a132f6407ac5832b7ac6ae9737674ac38e44035295c0c1c310b2630f383f2b5779ea90bf2849e6
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-datetimeformat@npm:6.18.1":
 | 
			
		||||
  version: 6.18.1
 | 
			
		||||
  resolution: "@formatjs/intl-datetimeformat@npm:6.18.1"
 | 
			
		||||
"@formatjs/intl-datetimeformat@npm:6.18.2":
 | 
			
		||||
  version: 6.18.2
 | 
			
		||||
  resolution: "@formatjs/intl-datetimeformat@npm:6.18.2"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    decimal.js: "npm:^10.4.3"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/66938778ecf37472a7e2f1d9349b0ac249fcbd5d684ae5614dea07287876182429980ba2fe3671224f981065baf017ac955f4b3c1f3c924c89bf2ec82dd1acd8
 | 
			
		||||
  checksum: 10/e6f80d0eb2049564502370839697a18858268a0dff8d199b1908137c4a229b1303131c12b8b8a8e8e259a1feba26dbc25b003b150adabea10d1c43f68086efbe
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-displaynames@npm:6.8.12":
 | 
			
		||||
  version: 6.8.12
 | 
			
		||||
  resolution: "@formatjs/intl-displaynames@npm:6.8.12"
 | 
			
		||||
"@formatjs/intl-displaynames@npm:6.8.13":
 | 
			
		||||
  version: 6.8.13
 | 
			
		||||
  resolution: "@formatjs/intl-displaynames@npm:6.8.13"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/7de27ef7e8cde2febce84d5443f00b70062cbd0c3f1039ce8ed1caacb15c4c7a36da16295f26657d59aa4663141a04d7b1083bfd1eea6a4e8ad9dc6093a2c886
 | 
			
		||||
  checksum: 10/adefd25fa42266c7bc33dd3cd50f3681bdce51d18b32a03c98f8ad7587dfd8b9291345e185a4b16f31f4eee10fc799fd1b6361bdfd3a2c9fe127744e1e0f3b07
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-durationformat@npm:0.7.5":
 | 
			
		||||
  version: 0.7.5
 | 
			
		||||
  resolution: "@formatjs/intl-durationformat@npm:0.7.5"
 | 
			
		||||
"@formatjs/intl-durationformat@npm:0.7.6":
 | 
			
		||||
  version: 0.7.6
 | 
			
		||||
  resolution: "@formatjs/intl-durationformat@npm:0.7.6"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/4dc81b112fed25dc8da0a16ddeff033b7c763bf9a1cfd7b1b25c1216f7f147eb67a47059a3cf95b4d4ade150c54a813542b84e69298905a4bc22548d74bf8567
 | 
			
		||||
  checksum: 10/442236ba85bcd9cb7296c43a708271fa09f110b1ca9d5899066d00812fc2965eaeaec6b5240be421b80daba62860352131088449ba0fcd2061f671cec6240f0b
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-enumerator@npm:1.8.11":
 | 
			
		||||
  version: 1.8.11
 | 
			
		||||
  resolution: "@formatjs/intl-enumerator@npm:1.8.11"
 | 
			
		||||
"@formatjs/intl-enumerator@npm:1.8.12":
 | 
			
		||||
  version: 1.8.12
 | 
			
		||||
  resolution: "@formatjs/intl-enumerator@npm:1.8.12"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/8646a517cd4160c1ceff888ec8fdf652caa3d375fa41231e829c13bc7be0cd156c9642e339b75e9cfa8ef60ae8140c766f9055318c62f1c1d9345f25cdb7f426
 | 
			
		||||
  checksum: 10/8dfd7ca5383b4dca530e1df5118a72f71347f4e0daa6131b82dbf7e860a8b96bec0fed43bfa6f6e650e55fa50fcd3e9e3a5253515131b578539d8eaa84630927
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -1793,26 +1793,26 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-listformat@npm:7.7.12":
 | 
			
		||||
  version: 7.7.12
 | 
			
		||||
  resolution: "@formatjs/intl-listformat@npm:7.7.12"
 | 
			
		||||
"@formatjs/intl-listformat@npm:7.7.13":
 | 
			
		||||
  version: 7.7.13
 | 
			
		||||
  resolution: "@formatjs/intl-listformat@npm:7.7.13"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/eee910e83ad28b3b3c24ab6e155720187ae5b5ac936ffa2c8ec6cc8c392c194fd5c79a166290da1c6de8dc1857e3d9d11241029832ec88f7a85cce1821b7f067
 | 
			
		||||
  checksum: 10/476d7cffb64eb996a888b1865aa237f04088de60fa7c65b6d073bca8a3c0f4304040ef12f16eafaf6587895976b773607296951afa7f119447d8f9b2c40daa55
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-locale@npm:4.2.12":
 | 
			
		||||
  version: 4.2.12
 | 
			
		||||
  resolution: "@formatjs/intl-locale@npm:4.2.12"
 | 
			
		||||
"@formatjs/intl-locale@npm:4.2.13":
 | 
			
		||||
  version: 4.2.13
 | 
			
		||||
  resolution: "@formatjs/intl-locale@npm:4.2.13"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/intl-enumerator": "npm:1.8.11"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-enumerator": "npm:1.8.12"
 | 
			
		||||
    "@formatjs/intl-getcanonicallocales": "npm:2.5.6"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/42111a3002a5a2076b3eb012073230f69c62355dc03647bc17f4d0805f39c7e720e2281b359277d020fef623944a5bcc1ddc3dae9a3af74886d876147680147d
 | 
			
		||||
  checksum: 10/865615561b4bad8b8d7d93539cae7eb3ed2d46b6156486ef3ccb1b8f9f46f075c7cf2f6e5325aba1cf07150e19280858dff7dfd86d530fbf45fd31ea4fabf8d4
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -1825,38 +1825,38 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-numberformat@npm:8.15.5":
 | 
			
		||||
  version: 8.15.5
 | 
			
		||||
  resolution: "@formatjs/intl-numberformat@npm:8.15.5"
 | 
			
		||||
"@formatjs/intl-numberformat@npm:8.15.6":
 | 
			
		||||
  version: 8.15.6
 | 
			
		||||
  resolution: "@formatjs/intl-numberformat@npm:8.15.6"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    decimal.js: "npm:^10.4.3"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/3440371a43c54cdd2aa3714cb518ad22e491dd19fbc0c046e712dde078d3f6ed709474376863d64d2bddb506957d1cf265d440f6723b88211044a7b56186e550
 | 
			
		||||
  checksum: 10/674c5fefa0b14fcd7c58d0c0e592b4887dc2563fa5a11d80a0a82328ac12b2bb82b9a5367fa0a4d80060d61d15a1821bca7085e20cad09aa93b87edb3cff68ea
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-pluralrules@npm:5.4.5":
 | 
			
		||||
  version: 5.4.5
 | 
			
		||||
  resolution: "@formatjs/intl-pluralrules@npm:5.4.5"
 | 
			
		||||
"@formatjs/intl-pluralrules@npm:5.4.6":
 | 
			
		||||
  version: 5.4.6
 | 
			
		||||
  resolution: "@formatjs/intl-pluralrules@npm:5.4.6"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    decimal.js: "npm:^10.4.3"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/00f650891893b743d126dd2bf0d17c1b16a8c9e0e0dd94cd0895e66cb556246116263e9603204e1991924814d0ed3a3503765914aff08181d5e4435dfc5e547c
 | 
			
		||||
  checksum: 10/88aa244e69ccfdf459899f5fa3c64df345f451ef91ce1188eab35b7e37daa225d22120f64be633f2cd8b826ea705d19831915118f555f2d17611ee842a9a86dc
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-relativetimeformat@npm:11.4.12":
 | 
			
		||||
  version: 11.4.12
 | 
			
		||||
  resolution: "@formatjs/intl-relativetimeformat@npm:11.4.12"
 | 
			
		||||
"@formatjs/intl-relativetimeformat@npm:11.4.13":
 | 
			
		||||
  version: 11.4.13
 | 
			
		||||
  resolution: "@formatjs/intl-relativetimeformat@npm:11.4.13"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/intl-localematcher": "npm:0.6.2"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/f6adca59738cb7f58d2ea985558d8fc45e567406de6fb6e67894afe790e2a9fa1a19d34853afc36805fa4a3d638e29c62d6c6ba3ec2a85628c240081dcdfebc1
 | 
			
		||||
  checksum: 10/c2058d5f29a13aa216d317d309a6ffd7d203f0fe11696b7bd524e17ac3cc22ae50ad56a26dbf18125e4c115a3e75f01e6cf2134a83df6c7916ae6d3fb21a1e9b
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -6925,10 +6925,10 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"core-js@npm:3.45.1":
 | 
			
		||||
  version: 3.45.1
 | 
			
		||||
  resolution: "core-js@npm:3.45.1"
 | 
			
		||||
  checksum: 10/b9dca79b1af8bb4f0d4af0752ea98d694fe157abaf55513fd4084df32dfd4398f0fc57898b32cdb643c1cecb87b9231c2a2ce535797c80ae328eac6d6078ee61
 | 
			
		||||
"core-js@npm:3.46.0":
 | 
			
		||||
  version: 3.46.0
 | 
			
		||||
  resolution: "core-js@npm:3.46.0"
 | 
			
		||||
  checksum: 10/82993ca487c6cbbf8bbf00e45eeb9705eb63dc2f9c90d7f35696733efbc3f4b52426e1f8dbef0f0b68ea16caa21e4f44cc5490e08120e1cad4a72b031ed8adaa
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -9182,25 +9182,25 @@ __metadata:
 | 
			
		||||
    "@babel/preset-env": "npm:7.28.3"
 | 
			
		||||
    "@babel/runtime": "npm:7.28.4"
 | 
			
		||||
    "@braintree/sanitize-url": "npm:7.1.1"
 | 
			
		||||
    "@bundle-stats/plugin-webpack-filter": "npm:4.21.4"
 | 
			
		||||
    "@bundle-stats/plugin-webpack-filter": "npm:4.21.5"
 | 
			
		||||
    "@codemirror/autocomplete": "npm:6.19.0"
 | 
			
		||||
    "@codemirror/commands": "npm:6.9.0"
 | 
			
		||||
    "@codemirror/language": "npm:6.11.3"
 | 
			
		||||
    "@codemirror/legacy-modes": "npm:6.5.2"
 | 
			
		||||
    "@codemirror/search": "npm:6.5.11"
 | 
			
		||||
    "@codemirror/state": "npm:6.5.2"
 | 
			
		||||
    "@codemirror/view": "npm:6.38.4"
 | 
			
		||||
    "@codemirror/view": "npm:6.38.5"
 | 
			
		||||
    "@date-fns/tz": "npm:1.4.1"
 | 
			
		||||
    "@egjs/hammerjs": "npm:2.0.17"
 | 
			
		||||
    "@formatjs/intl-datetimeformat": "npm:6.18.1"
 | 
			
		||||
    "@formatjs/intl-displaynames": "npm:6.8.12"
 | 
			
		||||
    "@formatjs/intl-durationformat": "npm:0.7.5"
 | 
			
		||||
    "@formatjs/intl-datetimeformat": "npm:6.18.2"
 | 
			
		||||
    "@formatjs/intl-displaynames": "npm:6.8.13"
 | 
			
		||||
    "@formatjs/intl-durationformat": "npm:0.7.6"
 | 
			
		||||
    "@formatjs/intl-getcanonicallocales": "npm:2.5.6"
 | 
			
		||||
    "@formatjs/intl-listformat": "npm:7.7.12"
 | 
			
		||||
    "@formatjs/intl-locale": "npm:4.2.12"
 | 
			
		||||
    "@formatjs/intl-numberformat": "npm:8.15.5"
 | 
			
		||||
    "@formatjs/intl-pluralrules": "npm:5.4.5"
 | 
			
		||||
    "@formatjs/intl-relativetimeformat": "npm:11.4.12"
 | 
			
		||||
    "@formatjs/intl-listformat": "npm:7.7.13"
 | 
			
		||||
    "@formatjs/intl-locale": "npm:4.2.13"
 | 
			
		||||
    "@formatjs/intl-numberformat": "npm:8.15.6"
 | 
			
		||||
    "@formatjs/intl-pluralrules": "npm:5.4.6"
 | 
			
		||||
    "@formatjs/intl-relativetimeformat": "npm:11.4.13"
 | 
			
		||||
    "@fullcalendar/core": "npm:6.1.19"
 | 
			
		||||
    "@fullcalendar/daygrid": "npm:6.1.19"
 | 
			
		||||
    "@fullcalendar/interaction": "npm:6.1.19"
 | 
			
		||||
@@ -9283,7 +9283,7 @@ __metadata:
 | 
			
		||||
    browserslist-useragent-regexp: "npm:4.1.3"
 | 
			
		||||
    color-name: "npm:2.0.2"
 | 
			
		||||
    comlink: "npm:4.4.2"
 | 
			
		||||
    core-js: "npm:3.45.1"
 | 
			
		||||
    core-js: "npm:3.46.0"
 | 
			
		||||
    cropperjs: "npm:1.6.2"
 | 
			
		||||
    culori: "npm:4.0.2"
 | 
			
		||||
    date-fns: "npm:4.1.0"
 | 
			
		||||
@@ -9317,7 +9317,7 @@ __metadata:
 | 
			
		||||
    html-minifier-terser: "npm:7.2.0"
 | 
			
		||||
    husky: "npm:9.1.7"
 | 
			
		||||
    idb-keyval: "npm:6.2.2"
 | 
			
		||||
    intl-messageformat: "npm:10.7.17"
 | 
			
		||||
    intl-messageformat: "npm:10.7.18"
 | 
			
		||||
    js-yaml: "npm:4.1.0"
 | 
			
		||||
    jsdom: "npm:27.0.0"
 | 
			
		||||
    jszip: "npm:3.10.1"
 | 
			
		||||
@@ -9332,7 +9332,7 @@ __metadata:
 | 
			
		||||
    lodash.template: "npm:4.5.0"
 | 
			
		||||
    luxon: "npm:3.7.2"
 | 
			
		||||
    map-stream: "npm:0.0.7"
 | 
			
		||||
    marked: "npm:16.3.0"
 | 
			
		||||
    marked: "npm:16.4.0"
 | 
			
		||||
    memoize-one: "npm:6.0.0"
 | 
			
		||||
    node-vibrant: "npm:4.0.3"
 | 
			
		||||
    object-hash: "npm:3.0.0"
 | 
			
		||||
@@ -9355,7 +9355,7 @@ __metadata:
 | 
			
		||||
    ts-lit-plugin: "npm:2.0.2"
 | 
			
		||||
    typescript: "npm:5.9.3"
 | 
			
		||||
    typescript-eslint: "npm:8.46.0"
 | 
			
		||||
    ua-parser-js: "npm:2.0.5"
 | 
			
		||||
    ua-parser-js: "npm:2.0.6"
 | 
			
		||||
    vite-tsconfig-paths: "npm:5.1.4"
 | 
			
		||||
    vitest: "npm:3.2.4"
 | 
			
		||||
    vue: "npm:2.7.16"
 | 
			
		||||
@@ -9712,15 +9712,15 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"intl-messageformat@npm:10.7.17":
 | 
			
		||||
  version: 10.7.17
 | 
			
		||||
  resolution: "intl-messageformat@npm:10.7.17"
 | 
			
		||||
"intl-messageformat@npm:10.7.18":
 | 
			
		||||
  version: 10.7.18
 | 
			
		||||
  resolution: "intl-messageformat@npm:10.7.18"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.5"
 | 
			
		||||
    "@formatjs/ecma402-abstract": "npm:2.3.6"
 | 
			
		||||
    "@formatjs/fast-memoize": "npm:2.2.7"
 | 
			
		||||
    "@formatjs/icu-messageformat-parser": "npm:2.11.3"
 | 
			
		||||
    "@formatjs/icu-messageformat-parser": "npm:2.11.4"
 | 
			
		||||
    tslib: "npm:^2.8.0"
 | 
			
		||||
  checksum: 10/4f8c30c998bfc14eb64894414b94a8923045ab31d7bbf0978dab6621c644d451ff5c533c04ce8128163b74dd6d59061ec1ef3acb1cbab3302d31cbdb21947620
 | 
			
		||||
  checksum: 10/96650d673912763d21bbfa14b50749b992d45f1901092a020e3155961e3c70f4644dd1731c3ecb1207a1eb94d84bedf4c34b1ac8127c29ad6b015b6a2a4045cb
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -10974,12 +10974,12 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"marked@npm:16.3.0":
 | 
			
		||||
  version: 16.3.0
 | 
			
		||||
  resolution: "marked@npm:16.3.0"
 | 
			
		||||
"marked@npm:16.4.0":
 | 
			
		||||
  version: 16.4.0
 | 
			
		||||
  resolution: "marked@npm:16.4.0"
 | 
			
		||||
  bin:
 | 
			
		||||
    marked: bin/marked.js
 | 
			
		||||
  checksum: 10/60497834b9acfb3b3994222509d359ecb9a197c885dfeb77e2050a287cd2f4ab19f00d5597172b47f9e0c54d9e1e13d8b2dd73322b7838599e1f16d1d6283f5b
 | 
			
		||||
  checksum: 10/5174b345ccc61e2030c2eb8abb3e5cbebeb6697a6d2b609f64ffa2ff6e482f5f1e1fda1912db19c747f43971b1fa54ae53c1ab1ce5d2f58566d6db4bc3016833
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -14379,17 +14379,16 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"ua-parser-js@npm:2.0.5":
 | 
			
		||||
  version: 2.0.5
 | 
			
		||||
  resolution: "ua-parser-js@npm:2.0.5"
 | 
			
		||||
"ua-parser-js@npm:2.0.6":
 | 
			
		||||
  version: 2.0.6
 | 
			
		||||
  resolution: "ua-parser-js@npm:2.0.6"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    detect-europe-js: "npm:^0.1.2"
 | 
			
		||||
    is-standalone-pwa: "npm:^0.1.1"
 | 
			
		||||
    ua-is-frozen: "npm:^0.1.2"
 | 
			
		||||
    undici: "npm:^7.12.0"
 | 
			
		||||
  bin:
 | 
			
		||||
    ua-parser-js: script/cli.js
 | 
			
		||||
  checksum: 10/e946cb1c85bfcd0f2d30c7d5e1b605e340bb458432e7e87fc4aa1b2f90117e4220521d4e0bc7dd8c2a5cadd0935dedb5ac434b70efdc0007221288c1d98b3cd5
 | 
			
		||||
  checksum: 10/b0049d3b272979049c7df6af2ec2ce032e4351316b10c33699f6e3f0bec701336f67530cc3ccb363c554b1bb5047b75d2f46575699afacd6e541762ca3861f4d
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
@@ -14452,13 +14451,6 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"undici@npm:^7.12.0":
 | 
			
		||||
  version: 7.16.0
 | 
			
		||||
  resolution: "undici@npm:7.16.0"
 | 
			
		||||
  checksum: 10/2bb71672b23d3dc0f56f1b7fb6c936e4487a350db46eaafc03f2f9107f99cdf8e51ecdd32e589e2381ef47a64b6369cfb31f328b2c3ea663023aa47bc5258b9e
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"unicode-canonical-property-names-ecmascript@npm:^2.0.0":
 | 
			
		||||
  version: 2.0.1
 | 
			
		||||
  resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user