diff --git a/package.json b/package.json index d67d582af2a9..2f1c2b10a773 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "@babel/plugin-transform-runtime": "7.24.7", "@babel/preset-env": "7.24.7", "@babel/preset-typescript": "7.24.7", - "@bundle-stats/plugin-webpack-filter": "4.13.2", + "@bundle-stats/plugin-webpack-filter": "4.13.3", "@koa/cors": "5.0.0", "@lokalise/node-api": "12.5.0", "@octokit/auth-oauth-device": "7.1.1", @@ -185,8 +185,8 @@ "@types/tar": "6.1.13", "@types/ua-parser-js": "0.7.39", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/eslint-plugin": "7.14.1", + "@typescript-eslint/parser": "7.14.1", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.3", @@ -220,7 +220,7 @@ "lodash.template": "4.5.0", "magic-string": "0.30.10", "map-stream": "0.0.7", - "mocha": "10.4.0", + "mocha": "10.5.0", "object-hash": "3.0.0", "open": "10.1.0", "pinst": "3.0.0", diff --git a/pyproject.toml b/pyproject.toml index 48b7f8fcea7c..4d2f4be0602b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240627.0" +version = "20240628.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" diff --git a/src/panels/config/application_credentials/dialog-add-application-credential.ts b/src/panels/config/application_credentials/dialog-add-application-credential.ts index d620f499c1a4..e30e494b4730 100644 --- a/src/panels/config/application_credentials/dialog-add-application-credential.ts +++ b/src/panels/config/application_credentials/dialog-add-application-credential.ts @@ -1,4 +1,3 @@ -import "@material/mwc-button"; import "@material/mwc-list/mwc-list-item"; import { mdiOpenInNew } from "@mdi/js"; import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; @@ -11,6 +10,7 @@ import "../../../components/ha-combo-box"; import { createCloseHeading } from "../../../components/ha-dialog"; import "../../../components/ha-markdown"; import "../../../components/ha-textfield"; +import "../../../components/ha-button"; import { ApplicationCredential, ApplicationCredentialsConfig, @@ -231,10 +231,10 @@ export class DialogAddApplicationCredential extends LitElement { ` : html` - + ${this.hass.localize("ui.common.cancel")} - - + + `} `; diff --git a/src/panels/config/application_credentials/ha-config-application-credentials.ts b/src/panels/config/application_credentials/ha-config-application-credentials.ts index 644759e148da..e11f0515f431 100644 --- a/src/panels/config/application_credentials/ha-config-application-credentials.ts +++ b/src/panels/config/application_credentials/ha-config-application-credentials.ts @@ -7,6 +7,7 @@ import { LocalizeFunc } from "../../../common/translations/localize"; import { DataTableColumnContainer, SelectionChangedEvent, + SortingChangedEvent, } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-fab"; import "../../../components/ha-help-tooltip"; @@ -27,6 +28,7 @@ import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage- import { HomeAssistant, Route } from "../../../types"; import { configSections } from "../ha-panel-config"; import { showAddApplicationCredentialDialog } from "./show-dialog-add-application-credential"; +import { storage } from "../../../common/decorators/storage"; @customElement("ha-config-application-credentials") export class HaConfigApplicationCredentials extends LitElement { @@ -45,6 +47,35 @@ export class HaConfigApplicationCredentials extends LitElement { @query("hass-tabs-subpage-data-table", true) private _dataTable!: HaTabsSubpageDataTable; + @storage({ + key: "application-credentials-table-sort", + state: false, + subscribe: false, + }) + private _activeSorting?: SortingChangedEvent; + + @storage({ + key: "application-credentials-table-column-order", + state: false, + subscribe: false, + }) + private _activeColumnOrder?: string[]; + + @storage({ + key: "application-credentials-table-hidden-columns", + state: false, + subscribe: false, + }) + private _activeHiddenColumns?: string[]; + + @storage({ + storage: "sessionStorage", + key: "application-credentials-table-search", + state: true, + subscribe: false, + }) + private _filter = ""; + private _columns = memoizeOne( (narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => { const columns: DataTableColumnContainer = { @@ -53,6 +84,7 @@ export class HaConfigApplicationCredentials extends LitElement { "ui.panel.config.application_credentials.picker.headers.name" ), sortable: true, + filterable: true, direction: "asc", grows: true, }, @@ -60,6 +92,7 @@ export class HaConfigApplicationCredentials extends LitElement { title: localize( "ui.panel.config.application_credentials.picker.headers.client_id" ), + filterable: true, width: "30%", hidden: narrow, }, @@ -68,6 +101,7 @@ export class HaConfigApplicationCredentials extends LitElement { "ui.panel.config.application_credentials.picker.headers.application" ), sortable: true, + filterable: true, width: "30%", direction: "asc", }, @@ -84,7 +118,7 @@ export class HaConfigApplicationCredentials extends LitElement { path: mdiDelete, warning: true, label: this.hass.localize("ui.common.delete"), - action: () => this._removeCredential(credential), + action: () => this._deleteCredential(credential), }, ]} > @@ -128,11 +162,18 @@ export class HaConfigApplicationCredentials extends LitElement { selectable .selected=${this._selected.length} @selection-changed=${this._handleSelectionChanged} + .initialSorting=${this._activeSorting} + .columnOrder=${this._activeColumnOrder} + .hiddenColumns=${this._activeHiddenColumns} + @columns-changed=${this._handleColumnsChanged} + @sorting-changed=${this._handleSortingChanged} + .filter=${this._filter} + @search-changed=${this._handleSearchChange} >
${!this.narrow ? html` - ${this.hass.localize( "ui.panel.config.application_credentials.picker.remove_selected.button" )} @@ -174,7 +215,7 @@ export class HaConfigApplicationCredentials extends LitElement { this._selected = ev.detail.value; } - private _removeCredential = async (credential) => { + private _deleteCredential = async (credential) => { const confirm = await showConfirmationDialog(this, { title: this.hass.localize( `ui.panel.config.application_credentials.picker.remove.confirm_title` @@ -190,9 +231,10 @@ export class HaConfigApplicationCredentials extends LitElement { return; } await deleteApplicationCredential(this.hass, credential.id); + await this._fetchApplicationCredentials(); }; - private _removeSelected() { + private _deleteSelected() { showConfirmationDialog(this, { title: this.hass.localize( `ui.panel.config.application_credentials.picker.remove_selected.confirm_title`, @@ -224,7 +266,7 @@ export class HaConfigApplicationCredentials extends LitElement { return; } this._dataTable.clearSelection(); - this._fetchApplicationCredentials(); + await this._fetchApplicationCredentials(); }, }); } @@ -252,6 +294,19 @@ export class HaConfigApplicationCredentials extends LitElement { }); } + private _handleSortingChanged(ev: CustomEvent) { + this._activeSorting = ev.detail; + } + + private _handleColumnsChanged(ev: CustomEvent) { + this._activeColumnOrder = ev.detail.columnOrder; + this._activeHiddenColumns = ev.detail.hiddenColumns; + } + + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value; + } + static get styles(): CSSResultGroup { return css` .table-header { diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index 67da2d580dc6..3c0f0d10df8c 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -265,7 +265,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { const columns: DataTableColumnContainer = { icon: { title: "", - label: localize("ui.panel.config.automation.picker.headers.state"), + label: localize("ui.panel.config.automation.picker.headers.icon"), type: "icon", moveable: false, showNarrow: true, diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index 0f47b0644c07..b889dc1094de 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -243,7 +243,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) { const columns: DataTableColumnContainer = { icon: { title: "", - label: localize("ui.panel.config.scene.picker.headers.state"), + label: localize("ui.panel.config.scene.picker.headers.icon"), moveable: false, showNarrow: true, type: "icon", diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index f89790c886ce..d35aed5f90d6 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -252,7 +252,7 @@ class HaScriptPicker extends SubscribeMixin(LitElement) { title: "", showNarrow: true, moveable: false, - label: localize("ui.panel.config.script.picker.headers.state"), + label: localize("ui.panel.config.script.picker.headers.icon"), type: "icon", template: (script) => html` hui-card { + display: contents; + } #root > hui-card > * { flex: 1 1 0; min-width: 0; diff --git a/src/translations/en.json b/src/translations/en.json index ffd25ca6bba2..4ee62dc063c6 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2733,7 +2733,8 @@ "actions": "Actions", "state": "State", "category": "Category", - "area": "Area" + "area": "Area", + "icon": "Icon" }, "bulk_action": "Action", "bulk_actions": { @@ -3608,7 +3609,8 @@ "name": "Name", "state": "State", "category": "Category", - "area": "Area" + "area": "Area", + "icon": "Icon" }, "edit_category": "[%key:ui::panel::config::automation::picker::edit_category%]", "assign_category": "[%key:ui::panel::config::automation::picker::assign_category%]", @@ -3727,7 +3729,8 @@ "name": "Name", "last_activated": "Last activated", "category": "Category", - "area": "Area" + "area": "Area", + "icon": "Icon" }, "edit_category": "[%key:ui::panel::config::automation::picker::edit_category%]", "assign_category": "[%key:ui::panel::config::automation::picker::assign_category%]", diff --git a/yarn.lock b/yarn.lock index 88dd85f65445..f26b8a6153bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1460,12 +1460,12 @@ __metadata: languageName: node linkType: hard -"@bundle-stats/plugin-webpack-filter@npm:4.13.2": - version: 4.13.2 - resolution: "@bundle-stats/plugin-webpack-filter@npm:4.13.2" +"@bundle-stats/plugin-webpack-filter@npm:4.13.3": + version: 4.13.3 + resolution: "@bundle-stats/plugin-webpack-filter@npm:4.13.3" peerDependencies: core-js: ^3.0.0 - checksum: 10/92c2e3c05998762613e3fbed465bceb133c94b4182db502c42e6cbfc2016867101f72adcecb5d1791f73ebcb44039e0c8046737dfb1f49bbad7b1b617599184c + checksum: 10/5de079362fe592d29a32598646164aeea329e81697b51356d2f760932bf95f0ca2e5ac8c45324e2850f8450c12e8a8ec95d851fd15ab25522832ebd3e64aacfe languageName: node linkType: hard @@ -4575,15 +4575,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.13.1" +"@typescript-eslint/eslint-plugin@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.14.1" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/type-utils": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/type-utils": "npm:7.14.1" + "@typescript-eslint/utils": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -4594,44 +4594,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/37fff8c302f93f5f88fc8d6e6c9151a7d1873a3c8af6e15547d737bdc066a6b8887fa54bcd8eb4e4ca6a11494051801c8e957eea8d8b4d4b078a477df6f10692 + checksum: 10/48c815dbb92399965483c93b27816fad576c3b3227b59eebfe5525e24d07b39ec8b0c7459de83865c8d61c818696519f50b229714dd3ed705d5b35973bfcc781 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/parser@npm:7.13.1" +"@typescript-eslint/parser@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/parser@npm:7.14.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/a76cfcf97c289110403b50a377e925f29cda74340de0526f68b0c34199ce643d9c31803e492217e0f3df28361d3019ced4806f974ea70529c559b26b70cec7ef + checksum: 10/f521462a7005cab5e4923937dcf36713d9438ded175b53332ae469d91cc9eb18cb3a23768b3c52063464280baae83f6b66db28cebb2e262d6d869d1a898b23f3 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/scope-manager@npm:7.13.1" +"@typescript-eslint/scope-manager@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/scope-manager@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - checksum: 10/fea9ab8f72ace1dd55d835037efe038c70021275581855820cdb7fc4b01e8afb51723856537adff1fdb0ea3899c1f8b593fd75c34b5087ca2ef2f7c72e610050 + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" + checksum: 10/600a7beb96f5b96f675125285137339c2438b5b26db203a66eef52dd409e8c0db0dafb22c94547dfb963f8efdf63b0fb59e05655e2dcf84d54624863365a59e7 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/type-utils@npm:7.13.1" +"@typescript-eslint/type-utils@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/type-utils@npm:7.14.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/utils": "npm:7.14.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -4639,23 +4639,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/cc03cd44e125933511ea657e386c5cf427eb6a386fdb110cba0858598195fb4f8c71173b00b187f388a6713e16b919a2037a86e0be10f4c40c18bcbdbe06d5de + checksum: 10/75c279948a7e7e546d692e85a0b48fc3b648ffee1773feb7ff199aba1b0847a9a16c432b133aa72d26e645627403852b7dd24829f9b3badd6d4711c4cc38e9e4 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/types@npm:7.13.1" - checksum: 10/006a5518608184c1d017b27fb4f66ce28bc75f89e2380ac42969ebdf0dc726af1cfcdf4ba36ce2858e9f6907d6f4295d3453859d7e9a35bc7855d4ebc900955d +"@typescript-eslint/types@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/types@npm:7.14.1" + checksum: 10/608057582bb195bd746a7bfb7c04dac4be1d4602b8fa681b2d1d50b564362b681dc2ca293b13cc4c7acc454f3a09f1ea2580415347efb7853e5df8ba34b7acdb languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.13.1" +"@typescript-eslint/typescript-estree@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -4665,31 +4665,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/5c68b5faa962e5f984067aa91770486af817858d2fa35b54a44fa4d5c0c612ba23b52b191d8051d9e4439e5425251e32861c81239e9400a29de057f8360537fb + checksum: 10/f75b956f7981712d3f85498f9d9fcc2243d79d6fe71b24bc688a7c43d2a4248f73ecfb78f9d58501fde87fc44b02e26c46f9ea2ae51eb8450db79ca169f91ef9 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/utils@npm:7.13.1" +"@typescript-eslint/utils@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/utils@npm:7.14.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" peerDependencies: eslint: ^8.56.0 - checksum: 10/e1bc916dcb567c6b35819f635a84561e015f40b28d650b987f74c79b013ec43fb4f5b61199d4039fcdf9480281f945f622650cba2e68739600822da05808a706 + checksum: 10/1ef74214ca84e32f151364512a51e82b7da5590dee03d0de0e1abcf18009e569f9a0638506cf03bd4a844af634b4935458e334b7b2459e9a50a67aba7d6228c7 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.13.1" +"@typescript-eslint/visitor-keys@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" + "@typescript-eslint/types": "npm:7.14.1" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/811e9642851359b5197d45a9878143c4c608aaef887a20c26f57f8b012ce9e316d232b82a311bdd52a2af0c8b8da5d4bd9401ce565fc7bdb43cd44556e76d225 + checksum: 10/42246f33cb3f9185c0b467c9a534e34a674e4fc08ba982a03aaa77dc1e569e916f1fca9ce9cd14c4df91f416e6e917bff51f98b8d8ca26ec5f67c253e8646bde languageName: node linkType: hard @@ -6274,25 +6274,6 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:3.5.3": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" - dependencies: - anymatch: "npm:~3.1.2" - braces: "npm:~3.0.2" - fsevents: "npm:~2.3.2" - glob-parent: "npm:~5.1.2" - is-binary-path: "npm:~2.1.0" - is-glob: "npm:~4.0.1" - normalize-path: "npm:~3.0.0" - readdirp: "npm:~3.6.0" - dependenciesMeta: - fsevents: - optional: true - checksum: 10/863e3ff78ee7a4a24513d2a416856e84c8e4f5e60efbe03e8ab791af1a183f569b62fc6f6b8044e2804966cb81277ddbbc1dc374fba3265bd609ea8efd62f5b3 - languageName: node - linkType: hard - "chokidar@npm:^3.4.3, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" @@ -8912,7 +8893,7 @@ __metadata: "@babel/preset-typescript": "npm:7.24.7" "@babel/runtime": "npm:7.24.7" "@braintree/sanitize-url": "npm:7.0.3" - "@bundle-stats/plugin-webpack-filter": "npm:4.13.2" + "@bundle-stats/plugin-webpack-filter": "npm:4.13.3" "@codemirror/autocomplete": "npm:6.16.3" "@codemirror/commands": "npm:6.6.0" "@codemirror/language": "npm:6.10.2" @@ -9003,8 +8984,8 @@ __metadata: "@types/tar": "npm:6.1.13" "@types/ua-parser-js": "npm:0.7.39" "@types/webspeechapi": "npm:0.0.29" - "@typescript-eslint/eslint-plugin": "npm:7.13.1" - "@typescript-eslint/parser": "npm:7.13.1" + "@typescript-eslint/eslint-plugin": "npm:7.14.1" + "@typescript-eslint/parser": "npm:7.14.1" "@vaadin/combo-box": "npm:24.4.0" "@vaadin/vaadin-themable-mixin": "npm:24.4.0" "@vibrant/color": "npm:3.2.1-alpha.1" @@ -9070,7 +9051,7 @@ __metadata: map-stream: "npm:0.0.7" marked: "npm:12.0.2" memoize-one: "npm:6.0.0" - mocha: "npm:10.4.0" + mocha: "npm:10.5.0" node-vibrant: "npm:3.2.1-alpha.1" object-hash: "npm:3.0.0" open: "npm:10.1.0" @@ -11169,13 +11150,13 @@ __metadata: languageName: node linkType: hard -"mocha@npm:10.4.0": - version: 10.4.0 - resolution: "mocha@npm:10.4.0" +"mocha@npm:10.5.0": + version: 10.5.0 + resolution: "mocha@npm:10.5.0" dependencies: ansi-colors: "npm:4.1.1" browser-stdout: "npm:1.3.1" - chokidar: "npm:3.5.3" + chokidar: "npm:^3.5.3" debug: "npm:4.3.4" diff: "npm:5.0.0" escape-string-regexp: "npm:4.0.0" @@ -11196,7 +11177,7 @@ __metadata: bin: _mocha: bin/_mocha mocha: bin/mocha.js - checksum: 10/0147b2a86c8a3b134b3bda949006aa5f2b08db606b9394e38eb3fa0d97dd2f54f06eb4afb270d4ae08aa6fb7674282737ed556b9a8bc407f9b8488380852eca4 + checksum: 10/64f5aace4a5b7eed23d8bcfaf1eacdaafbffdc5e3ee977ecb32ace8f91733b1520b8342ce02d7101e8d7b8bd4008e055e4f4f63a0e4a3da81baf0e41566a07ab languageName: node linkType: hard