20230201.0 (#15307)

This commit is contained in:
Bram Kragten 2023-02-01 17:17:12 +01:00 committed by GitHub
commit 0e06267055
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 299 additions and 239 deletions

View File

@ -26,7 +26,7 @@
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"@codemirror/autocomplete": "^6.4.0",
"@codemirror/commands": "^6.1.3",
"@codemirror/commands": "^6.2.0",
"@codemirror/language": "^6.4.0",
"@codemirror/legacy-modes": "^6.3.1",
"@codemirror/search": "^6.2.3",
@ -36,7 +36,7 @@
"@formatjs/intl-getcanonicallocales": "^2.0.5",
"@formatjs/intl-locale": "^3.0.11",
"@formatjs/intl-numberformat": "^7.2.5",
"@formatjs/intl-pluralrules": "^4.1.5",
"@formatjs/intl-pluralrules": "^5.1.8",
"@formatjs/intl-relativetimeformat": "^11.1.8",
"@fullcalendar/common": "^5.11.4",
"@fullcalendar/core": "^5.11.4",
@ -152,16 +152,16 @@
"@babel/plugin-proposal-decorators": "^7.20.7",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.20.2",
"@babel/plugin-proposal-optional-chaining": "^7.18.9",
"@babel/plugin-proposal-optional-chaining": "^7.20.7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@koa/cors": "^3.1.0",
"@koa/cors": "^4.0.0",
"@octokit/auth-oauth-device": "^4.0.4",
"@octokit/rest": "^19.0.7",
"@open-wc/dev-server-hmr": "^0.0.2",
"@open-wc/dev-server-hmr": "^0.1.3",
"@rollup/plugin-babel": "^5.2.1",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-json": "^4.0.3",
@ -192,7 +192,7 @@
"eslint-config-airbnb-typescript": "^14.0.0",
"eslint-config-prettier": "^8.6.0",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-plugin-disable": "^2.0.1",
"eslint-plugin-disable": "^2.0.3",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-lit": "^1.6.1",
"eslint-plugin-unused-imports": "^1.1.5",
@ -208,7 +208,7 @@
"gulp-zopfli-green": "^3.0.1",
"html-minifier": "^4.0.0",
"husky": "^8.0.3",
"instant-mocha": "^1.3.1",
"instant-mocha": "^1.5.0",
"jszip": "^3.10.1",
"lint-staged": "^13.1.0",
"lit-analyzer": "^1.2.1",
@ -229,7 +229,7 @@
"serve": "^11.3.2",
"sinon": "^15.0.1",
"source-map-url": "^0.4.0",
"systemjs": "^6.3.2",
"systemjs": "^6.13.0",
"tar": "^6.1.11",
"terser-webpack-plugin": "^5.2.4",
"ts-lit-plugin": "^1.2.1",

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20230130.0"
version = "20230201.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"

View File

@ -22,3 +22,11 @@ export const atLeastVersion = (
Number(haPatch) >= patch)
);
};
export const isDevVersion = (version: string): boolean => {
if (__DEMO__) {
return false;
}
return version.includes("dev");
};

View File

