Compare commits

..

13 Commits

Author SHA1 Message Date
Simon Lamon 0f7806db21 Merge branch 'dev' into pass-browser-list 2026-07-23 19:37:06 +02:00
Simon Lamon 88a3dd7818 Increase JS budgets 2026-07-23 17:29:13 +00:00
Simon Lamon df9cfeab58 Update .github/workflows/demo_deployment.yaml 2026-07-22 18:57:20 +02:00
Simon Lamon a31713a5ea Clean up and add some more documentation 2026-07-22 15:44:26 +00:00
Simon Lamon d5005ba951 Merge branch 'dev' into pass-browser-list 2026-07-22 17:41:03 +02:00
Maarten Lakerveld fa29f86b9d Fix pass-browser-list branch (#53243)
Add failsafe for empty browserlist. Add comment to describe prefix issue in literals. Use default browserlistEnv naming convention. SW uses more efficient browserlist only targeting browsers that support sw.
2026-07-22 17:38:42 +02:00
Simon Lamon 7844938ecd It's going to be green now 2026-07-22 09:54:48 +00:00
Simon Lamon f188f5de07 Getting closer 2026-07-22 09:43:26 +00:00
Simon Lamon ad0ad20cbe Should have read the documentation twice 2026-07-22 09:37:39 +00:00
Simon Lamon 25ed411198 Console logs to debug 2026-07-22 09:28:03 +00:00
Simon Lamon 988cd5ac82 Pass browserlist environment (since it's no longer a babel plugin and no longer set) 2026-07-22 09:02:20 +00:00
Simon Lamon ca074a1c03 Push deployment 2026-07-17 15:41:49 +00:00
Simon Lamon b8be36c5bb Pass browserlist targets to lightningcss 2026-07-14 17:18:12 +00:00
21 changed files with 289 additions and 989 deletions
+8 -8
View File
@@ -1,15 +1,15 @@
{
"_comment": "Initial JS budget (raw/uncompressed bytes) for the cold-load critical entrypoints. Enforced by build-scripts/check-bundle-size.cjs in CI. Re-seed after an intentional change with `--update --headroom=<percent>`.",
"frontend-modern": {
"app": 561513,
"core": 54473,
"authorize": 544272,
"onboarding": 647136
"app": 595204,
"core": 57741,
"authorize": 576928,
"onboarding": 685964
},
"frontend-legacy": {
"app": 790323,
"core": 237208,
"authorize": 765464,
"onboarding": 918679
"app": 861452,
"core": 258557,
"authorize": 834356,
"onboarding": 1001360
}
}
@@ -12,18 +12,42 @@
const remapping = require("@ampproject/remapping");
// minify-literals is ESM-only, so load it via dynamic import from this CJS loader.
let minifyPromise;
const getMinifier = () => {
if (!minifyPromise) {
minifyPromise = import("minify-literals").then((m) => m.minifyHTMLLiterals);
// Also map to cache loader promises per environment (e.g., 'modern', 'legacy')
const loaderInitPromises = new Map();
const initLoader = (browserslistEnv) => {
if (!loaderInitPromises.has(browserslistEnv)) {
loaderInitPromises.set(
browserslistEnv,
Promise.all([
import("minify-literals"),
import("browserslist"),
import("lightningcss"),
]).then(([minifyModule, browserslistModule, lightningcssModule]) => {
const browserslist = browserslistModule.default;
const { browserslistToTargets } = lightningcssModule;
const rawTargets = browserslist(null, { env: browserslistEnv });
if (!rawTargets.length) {
throw new Error(
`No browsers resolved for browserslist environment "${browserslistEnv}"`
);
}
const lightningcssTargets = browserslistToTargets(rawTargets);
return {
minifyHTMLLiterals: minifyModule.minifyHTMLLiterals,
lightningcssTargets,
};
})
);
}
return minifyPromise;
return loaderInitPromises.get(browserslistEnv);
};
// HTML options mirror the previous babel-plugin-template-html-minifier config
// (html-minifier-next is option-compatible with html-minifier-terser). CSS in
// css`` templates and inline <style> is handled by minify-literals' lightningcss
// default.
// css`` templates and inline <style> is handled by minify-literals'
// lightningcss. We pass in the targets from browserslist so lightningcss
// can minify CSS appropriately for the build environment.
//
// `keepClosingSlash` is required for `svg`` templates: SVG elements such as
// `<path />` and `<circle />` are not void elements in HTML, so dropping the
@@ -40,11 +64,16 @@ const htmlOptions = {
module.exports = function minifyTemplateLiteralsLoader(source, map, meta) {
const callback = this.async();
getMinifier()
.then((minifyHTMLLiterals) =>
const { browserslistEnv } = this.getOptions();
initLoader(browserslistEnv)
.then(({ minifyHTMLLiterals, lightningcssTargets }) =>
minifyHTMLLiterals(source, {
fileName: this.resourcePath,
html: htmlOptions,
css: {
targets: lightningcssTargets,
},
})
)
.then((result) => {
+5
View File
@@ -96,6 +96,11 @@ const createRspackConfig = ({
__dirname,
"minify-template-literals-loader.cjs"
),
options: {
browserslistEnv: latestBuild
? "modern"
: `legacy${info.issuerLayer === "sw" ? "-sw" : ""}`,
},
},
!latestBuild &&
info.resource.startsWith(
+18 -23
View File
@@ -41,30 +41,25 @@ class CastDemoRow extends LitElement implements LovelaceRow {
protected firstUpdated(changedProps: PropertyValues<this>) {
super.firstUpdated(changedProps);
import("../../../src/cast/cast_manager").then(({ getCastManager }) =>
getCastManager().then(
(mgr) => {
this._castManager = mgr;
mgr.addEventListener("state-changed", () => {
this.requestUpdate();
});
mgr.castContext.addEventListener(
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
(ev) => {
// On Android, opening a new session always results in SESSION_RESUMED.
// So treat both as the same.
if (
ev.sessionState === "SESSION_STARTED" ||
ev.sessionState === "SESSION_RESUMED"
) {
castSendShowDemo(mgr);
}
getCastManager().then((mgr) => {
this._castManager = mgr;
mgr.addEventListener("state-changed", () => {
this.requestUpdate();
});
mgr.castContext.addEventListener(
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
(ev) => {
// On Android, opening a new session always results in SESSION_RESUMED.
// So treat both as the same.
if (
ev.sessionState === "SESSION_STARTED" ||
ev.sessionState === "SESSION_RESUMED"
) {
castSendShowDemo(mgr);
}
);
},
() => {
this._castManager = null;
}
)
}
);
})
);
}
+6 -6
View File
@@ -115,7 +115,7 @@
"lit": "3.3.3",
"lit-html": "3.3.3",
"luxon": "3.7.2",
"marked": "18.0.7",
"marked": "18.0.6",
"memoize-one": "6.0.0",
"node-vibrant": "4.0.4",
"object-hash": "3.0.0",
@@ -151,8 +151,8 @@
"@octokit/plugin-retry": "8.1.0",
"@octokit/rest": "22.0.1",
"@playwright/test": "1.61.1",
"@rsdoctor/rspack-plugin": "1.6.1",
"@rspack/core": "2.1.5",
"@rsdoctor/rspack-plugin": "1.6.0",
"@rspack/core": "2.1.4",
"@rspack/dev-server": "2.1.0",
"@types/babel__plugin-transform-runtime": "7.9.5",
"@types/chromecast-caf-receiver": "6.0.26",
@@ -203,15 +203,15 @@
"map-stream": "0.0.7",
"minify-literals": "2.1.0",
"pinst": "3.0.0",
"prettier": "3.9.6",
"prettier": "3.9.5",
"rspack-manifest-plugin": "5.2.2",
"serve": "14.2.6",
"sinon": "22.1.0",
"sinon": "22.0.0",
"tar": "7.5.20",
"terser-webpack-plugin": "5.6.1",
"ts-lit-plugin": "2.0.2",
"typescript": "6.0.3",
"typescript-eslint": "8.65.0",
"typescript-eslint": "8.64.0",
"vite-tsconfig-paths": "6.1.1",
"vitest": "4.1.10",
"webpack-stats-plugin": "1.1.3",
+10 -11
View File
@@ -9,17 +9,16 @@ export const castApiAvailable = () => {
loadedPromise = new Promise((resolve) => {
(window as any).__onGCastApiAvailable = resolve;
// Any element with a specific ID will get set as a JS variable on window
// This will override the cast SDK if the iconset is loaded afterwards.
// Conflicting IDs will no longer mess with window, so we'll just append one.
const el = document.createElement("div");
el.id = "cast";
document.body.append(el);
loadJS(
"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
).catch(() => resolve(false));
});
// Any element with a specific ID will get set as a JS variable on window
// This will override the cast SDK if the iconset is loaded afterwards.
// Conflicting IDs will no longer mess with window, so we'll just append one.
const el = document.createElement("div");
el.id = "cast";
document.body.append(el);
loadJS(
"https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
);
return loadedPromise;
};
@@ -1,15 +0,0 @@
import type { EntityIdPart } from "../../data/entity_id_format";
import { slugify } from "../string/slugify";
export const computeEntityIdFormatExample = (
format: EntityIdPart[],
examples: Record<EntityIdPart, string>
): string => {
const parts = format
.map((item) => examples[item])
.filter(Boolean)
.map((part) => slugify(part, "_"))
.filter(Boolean);
return parts.join("_") || "unknown";
};
+1 -1
View File
@@ -126,7 +126,7 @@ export class HaProgressButton extends LitElement {
visibility: hidden;
}
.progress ha-svg-icon {
:host([appearance="brand"]) ha-svg-icon {
color: var(--white-color);
}
`;
-1
View File
@@ -27,7 +27,6 @@ export class HaInputChip extends InputChip {
);
--ha-input-chip-selected-container-opacity: 1;
--md-input-chip-label-text-font: Roboto, sans-serif;
--md-input-chip-label-text-weight: 400;
}
/** Set the size of mdc icons **/
::slotted([slot="icon"]) {
+9 -8
View File
@@ -1,6 +1,7 @@
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import type { HomeAssistant } from "../types";
import { subscribeLabFeature } from "../data/labs";
import { SubscribeMixin } from "../mixins/subscribe-mixin";
@@ -81,14 +82,14 @@ export class HaSnowflakes extends SubscribeMixin(LitElement) {
class="snowflake ${
this.narrow && flake.id >= 30 ? "hide-narrow" : ""
}"
style="
left: ${flake.left}%;
width: ${flake.size}px;
height: ${flake.size}px;
animation-duration: ${flake.duration}s;
animation-delay: ${flake.delay}s;
--rotation: ${flake.rotation}deg;
"
style=${styleMap({
left: `${flake.left}%`,
width: `${flake.size}px`,
height: `${flake.size}px`,
"animation-duration": `${flake.duration}s`,
"animation-delay": `${flake.delay}s`,
"--rotation": `${flake.rotation}deg`,
})}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
@@ -1,22 +0,0 @@
import type { HomeAssistantApi } from "../../types";
import type { EntityIdFormat } from "../entity_id_format";
export interface EntityRegistrySettings {
entity_id_parts: EntityIdFormat | null;
}
export const fetchEntityRegistrySettings = (
api: HomeAssistantApi
): Promise<EntityRegistrySettings> =>
api.callWS<EntityRegistrySettings>({
type: "config/entity_registry/settings/get",
});
export const updateEntityRegistrySettings = (
api: HomeAssistantApi,
updates: Partial<EntityRegistrySettings>
): Promise<EntityRegistrySettings> =>
api.callWS<EntityRegistrySettings>({
type: "config/entity_registry/settings/update",
...updates,
});
-12
View File
@@ -1,12 +0,0 @@
export type EntityIdPart = "area" | "device" | "entity" | "floor";
export type EntityIdFormat = EntityIdPart[];
export const DEFAULT_ENTITY_ID_FORMAT: EntityIdFormat = [
"area",
"device",
"entity",
];
export const isDefaultEntityIdFormat = (format: EntityIdFormat): boolean =>
JSON.stringify(format) === JSON.stringify(DEFAULT_ENTITY_ID_FORMAT);
@@ -145,10 +145,6 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
public connectedCallback() {
super.connectedCallback();
// Re-apply the type filter from the URL when the page is (re)displayed,
// e.g. when navigating back to a cached instance of this page with a
// different `type` query param.
this._setFiltersFromUrl();
window.addEventListener("location-changed", this._locationChanged);
window.addEventListener("popstate", this._popState);
}
-9
View File
@@ -22,7 +22,6 @@ import {
mdiPuzzle,
mdiRadioTower,
mdiRemote,
mdiRenameOutline,
mdiRobot,
mdiScrewdriver,
mdiScriptText,
@@ -495,14 +494,6 @@ export const configSections: Record<string, PageNavigation[]> = {
component: "backup",
adminOnly: true,
},
{
path: "/config/entity-id-format",
translationKey: "entity_id_format",
iconPath: mdiRenameOutline,
iconColor: "#24a5cb",
core: true,
adminOnly: true,
},
{
path: "/config/analytics",
translationKey: "analytics",
@@ -1,229 +0,0 @@
import { consume, type ContextType } from "@lit/context";
import { mdiRestore } from "@mdi/js";
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { consumeLocalize } from "../../../common/decorators/consume-context-entry";
import { computeEntityIdFormatExample } from "../../../common/entity/compute_entity_id_format_example";
import type { LocalizeFunc } from "../../../common/translations/localize";
import type { HaProgressButton } from "../../../components/buttons/ha-progress-button";
import "../../../components/buttons/ha-progress-button";
import "../../../components/ha-alert";
import "../../../components/ha-button";
import "../../../components/ha-card";
import "../../../components/ha-svg-icon";
import { apiContext, configContext } from "../../../data/context";
import {
fetchEntityRegistrySettings,
updateEntityRegistrySettings,
} from "../../../data/entity/entity_registry_settings";
import {
DEFAULT_ENTITY_ID_FORMAT,
isDefaultEntityIdFormat,
type EntityIdFormat,
type EntityIdPart,
} from "../../../data/entity_id_format";
import { haStyle } from "../../../resources/styles";
import { documentationUrl } from "../../../util/documentation-url";
import "./ha-entity-id-format-editor";
const EXAMPLE_DOMAIN = "sensor";
@customElement("ha-config-entity-id-format")
export class HaConfigEntityIdFormat extends LitElement {
@state()
@consumeLocalize()
private _localize!: LocalizeFunc;
@state()
@consume({ context: apiContext, subscribe: true })
private _api!: ContextType<typeof apiContext>;
@state()
@consume({ context: configContext, subscribe: true })
private _config!: ContextType<typeof configContext>;
@state() private _format?: EntityIdFormat;
@state() private _error?: string;
protected async firstUpdated(changedProps: PropertyValues<this>) {
super.firstUpdated(changedProps);
try {
const settings = await fetchEntityRegistrySettings(this._api);
this._format = settings.entity_id_parts ?? DEFAULT_ENTITY_ID_FORMAT;
} catch (err: any) {
this._error = err.message;
}
}
private _examples = memoizeOne(
(localize: LocalizeFunc): Record<EntityIdPart, string> => ({
area: localize(
"ui.panel.config.entity_id_format.card.editor.examples.area"
),
device: localize(
"ui.panel.config.entity_id_format.card.editor.examples.device"
),
entity: localize(
"ui.panel.config.entity_id_format.card.editor.examples.entity"
),
floor: localize(
"ui.panel.config.entity_id_format.card.editor.examples.floor"
),
})
);
protected render() {
return html`
<ha-card
outlined
.header=${this._localize(
"ui.panel.config.entity_id_format.card.header"
)}
>
<div class="card-content">
${
this._error
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
: nothing
}
<p class="description">
${this._localize(
"ui.panel.config.entity_id_format.card.description"
)}
<a
href=${documentationUrl(
this._config,
"/docs/configuration/customizing-devices/"
)}
target="_blank"
rel="noreferrer"
>${this._localize(
"ui.panel.config.entity_id_format.card.learn_more"
)}</a
>
</p>
${
this._format
? html`
<ha-entity-id-format-editor
.value=${this._format}
.label=${this._localize(
"ui.panel.config.entity_id_format.card.editor.label"
)}
@value-changed=${this._formatChanged}
></ha-entity-id-format-editor>
${this._renderPreview()}
`
: nothing
}
</div>
<div class="card-actions">
<ha-button
appearance="plain"
@click=${this._reset}
.disabled=${!this._format || isDefaultEntityIdFormat(this._format)}
>
<ha-svg-icon slot="start" .path=${mdiRestore}></ha-svg-icon>
${this._localize("ui.panel.config.entity_id_format.card.reset")}
</ha-button>
<ha-progress-button
appearance="filled"
@click=${this._save}
.disabled=${!this._format}
>
${this._localize("ui.common.save")}
</ha-progress-button>
</div>
</ha-card>
`;
}
private _renderPreview() {
const example = computeEntityIdFormatExample(
this._format!,
this._examples(this._localize)
);
return html`
<div class="preview">
<span class="preview-label">
${this._localize("ui.panel.config.entity_id_format.card.preview")}
</span>
<code>${EXAMPLE_DOMAIN}.${example}</code>
</div>
`;
}
private _formatChanged(ev: CustomEvent) {
this._format = ev.detail.value;
}
private _reset() {
this._format = [...DEFAULT_ENTITY_ID_FORMAT];
}
private async _save(ev: Event) {
const button = ev.currentTarget as HaProgressButton;
if (button.progress) {
return;
}
button.progress = true;
this._error = undefined;
try {
const format = this._format!;
const settings = await updateEntityRegistrySettings(this._api, {
entity_id_parts: isDefaultEntityIdFormat(format) ? null : format,
});
this._format = settings.entity_id_parts ?? DEFAULT_ENTITY_ID_FORMAT;
button.actionSuccess();
} catch (err: any) {
button.actionError();
this._error = err.message;
} finally {
button.progress = false;
}
}
static styles = [
haStyle,
css`
:host {
display: block;
}
.description {
margin-top: 0;
color: var(--secondary-text-color);
}
.preview {
display: flex;
flex-direction: column;
gap: var(--ha-space-1);
margin-top: var(--ha-space-5);
}
.preview-label {
font-weight: 500;
}
.preview code {
display: block;
padding: var(--ha-space-3);
border-radius: var(--ha-border-radius-md);
background-color: var(--secondary-background-color);
font-family: var(--ha-font-family-code);
overflow-wrap: anywhere;
}
.card-actions {
display: flex;
justify-content: space-between;
align-items: center;
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-config-entity-id-format": HaConfigEntityIdFormat;
}
}
@@ -1,51 +0,0 @@
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../layouts/hass-subpage";
import type { HomeAssistant } from "../../../types";
import "./ha-config-entity-id-format";
@customElement("ha-config-section-entity-id-format")
export class HaConfigSectionEntityIdFormat extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) public narrow = false;
protected render() {
return html`
<hass-subpage
back-path="/config/system"
.hass=${this.hass}
.narrow=${this.narrow}
.header=${this.hass.localize(
"ui.panel.config.entity_id_format.caption"
)}
>
<div class="content">
<ha-config-entity-id-format></ha-config-entity-id-format>
</div>
</hass-subpage>
`;
}
static styles = css`
.content {
padding: var(--ha-space-7) var(--ha-space-5) 0;
max-width: 1040px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: var(--ha-space-5);
}
ha-config-entity-id-format {
max-width: 600px;
margin: 0 auto;
width: 100%;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-config-section-entity-id-format": HaConfigSectionEntityIdFormat;
}
}
@@ -1,348 +0,0 @@
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiDragHorizontalVariant, mdiPlus } from "@mdi/js";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
import memoizeOne from "memoize-one";
import { consumeLocalize } from "../../../common/decorators/consume-context-entry";
import { fireEvent } from "../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../common/translations/localize";
import "../../../components/chips/ha-assist-chip";
import "../../../components/chips/ha-chip-set";
import "../../../components/chips/ha-input-chip";
import "../../../components/ha-combo-box-item";
import "../../../components/ha-generic-picker";
import type { HaGenericPicker } from "../../../components/ha-generic-picker";
import type { PickerComboBoxItem } from "../../../components/ha-picker-combo-box";
import "../../../components/ha-sortable";
import "../../../components/ha-svg-icon";
import type {
EntityIdFormat,
EntityIdPart,
} from "../../../data/entity_id_format";
import type { ValueChangedEvent } from "../../../types";
const STRUCTURAL_TYPES = ["area", "device", "entity", "floor"] as const;
const REQUIRED_TYPES: readonly EntityIdPart[] = ["device", "entity"];
const rowRenderer: RenderItemFunction<PickerComboBoxItem> = (item) => html`
<ha-combo-box-item type="button" compact>
<span slot="headline">${item.primary}</span>
</ha-combo-box-item>
`;
const encodeType = (type: EntityIdPart) => `___${type}___`;
const decodeType = (value: string): EntityIdPart | undefined => {
const type =
value.startsWith("___") && value.endsWith("___")
? value.slice(3, -3)
: value;
return (STRUCTURAL_TYPES as readonly string[]).includes(type)
? (type as EntityIdPart)
: undefined;
};
@customElement("ha-entity-id-format-editor")
export class HaEntityIdFormatEditor extends LitElement {
@state()
@consumeLocalize()
private _localize!: LocalizeFunc;
@property({ attribute: false }) public value: EntityIdFormat = [];
@property() public label?: string;
@property({ type: Boolean, reflect: true }) public disabled = false;
@query("ha-generic-picker") private _picker?: HaGenericPicker;
private _editIndex?: number;
protected render() {
return html`
<div class="container">
${this.label ? html`<label>${this.label}</label>` : nothing}
<ha-generic-picker
.disabled=${this.disabled}
.getItems=${this._getFilteredItems}
.rowRenderer=${rowRenderer}
.value=${this._getPickerValue()}
@value-changed=${this._pickerValueChanged}
.searchLabel=${this._localize(
"ui.panel.config.entity_id_format.card.editor.search"
)}
>
<div slot="field" class="field">
<ha-sortable
no-style
@item-moved=${this._moveItem}
.disabled=${this.disabled}
handle-selector="button.primary.action"
filter=".add"
>
<ha-chip-set>
${repeat(
this.value,
(item) => item,
(item: EntityIdPart, idx) => {
const label = this._formatType(item);
if (REQUIRED_TYPES.includes(item)) {
return html`
<ha-assist-chip
filled
class="required"
.label=${label}
.disabled=${this.disabled}
>
<ha-svg-icon
slot="icon"
.path=${mdiDragHorizontalVariant}
></ha-svg-icon>
</ha-assist-chip>
`;
}
return html`
<ha-input-chip
data-idx=${idx}
@remove=${this._removeItem}
@click=${this._editItem}
.label=${label}
.selected=${!this.disabled}
.disabled=${this.disabled}
>
<ha-svg-icon
slot="icon"
.path=${mdiDragHorizontalVariant}
></ha-svg-icon>
</ha-input-chip>
`;
}
)}
${
this.disabled
? nothing
: html`
<ha-assist-chip
@click=${this._addItem}
.disabled=${this.disabled}
label=${this._localize(
"ui.panel.config.entity_id_format.card.editor.add"
)}
class="add"
>
<ha-svg-icon
slot="icon"
.path=${mdiPlus}
></ha-svg-icon>
</ha-assist-chip>
`
}
</ha-chip-set>
</ha-sortable>
</div>
</ha-generic-picker>
</div>
`;
}
private async _addItem(ev: Event) {
ev.stopPropagation();
this._editIndex = undefined;
await this.updateComplete;
await this._picker?.open();
}
private async _editItem(ev: Event) {
ev.stopPropagation();
const idx = parseInt(
(ev.currentTarget as HTMLElement).dataset.idx || "",
10
);
this._editIndex = idx;
await this.updateComplete;
await this._picker?.open();
}
private _moveItem(ev: CustomEvent) {
ev.stopPropagation();
const { oldIndex, newIndex } = ev.detail;
const newValue = this.value.concat();
const element = newValue.splice(oldIndex, 1)[0];
newValue.splice(newIndex, 0, element);
this._setValue(newValue);
}
private _removeItem(ev: Event) {
ev.stopPropagation();
const value = [...this.value];
const idx = parseInt((ev.target as HTMLElement).dataset.idx || "", 10);
value.splice(idx, 1);
this._setValue(value);
}
private _pickerValueChanged(ev: ValueChangedEvent<string>): void {
ev.stopPropagation();
const value = ev.detail.value;
if (this.disabled || !value) {
return;
}
const type = decodeType(value);
if (!type) {
return;
}
const newValue = [...this.value];
if (this._editIndex != null) {
newValue[this._editIndex] = type;
this._editIndex = undefined;
} else {
newValue.push(type);
}
this._setValue(newValue);
if (this._picker) {
this._picker.value = undefined;
}
}
private _setValue(value: EntityIdFormat) {
this.value = value;
fireEvent(this, "value-changed", { value });
}
private _formatType = (type: EntityIdPart) =>
this._localize(`ui.components.entity.entity-name-picker.types.${type}`);
private _getItems = memoizeOne(
(localize: LocalizeFunc): PickerComboBoxItem[] =>
STRUCTURAL_TYPES.map((type) => {
const primary = localize(
`ui.components.entity.entity-name-picker.types.${type}`
);
const id = encodeType(type);
return {
id,
primary,
search_labels: { primary, id },
sorting_label: primary,
};
})
);
private _getPickerValue(): string | undefined {
if (this._editIndex != null) {
const item = this.value[this._editIndex];
return item ? encodeType(item) : undefined;
}
return undefined;
}
private _getFilteredItems = (): PickerComboBoxItem[] => {
const items = this._getItems(this._localize);
const currentValue =
this._editIndex != null
? encodeType(this.value[this._editIndex])
: undefined;
const usedValues = new Set(this.value.map((item) => encodeType(item)));
return items.filter(
(item) => !usedValues.has(item.id) || item.id === currentValue
);
};
static styles = css`
:host {
position: relative;
width: 100%;
}
.container {
display: flex;
flex-direction: column;
gap: var(--ha-space-2);
}
label {
display: block;
font-weight: 500;
}
ha-generic-picker {
width: 100%;
}
.field {
position: relative;
background-color: var(--mdc-text-field-fill-color, whitesmoke);
border-radius: var(--ha-border-radius-sm);
border-end-end-radius: var(--ha-border-radius-square);
border-end-start-radius: var(--ha-border-radius-square);
}
.field:after {
display: block;
content: "";
position: absolute;
pointer-events: none;
bottom: 0;
left: 0;
right: 0;
height: 1px;
width: 100%;
background-color: var(
--mdc-text-field-idle-line-color,
rgba(0, 0, 0, 0.42)
);
}
:host([disabled]) .field:after {
background-color: var(
--mdc-text-field-disabled-line-color,
rgba(0, 0, 0, 0.42)
);
}
.field:focus-within:after {
height: 2px;
background-color: var(--mdc-theme-primary);
}
ha-chip-set {
padding: var(--ha-space-3);
}
ha-assist-chip.required {
--ha-assist-chip-filled-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
}
.add {
order: 1;
}
.sortable-fallback {
display: none;
opacity: 0;
}
.sortable-ghost {
opacity: 0.4;
}
.sortable-drag {
cursor: grabbing;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-entity-id-format-editor": HaEntityIdFormatEditor;
}
}
-4
View File
@@ -170,10 +170,6 @@ class HaPanelConfig extends HassRouterPage {
tag: "ha-config-section-ai-tasks",
load: () => import("./core/ha-config-section-ai-tasks"),
},
"entity-id-format": {
tag: "ha-config-section-entity-id-format",
load: () => import("./core/ha-config-section-entity-id-format"),
},
zha: {
tag: "zha-config-dashboard-router",
load: () =>
@@ -34,8 +34,6 @@ export const supportsTrendGraphCardFeature = (
export const DEFAULT_HOURS_TO_SHOW = 24;
const HOUR = 60 * 60 * 1000;
@customElement("hui-trend-graph-card-feature")
class HuiHistoryChartCardFeature
extends LitElement
@@ -95,13 +93,9 @@ class HuiHistoryChartCardFeature
public connectedCallback() {
super.connectedCallback();
// recompute the graph every minute so the x-axis (and the horizontal fill
// to now) keeps advancing even while the sensor value stays constant
// redraw the graph every minute to update the time axis
clearInterval(this._interval);
this._interval = window.setInterval(
() => this._calculateCoordinates(),
1000 * 60
);
this._interval = window.setInterval(() => this.requestUpdate(), 1000 * 60);
if (this.hasUpdated) {
this._subscribeHistory();
}
@@ -152,18 +146,12 @@ class HuiHistoryChartCardFeature
? Math.max(10, width / 5, hourToShow)
: Math.max(10, hourToShow);
const useMean = !detail;
// Anchor the x-axis to the full time window so a constant value is drawn as
// a horizontal line up to now, instead of ending at the last state change.
const now = Date.now();
const { points, yAxisOrigin } = coordinatesMinimalResponseCompressedState(
this._stateHistory,
width,
height,
maxDetails,
{
minX: now - hourToShow * HOUR,
maxX: now,
},
undefined,
useMean
);
this._coordinates = points;
-22
View File
@@ -8599,28 +8599,6 @@
"caption": "AI tasks",
"description": "Configure AI suggestions and task preferences"
},
"entity_id_format": {
"caption": "Entity ID format",
"description": "Manage the format of newly created entity IDs",
"card": {
"header": "Entity ID format for new entities",
"description": "Entity IDs are used to reference entities in automations, scripts, and dashboards. This format only applies when a new entity is created. Using it is optional, and you can still rename each entity ID afterwards in its settings",
"learn_more": "Learn more",
"preview": "Preview",
"reset": "Reset to default",
"editor": {
"label": "Format",
"add": "Add",
"search": "Search part",
"examples": {
"area": "Living room",
"device": "Thermostat",
"entity": "Temperature",
"floor": "Ground floor"
}
}
}
},
"labs": {
"caption": "Labs",
"custom_integration": "Custom integration",
+191 -191
View File
@@ -4638,22 +4638,22 @@ __metadata:
languageName: node
linkType: hard
"@rsdoctor/client@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/client@npm:1.6.1"
checksum: 10/aefc3a378e3ecdc9f03c21272dfb06d4eb68ca5395d83edb0a44fd816ea96b45e894de8c862e605fcb02611d306014ffef4ca09723945cf75c9a33b7062d5d4b
"@rsdoctor/client@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/client@npm:1.6.0"
checksum: 10/c6311104c59978d486146d6e2e80fe2e58c1f783a21a2a5ede6dc2db59ab4db86a2f551b8b54cfad01df06bc28e3def8792cea2fa2f68f07861d4f2b0cf56503
languageName: node
linkType: hard
"@rsdoctor/core@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/core@npm:1.6.1"
"@rsdoctor/core@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/core@npm:1.6.0"
dependencies:
"@rsbuild/plugin-check-syntax": "npm:^1.6.1"
"@rsdoctor/graph": "npm:1.6.1"
"@rsdoctor/sdk": "npm:1.6.1"
"@rsdoctor/types": "npm:1.6.1"
"@rsdoctor/utils": "npm:1.6.1"
"@rsdoctor/graph": "npm:1.6.0"
"@rsdoctor/sdk": "npm:1.6.0"
"@rsdoctor/types": "npm:1.6.0"
"@rsdoctor/utils": "npm:1.6.0"
"@rspack/resolver": "npm:^0.2.8"
browserslist-load-config: "npm:^1.0.2"
es-toolkit: "npm:^1.49.0"
@@ -4661,60 +4661,60 @@ __metadata:
fs-extra: "npm:^11.1.1"
semver: "npm:^7.8.5"
source-map: "npm:^0.7.6"
checksum: 10/de5708e15e1efd67a23d753ed906e573ca6a6857428dbdfea0aff2f85f1ed3f631ff34e23bf40e955855ed878ed548c073c620a4edbd12959c20a3f9ff9c1cfd
checksum: 10/6e39bd687844fb309dfb294278dec0fcfabc50edd1e42bac51bff30504971a3567bf344156d6cb63078ba441d5f78a3032e8b3cd487598e5a5903f5034dea8ed
languageName: node
linkType: hard
"@rsdoctor/graph@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/graph@npm:1.6.1"
"@rsdoctor/graph@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/graph@npm:1.6.0"
dependencies:
"@rsdoctor/types": "npm:1.6.1"
"@rsdoctor/utils": "npm:1.6.1"
"@rsdoctor/types": "npm:1.6.0"
"@rsdoctor/utils": "npm:1.6.0"
es-toolkit: "npm:^1.49.0"
path-browserify: "npm:1.0.1"
source-map: "npm:^0.7.6"
checksum: 10/065c485f11939143021c12a1acff47a2539c22e9a9d5f8501c906578213ca16b71a35d08bc0a83035529d42a7906fc098b6e3c536d895cd13ee74b5340a39e40
checksum: 10/21ec99112e34f2fd855e44e6f82c4b791a90023b2e5fd23439874b23bc295f8e614134d089eeea2a7f9ec4e482daf539eafbc5af0bd6013a71572cedb8ecd0ef
languageName: node
linkType: hard
"@rsdoctor/rspack-plugin@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/rspack-plugin@npm:1.6.1"
"@rsdoctor/rspack-plugin@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/rspack-plugin@npm:1.6.0"
dependencies:
"@rsdoctor/core": "npm:1.6.1"
"@rsdoctor/graph": "npm:1.6.1"
"@rsdoctor/sdk": "npm:1.6.1"
"@rsdoctor/types": "npm:1.6.1"
"@rsdoctor/utils": "npm:1.6.1"
"@rsdoctor/core": "npm:1.6.0"
"@rsdoctor/graph": "npm:1.6.0"
"@rsdoctor/sdk": "npm:1.6.0"
"@rsdoctor/types": "npm:1.6.0"
"@rsdoctor/utils": "npm:1.6.0"
peerDependencies:
"@rspack/core": "*"
peerDependenciesMeta:
"@rspack/core":
optional: true
checksum: 10/8908f4a3c2b46fdaba2c6d39dd535623ddcc411fb50d358de949142a5628a512827f5206a93ae975bd93e5de6b72d5cd71f63463c65a37ba718727567187ce8e
checksum: 10/88b68253c81a07048f9f33197a50a91381a1587137d822c9fa6fee51c346926f79bc4f57c1cec8afe8639539520b31c1daa74e4a22ce293d8109ef2beff9904e
languageName: node
linkType: hard
"@rsdoctor/sdk@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/sdk@npm:1.6.1"
"@rsdoctor/sdk@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/sdk@npm:1.6.0"
dependencies:
"@rsdoctor/client": "npm:1.6.1"
"@rsdoctor/graph": "npm:1.6.1"
"@rsdoctor/types": "npm:1.6.1"
"@rsdoctor/utils": "npm:1.6.1"
"@rsdoctor/client": "npm:1.6.0"
"@rsdoctor/graph": "npm:1.6.0"
"@rsdoctor/types": "npm:1.6.0"
"@rsdoctor/utils": "npm:1.6.0"
launch-editor: "npm:^2.13.2"
safer-buffer: "npm:2.1.2"
socket.io: "npm:4.8.1"
tapable: "npm:2.3.3"
checksum: 10/d667d62d730bed7606bcf1ed2063fb7597024e31d9108c3ba9729313764866407c216499ccb3c7102f239d7d82463e510f2b2ec71270af6a40039cbe6f876d23
checksum: 10/f16cb445a6669ae8427b14228de4d049b64ff81b139b5c614663ad7407fe111590fde9cecd1c10a633753d3118ba042c737622720149cf2db5ae2799fa38a673
languageName: node
linkType: hard
"@rsdoctor/types@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/types@npm:1.6.1"
"@rsdoctor/types@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/types@npm:1.6.0"
dependencies:
"@types/connect": "npm:3.4.38"
"@types/estree": "npm:1.0.5"
@@ -4728,16 +4728,16 @@ __metadata:
optional: true
webpack:
optional: true
checksum: 10/1c4ae6c1aa6fa525d65ab78396954d86358880959ee3fdb68247c2f3215a35e4cb2aab3836cb82f6c208c2c3834cfe0dc8bf575ba59fd8e2ff89ffc92322fcad
checksum: 10/7348ceaab14d2d5365ca038b3b555576034456c6a135b4cd2bff6d2eef9039072492d3cdcb0841f609a49197dbcbc9005c89026b89370e25f1aa7231fb484942
languageName: node
linkType: hard
"@rsdoctor/utils@npm:1.6.1":
version: 1.6.1
resolution: "@rsdoctor/utils@npm:1.6.1"
"@rsdoctor/utils@npm:1.6.0":
version: 1.6.0
resolution: "@rsdoctor/utils@npm:1.6.0"
dependencies:
"@babel/code-frame": "npm:7.26.2"
"@rsdoctor/types": "npm:1.6.1"
"@rsdoctor/types": "npm:1.6.0"
"@types/estree": "npm:1.0.5"
acorn: "npm:^8.10.0"
acorn-import-attributes: "npm:^1.9.5"
@@ -4751,69 +4751,69 @@ __metadata:
picocolors: "npm:^1.1.1"
rslog: "npm:^2.1.2"
strip-ansi: "npm:^7.2.0"
checksum: 10/11f4e9136dd849fa05b0ab56ab0de3be3de43880d530dcbfb1835780dccad9976636f6a743852893948ae053e71fb7cd6144cac3ffac27929a87710e3981c048
checksum: 10/a01a68837abf5e47d979757bb8b59f68838beaf80a85acc462e89671155adf51fed68ac41780aeb36eae45e93baff1269757446970e58d5663b2ad5661db465a
languageName: node
linkType: hard
"@rspack/binding-darwin-arm64@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-darwin-arm64@npm:2.1.5"
"@rspack/binding-darwin-arm64@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-darwin-arm64@npm:2.1.4"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@rspack/binding-darwin-x64@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-darwin-x64@npm:2.1.5"
"@rspack/binding-darwin-x64@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-darwin-x64@npm:2.1.4"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@rspack/binding-linux-arm64-gnu@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-arm64-gnu@npm:2.1.5"
"@rspack/binding-linux-arm64-gnu@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-arm64-gnu@npm:2.1.4"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@rspack/binding-linux-arm64-musl@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-arm64-musl@npm:2.1.5"
"@rspack/binding-linux-arm64-musl@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-arm64-musl@npm:2.1.4"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@rspack/binding-linux-riscv64-gnu@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-riscv64-gnu@npm:2.1.5"
"@rspack/binding-linux-riscv64-gnu@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-riscv64-gnu@npm:2.1.4"
conditions: os=linux & cpu=riscv64 & libc=glibc
languageName: node
linkType: hard
"@rspack/binding-linux-riscv64-musl@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-riscv64-musl@npm:2.1.5"
"@rspack/binding-linux-riscv64-musl@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-riscv64-musl@npm:2.1.4"
conditions: os=linux & cpu=riscv64 & libc=musl
languageName: node
linkType: hard
"@rspack/binding-linux-x64-gnu@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-x64-gnu@npm:2.1.5"
"@rspack/binding-linux-x64-gnu@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-x64-gnu@npm:2.1.4"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@rspack/binding-linux-x64-musl@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-linux-x64-musl@npm:2.1.5"
"@rspack/binding-linux-x64-musl@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-linux-x64-musl@npm:2.1.4"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@rspack/binding-wasm32-wasi@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-wasm32-wasi@npm:2.1.5"
"@rspack/binding-wasm32-wasi@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-wasm32-wasi@npm:2.1.4"
dependencies:
"@emnapi/core": "npm:1.11.2"
"@emnapi/runtime": "npm:1.11.2"
@@ -4822,43 +4822,43 @@ __metadata:
languageName: node
linkType: hard
"@rspack/binding-win32-arm64-msvc@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-win32-arm64-msvc@npm:2.1.5"
"@rspack/binding-win32-arm64-msvc@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-win32-arm64-msvc@npm:2.1.4"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@rspack/binding-win32-ia32-msvc@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-win32-ia32-msvc@npm:2.1.5"
"@rspack/binding-win32-ia32-msvc@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-win32-ia32-msvc@npm:2.1.4"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@rspack/binding-win32-x64-msvc@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding-win32-x64-msvc@npm:2.1.5"
"@rspack/binding-win32-x64-msvc@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding-win32-x64-msvc@npm:2.1.4"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@rspack/binding@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/binding@npm:2.1.5"
"@rspack/binding@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/binding@npm:2.1.4"
dependencies:
"@rspack/binding-darwin-arm64": "npm:2.1.5"
"@rspack/binding-darwin-x64": "npm:2.1.5"
"@rspack/binding-linux-arm64-gnu": "npm:2.1.5"
"@rspack/binding-linux-arm64-musl": "npm:2.1.5"
"@rspack/binding-linux-riscv64-gnu": "npm:2.1.5"
"@rspack/binding-linux-riscv64-musl": "npm:2.1.5"
"@rspack/binding-linux-x64-gnu": "npm:2.1.5"
"@rspack/binding-linux-x64-musl": "npm:2.1.5"
"@rspack/binding-wasm32-wasi": "npm:2.1.5"
"@rspack/binding-win32-arm64-msvc": "npm:2.1.5"
"@rspack/binding-win32-ia32-msvc": "npm:2.1.5"
"@rspack/binding-win32-x64-msvc": "npm:2.1.5"
"@rspack/binding-darwin-arm64": "npm:2.1.4"
"@rspack/binding-darwin-x64": "npm:2.1.4"
"@rspack/binding-linux-arm64-gnu": "npm:2.1.4"
"@rspack/binding-linux-arm64-musl": "npm:2.1.4"
"@rspack/binding-linux-riscv64-gnu": "npm:2.1.4"
"@rspack/binding-linux-riscv64-musl": "npm:2.1.4"
"@rspack/binding-linux-x64-gnu": "npm:2.1.4"
"@rspack/binding-linux-x64-musl": "npm:2.1.4"
"@rspack/binding-wasm32-wasi": "npm:2.1.4"
"@rspack/binding-win32-arm64-msvc": "npm:2.1.4"
"@rspack/binding-win32-ia32-msvc": "npm:2.1.4"
"@rspack/binding-win32-x64-msvc": "npm:2.1.4"
dependenciesMeta:
"@rspack/binding-darwin-arm64":
optional: true
@@ -4884,15 +4884,15 @@ __metadata:
optional: true
"@rspack/binding-win32-x64-msvc":
optional: true
checksum: 10/d1054348d3ba734485f977d574c6311311707adfcc5e53f03c8dbbbdc5778cff9b815e1d675992e2832241606d4cce7678acc3999b259139120b4ec30751f1e1
checksum: 10/425bf152dba708992ce16114ce6bc8dfa424071694e85201317518dce1899eeae873a2adbd23b214bb8d223f7290e000fd78ad9bf262c633e12d3d4ff73bbdcd
languageName: node
linkType: hard
"@rspack/core@npm:2.1.5":
version: 2.1.5
resolution: "@rspack/core@npm:2.1.5"
"@rspack/core@npm:2.1.4":
version: 2.1.4
resolution: "@rspack/core@npm:2.1.4"
dependencies:
"@rspack/binding": "npm:2.1.5"
"@rspack/binding": "npm:2.1.4"
peerDependencies:
"@module-federation/runtime-tools": ^0.24.1 || ^2.0.0
"@swc/helpers": ^0.5.23
@@ -4901,7 +4901,7 @@ __metadata:
optional: true
"@swc/helpers":
optional: true
checksum: 10/714064de701211724f7d859bc269d357fa2ad2f7ea0ac34d1e4e48b534981cf3961bd723c0659b9c093330f04e01e16a0c5587d6a18301727e27d717f764ded7
checksum: 10/3c7aa9e8dbe8b132b51fc017a6c2c76ddf346cf663cad2a8912ba61469d80468acd045503d405bf962bb5ec44f44036512dd6d6233ea6d1419979e5c17e1dbd8
languageName: node
linkType: hard
@@ -5761,105 +5761,105 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.65.0"
"@typescript-eslint/eslint-plugin@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.64.0"
dependencies:
"@eslint-community/regexpp": "npm:^4.12.2"
"@typescript-eslint/scope-manager": "npm:8.65.0"
"@typescript-eslint/type-utils": "npm:8.65.0"
"@typescript-eslint/utils": "npm:8.65.0"
"@typescript-eslint/visitor-keys": "npm:8.65.0"
"@typescript-eslint/scope-manager": "npm:8.64.0"
"@typescript-eslint/type-utils": "npm:8.64.0"
"@typescript-eslint/utils": "npm:8.64.0"
"@typescript-eslint/visitor-keys": "npm:8.64.0"
ignore: "npm:^7.0.5"
natural-compare: "npm:^1.4.0"
ts-api-utils: "npm:^2.5.0"
peerDependencies:
"@typescript-eslint/parser": ^8.65.0
"@typescript-eslint/parser": ^8.64.0
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.1.0"
checksum: 10/20b1e5fd0c01d450c345750582e4911affef8ba934b2b78953ff593102d2a01f21c5f6469e13239fdd6a0e30152d6122906e7623f53aa8c937c6faae9407be47
checksum: 10/ec7cbcb44968386a4b9aff9272ce6b75bdcc7f398db5f2d07a21854baf0364ca33c74268c0e19d21386c6b87b9358b141df7bef3d26e4e4e7a9eb5f8f394dc75
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/parser@npm:8.65.0"
"@typescript-eslint/parser@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/parser@npm:8.64.0"
dependencies:
"@typescript-eslint/scope-manager": "npm:8.65.0"
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/typescript-estree": "npm:8.65.0"
"@typescript-eslint/visitor-keys": "npm:8.65.0"
"@typescript-eslint/scope-manager": "npm:8.64.0"
"@typescript-eslint/types": "npm:8.64.0"
"@typescript-eslint/typescript-estree": "npm:8.64.0"
"@typescript-eslint/visitor-keys": "npm:8.64.0"
debug: "npm:^4.4.3"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.1.0"
checksum: 10/55f68666953c02c8adae35a46076848da6456181b1849a28ec836a5866ca37b902f475fb4c32ba7aa3a6a7e5d66828df8859edec297da09181fb937aeea30f8e
checksum: 10/7239b16a6ca6bb1764ad04bc1eb46997336541d049fcffb4966ef404fbb02324b2b33aed50c2b976359ec8d3c97b90668cfd6aa9177228b4b799152f01a3904a
languageName: node
linkType: hard
"@typescript-eslint/project-service@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/project-service@npm:8.65.0"
"@typescript-eslint/project-service@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/project-service@npm:8.64.0"
dependencies:
"@typescript-eslint/tsconfig-utils": "npm:^8.65.0"
"@typescript-eslint/types": "npm:^8.65.0"
"@typescript-eslint/tsconfig-utils": "npm:^8.64.0"
"@typescript-eslint/types": "npm:^8.64.0"
debug: "npm:^4.4.3"
peerDependencies:
typescript: ">=4.8.4 <6.1.0"
checksum: 10/915662449a66d90f03661a805f7c62a5efaa8f7887671272e08b684b41edab51a9021f47aac4d78001a0f87960e8587adc037424d56f13de883e0ce699e7ca55
checksum: 10/511b9a8f1dcb32c99003cab9791309056ac6e889fe46227600deb743e869a63b3e78d7d2d3ef1bf65b2d5e574b73add3040fbef4c0f94aed587368aaea149559
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/scope-manager@npm:8.65.0"
"@typescript-eslint/scope-manager@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/scope-manager@npm:8.64.0"
dependencies:
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/visitor-keys": "npm:8.65.0"
checksum: 10/038e208c907aa45fe5bb7168e1dccf89c1fc6678d1715a9c04f4b332d4e79ab719b5b43a4e0c2d5a183ea863813ff59fda040b2717fe5517468453af6b99a50a
"@typescript-eslint/types": "npm:8.64.0"
"@typescript-eslint/visitor-keys": "npm:8.64.0"
checksum: 10/3c72c4915cee19d632ddc7491c3a4668dd04aa8bcb112fde8ac10aea2cc0364aaa8439d9939d0c62a7b4159fc22f4ced7cba3a77df4422b21d76497068f08076
languageName: node
linkType: hard
"@typescript-eslint/tsconfig-utils@npm:8.65.0, @typescript-eslint/tsconfig-utils@npm:^8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/tsconfig-utils@npm:8.65.0"
"@typescript-eslint/tsconfig-utils@npm:8.64.0, @typescript-eslint/tsconfig-utils@npm:^8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/tsconfig-utils@npm:8.64.0"
peerDependencies:
typescript: ">=4.8.4 <6.1.0"
checksum: 10/f88253a4df1d599a1bebeeb403611538485e22c52213f2f2b9c435bde8ebce64645d6bb985c900b01ef221032835fcd4f6fea4b94d178220c18de5d93af905c4
checksum: 10/905469c5067a9a2d18d065848c6497081ab787b22a9d7c06499f4bb593b7d67f9fb17e7861a114c46626555853cc52d4542db5311c8dc7cd138e45461a73e589
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/type-utils@npm:8.65.0"
"@typescript-eslint/type-utils@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/type-utils@npm:8.64.0"
dependencies:
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/typescript-estree": "npm:8.65.0"
"@typescript-eslint/utils": "npm:8.65.0"
"@typescript-eslint/types": "npm:8.64.0"
"@typescript-eslint/typescript-estree": "npm:8.64.0"
"@typescript-eslint/utils": "npm:8.64.0"
debug: "npm:^4.4.3"
ts-api-utils: "npm:^2.5.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.1.0"
checksum: 10/d52e0c341c9731d8f3bfd2f475bbcd5a5632434e11fc39e8e21acb706145bedb8c6c1998b8ced73e132b43179dd95f2c318effc36c9a1dd61f14546b07b25852
checksum: 10/7ab1fd8c0d292c0155cf137d316b1618681eca0fe4cf446a05d909de41311ec6bb64fed82513e822063a962508d5b3e615fb0155a4a565d6b9c6cb81d06a5cd2
languageName: node
linkType: hard
"@typescript-eslint/types@npm:8.65.0, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/types@npm:8.65.0"
checksum: 10/a6fc10a733adbb98bbb9c312c8d99791e1a2fd3efef5c2a5b51da1c166aac3db4427c30bf32059808abe305a289f820bf610683914e897baeb18315af6a1d16c
"@typescript-eslint/types@npm:8.64.0, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/types@npm:8.64.0"
checksum: 10/b8951c00ce9b9702f3201f017354774ea5f39c30c2b6f815cb50d91f53f61c325e30f548329daf731d5169d752095cf102da54b754fb202bcfb619faa56fa9f4
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/typescript-estree@npm:8.65.0"
"@typescript-eslint/typescript-estree@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/typescript-estree@npm:8.64.0"
dependencies:
"@typescript-eslint/project-service": "npm:8.65.0"
"@typescript-eslint/tsconfig-utils": "npm:8.65.0"
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/visitor-keys": "npm:8.65.0"
"@typescript-eslint/project-service": "npm:8.64.0"
"@typescript-eslint/tsconfig-utils": "npm:8.64.0"
"@typescript-eslint/types": "npm:8.64.0"
"@typescript-eslint/visitor-keys": "npm:8.64.0"
debug: "npm:^4.4.3"
minimatch: "npm:^10.2.2"
semver: "npm:^7.7.3"
@@ -5867,32 +5867,32 @@ __metadata:
ts-api-utils: "npm:^2.5.0"
peerDependencies:
typescript: ">=4.8.4 <6.1.0"
checksum: 10/711fdb5eff67ff34437c56a1a661b16a2e1d6bcd96c9f96196c4242b8d4ddaea8e835ca8badd340c703e043d8dfe8cfca90b32eca60069a4f1d2880afdb670fb
checksum: 10/833101d25e820d1d0e317dfc9beca985b3c87e5458b20ed002c86c2d425667aa506f756f1759b54f724033effb529266f836f912c460ee662f347fb43dded6ed
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/utils@npm:8.65.0"
"@typescript-eslint/utils@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/utils@npm:8.64.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.9.1"
"@typescript-eslint/scope-manager": "npm:8.65.0"
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/typescript-estree": "npm:8.65.0"
"@typescript-eslint/scope-manager": "npm:8.64.0"
"@typescript-eslint/types": "npm:8.64.0"
"@typescript-eslint/typescript-estree": "npm:8.64.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.1.0"
checksum: 10/c1dcd555b58aef1e066164978335e521809acac36b56bd6a6dae62cffae80f3ea5f43527506be76dfef0fe3d4c8382a24355a28867c4904b0a7729691ba45656
checksum: 10/ff7e5374bd6ef60d7df723e6440468e3a5d4879d1d9876e322904319a1f1d2f98d858fc9b9169dbbd7ee0786a07102a058f13e2b6c16d1bf9aae9eb836a258a3
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:8.65.0":
version: 8.65.0
resolution: "@typescript-eslint/visitor-keys@npm:8.65.0"
"@typescript-eslint/visitor-keys@npm:8.64.0":
version: 8.64.0
resolution: "@typescript-eslint/visitor-keys@npm:8.64.0"
dependencies:
"@typescript-eslint/types": "npm:8.65.0"
"@typescript-eslint/types": "npm:8.64.0"
eslint-visitor-keys: "npm:^5.0.0"
checksum: 10/e7f86d21f0bf03ca7cff9fa9428aab98620564d15fb06c9f56a294c13cee324624d42f9115f3d76fbad92266220479cca334b5c66562f885da5c4d2bda3d87b3
checksum: 10/d149be4ac0e67c51097cdb7335d8e2d29b9dc0de173961c5cc550e938a00a3af28b1f8ecd7ad832fcfe489d1b11e36fdd394b6ea92115a7558123562e31a704f
languageName: node
linkType: hard
@@ -9954,8 +9954,8 @@ __metadata:
"@octokit/rest": "npm:22.0.1"
"@playwright/test": "npm:1.61.1"
"@replit/codemirror-indentation-markers": "npm:6.5.3"
"@rsdoctor/rspack-plugin": "npm:1.6.1"
"@rspack/core": "npm:2.1.5"
"@rsdoctor/rspack-plugin": "npm:1.6.0"
"@rspack/core": "npm:2.1.4"
"@rspack/dev-server": "npm:2.1.0"
"@swc/helpers": "npm:0.5.23"
"@thomasloven/round-slider": "npm:0.6.0"
@@ -10038,13 +10038,13 @@ __metadata:
lodash.template: "npm:4.18.1"
luxon: "npm:3.7.2"
map-stream: "npm:0.0.7"
marked: "npm:18.0.7"
marked: "npm:18.0.6"
memoize-one: "npm:6.0.0"
minify-literals: "npm:2.1.0"
node-vibrant: "npm:4.0.4"
object-hash: "npm:3.0.0"
pinst: "npm:3.0.0"
prettier: "npm:3.9.6"
prettier: "npm:3.9.5"
punycode: "npm:2.3.1"
qr-scanner: "npm:1.4.2"
qrcode: "npm:1.5.4"
@@ -10052,7 +10052,7 @@ __metadata:
rrule: "npm:2.8.1"
rspack-manifest-plugin: "npm:5.2.2"
serve: "npm:14.2.6"
sinon: "npm:22.1.0"
sinon: "npm:22.0.0"
sortablejs: "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch"
stacktrace-js: "npm:2.0.2"
superstruct: "npm:2.0.2"
@@ -10061,7 +10061,7 @@ __metadata:
tinykeys: "patch:tinykeys@npm%3A4.0.0#~/.yarn/patches/tinykeys-npm-4.0.0-a6ca3fd771.patch"
ts-lit-plugin: "npm:2.0.2"
typescript: "npm:6.0.3"
typescript-eslint: "npm:8.65.0"
typescript-eslint: "npm:8.64.0"
vite-tsconfig-paths: "npm:6.1.1"
vitest: "npm:4.1.10"
webpack-stats-plugin: "npm:1.1.3"
@@ -11681,12 +11681,12 @@ __metadata:
languageName: node
linkType: hard
"marked@npm:18.0.7":
version: 18.0.7
resolution: "marked@npm:18.0.7"
"marked@npm:18.0.6":
version: 18.0.6
resolution: "marked@npm:18.0.6"
bin:
marked: bin/marked.js
checksum: 10/7ea7b8556a9e8cab2881b194815a7550c61d77639c6b8f8d9022f96790fd2b289b2ea28969cea6e01c24c3b8ec822373288ee02b7c50f178bc3ec79aa42d05f1
checksum: 10/ab4747d071888726a91ccf381416366c17345c6cdf6bf8739d114482f633740bb9227aff03324d20b1e14c8052f4c6b523c5d5974f7346b240aef45c900c7d27
languageName: node
linkType: hard
@@ -12878,12 +12878,12 @@ __metadata:
languageName: node
linkType: hard
"prettier@npm:3.9.6":
version: 3.9.6
resolution: "prettier@npm:3.9.6"
"prettier@npm:3.9.5":
version: 3.9.5
resolution: "prettier@npm:3.9.5"
bin:
prettier: bin/prettier.cjs
checksum: 10/1dd1a1e0e40ec3b91cda9d294c4a95022aef61880ca3f441aad99b1252279f58a766c4cece81132c01550dcff1fd445efbd8812ea4a2374313e7fc6c8136f11f
checksum: 10/b6587f1582ba653ce5207ee227aff646500e5098646931088f176d1ab090b1f47d5a333f1facd634e9aa7dcb15c45940e2cec13a5962534cf0200617517b67b6
languageName: node
linkType: hard
@@ -13879,15 +13879,15 @@ __metadata:
languageName: node
linkType: hard
"sinon@npm:22.1.0":
version: 22.1.0
resolution: "sinon@npm:22.1.0"
"sinon@npm:22.0.0":
version: 22.0.0
resolution: "sinon@npm:22.0.0"
dependencies:
"@sinonjs/commons": "npm:^3.0.1"
"@sinonjs/fake-timers": "npm:^15.4.0"
"@sinonjs/samsam": "npm:^10.0.2"
diff: "npm:^9.0.0"
checksum: 10/f49455cc9613c80765350a39cc2868ce238c35c5ba738e9075a5113f81951a616850e5ebbe77e19f8494ed24780b6a5d3496300cb1b76c12020f77adc72e0232
checksum: 10/5d0a692c2f1cc463b86d18a57e8db80e1a7f5829252edfc4d11162a555e4d005bf03698549d7cf9ad65f79b7e77a4f87534b4c76220bb81a1ec5e2b30be19929
languageName: node
linkType: hard
@@ -14950,18 +14950,18 @@ __metadata:
languageName: node
linkType: hard
"typescript-eslint@npm:8.65.0":
version: 8.65.0
resolution: "typescript-eslint@npm:8.65.0"
"typescript-eslint@npm:8.64.0":
version: 8.64.0
resolution: "typescript-eslint@npm:8.64.0"
dependencies:
"@typescript-eslint/eslint-plugin": "npm:8.65.0"
"@typescript-eslint/parser": "npm:8.65.0"
"@typescript-eslint/typescript-estree": "npm:8.65.0"
"@typescript-eslint/utils": "npm:8.65.0"
"@typescript-eslint/eslint-plugin": "npm:8.64.0"
"@typescript-eslint/parser": "npm:8.64.0"
"@typescript-eslint/typescript-estree": "npm:8.64.0"
"@typescript-eslint/utils": "npm:8.64.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: ">=4.8.4 <6.1.0"
checksum: 10/5b2242f59005afdd57190849be7df2e86ce33b007fa0bf605f700ad0e38ea14fc14c48deafdf4a039614c1f012b71c61a19edb27f76d52fdc924cde476a100d1
checksum: 10/7812e25506003c2a5b395a51ca3c31929028485d191049e6a813e65829e79fcebb07251ba42c5d75af8d15233a5bbb44dd37138345787779eabe07b88fcf75ec
languageName: node
linkType: hard