@ -64,6 +64,8 @@ export class StateHistoryChartTimeline extends LitElement {
}
if (
changedProps.has("startTime") ||
changedProps.has("endTime") ||
changedProps.has("data") ||
this._chartTime <
new Date(this.endTime.getTime() - MIN_TIME_BETWEEN_UPDATES)

View File

@ -38,7 +38,7 @@ declare global {
}
@customElement("state-history-charts")
class StateHistoryCharts extends LitElement {
export class StateHistoryCharts extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public historyData!: HistoryResult;
@ -71,7 +71,6 @@ class StateHistoryCharts extends LitElement {
// @ts-ignore
@restoreScroll(".container") private _savedScrollPos?: number;
@eventOptions({ passive: true })
protected render(): TemplateResult {
if (!isComponentLoaded(this.hass, "history")) {
return html`<div class="info">

View File

@ -1,3 +1,4 @@
import "../ha-list-item";
import { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
@ -9,7 +10,6 @@ import { computeStateName } from "../../common/entity/compute_state_name";
import { caseInsensitiveStringCompare } from "../../common/string/compare";
import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types";
import "../ha-list-item";
import "../ha-combo-box";
import type { HaComboBox } from "../ha-combo-box";
import "../ha-icon-button";

View File

@ -0,0 +1,24 @@
import { Button } from "@material/mwc-button";
import { css } from "lit";
import { customElement } from "lit/decorators";
import { styles } from "@material/mwc-button/styles.css";
@customElement("ha-button")
export class HaButton extends Button {
static override styles = [
styles,
css`
::slotted([slot="icon"]) {
margin-inline-start: 0px;
margin-inline-end: 8px;
direction: var(--direction);
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-button": HaButton;
}
}

View File

@ -16,7 +16,6 @@ import { fireEvent } from "../common/dom/fire_event";
import { HomeAssistant } from "../types";
import "./ha-list-item";
import "./ha-icon-button";
import "./ha-textfield";
import type { HaTextField } from "./ha-textfield";
registerStyles(

View File

@ -30,7 +30,6 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
device_class?: string;
original_device_class?: string;
aliases: string[];
options: EntityRegistryOptions | null;
}
export interface UpdateEntityRegistryEntryResult {
@ -40,7 +39,6 @@ export interface UpdateEntityRegistryEntryResult {
}
export interface SensorEntityOptions {
precision?: number | null;
unit_of_measurement?: string | null;
}
@ -56,12 +54,6 @@ export interface WeatherEntityOptions {
wind_speed_unit?: string | null;
}
export interface EntityRegistryOptions {
number?: NumberEntityOptions;
sensor?: SensorEntityOptions;
weather?: WeatherEntityOptions;
}
export interface EntityRegistryEntryUpdateParams {
name?: string | null;
icon?: string | null;

View File

@ -117,7 +117,7 @@ export const fetchDateWS = (
export const subscribeHistory = (
hass: HomeAssistant,
callbackFunction: (message: HistoryStreamMessage) => void,
callbackFunction: (data: HistoryStates) => void,
startTime: Date,
endTime: Date,
entityIds: string[]
@ -132,8 +132,9 @@ export const subscribeHistory = (
entityIdHistoryNeedsAttributes(hass, entityId)
),
};
const stream = new HistoryStream(hass);
return hass.connection.subscribeMessage<HistoryStreamMessage>(
(message) => callbackFunction(message),
(message) => callbackFunction(stream.processMessage(message)),
params
);
};
@ -141,11 +142,11 @@ export const subscribeHistory = (
class HistoryStream {
hass: HomeAssistant;
hoursToShow: number;
hoursToShow?: number;
combinedHistory: HistoryStates;
constructor(hass: HomeAssistant, hoursToShow: number) {
constructor(hass: HomeAssistant, hoursToShow?: number) {
this.hass = hass;
this.hoursToShow = hoursToShow;
this.combinedHistory = {};
@ -161,8 +162,9 @@ class HistoryStream {
// indicate no more historical events
return this.combinedHistory;
}
const purgeBeforePythonTime =
(new Date().getTime() - 60 * 60 * this.hoursToShow * 1000) / 1000;
const purgeBeforePythonTime = this.hoursToShow
? (new Date().getTime() - 60 * 60 * this.hoursToShow * 1000) / 1000
: undefined;
const newHistory: HistoryStates = {};
for (const entityId of Object.keys(this.combinedHistory)) {
newHistory[entityId] = [];
@ -195,7 +197,7 @@ class HistoryStream {
newHistory[entityId] = streamMessage.states[entityId];
}
// Remove old history
if (entityId in this.combinedHistory) {
if (purgeBeforePythonTime && entityId in this.combinedHistory) {
const expiredStates = newHistory[entityId].filter(
(state) => state.lu < purgeBeforePythonTime
);

View File

@ -11,6 +11,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { stringCompare } from "../../../../common/string/compare";
import { LocalizeFunc } from "../../../../common/translations/localize";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-button";
import type { HaSelect } from "../../../../components/ha-select";
import "../../../../components/ha-svg-icon";
import { ACTION_TYPES } from "../../../../data/action";
@ -132,7 +133,7 @@ export default class HaAutomationAction extends LitElement {
@action=${this._addAction}
.disabled=${this.disabled}
>
<mwc-button
<ha-button
slot="trigger"
outlined
.disabled=${this.disabled}
@ -141,7 +142,7 @@ export default class HaAutomationAction extends LitElement {
)}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</mwc-button>
</ha-button>
${this._processedTypes(this.hass.localize).map(
([opt, label, icon]) => html`
<mwc-list-item .value=${opt} graphic="icon">

View File

@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { ensureArray } from "../../../../../common/array/ensure-array";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-button";
import { Condition } from "../../../../../data/automation";
import { Action, ChooseAction } from "../../../../../data/script";
import { haStyle } from "../../../../../resources/styles";
@ -80,7 +81,7 @@ export class HaChooseAction extends LitElement implements ActionElement {
</div>
</ha-card>`
)}
<mwc-button
<ha-button
outlined
.label=${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.add_option"
@ -89,7 +90,7 @@ export class HaChooseAction extends LitElement implements ActionElement {
@click=${this._addOption}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</mwc-button>
</ha-button>
${this._showDefault || action.default
? html`
<h2>
@ -196,6 +197,9 @@ export class HaChooseAction extends LitElement implements ActionElement {
ha-icon-button {
position: absolute;
right: 0;
inset-inline-start: initial;
inset-inline-end: 0;
direction: var(--direction);
padding: 4px;
}
ha-svg-icon {

View File

@ -8,6 +8,7 @@ import { repeat } from "lit/directives/repeat";
import memoizeOne from "memoize-one";
import type { SortableEvent } from "sortablejs";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-svg-icon";
import type { Condition } from "../../../../data/automation";
@ -177,7 +178,7 @@ export default class HaAutomationCondition extends LitElement {
@action=${this._addCondition}
.disabled=${this.disabled}
>
<mwc-button
<ha-button
slot="trigger"
outlined
.disabled=${this.disabled}
@ -186,7 +187,7 @@ export default class HaAutomationCondition extends LitElement {
)}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</mwc-button>
</ha-button>
${this._processedTypes(this.hass.localize).map(
([opt, label, icon]) => html`
<mwc-list-item .value=${opt} graphic="icon">

View File

@ -11,6 +11,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { stringCompare } from "../../../../common/string/compare";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-button";
import type { HaSelect } from "../../../../components/ha-select";
import "../../../../components/ha-svg-icon";
import { Trigger } from "../../../../data/automation";
@ -125,7 +126,7 @@ export default class HaAutomationTrigger extends LitElement {
)}
</div>
<ha-button-menu @action=${this._addTrigger} .disabled=${this.disabled}>
<mwc-button
<ha-button
slot="trigger"
outlined
.label=${this.hass.localize(
@ -134,7 +135,7 @@ export default class HaAutomationTrigger extends LitElement {
.disabled=${this.disabled}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</mwc-button>
</ha-button>
${this._processedTypes(this.hass.localize).map(
([opt, label, icon]) => html`
<mwc-list-item .value=${opt} graphic="icon">

View File

@ -63,7 +63,6 @@ import {
EntityRegistryEntry,
EntityRegistryEntryUpdateParams,
ExtEntityRegistryEntry,
SensorEntityOptions,
fetchEntityRegistry,
removeEntityRegistryEntry,
updateEntityRegistryEntry,
@ -127,16 +126,6 @@ const OVERRIDE_WEATHER_UNITS = {
const SWITCH_AS_DOMAINS = ["cover", "fan", "light", "lock", "siren"];
const PRECISIONS = [0, 1, 2, 3, 4, 5, 6];
function precisionLabel(precision: number, _state?: string) {
const state_float =
_state === undefined || isNaN(parseFloat(_state))
? 0.0
: parseFloat(_state);
return state_float.toFixed(precision);
}
@customElement("entity-registry-settings")
export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -165,8 +154,6 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@state() private _unit_of_measurement?: string | null;
@state() private _precision?: number | null;
@state() private _precipitation_unit?: string | null;
@state() private _pressure_unit?: string | null;
@ -264,10 +251,6 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._unit_of_measurement = stateObj?.attributes?.unit_of_measurement;
}
if (domain === "sensor") {
this._precision = this.entry.options?.sensor?.precision;
}
if (domain === "weather") {
const stateObj: HassEntity | undefined =
this.hass.states[this.entry.entity_id];
@ -485,44 +468,6 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
</ha-select>
`
: ""}
${domain === "sensor" &&
// Allow customizing the precision for a sensor with numerical device class,
// a unit of measurement or state class
((this._deviceClass &&
!["date", "enum", "timestamp"].includes(this._deviceClass)) ||
stateObj?.attributes.unit_of_measurement ||
stateObj?.attributes.state_class)
? html`
<ha-select
.label=${this.hass.localize(
"ui.dialogs.entity_registry.editor.precision"
)}
.value=${this._precision == null
? "default"
: this._precision.toString()}
naturalMenuWidth
fixedMenuPosition
@selected=${this._precisionChanged}
@closed=${stopPropagation}
>
<mwc-list-item .value=${"default"}
>${this.hass.localize(
"ui.dialogs.entity_registry.editor.precision_default"
)}</mwc-list-item
>
${PRECISIONS.map(
(precision) => html`
<mwc-list-item .value=${precision.toString()}>
${precisionLabel(
precision,
this.hass.states[this.entry.entity_id]?.state
)}
</mwc-list-item>
`
)}
</ha-select>
`
: ""}
${domain === "weather"
? html`
<ha-select
@ -948,12 +893,6 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._precipitation_unit = ev.target.value;
}
private _precisionChanged(ev): void {
this._error = undefined;
this._precision =
ev.target.value === "default" ? null : Number(ev.target.value);
}
private _pressureUnitChanged(ev): void {
this._error = undefined;
this._pressure_unit = ev.target.value;
@ -1149,16 +1088,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
stateObj?.attributes?.unit_of_measurement !== this._unit_of_measurement
) {
params.options_domain = domain;
params.options = this.entry.options?.[domain] || {};
params.options.unit_of_measurement = this._unit_of_measurement;
}
if (
domain === "sensor" &&
this.entry.options?.[domain]?.precision !== this._precision
) {
params.options_domain = domain;
params.options = params.options || this.entry.options?.[domain] || {};
(params.options as SensorEntityOptions).precision = this._precision;
params.options = { unit_of_measurement: this._unit_of_measurement };
}
if (
domain === "weather" &&

View File

@ -15,6 +15,7 @@ import "../../../../../components/ha-alert";
import { showPromptDialog } from "../../../../../dialogs/generic/show-dialog-box";
import { navigate } from "../../../../../common/navigate";
import { isComponentLoaded } from "../../../../../common/config/is_component_loaded";
import { isDevVersion } from "../../../../../common/config/version";
@customElement("matter-config-panel")
export class MatterConfigPanel extends LitElement {
@ -61,15 +62,19 @@ export class MatterConfigPanel extends LitElement {
>Commission device with mobile app</mwc-button
>`
: ""}
${isDevVersion(this.hass.config.version)
? html`<mwc-button @click=${this._commission}
>Commission device</mwc-button
>
<mwc-button @click=${this._acceptSharedDevice}
>Add shared device</mwc-button
>`
: ""}
<mwc-button @click=${this._setWifi}
>Set WiFi Credentials</mwc-button
>
<mwc-button @click=${this._setThread}>Set Thread</mwc-button>
<mwc-button @click=${this._commission}
>Commission device</mwc-button
>
<mwc-button @click=${this._acceptSharedDevice}
>Add shared device</mwc-button
<mwc-button @click=${this._setThread}
>Set Thread Credentials</mwc-button
>
</div>
</ha-card>

View File

@ -4,6 +4,7 @@ import { customElement, property, query, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { extractSearchParam } from "../../../common/url/search-params";
import "../../../components/ha-button-menu";
import "../../../components/ha-button";
import "../../../components/search-input";
import { LogProvider } from "../../../data/error_log";
import { fetchHassioAddonsInfo } from "../../../data/hassio/addon";
@ -115,7 +116,7 @@ export class HaConfigLogs extends LitElement {
this.hass.userData?.showAdvanced
? html`
<ha-button-menu corner="BOTTOM_START" slot="toolbar-icon">
<mwc-button
<ha-button
slot="trigger"
.label=${this._logProviders.find(
(p) => p.key === this._selectedLogProvider
@ -125,7 +126,7 @@ export class HaConfigLogs extends LitElement {
slot="trailingIcon"
.path=${mdiChevronDown}
></ha-svg-icon>
</mwc-button>
</ha-button>
${this._logProviders.map(
(provider) => html`
<mwc-list-item

View File

@ -3,6 +3,7 @@ import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import {
addDays,
differenceInHours,
endOfToday,
endOfWeek,
endOfYesterday,
@ -15,17 +16,19 @@ import {
UnsubscribeFunc,
} from "home-assistant-js-websocket/dist/types";
import { css, html, LitElement, PropertyValues } from "lit";
import { property, state } from "lit/decorators";
import { property, query, state } from "lit/decorators";
import { ensureArray } from "../../common/array/ensure-array";
import { firstWeekdayIndex } from "../../common/datetime/first_weekday";
import { LocalStorage } from "../../common/decorators/local-storage";
import { ensureArray } from "../../common/array/ensure-array";
import { navigate } from "../../common/navigate";
import {
createSearchParam,
extractSearchParamsObject,
} from "../../common/url/search-params";
import { computeRTL } from "../../common/util/compute_rtl";
import { MIN_TIME_BETWEEN_UPDATES } from "../../components/chart/ha-chart-base";
import "../../components/chart/state-history-charts";
import type { StateHistoryCharts } from "../../components/chart/state-history-charts";
import "../../components/ha-circular-progress";
import "../../components/ha-date-range-picker";
import type { DateRangePickerRanges } from "../../components/ha-date-range-picker";
@ -44,7 +47,11 @@ import {
subscribeDeviceRegistry,
} from "../../data/device_registry";
import { subscribeEntityRegistry } from "../../data/entity_registry";
import { computeHistory, fetchDateWS } from "../../data/history";
import {
computeHistory,
HistoryResult,
subscribeHistory,
} from "../../data/history";
import "../../layouts/ha-app-layout";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { haStyle } from "../../resources/styles";
@ -66,7 +73,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
@state() private _isLoading = false;
@state() private _stateHistory?;
@state() private _stateHistory?: HistoryResult;
@state() private _ranges?: DateRangePickerRanges;
@ -76,18 +83,37 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
@state() private _areaDeviceLookup?: AreaDeviceLookup;
@query("state-history-charts")
private _stateHistoryCharts?: StateHistoryCharts;
private _subscribed?: Promise<UnsubscribeFunc>;
private _interval?: number;
public constructor() {
super();
const start = new Date();
start.setHours(start.getHours() - 2, 0, 0, 0);
start.setHours(start.getHours() - 1, 0, 0, 0);
this._startDate = start;
const end = new Date();
end.setHours(end.getHours() + 1, 0, 0, 0);
end.setHours(end.getHours() + 2, 0, 0, 0);
this._endDate = end;
}
public connectedCallback() {
super.connectedCallback();
if (this.hasUpdated) {
this._getHistory();
}
}
public disconnectedCallback() {
super.disconnectedCallback();
this._unsubscribeHistory();
}
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeEntityRegistry(this.hass.connection!, (entities) => {
@ -270,24 +296,63 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
if (entityIds.length === 0) {
this._isLoading = false;
this._stateHistory = [];
this._stateHistory = { line: [], timeline: [] };
return;
}
try {
const dateHistory = await fetchDateWS(
this.hass,
this._startDate,
this._endDate,
entityIds
);
this._stateHistory = computeHistory(
this.hass,
dateHistory,
this.hass.localize
);
} finally {
if (this._subscribed) {
this._unsubscribeHistory();
}
const now = new Date();
this._subscribed = subscribeHistory(
this.hass,
(history) => {
this._isLoading = false;
this._stateHistory = computeHistory(
this.hass,
history,
this.hass.localize
);
},
this._startDate,
this._endDate,
entityIds
);
this._subscribed.catch(() => {
this._isLoading = false;
this._unsubscribeHistory();
});
if (this._endDate > now) {
this._setRedrawTimer();
}
}
private _setRedrawTimer() {
clearInterval(this._interval);
const now = new Date();
const end = this._endDate > now ? now : this._endDate;
const timespan = differenceInHours(this._startDate, end);
this._interval = window.setInterval(
() => this._stateHistoryCharts?.requestUpdate(),
// if timespan smaller than 1 hour, update every 10 seconds, smaller than 5 hours, redraw every minute, otherwise every 5 minutes
timespan < 2
? 10000
: timespan < 10
? 60 * 1000
: MIN_TIME_BETWEEN_UPDATES
);
}
private _unsubscribeHistory() {
if (this._interval) {
clearInterval(this._interval);
this._interval = undefined;
}
if (this._subscribed) {
this._subscribed.then((unsub) => unsub?.());
this._subscribed = undefined;
}
}

View File

@ -15,6 +15,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../common/dom/stop_propagation";
import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-button";
import "../../../../components/ha-svg-icon";
import { sortableStyles } from "../../../../resources/ha-sortable-style";
import {
@ -160,7 +161,7 @@ export class HuiTileCardFeaturesEditor extends LitElement {
@action=${this._addFeature}
@closed=${stopPropagation}
>
<mwc-button
<ha-button
slot="trigger"
outlined
.label=${this.hass!.localize(
@ -168,7 +169,7 @@ export class HuiTileCardFeaturesEditor extends LitElement {
)}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</mwc-button>
</ha-button>
${this._supportedFeatureTypes.map(
(featureType) => html`<mwc-list-item .value=${featureType}>
<ha-svg-icon

View File

@ -30,6 +30,7 @@ import { computeStateName } from "../../common/entity/compute_state_name";
import { domainIcon } from "../../common/entity/domain_icon";
import { supportsFeature } from "../../common/entity/supports-feature";
import "../../components/ha-button-menu";
import "../../components/ha-button";
import "../../components/ha-circular-progress";
import "../../components/ha-icon-button";
import { UNAVAILABLE } from "../../data/entity";
@ -323,7 +324,7 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
></ha-icon-button>
`
: html`
<mwc-button
<ha-button
slot="trigger"
.label=${this.narrow
? ""
@ -344,7 +345,7 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
slot="trailingIcon"
.path=${mdiChevronDown}
></ha-svg-icon>
</mwc-button>
</ha-button>
`
}
<mwc-list-item
@ -720,11 +721,6 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
font-weight: bold;
}
ha-svg-icon[slot="icon"] {
margin-inline-start: 8px !important;
margin-inline-end: 8px !important;
direction: var(--direction);
}
ha-svg-icon[slot="trailingIcon"] {
margin-inline-start: 8px !important;
margin-inline-end: 0px !important;

View File

@ -906,8 +906,6 @@
"entity_id": "Entity ID",
"unit_of_measurement": "Unit of Measurement",
"precipitation_unit": "Precipitation unit",
"precision": "Precision",
"precision_default": "Use default",
"pressure_unit": "Barometric pressure unit",
"temperature_unit": "Temperature unit",
"visibility_unit": "Visibility unit",

217
yarn.lock
View File

@ -419,7 +419,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-proposal-class-properties@npm:^7.12.1, @babel/plugin-proposal-class-properties@npm:^7.18.6":
"@babel/plugin-proposal-class-properties@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6"
dependencies:
@ -558,16 +558,16 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-proposal-optional-chaining@npm:^7.18.9":
version: 7.18.9
resolution: "@babel/plugin-proposal-optional-chaining@npm:7.18.9"
"@babel/plugin-proposal-optional-chaining@npm:^7.18.9, @babel/plugin-proposal-optional-chaining@npm:^7.20.7":
version: 7.20.7
resolution: "@babel/plugin-proposal-optional-chaining@npm:7.20.7"
dependencies:
"@babel/helper-plugin-utils": ^7.18.9
"@babel/helper-skip-transparent-expression-wrappers": ^7.18.9
"@babel/helper-plugin-utils": ^7.20.2
"@babel/helper-skip-transparent-expression-wrappers": ^7.20.0
"@babel/plugin-syntax-optional-chaining": ^7.8.3
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: f2db40e26172f07c50b635cb61e1f36165de3ba868fcf608d967642f0d044b7c6beb0e7ecf17cbd421144b99e1eae7ad6031ded92925343bb0ed1d08707b514f
checksum: 274b8932335bd064ca24cf1a4da2b2c20c92726d4bfa8b0cb5023857479b8481feef33505c16650c7b9239334e5c6959babc924816324c4cf223dd91c7ca79bc
languageName: node
linkType: hard
@ -1384,15 +1384,15 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/commands@npm:^6.1.3":
version: 6.1.3
resolution: "@codemirror/commands@npm:6.1.3"
"@codemirror/commands@npm:^6.2.0":
version: 6.2.0
resolution: "@codemirror/commands@npm:6.2.0"
dependencies:
"@codemirror/language": ^6.0.0
"@codemirror/state": ^6.2.0
"@codemirror/view": ^6.0.0
"@lezer/common": ^1.0.0
checksum: beca0248fa2528005e4088a46840bc2a057d34e5b51c60cb20703ca734761dc55f5e205f5dcf94280ffbb5c3366753f46f2d03a5abfd69bd95eac8a67c2e96bb
checksum: 13475fcd348335b4c31e563cbe83b98fdaa99218da882e3fbe6bad66841c55a69030e4a1a5f475ba2607db194d3b43b91e38fd088f9f4196b1ed4eac5b523909
languageName: node
linkType: hard
@ -1581,14 +1581,14 @@ __metadata:
languageName: node
linkType: hard
"@formatjs/intl-pluralrules@npm:^4.1.5":
version: 4.1.5
resolution: "@formatjs/intl-pluralrules@npm:4.1.5"
"@formatjs/intl-pluralrules@npm:^5.1.8":
version: 5.1.8
resolution: "@formatjs/intl-pluralrules@npm:5.1.8"
dependencies:
"@formatjs/ecma402-abstract": 1.10.0
"@formatjs/intl-localematcher": 0.2.21
tslib: ^2.1.0
checksum: ad552ae374b5706929dfa6384fde50aa03e50995e4f71d402142d34caeef5c0778c2f4078cfca89b80dd064783f66ee9cdf460b906ef5ba99fb558e33944dc54
"@formatjs/ecma402-abstract": 1.14.3
"@formatjs/intl-localematcher": 0.2.32
tslib: ^2.4.0
checksum: 89c2cb25ab073da29a7951ee381206f92458403c13481f9bebecdf488ae6e0d5dace3bead796c499ba7cbe38800b0b5d561fe849cdeb6365f9c0685ac8c43c91
languageName: node
linkType: hard
@ -1876,12 +1876,12 @@ __metadata:
languageName: node
linkType: hard
"@koa/cors@npm:^3.1.0":
version: 3.1.0
resolution: "@koa/cors@npm:3.1.0"
"@koa/cors@npm:^4.0.0":
version: 4.0.0
resolution: "@koa/cors@npm:4.0.0"
dependencies:
vary: ^1.1.2
checksum: b6f18de404a967696fe19c9a8d35816e2a845be51f9aa49f1a8d31bbea095eaa20c35eceafe1b764a7e3a912052ca6eaf1965ac34b00020b1ec2823cb60a9b5d
checksum: e0760544823532f2d71d792e3076858e38bab9b1c090abea175f1319fd91ea58a1da384a2fe7f5108f1c681e3830b01f62a1cafe271d6406751976af443187aa
languageName: node
linkType: hard
@ -3368,18 +3368,18 @@ __metadata:
languageName: node
linkType: hard
"@open-wc/dev-server-hmr@npm:^0.0.2":
version: 0.0.2
resolution: "@open-wc/dev-server-hmr@npm:0.0.2"
"@open-wc/dev-server-hmr@npm:^0.1.3":
version: 0.1.3
resolution: "@open-wc/dev-server-hmr@npm:0.1.3"
dependencies:
"@babel/core": ^7.12.3
"@babel/plugin-proposal-class-properties": ^7.12.1
"@babel/plugin-syntax-class-properties": ^7.12.13
"@babel/plugin-syntax-import-assertions": ^7.12.1
"@babel/plugin-syntax-top-level-await": ^7.12.1
"@web/dev-server-core": ^0.2.18
"@web/dev-server-core": ^0.3.10
"@web/dev-server-hmr": ^0.1.6
picomatch: ^2.2.2
checksum: 4abb61cf6b13ef5bbc8ab7be6c3760d1791e2698b9fe1fcf6d281c2f0bb1e2acd2238e4f79f8e4079b200ca7ec422d3e113cc010d323b8416e687ccbdced2641
checksum: 993ddbdea4d919d5414ce2cbed8d49253658f4a0311b66f2e45d03ab9ea7354596144d46622a915683f72ca2b3c045b47362104327b4033bede1456446e085ff
languageName: node
linkType: hard
@ -4317,14 +4317,7 @@ __metadata:
languageName: node
linkType: hard
"@types/parse5@npm:^5.0.3":
version: 5.0.3
resolution: "@types/parse5@npm:5.0.3"
checksum: d6b7495cb1850f9f2e9c5e103ede9f2d30a5320669707b105c403868adc9e4bf8d3a7ff314cc23f67826bbbbbc0e6147346ce9062ab429f099dba7a01f463919
languageName: node
linkType: hard
"@types/parse5@npm:^6.0.0":
"@types/parse5@npm:^6.0.0, @types/parse5@npm:^6.0.1":
version: 6.0.3
resolution: "@types/parse5@npm:6.0.3"
checksum: ddb59ee4144af5dfcc508a8dcf32f37879d11e12559561e65788756b95b33e6f03ea027d88e1f5408f9b7bfb656bf630ace31a2169edf44151daaf8dd58df1b7
@ -4452,12 +4445,12 @@ __metadata:
languageName: node
linkType: hard
"@types/ws@npm:^7.2.6":
version: 7.4.0
resolution: "@types/ws@npm:7.4.0"
"@types/ws@npm:^7.2.6, @types/ws@npm:^7.4.0":
version: 7.4.7
resolution: "@types/ws@npm:7.4.7"
dependencies:
"@types/node": "*"
checksum: afc0060614ccc9382e0e2900220088bedbbdf9cf828b03990bcca9c9c0167bd2aa8b59cd001419ea804e5cc3b1668cc0c6c4aeb60f63c2a36814bed3f0d20528
checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3
languageName: node
linkType: hard
@ -4949,6 +4942,32 @@ __metadata:
languageName: node
linkType: hard
"@web/dev-server-core@npm:^0.3.10":
version: 0.3.19
resolution: "@web/dev-server-core@npm:0.3.19"
dependencies:
"@types/koa": ^2.11.6
"@types/ws": ^7.4.0
"@web/parse5-utils": ^1.2.0
chokidar: ^3.4.3
clone: ^2.1.2
es-module-lexer: ^1.0.0
get-stream: ^6.0.0
is-stream: ^2.0.0
isbinaryfile: ^4.0.6
koa: ^2.13.0
koa-etag: ^4.0.0
koa-send: ^5.0.1
koa-static: ^5.0.0
lru-cache: ^6.0.0
mime-types: ^2.1.27
parse5: ^6.0.1
picomatch: ^2.2.2
ws: ^7.4.2
checksum: 00b3cafc7d9c25806ae4af824d34d44928b09e039c7cf87e66ddc7b2f7d3198ab667f860282f8f8287cf26aeea1e8f4b348609eba4e05259cc52f4a7451c174f
languageName: node
linkType: hard
"@web/dev-server-hmr@npm:^0.1.6":
version: 0.1.6
resolution: "@web/dev-server-hmr@npm:0.1.6"
@ -4997,13 +5016,13 @@ __metadata:
languageName: node
linkType: hard
"@web/parse5-utils@npm:^1.0.0":
version: 1.1.2
resolution: "@web/parse5-utils@npm:1.1.2"
"@web/parse5-utils@npm:^1.0.0, @web/parse5-utils@npm:^1.2.0":
version: 1.3.0
resolution: "@web/parse5-utils@npm:1.3.0"
dependencies:
"@types/parse5": ^5.0.3
"@types/parse5": ^6.0.1
parse5: ^6.0.1
checksum: 5158e8d2b95d653d8a4d74521c13acd9cc1855cdff574372c867c55a1378afb4600864f9406ba2403bdd418a6b04a18960028fcca43a7d4dff0b3f131937d1ff
checksum: 379849c1b0a060d50037c7dc90d27231dc68f57b1034d87f89129c3cd87fa27d3a0f8e550e1ab3be00bb1c0d440a8fa95c153a481ed8c2c705fd46fbc8a8433d
languageName: node
linkType: hard
@ -5306,7 +5325,7 @@ __metadata:
languageName: node
linkType: hard
"aggregate-error@npm:^3.0.0, aggregate-error@npm:^3.1.0":
"aggregate-error@npm:^3.0.0":
version: 3.1.0
resolution: "aggregate-error@npm:3.1.0"
dependencies:
@ -5430,7 +5449,7 @@ __metadata:
languageName: node
linkType: hard
"ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2":
"ansi-escapes@npm:^4.3.0":
version: 4.3.2
resolution: "ansi-escapes@npm:4.3.2"
dependencies:
@ -7632,6 +7651,13 @@ __metadata:
languageName: node
linkType: hard
"es-module-lexer@npm:^1.0.0":
version: 1.1.0
resolution: "es-module-lexer@npm:1.1.0"
checksum: 3e9f5019b69c6b2f04eb8478c4fdb4ed72cb8b4c97511b5dd39c1f498386ed8f5083c32067c15efcfabc7e8460cb65ed4627dd32405475715a898009922f41fa
languageName: node
linkType: hard
"es-to-primitive@npm:^1.2.1":
version: 1.2.1
resolution: "es-to-primitive@npm:1.2.1"
@ -7799,15 +7825,14 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-disable@npm:^2.0.1":
version: 2.0.1
resolution: "eslint-plugin-disable@npm:2.0.1"
"eslint-plugin-disable@npm:^2.0.3":
version: 2.0.3
resolution: "eslint-plugin-disable@npm:2.0.3"
dependencies:
eslint: ">=0.16.0"
resolve: ^1.1.6
peerDependencies:
eslint: ">=0.16.0"
checksum: 55d541a6378fe2a4c7c6cee17c937df8bb372d907a0b6b79aabb8ded0bb2bbde5f333fdbdfc16af959425e42b679e7048ee9c4ee1524b9f545866e711775397e
checksum: 71893242172d633b63d3442393bf103f8f63ce97958ca63f6c5dacea0e4d4cdb4e35f1200b5e66c219034e26003177d18adf88e35af9ae1154739578832ec8ce
languageName: node
linkType: hard
@ -7934,7 +7959,7 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:>=0.16.0, eslint@npm:^7.32.0":
"eslint@npm:^7.32.0":
version: 7.32.0
resolution: "eslint@npm:7.32.0"
dependencies:
@ -8058,7 +8083,7 @@ __metadata:
languageName: node
linkType: hard
"etag@npm:^1.3.0, etag@npm:~1.8.1":
"etag@npm:^1.3.0, etag@npm:^1.8.1, etag@npm:~1.8.1":
version: 1.8.1
resolution: "etag@npm:1.8.1"
checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff
@ -8712,10 +8737,10 @@ __metadata:
languageName: node
linkType: hard
"fs-require@npm:^1.1.0":
version: 1.1.0
resolution: "fs-require@npm:1.1.0"
checksum: c0fc2468a21f6264b29a5287920d63b4db8a21fd32b26774d6da95798c3a54a7542fbb2889173b5d8ac07c25468a04e45a8d76c816c9c37e568a77c3695f4822
"fs-require@npm:^1.4.0":
version: 1.6.0
resolution: "fs-require@npm:1.6.0"
checksum: 085145a3021e142ae8d591d955f7e1d9cab17191666294e0ad394df5cb9ee379817b89c50de63bd861138dcb6adec589289d347c23de9bfe1ac82aeba6b1a128
languageName: node
linkType: hard
@ -9347,7 +9372,7 @@ fsevents@^1.2.7:
"@babel/plugin-proposal-decorators": ^7.20.7
"@babel/plugin-proposal-nullish-coalescing-operator": ^7.18.6
"@babel/plugin-proposal-object-rest-spread": ^7.20.2
"@babel/plugin-proposal-optional-chaining": ^7.18.9
"@babel/plugin-proposal-optional-chaining": ^7.20.7
"@babel/plugin-syntax-dynamic-import": ^7.8.3
"@babel/plugin-syntax-import-meta": ^7.10.4
"@babel/plugin-syntax-top-level-await": ^7.14.5
@ -9355,7 +9380,7 @@ fsevents@^1.2.7:
"@babel/preset-typescript": ^7.18.6
"@braintree/sanitize-url": ^6.0.0
"@codemirror/autocomplete": ^6.4.0
"@codemirror/commands": ^6.1.3
"@codemirror/commands": ^6.2.0
"@codemirror/language": ^6.4.0
"@codemirror/legacy-modes": ^6.3.1
"@codemirror/search": ^6.2.3
@ -9365,7 +9390,7 @@ fsevents@^1.2.7:
"@formatjs/intl-getcanonicallocales": ^2.0.5
"@formatjs/intl-locale": ^3.0.11
"@formatjs/intl-numberformat": ^7.2.5
"@formatjs/intl-pluralrules": ^4.1.5
"@formatjs/intl-pluralrules": ^5.1.8
"@formatjs/intl-relativetimeformat": ^11.1.8
"@fullcalendar/common": ^5.11.4
"@fullcalendar/core": ^5.11.4
@ -9373,7 +9398,7 @@ fsevents@^1.2.7:
"@fullcalendar/interaction": ^5.11.4
"@fullcalendar/list": ^5.11.4
"@fullcalendar/timegrid": ^5.11.4
"@koa/cors": ^3.1.0
"@koa/cors": ^4.0.0
"@lezer/highlight": ^1.1.3
"@lit-labs/motion": ^1.0.3
"@lit-labs/virtualizer": ^1.0.1
@ -9405,7 +9430,7 @@ fsevents@^1.2.7:
"@mdi/svg": 7.1.96
"@octokit/auth-oauth-device": ^4.0.4
"@octokit/rest": ^19.0.7
"@open-wc/dev-server-hmr": ^0.0.2
"@open-wc/dev-server-hmr": ^0.1.3
"@polymer/app-layout": ^3.1.0
"@polymer/iron-flex-layout": ^3.0.1
"@polymer/iron-icon": ^3.0.1
@ -9468,7 +9493,7 @@ fsevents@^1.2.7:
eslint-config-airbnb-typescript: ^14.0.0
eslint-config-prettier: ^8.6.0
eslint-import-resolver-webpack: ^0.13.1
eslint-plugin-disable: ^2.0.1
eslint-plugin-disable: ^2.0.3
eslint-plugin-import: ^2.24.2
eslint-plugin-lit: ^1.6.1
eslint-plugin-unused-imports: ^1.1.5
@ -9490,7 +9515,7 @@ fsevents@^1.2.7:
html-minifier: ^4.0.0
husky: ^8.0.3
idb-keyval: ^5.1.3
instant-mocha: ^1.3.1
instant-mocha: ^1.5.0
intl-messageformat: ^10.3.0
js-yaml: ^4.1.0
jszip: ^3.10.1
@ -9529,7 +9554,7 @@ fsevents@^1.2.7:
sortablejs: ^1.14.0
source-map-url: ^0.4.0
superstruct: ^1.0.3
systemjs: ^6.3.2
systemjs: ^6.13.0
tar: ^6.1.11
terser-webpack-plugin: ^5.2.4
tinykeys: ^1.1.3
@ -9942,23 +9967,20 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"instant-mocha@npm:^1.3.1":
version: 1.3.1
resolution: "instant-mocha@npm:1.3.1"
"instant-mocha@npm:^1.5.0":
version: 1.5.0
resolution: "instant-mocha@npm:1.5.0"
dependencies:
aggregate-error: ^3.1.0
ansi-escapes: ^4.3.2
fs-require: ^1.1.0
memfs: ^3.2.2
minimist: ^1.2.5
source-map-support: ^0.5.19
fs-require: ^1.4.0
memfs: ^3.4.12
source-map-support: ^0.5.21
yargs: ^16.2.0
peerDependencies:
mocha: ^6.1.4 || ^8.3.2
webpack: ^4.40.0 || ^5.0.0
mocha: 8 || 9 || 10
webpack: 4 || 5
bin:
instant-mocha: bin/instant-mocha.js
checksum: f4313d75249b63ef58cf62bb92a44bc284c556d6ce8430483e564718fea75797a0f587640af7efe69252690df1c3f10fd9ebda4d445f4da3fac35f41249c2e8d
instant-mocha: dist/cli.js
checksum: 77741864a0b6602e7599dc93e3bd3dfc3451c58e84881c7163b8fc9494c095528ba3cc2c8b74be41e885a659711d81777ff7fd761523c34d4eabcd9fb555156d
languageName: node
linkType: hard
@ -10872,7 +10894,16 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"koa-send@npm:^5.0.0":
"koa-etag@npm:^4.0.0":
version: 4.0.0
resolution: "koa-etag@npm:4.0.0"
dependencies:
etag: ^1.8.1
checksum: b5f413574e1edbd60fbbd0d31720e66565d51bfcb407d1bc3f48d9dd5b45fa5a9e4f69a60e749fad7397348e90de23e943307578d007a69da30faaae432deaf6
languageName: node
linkType: hard
"koa-send@npm:^5.0.0, koa-send@npm:^5.0.1":
version: 5.0.1
resolution: "koa-send@npm:5.0.1"
dependencies:
@ -11456,7 +11487,7 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"memfs@npm:^3.2.2, memfs@npm:^3.4.3":
"memfs@npm:^3.4.12, memfs@npm:^3.4.3":
version: 3.4.13
resolution: "memfs@npm:3.4.13"
dependencies:
@ -14372,13 +14403,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"source-map-support@npm:^0.5.19, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20":
version: 0.5.20
resolution: "source-map-support@npm:0.5.20"
"source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20":
version: 0.5.21
resolution: "source-map-support@npm:0.5.21"
dependencies:
buffer-from: ^1.0.0
source-map: ^0.6.0
checksum: 43946aff452011960d16154304b11011e0185549493e65dd90da045959409fb2d266ba1c854fff3d5949f8e59382e3fcc7f7c5fa66136007a6750ad06c6c0baa
checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137
languageName: node
linkType: hard
@ -14849,10 +14880,10 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
"systemjs@npm:^6.3.2":
version: 6.3.2
resolution: "systemjs@npm:6.3.2"
checksum: 640ee144b1bd85e41a1ed2fbd222a2341f996b8ec67cd8a22ee7d8afdf570cebd2953219862f6e780137a0d7fee77562c195f81dc9827edb4c648251c481b487
"systemjs@npm:^6.13.0":
version: 6.13.0
resolution: "systemjs@npm:6.13.0"
checksum: df8d7374249778291f3a85278fdb3e1b9d81ac07767b0a7f9edeca0ee45d847c19bceb01522c817605e2908d32a4fcfed6bacd707bfb7bd577774ab900d3707d
languageName: node
linkType: hard
@ -16510,9 +16541,9 @@ typescript@^3.8.3:
languageName: node
linkType: hard
"ws@npm:^7.3.1":
version: 7.4.0
resolution: "ws@npm:7.4.0"
"ws@npm:^7.3.1, ws@npm:^7.4.2":
version: 7.5.9
resolution: "ws@npm:7.5.9"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
@ -16521,7 +16552,7 @@ typescript@^3.8.3:
optional: true
utf-8-validate:
optional: true
checksum: 83a19a742aa2254ac5d7aa5d8f9a3bf7f2312bd147427fed02fc13168545c938450f1da9d8371133b292f63d1a21dcf7e7a09c6f89b8603581a27ed6c8e24e09
checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138
languageName: node
linkType: hard