Compare commits

...

56 Commits

Author SHA1 Message Date
Pascal Vizeli
15a6f38ebb Make sure device is ready initialize on udev (#2504)
* Make sure device is ready initialize on udev

* fix style

* let's start with 2sec

* better logic

* style

* add change events back
2021-02-02 09:53:09 +01:00
dependabot[bot]
227f2e5a21 Bump pyupgrade from 2.8.0 to 2.9.0 (#2505)
Bumps [pyupgrade](https://github.com/asottile/pyupgrade) from 2.8.0 to 2.9.0.
- [Release notes](https://github.com/asottile/pyupgrade/releases)
- [Commits](https://github.com/asottile/pyupgrade/compare/v2.8.0...v2.9.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-02 09:52:51 +01:00
Pascal Vizeli
517d6ee981 Lookup udev device in monitor thread (#2503) 2021-02-01 18:29:05 +01:00
Pascal Vizeli
184eeb7f49 Udev - move away form depricated callback / increase buffer (#2502)
* Use new callback from udev / only forward

* minimize loop

* Udev - move away form depricated callback / increase buffer

* code cleanup
2021-02-01 17:33:53 +01:00
Joakim Sørensen
a3555c74e8 Bump awesomeversion from 21.1.8 to 21.2.0 (#2501) 2021-02-01 15:45:35 +01:00
Pascal Vizeli
657bafd458 Fix handling with shm and shared /dev (#2499)
* Fix handling with shm and shared /dev

* address commends

* let's share shm
2021-02-01 14:44:02 +01:00
Joakim Sørensen
2ad5df420c Rerun label check on synchronize (#2500) 2021-02-01 14:37:56 +01:00
Joakim Sørensen
b24d489ec5 Update frontend to a9192ae2 (#2498) 2021-02-01 13:26:54 +01:00
Franck Nijhof
6bb0210f1f Fix add-on is_valid check (#2497) 2021-02-01 11:27:34 +01:00
dependabot[bot]
c1de50266a Bump pytz from 2020.5 to 2021.1 (#2496)
Bumps [pytz](https://github.com/stub42/pytz) from 2020.5 to 2021.1.
- [Release notes](https://github.com/stub42/pytz/releases)
- [Commits](https://github.com/stub42/pytz/compare/release_2020.5...release_2021.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-01 11:27:17 +01:00
dependabot[bot]
562e02bc64 Bump pyupgrade from 2.7.4 to 2.8.0 (#2494)
Bumps [pyupgrade](https://github.com/asottile/pyupgrade) from 2.7.4 to 2.8.0.
- [Release notes](https://github.com/asottile/pyupgrade/releases)
- [Commits](https://github.com/asottile/pyupgrade/compare/v2.7.4...v2.8.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-01 11:27:04 +01:00
dependabot[bot]
f71ec7913a Bump awesomeversion from 21.1.5 to 21.1.8 (#2493)
Bumps [awesomeversion](https://github.com/ludeeus/awesomeversion) from 21.1.5 to 21.1.8.
- [Release notes](https://github.com/ludeeus/awesomeversion/releases)
- [Commits](https://github.com/ludeeus/awesomeversion/compare/21.1.5...21.1.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-01 11:26:51 +01:00
dependabot[bot]
d98baaf660 Bump jinja2 from 2.11.2 to 2.11.3 (#2495)
Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.2 to 2.11.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/2.11.2...2.11.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-01 11:26:30 +01:00
Pascal Vizeli
72db591576 Validate build env before using it (#2492) 2021-02-01 09:46:48 +01:00
Wouter Schoot
509a37fc04 Typofix exsist -> exist (#2491)
* Typofix exsist -> exist

* Typofix exist -> exists
2021-02-01 09:34:17 +01:00
Pascal Vizeli
17f62b6e86 Handle corrupt store branch / ignore local reset on corruption (#2490)
* Handle corrupt store branch / ignore local reset on corruption

* Update data.py

* Update data.py
2021-01-31 22:55:43 +01:00
Pascal Vizeli
b09aee7644 Filter out virtual vcs devices (#2489)
* Filter out virtual vcs devices

* fix test
2021-01-31 14:40:14 +01:00
Pascal Vizeli
babcc0de0c Cleanup supervisor/udev device action / add GPIO (#2488)
* Cleanup supervisor/udev device action / add GPIO

* Apply francks comment
2021-01-31 14:24:22 +01:00
Franck Nijhof
5cc47c9222 Re-enable old template until form is resolved (#2486) 2021-01-30 19:47:45 +01:00
Franck Nijhof
833559a3b3 Add initial GitHub Issue Form (#2485)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
2021-01-30 19:35:15 +01:00
Pascal Vizeli
b8a976b344 Change handling kernel udev events (#2484)
* Change handling kernel udev events / add USB events

* finish USB

* map dev ro

* fix bind
2021-01-30 14:19:53 +01:00
Joakim Sørensen
10b14132b9 Update frontend to 86847263 (#2483) 2021-01-29 18:23:58 +01:00
Pascal Vizeli
18953f0b7c plug & play devices (#2482)
* Add support for plug&play container & full udev passtrhough

* plug & play devices

* this hack is not needed anymore

* Fix GPIO issue

* Apply suggestions from code review

Co-authored-by: Franck Nijhof <git@frenck.dev>

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-01-29 17:17:41 +01:00
Joakim Sørensen
19f5fba3aa Bump awesomeversion from 21.1.4 to 21.1.5 (#2481) 2021-01-29 14:10:06 +01:00
Pascal Vizeli
636bc3e61a Handle GPIO / VIDEO map with subystem (#2478)
* Handle GPIO / VIDEO mapping with subystem

* fix tests

* add udev support

* init udev data

* fix
2021-01-29 11:28:16 +01:00
Pascal Vizeli
521037e1a6 Fix mknod creating of the device on runtime time (#2477) 2021-01-28 17:07:33 +01:00
Pascal Vizeli
e024c3e38d Improve device selection and show device by id if available (#2476) 2021-01-28 15:43:06 +01:00
Pascal Vizeli
6a0206c1e7 Next generation hardware handling (#2429)
* Next generation hardware handling

* need daemon for some details

* fix tests

* fix wrong coresys lookup

* test initial import

* test device lookup

* validate if device exists

* Add cgroups rules manager

* mapping udev from host

* Modify validation/options handling

* lookup devices

* add support for host udev mapping

* next

* Add policy support to add-ons

* Depricate hardware trigger call

* next cleanup round

* detect USB linking

* optimize

* readd udev utils for backwards compatibility

* fix tests

* Add more tests

* fix tests

* Make device explicit

* Add filter

* work on tests

* Add migration step

* clean out auto_uart

* Fix all tests

* Expose all device information

* small  improvment

* Fix loop over right devices

* Use migration for new device format

* Update rootfs/etc/cont-init.d/udev.sh

Co-authored-by: Franck Nijhof <git@frenck.dev>

* Fix old helper

* Fix API

* add helper for by-id

* fix tests

* Fix serial helper

* Fix hardware API schema

* Hide some virtual devices from tracking

* Apply suggestions from code review

Co-authored-by: Stefan Agner <stefan@agner.ch>

* Update supervisor/addons/validate.py

Co-authored-by: Stefan Agner <stefan@agner.ch>

* Update supervisor/addons/validate.py

Co-authored-by: Stefan Agner <stefan@agner.ch>

* fix lint

* Apply suggestions from code review

Co-authored-by: Joakim Sørensen <joasoe@gmail.com>

* Apply suggestions from code review

Co-authored-by: Joakim Sørensen <joasoe@gmail.com>

* fix black

* fix lint

Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Stefan Agner <stefan@agner.ch>
Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
2021-01-28 15:26:56 +01:00
Joakim Sørensen
69a8a83528 Limit label check (#2475) 2021-01-28 12:07:42 +01:00
Joakim Sørensen
0307d700fa Add TypeError guard for docker stats (#2474) 2021-01-28 11:58:04 +01:00
Joakim Sørensen
919c383b41 Bump awesomeversion from 21.1.3 to 21.1.4 (#2473) 2021-01-28 11:41:11 +01:00
dependabot[bot]
d331af4d5a Bump pre-commit from 2.9.3 to 2.10.0 (#2472)
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.9.3 to 2.10.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v2.9.3...v2.10.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-28 08:46:29 +01:00
Joakim Sørensen
b5467d3c23 Update frontend to 5ee0250b (#2471) 2021-01-28 08:45:33 +01:00
dependabot[bot]
3ef0040d66 Bump coverage from 5.3.1 to 5.4 (#2470)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.3.1 to 5.4.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/coverage-5.3.1...coverage-5.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-27 08:41:22 +01:00
Joakim Sørensen
ec4dfd2172 Add action to check PR labels (#2469)
* Check PR labels

* update

* update

* update

* only use lable events

* remove env stuff

* add back types
2021-01-26 14:21:05 +01:00
Pascal Vizeli
8f54d7c8e9 New version logic NM (#2466) 2021-01-26 10:33:35 +01:00
dependabot[bot]
b59e709dc0 Bump home-assistant/builder from 2020.11.0 to 2021.01.1 (#2468)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2020.11.0 to 2021.01.1.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2020.11.0...e33ea8af3ad98e9ed7513cad92cc88fb303b42ff)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 10:17:50 +01:00
dependabot[bot]
b236e6c886 Bump pytest from 6.2.1 to 6.2.2 (#2467)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-26 09:47:45 +01:00
Pascal Vizeli
8acbb7d6f0 Fix API info calls access (#2464) 2021-01-25 10:45:08 +01:00
dependabot[bot]
49e4bc9381 Bump actions/stale from v3.0.14 to v3.0.15 (#2463)
Bumps [actions/stale](https://github.com/actions/stale) from v3.0.14 to v3.0.15.
- [Release notes](https://github.com/actions/stale/releases)
- [Commits](https://github.com/actions/stale/compare/v3.0.14...86561461b92875de77a8b2d2e75f004c826e8f45)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-25 09:59:20 +01:00
Philip Allgaier
36106cc08d Small README tweaks (#2460) 2021-01-24 21:18:06 +01:00
Pascal Vizeli
8f1763abe2 Fix OSError with custom component check (#2458) 2021-01-24 16:46:49 +01:00
Joakim Sørensen
480eebc6cb Update alert notification (#2457) 2021-01-23 21:06:55 +01:00
Pascal Vizeli
dccfffd979 Improve fixups with Job condition checks (#2451) 2021-01-21 16:48:25 +01:00
dependabot[bot]
1a978f4762 Bump pytest-cov from 2.11.0 to 2.11.1 (#2455)
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.11.0 to 2.11.1.
- [Release notes](https://github.com/pytest-dev/pytest-cov/releases)
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v2.11.0...v2.11.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-21 09:29:47 +01:00
Pascal Vizeli
1fbc8f4060 Add discovery support for zwave_js (#2454)
* Add discovery support for zwave_js

* New schema

* hmm

* address comments
2021-01-20 16:51:51 +01:00
Pascal Vizeli
db3fc1421c Fix: stable issue with corrupt git repository / submodule (#2452) 2021-01-19 14:21:27 +01:00
dependabot[bot]
9ecd03db0e Bump pytest-cov from 2.10.1 to 2.11.0 (#2446)
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.10.1 to 2.11.0.
- [Release notes](https://github.com/pytest-dev/pytest-cov/releases)
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v2.10.1...v2.11.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-18 13:54:22 +01:00
dependabot[bot]
f111ccb1b6 Bump awesomeversion from 21.1.2 to 21.1.3 (#2445)
Bumps [awesomeversion](https://github.com/ludeeus/awesomeversion) from 21.1.2 to 21.1.3.
- [Release notes](https://github.com/ludeeus/awesomeversion/releases)
- [Commits](https://github.com/ludeeus/awesomeversion/compare/21.1.2...21.1.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-18 13:54:07 +01:00
Joakim Sørensen
a32341cc5d Update frontend to 08c1b864 (#2444) 2021-01-17 17:54:42 +01:00
Pascal Vizeli
f73e277230 Fix issues with awesomeversion and representation (#2443) 2021-01-17 16:39:34 +01:00
Joakim Sørensen
8d8587ca29 Update wording in notification (#2438)
* Update wording in notification

* Update notify.py
2021-01-15 21:49:52 +01:00
Joakim Sørensen
88eb9511bf Add core version check (#2436)
* Add core version check

* Fix version handling, rename and use correct paths

* simplify check

* wrap approve check
2021-01-15 21:13:42 +01:00
Pascal Vizeli
e1068997ea Fix submodule update (#2434) 2021-01-15 14:28:31 +01:00
dependabot[bot]
560e04c64a Bump colorlog from 4.6.2 to 4.7.2 (#2432)
Bumps [colorlog](https://github.com/borntyping/python-colorlog) from 4.6.2 to 4.7.2.
- [Release notes](https://github.com/borntyping/python-colorlog/releases)
- [Commits](https://github.com/borntyping/python-colorlog/compare/v4.6.2...v4.7.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-15 14:24:40 +01:00
Joakim Sørensen
621ec03971 Ignore wheels on release (#2428)
* Fix wheels on publish

* ignore wheels for publish

* test

* revert test
2021-01-12 15:45:35 +01:00
172 changed files with 4602 additions and 2499 deletions

View File

@@ -0,0 +1,80 @@
name: Bug Report Form
about: Report an issue related to the Home Assistant Supervisor.
labels: bug
title: ""
issue_body: true
inputs:
- type: description
attributes:
value: |
This issue form is for reporting bugs with **supported** setups only!
If you have a feature or enhancement request, please use the [feature request][fr] section of our [Community Forum][fr].
[fr]: https://community.home-assistant.io/c/feature-requests
- type: input
attributes:
label: What is the version of the Supervisor used?
required: true
placeholder: supervisor-
description: >
Can be found in the Supervisor panel -> System tab. Starts with
`supervisor-....`.
- type: dropdown
attributes:
label: What type of installation are you running?
required: true
description: >
If you don't know, you can find it in: Configuration panel -> Info.
choices:
- Home Assistant OS
- Home Assistant Supervised
- type: dropdown
attributes:
label: Which operating system are you running on?
required: true
choices:
- Home Assistant Operating System
- Debian
- Other (e.g., Raspbian/Raspberry Pi OS/Fedora)
- type: input
attributes:
label: What is the version of your installed operating system?
required: true
placeholder: 5.10
description: Can be found in the Supervisor panel -> System tab.
- type: input
attributes:
label: What version of Home Assistant Core is installed?
required: true
placeholder: core-
description: >
Can be found in the Supervisor panel -> System tab. Starts with
`core-....`.
- type: textarea
attributes:
label: Describe the issue you are experiencing
required: true
description: Provide a clear and concise description of what the bug is.
- type: textarea
attributes:
label: Steps to reproduce the issue
required: true
description: |
Please tell us exactly how to reproduce your issue.
Provide clear and concise step by step instructions and add code snippets if needed.
value: |
1.
2.
3.
...
- type: textarea
attributes:
label: Anything in the Supervisor logs that might be useful for us?
required: false
description: >
The Supervisor logs can be found in the Supervisor panel -> System tab.
- type: description
attributes:
value: |
If you have any additional information for us, use the field below.
Please note, you can attach screenshots or screen recordings here.

View File

@@ -65,6 +65,7 @@ jobs:
- name: Get changed files
id: changed_files
if: steps.version.outputs.publish == 'false'
uses: jitterbit/get-changed-files@v1
- name: Check if requirements files changed
@@ -118,7 +119,7 @@ jobs:
run: echo "BUILD_ARGS=--test" >> $GITHUB_ENV
- name: Build supervisor
uses: home-assistant/builder@2020.11.0
uses: home-assistant/builder@2021.01.1
with:
args: |
$BUILD_ARGS \
@@ -160,7 +161,7 @@ jobs:
uses: actions/checkout@v2
- name: Build the Supervisor
uses: home-assistant/builder@2020.11.0
uses: home-assistant/builder@2021.01.1
with:
args: |
--test \

19
.github/workflows/check_pr_labels.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Check PR
on:
pull_request:
branches: ["main"]
types: [labeled, unlabeled, synchronize]
jobs:
init:
name: Check labels
runs-on: ubuntu-latest
steps:
- name: Check labels
run: |
labels=$(jq -r '.pull_request.labels[] | .name' ${{github.event_path }})
echo "$labels"
if [ "$labels" == "cla-signed" ]; then
exit 1
fi

View File

@@ -9,7 +9,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3.0.14
- uses: actions/stale@v3.0.15
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 60

View File

@@ -21,12 +21,12 @@ Development instructions can be found [here][development].
Releases are done in 3 stages (channels) with this structure:
1. Pull requests are merged to the `main` branch
1. Pull requests are merged to the `main` branch.
2. A new build is pushed to the `dev` stage.
3. Releases are published
3. Releases are published.
4. A new build is pushed to the `beta` stage.
5. The [`stable.json][stable] file is updated
6. The build that was pushed to `beta` will now be pushed to `stable`
5. The [`stable.json`][stable] file is updated.
6. The build that was pushed to `beta` will now be pushed to `stable`.
[development]: https://developers.home-assistant.io/docs/supervisor/development
[stable]: https://github.com/home-assistant/version/blob/master/stable.json

View File

@@ -2,19 +2,18 @@ aiohttp==3.7.3
async_timeout==3.0.1
atomicwrites==1.4.0
attrs==20.3.0
awesomeversion==21.1.0
awesomeversion==21.2.0
brotli==1.0.9
cchardet==2.1.7
colorlog==4.6.2
colorlog==4.7.2
cpe==1.2.1
cryptography==3.3.1
debugpy==1.2.1
docker==4.4.1
gitpython==3.1.12
jinja2==2.11.2
packaging==20.4
jinja2==2.11.3
pulsectl==20.5.1
pytz==2020.5
pytz==2021.1
pyudev==0.22.0
ruamel.yaml==0.15.100
sentry-sdk==0.19.5

View File

@@ -1,14 +1,14 @@
black==20.8b1
codecov==2.1.11
coverage==5.3.1
coverage==5.4
flake8-docstrings==1.5.0
flake8==3.8.4
pre-commit==2.9.3
pre-commit==2.10.0
pydocstyle==5.1.1
pylint==2.6.0
pytest-aiohttp==0.3.0
pytest-asyncio==0.12.0 # NB!: Versions over 0.12.0 breaks pytest-aiohttp (https://github.com/aio-libs/pytest-aiohttp/issues/16)
pytest-cov==2.10.1
pytest-cov==2.11.1
pytest-timeout==1.4.2
pytest==6.2.1
pyupgrade==2.7.4
pytest==6.2.2
pyupgrade==2.9.0

View File

@@ -2,9 +2,16 @@
# ==============================================================================
# Start udev service
# ==============================================================================
if bashio::fs.directory_exists /run/udev; then
bashio::log.info "Using udev information from host"
bashio::exit.ok
fi
bashio::log.info "Setup udev backend inside container"
udevd --daemon
bashio::log.info "Update udev information"
if udevadm trigger; then
udevadm settle || true
else

View File

@@ -23,9 +23,10 @@ function run_supervisor() {
--privileged \
--security-opt seccomp=unconfined \
--security-opt apparmor:unconfined \
-v /run/docker.sock:/run/docker.sock \
-v /run/dbus:/run/dbus \
-v "/workspaces/test_supervisor":/data \
-v /run/docker.sock:/run/docker.sock:rw \
-v /run/dbus:/run/dbus:ro \
-v /run/udev:/run/udev:ro \
-v "/workspaces/test_supervisor":/data:rw \
-v /etc/machine-id:/etc/machine-id:ro \
-v /workspaces/supervisor:/usr/src/supervisor \
-e SUPERVISOR_SHARE="/workspaces/test_supervisor" \
@@ -55,6 +56,24 @@ function init_dbus() {
dbus-daemon --system --print-address
}
function init_udev() {
if pgrep systemd-udevd; then
echo "udev is running"
return 0
fi
echo "Startup udev"
# cleanups
mkdir -p /run/udev
# run
/lib/systemd/systemd-udevd --daemon
sleep 3
udevadm trigger && udevadm settle
}
echo "Run Supervisor"
start_docker
@@ -65,6 +84,7 @@ if [ "$( docker container inspect -f '{{.State.Status}}' hassio_supervisor )" ==
echo "Restarting Supervisor"
docker rm -f hassio_supervisor
init_dbus
init_udev
cleanup_lastboot
run_supervisor
stop_docker
@@ -76,6 +96,7 @@ else
cleanup_lastboot
cleanup_docker
init_dbus
init_udev
run_supervisor
stop_docker
fi

View File

@@ -10,7 +10,7 @@ import secrets
import shutil
import tarfile
from tempfile import TemporaryDirectory
from typing import Any, Awaitable, Dict, List, Optional
from typing import Any, Awaitable, Dict, List, Optional, Set
import aiohttp
import voluptuous as vol
@@ -55,13 +55,15 @@ from ..exceptions import (
HostAppArmorError,
JsonFileError,
)
from ..hardware.data import Device
from ..utils import check_port
from ..utils.apparmor import adjust_profile
from ..utils.json import read_json_file, write_json_file
from ..utils.tar import atomic_contents_add, secure_path
from .model import AddonModel, Data
from .options import AddonOptions
from .utils import remove_data
from .validate import SCHEMA_ADDON_SNAPSHOT, validate_options
from .validate import SCHEMA_ADDON_SNAPSHOT
_LOGGER: logging.Logger = logging.getLogger(__name__)
@@ -394,6 +396,20 @@ class Addon(AddonModel):
"""Return path to asound config for Docker."""
return Path(self.sys_config.path_extern_tmp, f"{self.slug}_pulse")
@property
def devices(self) -> Set[Device]:
"""Create a schema for add-on options."""
raw_schema = self.data[ATTR_SCHEMA]
if isinstance(raw_schema, bool) or not raw_schema:
return set()
# Validate devices
options_validator = AddonOptions(self.coresys, raw_schema)
with suppress(vol.Invalid):
options_validator(self.options)
return options_validator.devices
def save_persist(self) -> None:
"""Save data of add-on."""
self.sys_addons.data.save_data()
@@ -442,20 +458,17 @@ class Addon(AddonModel):
async def write_options(self) -> None:
"""Return True if add-on options is written to data."""
schema = self.schema
options = self.options
# Update secrets for validation
await self.sys_homeassistant.secrets.reload()
try:
options = schema(options)
options = self.schema(self.options)
write_json_file(self.path_options, options)
except vol.Invalid as ex:
_LOGGER.error(
"Add-on %s has invalid options: %s",
self.slug,
humanize_error(options, ex),
humanize_error(self.options, ex),
)
except JsonFileError:
_LOGGER.error("Add-on %s can't write options", self.slug)
@@ -538,7 +551,7 @@ class Addon(AddonModel):
# create voluptuous
new_schema = vol.Schema(
vol.All(dict, validate_options(self.coresys, new_raw_schema))
vol.All(dict, AddonOptions(self.coresys, new_raw_schema))
)
# validate

View File

@@ -48,6 +48,16 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
"""Return additional Docker build arguments."""
return self._data[ATTR_ARGS]
@property
def is_valid(self) -> bool:
"""Return true if the build env is valid."""
return all(
[
self.addon.path_location.is_dir(),
Path(self.addon.path_location, "Dockerfile").is_file(),
]
)
def get_docker_args(self, version: AwesomeVersion):
"""Create a dict with Docker build arguments."""
args = {

View File

@@ -12,7 +12,6 @@ from ..const import (
ATTR_ARCH,
ATTR_AUDIO,
ATTR_AUTH_API,
ATTR_AUTO_UART,
ATTR_BOOT,
ATTR_DESCRIPTON,
ATTR_DEVICES,
@@ -56,6 +55,7 @@ from ..const import (
ATTR_STDIN,
ATTR_TIMEOUT,
ATTR_TMPFS,
ATTR_UART,
ATTR_UDEV,
ATTR_URL,
ATTR_USB,
@@ -71,7 +71,8 @@ from ..const import (
AddonStartup,
)
from ..coresys import CoreSys, CoreSysAttributes
from .validate import RE_SERVICE, RE_VOLUME, schema_ui_options, validate_options
from .options import AddonOptions, UiOptions
from .validate import RE_SERVICE, RE_VOLUME
Data = Dict[str, Any]
@@ -296,14 +297,9 @@ class AddonModel(CoreSysAttributes, ABC):
return self.data[ATTR_HOST_DBUS]
@property
def devices(self) -> List[str]:
"""Return devices of add-on."""
return self.data.get(ATTR_DEVICES, [])
@property
def tmpfs(self) -> Optional[str]:
"""Return tmpfs of add-on."""
return self.data.get(ATTR_TMPFS)
def static_devices(self) -> List[Path]:
"""Return static devices of add-on."""
return [Path(node) for node in self.data.get(ATTR_DEVICES, [])]
@property
def environment(self) -> Optional[Dict[str, str]]:
@@ -387,7 +383,7 @@ class AddonModel(CoreSysAttributes, ABC):
@property
def with_uart(self) -> bool:
"""Return True if we should map all UART device."""
return self.data[ATTR_AUTO_UART]
return self.data[ATTR_UART]
@property
def with_udev(self) -> bool:
@@ -409,6 +405,11 @@ class AddonModel(CoreSysAttributes, ABC):
"""Return True if the add-on read access to devicetree."""
return self.data[ATTR_DEVICETREE]
@property
def with_tmpfs(self) -> Optional[str]:
"""Return if tmp is in memory of add-on."""
return self.data[ATTR_TMPFS]
@property
def access_auth_api(self) -> bool:
"""Return True if the add-on access to login/auth backend."""
@@ -522,8 +523,8 @@ class AddonModel(CoreSysAttributes, ABC):
raw_schema = self.data[ATTR_SCHEMA]
if isinstance(raw_schema, bool):
return vol.Schema(dict)
return vol.Schema(vol.All(dict, validate_options(self.coresys, raw_schema)))
raw_schema = {}
return vol.Schema(vol.All(dict, AddonOptions(self.coresys, raw_schema)))
@property
def schema_ui(self) -> Optional[List[Dict[str, Any]]]:
@@ -532,7 +533,7 @@ class AddonModel(CoreSysAttributes, ABC):
if isinstance(raw_schema, bool):
return None
return schema_ui_options(raw_schema)
return UiOptions(self.coresys)(raw_schema)
def __eq__(self, other):
"""Compaired add-on objects."""

View File

@@ -0,0 +1,381 @@
"""Add-on Options / UI rendering."""
import logging
from pathlib import Path
import re
from typing import Any, Dict, List, Set, Union
import voluptuous as vol
from ..coresys import CoreSys, CoreSysAttributes
from ..exceptions import HardwareNotFound
from ..hardware.const import UdevSubsystem
from ..hardware.data import Device
from ..validate import network_port
_LOGGER: logging.Logger = logging.getLogger(__name__)
_STR = "str"
_INT = "int"
_FLOAT = "float"
_BOOL = "bool"
_PASSWORD = "password"
_EMAIL = "email"
_URL = "url"
_PORT = "port"
_MATCH = "match"
_LIST = "list"
_DEVICE = "device"
RE_SCHEMA_ELEMENT = re.compile(
r"^(?:"
r"|bool"
r"|email"
r"|url"
r"|port"
r"|device(?:\((?P<filter>subsystem=[a-z]+)\))?"
r"|str(?:\((?P<s_min>\d+)?,(?P<s_max>\d+)?\))?"
r"|password(?:\((?P<p_min>\d+)?,(?P<p_max>\d+)?\))?"
r"|int(?:\((?P<i_min>\d+)?,(?P<i_max>\d+)?\))?"
r"|float(?:\((?P<f_min>[\d\.]+)?,(?P<f_max>[\d\.]+)?\))?"
r"|match\((?P<match>.*)\)"
r"|list\((?P<list>.+)\)"
r")\??$"
)
_SCHEMA_LENGTH_PARTS = (
"i_min",
"i_max",
"f_min",
"f_max",
"s_min",
"s_max",
"p_min",
"p_max",
)
class AddonOptions(CoreSysAttributes):
"""Validate Add-ons Options."""
def __init__(
self,
coresys: CoreSys,
raw_schema: Dict[str, Any],
):
"""Validate schema."""
self.coresys: CoreSys = coresys
self.raw_schema: Dict[str, Any] = raw_schema
self.devices: Set[Device] = set()
def __call__(self, struct):
"""Create schema validator for add-ons options."""
options = {}
# read options
for key, value in struct.items():
# Ignore unknown options / remove from list
if key not in self.raw_schema:
_LOGGER.warning("Unknown options %s", key)
continue
typ = self.raw_schema[key]
try:
if isinstance(typ, list):
# nested value list
options[key] = self._nested_validate_list(typ[0], value, key)
elif isinstance(typ, dict):
# nested value dict
options[key] = self._nested_validate_dict(typ, value, key)
else:
# normal value
options[key] = self._single_validate(typ, value, key)
except (IndexError, KeyError):
raise vol.Invalid(f"Type error for {key}") from None
self._check_missing_options(self.raw_schema, options, "root")
return options
# pylint: disable=no-value-for-parameter
def _single_validate(self, typ: str, value: Any, key: str):
"""Validate a single element."""
# if required argument
if value is None:
raise vol.Invalid(f"Missing required option '{key}'") from None
# Lookup secret
if str(value).startswith("!secret "):
secret: str = value.partition(" ")[2]
value = self.sys_homeassistant.secrets.get(secret)
if value is None:
raise vol.Invalid(f"Unknown secret {secret}") from None
# parse extend data from type
match = RE_SCHEMA_ELEMENT.match(typ)
if not match:
raise vol.Invalid(f"Unknown type {typ}") from None
# prepare range
range_args = {}
for group_name in _SCHEMA_LENGTH_PARTS:
group_value = match.group(group_name)
if group_value:
range_args[group_name[2:]] = float(group_value)
if typ.startswith(_STR) or typ.startswith(_PASSWORD):
return vol.All(str(value), vol.Range(**range_args))(value)
elif typ.startswith(_INT):
return vol.All(vol.Coerce(int), vol.Range(**range_args))(value)
elif typ.startswith(_FLOAT):
return vol.All(vol.Coerce(float), vol.Range(**range_args))(value)
elif typ.startswith(_BOOL):
return vol.Boolean()(value)
elif typ.startswith(_EMAIL):
return vol.Email()(value)
elif typ.startswith(_URL):
return vol.Url()(value)
elif typ.startswith(_PORT):
return network_port(value)
elif typ.startswith(_MATCH):
return vol.Match(match.group("match"))(str(value))
elif typ.startswith(_LIST):
return vol.In(match.group("list").split("|"))(str(value))
elif typ.startswith(_DEVICE):
try:
device = self.sys_hardware.get_by_path(Path(value))
except HardwareNotFound:
raise vol.Invalid(f"Device {value} does not exists!") from None
# Have filter
if match.group("filter"):
str_filter = match.group("filter")
device_filter = _create_device_filter(str_filter)
if device not in self.sys_hardware.filter_devices(**device_filter):
raise vol.Invalid(
f"Device {value} don't match the filter {str_filter}!"
)
# Device valid
self.devices.add(device)
return str(device.path)
raise vol.Invalid(f"Fatal error for {key} type {typ}") from None
def _nested_validate_list(self, typ: Any, data_list: List[Any], key: str):
"""Validate nested items."""
options = []
# Make sure it is a list
if not isinstance(data_list, list):
raise vol.Invalid(f"Invalid list for {key}") from None
# Process list
for element in data_list:
# Nested?
if isinstance(typ, dict):
c_options = self._nested_validate_dict(typ, element, key)
options.append(c_options)
else:
options.append(self._single_validate(typ, element, key))
return options
def _nested_validate_dict(
self, typ: Dict[Any, Any], data_dict: Dict[Any, Any], key: str
):
"""Validate nested items."""
options = {}
# Make sure it is a dict
if not isinstance(data_dict, dict):
raise vol.Invalid(f"Invalid dict for {key}") from None
# Process dict
for c_key, c_value in data_dict.items():
# Ignore unknown options / remove from list
if c_key not in typ:
_LOGGER.warning("Unknown options %s", c_key)
continue
# Nested?
if isinstance(typ[c_key], list):
options[c_key] = self._nested_validate_list(
typ[c_key][0], c_value, c_key
)
else:
options[c_key] = self._single_validate(typ[c_key], c_value, c_key)
self._check_missing_options(typ, options, key)
return options
def _check_missing_options(
self, origin: Dict[Any, Any], exists: Dict[Any, Any], root: str
) -> None:
"""Check if all options are exists."""
missing = set(origin) - set(exists)
for miss_opt in missing:
if isinstance(origin[miss_opt], str) and origin[miss_opt].endswith("?"):
continue
raise vol.Invalid(f"Missing option {miss_opt} in {root}") from None
class UiOptions(CoreSysAttributes):
"""Render UI Add-ons Options."""
def __init__(self, coresys: CoreSys) -> None:
"""Initialize UI option render."""
self.coresys = coresys
def __call__(self, raw_schema: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Generate UI schema."""
ui_schema: List[Dict[str, Any]] = []
# read options
for key, value in raw_schema.items():
if isinstance(value, list):
# nested value list
self._nested_ui_list(ui_schema, value, key)
elif isinstance(value, dict):
# nested value dict
self._nested_ui_dict(ui_schema, value, key)
else:
# normal value
self._single_ui_option(ui_schema, value, key)
return ui_schema
def _single_ui_option(
self,
ui_schema: List[Dict[str, Any]],
value: str,
key: str,
multiple: bool = False,
) -> None:
"""Validate a single element."""
ui_node: Dict[str, Union[str, bool, float, List[str]]] = {"name": key}
# If multiple
if multiple:
ui_node["multiple"] = True
# Parse extend data from type
match = RE_SCHEMA_ELEMENT.match(value)
if not match:
return
# Prepare range
for group_name in _SCHEMA_LENGTH_PARTS:
group_value = match.group(group_name)
if not group_value:
continue
if group_name[2:] == "min":
ui_node["lengthMin"] = float(group_value)
elif group_name[2:] == "max":
ui_node["lengthMax"] = float(group_value)
# If required
if value.endswith("?"):
ui_node["optional"] = True
else:
ui_node["required"] = True
# Data types
if value.startswith(_STR):
ui_node["type"] = "string"
elif value.startswith(_PASSWORD):
ui_node["type"] = "string"
ui_node["format"] = "password"
elif value.startswith(_INT):
ui_node["type"] = "integer"
elif value.startswith(_FLOAT):
ui_node["type"] = "float"
elif value.startswith(_BOOL):
ui_node["type"] = "boolean"
elif value.startswith(_EMAIL):
ui_node["type"] = "string"
ui_node["format"] = "email"
elif value.startswith(_URL):
ui_node["type"] = "string"
ui_node["format"] = "url"
elif value.startswith(_PORT):
ui_node["type"] = "integer"
elif value.startswith(_MATCH):
ui_node["type"] = "string"
elif value.startswith(_LIST):
ui_node["type"] = "select"
ui_node["options"] = match.group("list").split("|")
elif value.startswith(_DEVICE):
ui_node["type"] = "select"
# Have filter
if match.group("filter"):
device_filter = _create_device_filter(match.group("filter"))
ui_node["options"] = [
(device.by_id or device.path).as_posix()
for device in self.sys_hardware.filter_devices(**device_filter)
]
else:
ui_node["options"] = [
(device.by_id or device.path).as_posix()
for device in self.sys_hardware.devices()
]
ui_schema.append(ui_node)
def _nested_ui_list(
self,
ui_schema: List[Dict[str, Any]],
option_list: List[Any],
key: str,
) -> None:
"""UI nested list items."""
try:
element = option_list[0]
except IndexError:
_LOGGER.error("Invalid schema %s", key)
return
if isinstance(element, dict):
self._nested_ui_dict(ui_schema, element, key, multiple=True)
else:
self._single_ui_option(ui_schema, element, key, multiple=True)
def _nested_ui_dict(
self,
ui_schema: List[Dict[str, Any]],
option_dict: Dict[str, Any],
key: str,
multiple: bool = False,
) -> None:
"""UI nested dict items."""
ui_node = {
"name": key,
"type": "schema",
"optional": True,
"multiple": multiple,
}
nested_schema = []
for c_key, c_value in option_dict.items():
# Nested?
if isinstance(c_value, list):
self._nested_ui_list(nested_schema, c_value, c_key)
else:
self._single_ui_option(nested_schema, c_value, c_key)
ui_node["schema"] = nested_schema
ui_schema.append(ui_node)
def _create_device_filter(str_filter: str) -> Dict[str, Any]:
"""Generate device Filter."""
raw_filter = dict(value.split("=") for value in str_filter.split(";"))
clean_filter = {}
for key, value in raw_filter.items():
if key == "subsystem":
clean_filter[key] = UdevSubsystem(value)
else:
clean_filter[key] = value
return clean_filter

View File

@@ -2,7 +2,7 @@
import logging
import re
import secrets
from typing import Any, Dict, List, Union
from typing import Any, Dict
import uuid
import voluptuous as vol
@@ -18,7 +18,6 @@ from ..const import (
ATTR_AUDIO_INPUT,
ATTR_AUDIO_OUTPUT,
ATTR_AUTH_API,
ATTR_AUTO_UART,
ATTR_AUTO_UPDATE,
ATTR_BOOT,
ATTR_BUILD_FROM,
@@ -73,6 +72,7 @@ from ..const import (
ATTR_SYSTEM,
ATTR_TIMEOUT,
ATTR_TMPFS,
ATTR_UART,
ATTR_UDEV,
ATTR_URL,
ATTR_USB,
@@ -90,7 +90,6 @@ from ..const import (
AddonStartup,
AddonState,
)
from ..coresys import CoreSys
from ..discovery.validate import valid_discovery_service
from ..validate import (
docker_image,
@@ -101,49 +100,13 @@ from ..validate import (
uuid_match,
version_tag,
)
from .options import RE_SCHEMA_ELEMENT
_LOGGER: logging.Logger = logging.getLogger(__name__)
RE_VOLUME = re.compile(r"^(config|ssl|addons|backup|share|media)(?::(rw|ro))?$")
RE_SERVICE = re.compile(r"^(?P<service>mqtt|mysql):(?P<rights>provide|want|need)$")
V_STR = "str"
V_INT = "int"
V_FLOAT = "float"
V_BOOL = "bool"
V_PASSWORD = "password"
V_EMAIL = "email"
V_URL = "url"
V_PORT = "port"
V_MATCH = "match"
V_LIST = "list"
RE_SCHEMA_ELEMENT = re.compile(
r"^(?:"
r"|bool"
r"|email"
r"|url"
r"|port"
r"|str(?:\((?P<s_min>\d+)?,(?P<s_max>\d+)?\))?"
r"|password(?:\((?P<p_min>\d+)?,(?P<p_max>\d+)?\))?"
r"|int(?:\((?P<i_min>\d+)?,(?P<i_max>\d+)?\))?"
r"|float(?:\((?P<f_min>[\d\.]+)?,(?P<f_max>[\d\.]+)?\))?"
r"|match\((?P<match>.*)\)"
r"|list\((?P<list>.+)\)"
r")\??$"
)
_SCHEMA_LENGTH_PARTS = (
"i_min",
"i_max",
"f_min",
"f_max",
"s_min",
"s_max",
"p_min",
"p_max",
)
RE_DOCKER_IMAGE_BUILD = re.compile(
r"^([a-zA-Z\-\.:\d{}]+/)*?([\-\w{}]+)/([\-\w{}]+)(:[\.\-\w{}]+)?$"
@@ -173,27 +136,72 @@ RE_MACHINE = re.compile(
)
def _simple_startup(value) -> str:
"""Define startup schema."""
if value == "before":
return AddonStartup.SERVICES.value
if value == "after":
return AddonStartup.APPLICATION.value
return value
def _migrate_addon_config(protocol=False):
"""Migrate addon config."""
def _migrate(config: Dict[str, Any]):
name = config.get(ATTR_NAME)
if not name:
raise vol.Invalid("Invalid Add-on config!")
# Startup 2018-03-30
if config.get(ATTR_STARTUP) in ("before", "after"):
value = config[ATTR_STARTUP]
if protocol:
_LOGGER.warning(
"Add-on config 'startup' with '%s' is depircated. Please report this to the maintainer of %s",
value,
name,
)
if value == "before":
config[ATTR_STARTUP] = AddonStartup.SERVICES.value
elif value == "after":
config[ATTR_STARTUP] = AddonStartup.APPLICATION.value
# UART 2021-01-20
if "auto_uart" in config:
if protocol:
_LOGGER.warning(
"Add-on config 'auto_uart' is deprecated, use 'uart'. Please report this to the maintainer of %s",
name,
)
config[ATTR_UART] = config.pop("auto_uart")
# Device 2021-01-20
if ATTR_DEVICES in config and any(":" in line for line in config[ATTR_DEVICES]):
if protocol:
_LOGGER.warning(
"Add-on config 'devices' use a deprecated format, the new format uses a list of paths only. Please report this to the maintainer of %s",
name,
)
config[ATTR_DEVICES] = [line.split(":")[0] for line in config[ATTR_DEVICES]]
# TMPFS 2021-02-01
if ATTR_TMPFS in config and not isinstance(config[ATTR_TMPFS], bool):
if protocol:
_LOGGER.warning(
"Add-on config 'tmpfs' use a deprecated format, new it's only a boolean. Please report this to the maintainer of %s",
name,
)
config[ATTR_TMPFS] = True
return config
return _migrate
# pylint: disable=no-value-for-parameter
SCHEMA_ADDON_CONFIG = vol.Schema(
_SCHEMA_ADDON_CONFIG = vol.Schema(
{
vol.Required(ATTR_NAME): vol.Coerce(str),
vol.Required(ATTR_NAME): str,
vol.Required(ATTR_VERSION): version_tag,
vol.Required(ATTR_SLUG): vol.Coerce(str),
vol.Required(ATTR_DESCRIPTON): vol.Coerce(str),
vol.Required(ATTR_SLUG): str,
vol.Required(ATTR_DESCRIPTON): str,
vol.Required(ATTR_ARCH): [vol.In(ARCH_ALL)],
vol.Optional(ATTR_MACHINE): vol.All([vol.Match(RE_MACHINE)], vol.Unique()),
vol.Optional(ATTR_URL): vol.Url(),
vol.Optional(ATTR_STARTUP, default=AddonStartup.APPLICATION): vol.All(
_simple_startup, vol.Coerce(AddonStartup)
vol.Optional(ATTR_STARTUP, default=AddonStartup.APPLICATION): vol.Coerce(
AddonStartup
),
vol.Optional(ATTR_BOOT, default=AddonBoot.AUTO): vol.Coerce(AddonBoot),
vol.Optional(ATTR_INIT, default=True): vol.Boolean(),
@@ -211,21 +219,20 @@ SCHEMA_ADDON_CONFIG = vol.Schema(
vol.Optional(ATTR_INGRESS_PORT, default=8099): vol.Any(
network_port, vol.Equal(0)
),
vol.Optional(ATTR_INGRESS_ENTRY): vol.Coerce(str),
vol.Optional(ATTR_PANEL_ICON, default="mdi:puzzle"): vol.Coerce(str),
vol.Optional(ATTR_PANEL_TITLE): vol.Coerce(str),
vol.Optional(ATTR_INGRESS_ENTRY): str,
vol.Optional(ATTR_PANEL_ICON, default="mdi:puzzle"): str,
vol.Optional(ATTR_PANEL_TITLE): str,
vol.Optional(ATTR_PANEL_ADMIN, default=True): vol.Boolean(),
vol.Optional(ATTR_HOMEASSISTANT): vol.Maybe(version_tag),
vol.Optional(ATTR_HOST_NETWORK, default=False): vol.Boolean(),
vol.Optional(ATTR_HOST_PID, default=False): vol.Boolean(),
vol.Optional(ATTR_HOST_IPC, default=False): vol.Boolean(),
vol.Optional(ATTR_HOST_DBUS, default=False): vol.Boolean(),
vol.Optional(ATTR_DEVICES): [vol.Match(r"^(.*):(.*):([rwm]{1,3})$")],
vol.Optional(ATTR_AUTO_UART, default=False): vol.Boolean(),
vol.Optional(ATTR_DEVICES): [str],
vol.Optional(ATTR_UDEV, default=False): vol.Boolean(),
vol.Optional(ATTR_TMPFS): vol.Match(r"^size=(\d)*[kmg](,uid=\d{1,4})?(,rw)?$"),
vol.Optional(ATTR_TMPFS, default=False): vol.Boolean(),
vol.Optional(ATTR_MAP, default=list): [vol.Match(RE_VOLUME)],
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): vol.Coerce(str)},
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): str},
vol.Optional(ATTR_PRIVILEGED): [vol.In(PRIVILEGED_ALL)],
vol.Optional(ATTR_APPARMOR, default=True): vol.Boolean(),
vol.Optional(ATTR_FULL_ACCESS, default=False): vol.Boolean(),
@@ -233,6 +240,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema(
vol.Optional(ATTR_VIDEO, default=False): vol.Boolean(),
vol.Optional(ATTR_GPIO, default=False): vol.Boolean(),
vol.Optional(ATTR_USB, default=False): vol.Boolean(),
vol.Optional(ATTR_UART, default=False): vol.Boolean(),
vol.Optional(ATTR_DEVICETREE, default=False): vol.Boolean(),
vol.Optional(ATTR_KERNEL_MODULES, default=False): vol.Boolean(),
vol.Optional(ATTR_HASSIO_API, default=False): vol.Boolean(),
@@ -244,26 +252,20 @@ SCHEMA_ADDON_CONFIG = vol.Schema(
vol.Optional(ATTR_AUTH_API, default=False): vol.Boolean(),
vol.Optional(ATTR_SERVICES): [vol.Match(RE_SERVICE)],
vol.Optional(ATTR_DISCOVERY): [valid_discovery_service],
vol.Optional(ATTR_SNAPSHOT_EXCLUDE): [vol.Coerce(str)],
vol.Optional(ATTR_SNAPSHOT_EXCLUDE): [str],
vol.Optional(ATTR_OPTIONS, default={}): dict,
vol.Optional(ATTR_SCHEMA, default={}): vol.Any(
vol.Schema(
{
vol.Coerce(str): vol.Any(
str: vol.Any(
SCHEMA_ELEMENT,
[
vol.Any(
SCHEMA_ELEMENT,
{
vol.Coerce(str): vol.Any(
SCHEMA_ELEMENT, [SCHEMA_ELEMENT]
)
},
{str: vol.Any(SCHEMA_ELEMENT, [SCHEMA_ELEMENT])},
)
],
vol.Schema(
{vol.Coerce(str): vol.Any(SCHEMA_ELEMENT, [SCHEMA_ELEMENT])}
),
vol.Schema({str: vol.Any(SCHEMA_ELEMENT, [SCHEMA_ELEMENT])}),
)
}
),
@@ -277,6 +279,8 @@ SCHEMA_ADDON_CONFIG = vol.Schema(
extra=vol.REMOVE_EXTRA,
)
SCHEMA_ADDON_CONFIG = vol.All(_migrate_addon_config(True), _SCHEMA_ADDON_CONFIG)
# pylint: disable=no-value-for-parameter
SCHEMA_BUILD_CONFIG = vol.Schema(
@@ -300,15 +304,13 @@ SCHEMA_ADDON_USER = vol.Schema(
vol.Optional(ATTR_IMAGE): docker_image,
vol.Optional(ATTR_UUID, default=lambda: uuid.uuid4().hex): uuid_match,
vol.Optional(ATTR_ACCESS_TOKEN): token,
vol.Optional(ATTR_INGRESS_TOKEN, default=secrets.token_urlsafe): vol.Coerce(
str
),
vol.Optional(ATTR_INGRESS_TOKEN, default=secrets.token_urlsafe): str,
vol.Optional(ATTR_OPTIONS, default=dict): dict,
vol.Optional(ATTR_AUTO_UPDATE, default=False): vol.Boolean(),
vol.Optional(ATTR_BOOT): vol.Coerce(AddonBoot),
vol.Optional(ATTR_NETWORK): docker_ports,
vol.Optional(ATTR_AUDIO_OUTPUT): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_AUDIO_INPUT): vol.Maybe(vol.Coerce(str)),
vol.Optional(ATTR_AUDIO_OUTPUT): vol.Maybe(str),
vol.Optional(ATTR_AUDIO_INPUT): vol.Maybe(str),
vol.Optional(ATTR_PROTECTED, default=True): vol.Boolean(),
vol.Optional(ATTR_INGRESS_PANEL, default=False): vol.Boolean(),
vol.Optional(ATTR_WATCHDOG, default=False): vol.Boolean(),
@@ -317,18 +319,21 @@ SCHEMA_ADDON_USER = vol.Schema(
)
SCHEMA_ADDON_SYSTEM = SCHEMA_ADDON_CONFIG.extend(
{
vol.Required(ATTR_LOCATON): vol.Coerce(str),
vol.Required(ATTR_REPOSITORY): vol.Coerce(str),
}
SCHEMA_ADDON_SYSTEM = vol.All(
_migrate_addon_config(),
_SCHEMA_ADDON_CONFIG.extend(
{
vol.Required(ATTR_LOCATON): str,
vol.Required(ATTR_REPOSITORY): str,
}
),
)
SCHEMA_ADDONS_FILE = vol.Schema(
{
vol.Optional(ATTR_USER, default=dict): {vol.Coerce(str): SCHEMA_ADDON_USER},
vol.Optional(ATTR_SYSTEM, default=dict): {vol.Coerce(str): SCHEMA_ADDON_SYSTEM},
vol.Optional(ATTR_USER, default=dict): {str: SCHEMA_ADDON_USER},
vol.Optional(ATTR_SYSTEM, default=dict): {str: SCHEMA_ADDON_SYSTEM},
}
)
@@ -338,263 +343,7 @@ SCHEMA_ADDON_SNAPSHOT = vol.Schema(
vol.Required(ATTR_USER): SCHEMA_ADDON_USER,
vol.Required(ATTR_SYSTEM): SCHEMA_ADDON_SYSTEM,
vol.Required(ATTR_STATE): vol.Coerce(AddonState),
vol.Required(ATTR_VERSION): vol.Coerce(str),
vol.Required(ATTR_VERSION): version_tag,
},
extra=vol.REMOVE_EXTRA,
)
def validate_options(coresys: CoreSys, raw_schema: Dict[str, Any]):
"""Validate schema."""
def validate(struct):
"""Create schema validator for add-ons options."""
options = {}
# read options
for key, value in struct.items():
# Ignore unknown options / remove from list
if key not in raw_schema:
_LOGGER.warning("Unknown options %s", key)
continue
typ = raw_schema[key]
try:
if isinstance(typ, list):
# nested value list
options[key] = _nested_validate_list(coresys, typ[0], value, key)
elif isinstance(typ, dict):
# nested value dict
options[key] = _nested_validate_dict(coresys, typ, value, key)
else:
# normal value
options[key] = _single_validate(coresys, typ, value, key)
except (IndexError, KeyError):
raise vol.Invalid(f"Type error for {key}") from None
_check_missing_options(raw_schema, options, "root")
return options
return validate
# pylint: disable=no-value-for-parameter
# pylint: disable=inconsistent-return-statements
def _single_validate(coresys: CoreSys, typ: str, value: Any, key: str):
"""Validate a single element."""
# if required argument
if value is None:
raise vol.Invalid(f"Missing required option '{key}'") from None
# Lookup secret
if str(value).startswith("!secret "):
secret: str = value.partition(" ")[2]
value = coresys.homeassistant.secrets.get(secret)
if value is None:
raise vol.Invalid(f"Unknown secret {secret}") from None
# parse extend data from type
match = RE_SCHEMA_ELEMENT.match(typ)
if not match:
raise vol.Invalid(f"Unknown type {typ}") from None
# prepare range
range_args = {}
for group_name in _SCHEMA_LENGTH_PARTS:
group_value = match.group(group_name)
if group_value:
range_args[group_name[2:]] = float(group_value)
if typ.startswith(V_STR) or typ.startswith(V_PASSWORD):
return vol.All(str(value), vol.Range(**range_args))(value)
elif typ.startswith(V_INT):
return vol.All(vol.Coerce(int), vol.Range(**range_args))(value)
elif typ.startswith(V_FLOAT):
return vol.All(vol.Coerce(float), vol.Range(**range_args))(value)
elif typ.startswith(V_BOOL):
return vol.Boolean()(value)
elif typ.startswith(V_EMAIL):
return vol.Email()(value)
elif typ.startswith(V_URL):
return vol.Url()(value)
elif typ.startswith(V_PORT):
return network_port(value)
elif typ.startswith(V_MATCH):
return vol.Match(match.group("match"))(str(value))
elif typ.startswith(V_LIST):
return vol.In(match.group("list").split("|"))(str(value))
raise vol.Invalid(f"Fatal error for {key} type {typ}") from None
def _nested_validate_list(coresys, typ, data_list, key):
"""Validate nested items."""
options = []
# Make sure it is a list
if not isinstance(data_list, list):
raise vol.Invalid(f"Invalid list for {key}") from None
# Process list
for element in data_list:
# Nested?
if isinstance(typ, dict):
c_options = _nested_validate_dict(coresys, typ, element, key)
options.append(c_options)
else:
options.append(_single_validate(coresys, typ, element, key))
return options
def _nested_validate_dict(coresys, typ, data_dict, key):
"""Validate nested items."""
options = {}
# Make sure it is a dict
if not isinstance(data_dict, dict):
raise vol.Invalid(f"Invalid dict for {key}") from None
# Process dict
for c_key, c_value in data_dict.items():
# Ignore unknown options / remove from list
if c_key not in typ:
_LOGGER.warning("Unknown options %s", c_key)
continue
# Nested?
if isinstance(typ[c_key], list):
options[c_key] = _nested_validate_list(
coresys, typ[c_key][0], c_value, c_key
)
else:
options[c_key] = _single_validate(coresys, typ[c_key], c_value, c_key)
_check_missing_options(typ, options, key)
return options
def _check_missing_options(origin, exists, root):
"""Check if all options are exists."""
missing = set(origin) - set(exists)
for miss_opt in missing:
if isinstance(origin[miss_opt], str) and origin[miss_opt].endswith("?"):
continue
raise vol.Invalid(f"Missing option {miss_opt} in {root}") from None
def schema_ui_options(raw_schema: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Generate UI schema."""
ui_schema: List[Dict[str, Any]] = []
# read options
for key, value in raw_schema.items():
if isinstance(value, list):
# nested value list
_nested_ui_list(ui_schema, value, key)
elif isinstance(value, dict):
# nested value dict
_nested_ui_dict(ui_schema, value, key)
else:
# normal value
_single_ui_option(ui_schema, value, key)
return ui_schema
def _single_ui_option(
ui_schema: List[Dict[str, Any]], value: str, key: str, multiple: bool = False
) -> None:
"""Validate a single element."""
ui_node: Dict[str, Union[str, bool, float, List[str]]] = {"name": key}
# If multiple
if multiple:
ui_node["multiple"] = True
# Parse extend data from type
match = RE_SCHEMA_ELEMENT.match(value)
if not match:
return
# Prepare range
for group_name in _SCHEMA_LENGTH_PARTS:
group_value = match.group(group_name)
if not group_value:
continue
if group_name[2:] == "min":
ui_node["lengthMin"] = float(group_value)
elif group_name[2:] == "max":
ui_node["lengthMax"] = float(group_value)
# If required
if value.endswith("?"):
ui_node["optional"] = True
else:
ui_node["required"] = True
# Data types
if value.startswith(V_STR):
ui_node["type"] = "string"
elif value.startswith(V_PASSWORD):
ui_node["type"] = "string"
ui_node["format"] = "password"
elif value.startswith(V_INT):
ui_node["type"] = "integer"
elif value.startswith(V_FLOAT):
ui_node["type"] = "float"
elif value.startswith(V_BOOL):
ui_node["type"] = "boolean"
elif value.startswith(V_EMAIL):
ui_node["type"] = "string"
ui_node["format"] = "email"
elif value.startswith(V_URL):
ui_node["type"] = "string"
ui_node["format"] = "url"
elif value.startswith(V_PORT):
ui_node["type"] = "integer"
elif value.startswith(V_MATCH):
ui_node["type"] = "string"
elif value.startswith(V_LIST):
ui_node["type"] = "select"
ui_node["options"] = match.group("list").split("|")
ui_schema.append(ui_node)
def _nested_ui_list(
ui_schema: List[Dict[str, Any]], option_list: List[Any], key: str
) -> None:
"""UI nested list items."""
try:
element = option_list[0]
except IndexError:
_LOGGER.error("Invalid schema %s", key)
return
if isinstance(element, dict):
_nested_ui_dict(ui_schema, element, key, multiple=True)
else:
_single_ui_option(ui_schema, element, key, multiple=True)
def _nested_ui_dict(
ui_schema: List[Dict[str, Any]],
option_dict: Dict[str, Any],
key: str,
multiple: bool = False,
) -> None:
"""UI nested dict items."""
ui_node = {"name": key, "type": "schema", "optional": True, "multiple": multiple}
nested_schema = []
for c_key, c_value in option_dict.items():
# Nested?
if isinstance(c_value, list):
_nested_ui_list(nested_schema, c_value, c_key)
else:
_single_ui_option(nested_schema, c_value, c_key)
ui_node["schema"] = nested_schema
ui_schema.append(ui_node)

View File

@@ -82,6 +82,7 @@ from ..const import (
ATTR_STARTUP,
ATTR_STATE,
ATTR_STDIN,
ATTR_UART,
ATTR_UDEV,
ATTR_UPDATE_AVAILABLE,
ATTR_URL,
@@ -237,7 +238,7 @@ class APIAddons(CoreSysAttributes):
ATTR_PRIVILEGED: addon.privileged,
ATTR_FULL_ACCESS: addon.with_full_access,
ATTR_APPARMOR: addon.apparmor,
ATTR_DEVICES: _pretty_devices(addon),
ATTR_DEVICES: addon.static_devices,
ATTR_ICON: addon.with_icon,
ATTR_LOGO: addon.with_logo,
ATTR_CHANGELOG: addon.with_changelog,
@@ -250,6 +251,7 @@ class APIAddons(CoreSysAttributes):
ATTR_HOMEASSISTANT_API: addon.access_homeassistant_api,
ATTR_GPIO: addon.with_gpio,
ATTR_USB: addon.with_usb,
ATTR_UART: addon.with_uart,
ATTR_KERNEL_MODULES: addon.with_kernel_modules,
ATTR_DEVICETREE: addon.with_devicetree,
ATTR_UDEV: addon.with_udev,
@@ -286,6 +288,8 @@ class APIAddons(CoreSysAttributes):
ATTR_VERSION: addon.version,
ATTR_UPDATE_AVAILABLE: addon.need_update,
ATTR_WATCHDOG: addon.watchdog,
ATTR_DEVICES: addon.static_devices
+ [device.path for device in addon.devices],
}
)

View File

@@ -1,50 +1,46 @@
"""Init file for Supervisor hardware RESTful API."""
import asyncio
import logging
from typing import Any, Awaitable, Dict, List
from typing import Any, Awaitable, Dict
from aiohttp import web
from ..const import (
ATTR_AUDIO,
ATTR_DISK,
ATTR_GPIO,
ATTR_INPUT,
ATTR_OUTPUT,
ATTR_SERIAL,
ATTR_USB,
)
from ..const import ATTR_AUDIO, ATTR_DEVICES, ATTR_INPUT, ATTR_NAME, ATTR_OUTPUT
from ..coresys import CoreSysAttributes
from ..hardware.const import (
ATTR_ATTRIBUTES,
ATTR_BY_ID,
ATTR_DEV_PATH,
ATTR_SUBSYSTEM,
ATTR_SYSFS,
)
from ..hardware.data import Device
from .utils import api_process
_LOGGER: logging.Logger = logging.getLogger(__name__)
def device_struct(device: Device) -> Dict[str, Any]:
"""Return a dict with information of a interface to be used in th API."""
return {
ATTR_NAME: device.name,
ATTR_SYSFS: device.sysfs,
ATTR_DEV_PATH: device.path,
ATTR_SUBSYSTEM: device.subsystem,
ATTR_BY_ID: device.by_id,
ATTR_ATTRIBUTES: device.attributes,
}
class APIHardware(CoreSysAttributes):
"""Handle RESTful API for hardware functions."""
@api_process
async def info(self, request: web.Request) -> Dict[str, Any]:
"""Show hardware info."""
serial: List[str] = []
# Create Serial list with device links
for device in self.sys_hardware.serial_devices:
serial.append(device.path.as_posix())
for link in device.links:
serial.append(link.as_posix())
return {
ATTR_SERIAL: serial,
ATTR_INPUT: list(self.sys_hardware.input_devices),
ATTR_DISK: [
device.path.as_posix() for device in self.sys_hardware.disk_devices
],
ATTR_GPIO: list(self.sys_hardware.gpio_devices),
ATTR_USB: [
device.path.as_posix() for device in self.sys_hardware.usb_devices
],
ATTR_AUDIO: self.sys_hardware.audio_devices,
ATTR_DEVICES: [
device_struct(device) for device in self.sys_hardware.devices
]
}
@api_process
@@ -64,6 +60,6 @@ class APIHardware(CoreSysAttributes):
}
@api_process
def trigger(self, request: web.Request) -> Awaitable[None]:
async def trigger(self, request: web.Request) -> Awaitable[None]:
"""Trigger a udev device reload."""
return asyncio.shield(self.sys_hardware.udev_trigger())
_LOGGER.warning("Ignoring DEPRECATED hardware trigger function call.")

View File

@@ -155,7 +155,7 @@ class APINetwork(CoreSysAttributes):
except HostNetworkNotFound:
pass
raise APIError(f"Interface {name} does not exsist") from None
raise APIError(f"Interface {name} does not exist") from None
@api_process
async def info(self, request: web.Request) -> Dict[str, Any]:

View File

@@ -1,9 +1,9 @@
try {
new Function("import('/api/hassio/app/frontend_latest/entrypoint.266bc30f.js')")();
new Function("import('/api/hassio/app/frontend_latest/entrypoint.cf81f6d9.js')")();
} catch (err) {
var el = document.createElement('script');
el.src = '/api/hassio/app/frontend_es5/entrypoint.585f219b.js';
el.src = '/api/hassio/app/frontend_es5/entrypoint.c258a457.js';
document.body.appendChild(el);
}

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.0746f465754eb7b6784e.js","sources":["webpack://home-assistant-frontend/chunk.0746f465754eb7b6784e.js"],"mappings":"AAAA","sourceRoot":""}

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.0ca880f618245e0de2ab.js","sources":["webpack://home-assistant-frontend/chunk.0ca880f618245e0de2ab.js"],"mappings":"AAAA","sourceRoot":""}

View File

@@ -1,2 +0,0 @@
!function(){"use strict";var n,t={14971:function(n,t,e){e(58556);var r,o,i=e(91107),u=e(9902),a=e.n(u),s=e(62173),f={renderMarkdown:function(n,t){var e,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r||(r=Object.assign({},(0,s.getDefaultWhiteList)(),{"ha-icon":["icon"],"ha-svg-icon":["path"]})),i.allowSvg?(o||(o=Object.assign({},r,{svg:["xmlns","height","width"],path:["transform","stroke","d"],img:["src"]})),e=o):e=r,(0,s.filterXSS)(a()(n,t),{whiteList:e})}};(0,i.Jj)(f)}},e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={exports:{}};return t[n].call(o.exports,o,o.exports,r),o.exports}r.m=t,r.x=function(){r(14971)},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,{a:t}),t},r.d=function(n,t){for(var e in t)r.o(t,e)&&!r.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:t[e]})},r.f={},r.e=function(n){return Promise.all(Object.keys(r.f).reduce((function(t,e){return r.f[e](n,t),t}),[]))},r.u=function(n){return"chunk.d93e72d29a82b1218f4a.js"},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},n=r.x,r.x=function(){return r.e(474).then(n)},r.p="/api/hassio/app/frontend_es5/",function(){var n={971:1};r.f.i=function(t,e){n[t]||importScripts(""+r.u(t))};var t=self.webpackChunkhome_assistant_frontend=self.webpackChunkhome_assistant_frontend||[],e=t.push.bind(t);t.push=function(t){var o=t[0],i=t[1],u=t[2];for(var a in i)r.o(i,a)&&(r.m[a]=i[a]);for(u&&u(r);o.length;)n[o.pop()]=1;e(t)}}(),r.x()}();
//# sourceMappingURL=chunk.0cd3dee90fe9e2ba789d.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.0cd3dee90fe9e2ba789d.js","sources":["webpack://home-assistant-frontend/chunk.0cd3dee90fe9e2ba789d.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.0ec8f0e5a96085d222a0.js","sources":["webpack://home-assistant-frontend/chunk.0ec8f0e5a96085d222a0.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.1da2af7a753728051dc0.js","sources":["webpack://home-assistant-frontend/chunk.1da2af7a753728051dc0.js"],"mappings":";AAAA","sourceRoot":""}

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.42b19ffa1fa277adc9cd.js","sources":["webpack://home-assistant-frontend/chunk.42b19ffa1fa277adc9cd.js"],"mappings":"AAAA","sourceRoot":""}

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.4c51a194fe9fc242f107.js","sources":["webpack://home-assistant-frontend/chunk.4c51a194fe9fc242f107.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.63747632f287a94ecaa7.js","sources":["webpack://home-assistant-frontend/chunk.63747632f287a94ecaa7.js"],"mappings":"AAAA","sourceRoot":""}

View File

@@ -0,0 +1,2 @@
!function(){"use strict";var n,t={14971:function(n,t,e){var r,o,i=e(91107),u=e(9902),a=e.n(u),s=(e(58556),e(62173)),f={renderMarkdown:function(n,t){var e,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r||(r=Object.assign({},(0,s.getDefaultWhiteList)(),{"ha-icon":["icon"],"ha-svg-icon":["path"]})),i.allowSvg?(o||(o=Object.assign({},r,{svg:["xmlns","height","width"],path:["transform","stroke","d"],img:["src"]})),e=o):e=r,(0,s.filterXSS)(a()(n,t),{whiteList:e})}};(0,i.Jj)(f)}},e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={exports:{}};return t[n].call(o.exports,o,o.exports,r),o.exports}r.m=t,r.x=function(){r(14971)},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,{a:t}),t},r.d=function(n,t){for(var e in t)r.o(t,e)&&!r.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:t[e]})},r.f={},r.e=function(n){return Promise.all(Object.keys(r.f).reduce((function(t,e){return r.f[e](n,t),t}),[]))},r.u=function(n){return"chunk.d93e72d29a82b1218f4a.js"},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},n=r.x,r.x=function(){return r.e(474).then(n)},r.p="/api/hassio/app/frontend_es5/",function(){var n={971:1};r.f.i=function(t,e){n[t]||importScripts(""+r.u(t))};var t=self.webpackChunkhome_assistant_frontend=self.webpackChunkhome_assistant_frontend||[],e=t.push.bind(t);t.push=function(t){var o=t[0],i=t[1],u=t[2];for(var a in i)r.o(i,a)&&(r.m[a]=i[a]);for(u&&u(r);o.length;)n[o.pop()]=1;e(t)}}(),r.x()}();
//# sourceMappingURL=chunk.67e3627d3c04d75f6f9d.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.67e3627d3c04d75f6f9d.js","sources":["webpack://home-assistant-frontend/chunk.67e3627d3c04d75f6f9d.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.79b4e240c46ccbe25e4d.js","sources":["webpack://home-assistant-frontend/chunk.79b4e240c46ccbe25e4d.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.8c95d60c89a57c50576d.js","sources":["webpack://home-assistant-frontend/chunk.8c95d60c89a57c50576d.js"],"mappings":";AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.d0222f0b152d21991ec4.js","sources":["webpack://home-assistant-frontend/chunk.d0222f0b152d21991ec4.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.de3430632b35ee0356b5.js","sources":["webpack://home-assistant-frontend/chunk.de3430632b35ee0356b5.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.f5cf4c1fdbd3d8c6f907.js","sources":["webpack://home-assistant-frontend/chunk.f5cf4c1fdbd3d8c6f907.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"entrypoint.585f219b.js","sources":["webpack://home-assistant-frontend/entrypoint.585f219b.js"],"mappings":";AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"entrypoint.c258a457.js","sources":["webpack://home-assistant-frontend/entrypoint.c258a457.js"],"mappings":";AAAA","sourceRoot":""}

View File

@@ -1,3 +1,3 @@
{
"entrypoint.js": "/api/hassio/app/frontend_es5/entrypoint.585f219b.js"
"entrypoint.js": "/api/hassio/app/frontend_es5/entrypoint.c258a457.js"
}

View File

@@ -1,2 +1,2 @@
(()=>{"use strict";var e,t={4971:(e,t,r)=>{var n=r(1107),o=r(9902),s=r.n(o),a=r(2173);let i,p;const h={renderMarkdown:(e,t,r={})=>{let n;return i||(i={...(0,a.getDefaultWhiteList)(),"ha-icon":["icon"],"ha-svg-icon":["path"]}),r.allowSvg?(p||(p={...i,svg:["xmlns","height","width"],path:["transform","stroke","d"],img:["src"]}),n=p):n=i,(0,a.filterXSS)(s()(e,t),{whiteList:n})}};(0,n.Jj)(h)}},r={};function n(e){if(r[e])return r[e].exports;var o=r[e]={exports:{}};return t[e].call(o.exports,o,o.exports,n),o.exports}n.m=t,n.x=()=>{n(4971)},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce(((t,r)=>(n.f[r](e,t),t)),[])),n.u=e=>"chunk.912db116e709889ddb20.js",n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e=n.x,n.x=()=>n.e(219).then(e),n.p="/api/hassio/app/frontend_latest/",(()=>{var e={971:1};n.f.i=(t,r)=>{e[t]||importScripts(""+n.u(t))};var t=self.webpackChunkhome_assistant_frontend=self.webpackChunkhome_assistant_frontend||[],r=t.push.bind(t);t.push=t=>{var[o,s,a]=t;for(var i in s)n.o(s,i)&&(n.m[i]=s[i]);for(a&&a(n);o.length;)e[o.pop()]=1;r(t)}})(),n.x()})();
//# sourceMappingURL=chunk.7858204150418d6d4b9c.js.map
//# sourceMappingURL=chunk.1f8c4c0bad1eec9e4ef3.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.1f8c4c0bad1eec9e4ef3.js","sources":["webpack://home-assistant-frontend/chunk.1f8c4c0bad1eec9e4ef3.js"],"mappings":"AAAA","sourceRoot":""}

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.2a461c1bd77195b530dc.js","sources":["webpack://home-assistant-frontend/chunk.2a461c1bd77195b530dc.js"],"mappings":"AAAA;AAgPA;AACA;AACA;AANA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA","sourceRoot":""}

View File

@@ -3,7 +3,7 @@
open
?scrimClickAction=${e}
?escapeKeyAction=${e}
@closed=${this._dialogClosed}
@closing=${this._dialogClosed}
defaultAction="ignore"
.heading=${this._params.title?this._params.title:this._params.confirmation&&this.hass.localize("ui.dialogs.generic.default_confirmation_title")}
>
@@ -67,4 +67,4 @@
color: var(--warning-color);
}
`]}}]}}),i.oi)}}]);
//# sourceMappingURL=chunk.2bcd032c31fa95258744.js.map
//# sourceMappingURL=chunk.3b0c9ad1cbf10466830f.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"chunk.2bcd032c31fa95258744.js","sources":["webpack://home-assistant-frontend/chunk.2bcd032c31fa95258744.js"],"mappings":"AAAA;;;AA6HA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;;AAIA;AACA;;;AAGA;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGA","sourceRoot":""}
{"version":3,"file":"chunk.3b0c9ad1cbf10466830f.js","sources":["webpack://home-assistant-frontend/chunk.3b0c9ad1cbf10466830f.js"],"mappings":"AAAA;;;AA6HA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;;AAIA;AACA;;;AAGA;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGA","sourceRoot":""}

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.7858204150418d6d4b9c.js","sources":["webpack://home-assistant-frontend/chunk.7858204150418d6d4b9c.js"],"mappings":"AAAA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.7bbe51a5fb5b09f91508.js","sources":["webpack://home-assistant-frontend/chunk.7bbe51a5fb5b09f91508.js"],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA;;;;;;;;;;;;;;;;;;;;;;;;;AA6VA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsZA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.7f03101cdd9a866adc52.js","sources":["webpack://home-assistant-frontend/chunk.7f03101cdd9a866adc52.js"],"mappings":"AAAA;;;AAmLA;AACA;;;AAGA;;;;;AAKA;;AAEA;AAEA;AACA;;;;;;;AAQA;;;;;AAKA;;AAEA;AAEA;AACA;;;;;;;AAQA;;;;;AAOA;;;;;;;;;;;;;;;;AAuBA;AAunBA;;AAEA;;AAEA;AACA;;AAIA;AA0JA;;;;AAIA;;AAEA;AACA;;;AAGA;;;;AAIA;AACA;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;AA6HA;;;AAyGA;AACA;;;;;;;;AAQA;;AAGA;;;AAGA;;AAEA;AACA;;;;AAIA;;;;;;;AAQA;;;AAGA;;;;;AAvCA;;;;;;;;;;;;;;;AA8KA;;AAkFA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAIA;;;;;;;;;;;AAoBA;;;AA4GA;;AAEA;;;;AARA;;;;;;;;;;;;AAiCA;;AA8BA;AACA;AACA;;;AAMA;;;;AA4IA;;;AAMA;AACA;;;AAGA;;AAEA;;AAKA;;AAEA;;AAEA;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA;AAiLA;;;;AAIA;AACA;AACA;AACA;;;AAGA;;;;;;;;AAQA;AACA;AACA;;;;AAIA;AACA;;;AAGA;;;AAGA;AACA;;;;;;;AAOA;;;;;;;;;AASA;;AAEA;AACA;;;;AAIA;;AAEA;;;;AAIA;;;AAGA;;;;AAIA;AACA;AACA;;;AAGA;;;;;;AAMA;;AAEA;AACA;;;;AAIA;;;AAGA;;AAEA;;AAEA;AACA;AAIA;;;;;;AAMA;;AAEA;AACA;;AAEA;AAKA;;AAEA;;;;AAIA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;AACA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;;AAMA;;;AAGA;;;AAGA;;AAEA;;;;;;;;AAQA;AACA;;;;;AAKA;AACA;;;;;;;;AAQA;AACA;;;;AAIA;AACA;AACA;;;;;;;;;AASA;AACA;;;;AAIA;AACA;AACA;;;;;AAKA;;;AAGA;AACA;AACA;;;;AAIA;AACA;AACA;;;;;;;;AAQA;AACA;;;;AAIA;;AAEA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;;;;AAMA;AACA;;;;AAIA;AACA;;;;AAIA;;AAEA;;;;;;;;;;AAUA;AACA;AACA;;;AAGA;;;AAGA;;;;AAIA;;;AAGA;AACA;;;;AAIA;AACA;AACA;;;;;;AAMA;AACA;;;;;;;;AAQA;;;;AAIA;;;;AAIA;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8bA;;;AAoFA;AACA;AACA;;;AARA;;;;;;AA4BA;AAoGA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;;AAKA;;;;;;;;;AAgBA;;;AAiGA;AACA;;;AAPA;;;;;;AA2BA;;AAmQA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.897458ecb98dd6f360b5.js","sources":["webpack://home-assistant-frontend/chunk.897458ecb98dd6f360b5.js"],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.97b95a62afbc18471344.js","sources":["webpack://home-assistant-frontend/chunk.97b95a62afbc18471344.js"],"mappings":"AAAA;;;AAmLA;AACA;;;AAGA;;;;;AAKA;;AAEA;AAEA;AACA;;;;;;;AAQA;;;;;AAKA;;AAEA;AAEA;AACA;;;;;;;AAQA;;;;;AAOA;;;;;;;;;;;;;;;;AAuBA;AA0NA;AACA;;AAIA;;;;;AAsBA;;;;;;;AAkGA;;AA0FA;AACA;AACA;AACA;AACA;;AAEA;;AAIA;;AA6NA;;AAEA;;AAEA;AACA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;;;;AAIA;;;AAGA;AACA;AACA;AACA;AACA;;AAIA;;;;;;;;AAgDA;;;;;;;;AAuHA;AACA;;;;;;;;;;;;;;;;AAgBA;AACA;AACA;;AAIA;AAIA;;AAEA;;;AAGA;;;;;AAQA;;;;;;;;;;;;;;;AAwEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiOA;;AAwYA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAWA;;AAwLA;AACA;AACA;;AAMA;AA0GA;;;;AAIA;AACA;;AAIA;AACA;AACA;;;;;AAOA;;;;AAqCA;;AAoGA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;;;AAGA;;;;;AAKA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAIA;AA+IA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAMA;AACA;;AAEA;;AAEA;AACA;AASA;;;;AAsDA;AA2hBA;;AAEA;;AAEA;AACA;;AAIA;AAsLA;;;;;AAKA;;AAEA;;AAEA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;AAIA;AACA;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyLA;;;AAyGA;AACA;;;;;;;;AAQA;;AAGA;;;AAGA;;AAEA;AACA;;;;AAIA;;;;;;;AAQA;;;AAGA;;;;;AAvCA;;;;;;;;;;;;;;;AA8KA;;AAkFA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAIA;;;;;;;;;;;AAoBA;;;AA4GA;;AAEA;;;;AARA;;;;;;;;;;;;AAiCA;;AA8BA;AACA;AACA;;;AAMA;;;;AA0IA;;;AAMA;AACA;;;AAGA;;AAEA;;AAKA;;AAEA;;AAEA;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA;AA0MA;;;;AAIA;AACA;AACA;AACA;;;AAGA;;;;;;;;AAQA;AACA;AACA;;;;AAIA;AACA;;;AAGA;;;AAGA;AACA;;;;;;;AAOA;;;;;;;;;AASA;;AAEA;AACA;;;;AAIA;;AAEA;;;;AAIA;;;AAGA;;;;AAIA;AACA;AACA;;;AAGA;;;;;;AAMA;;AAEA;AACA;;;;;;AAMA;;;AAGA;;AAEA;;AAEA;AACA;AAIA;;;;;;AAMA;;AAEA;AACA;;AAEA;AAKA;;AAEA;;;;AAIA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;AACA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;AAKA;;AAEA;AACA;;AAEA;;;;;;AAMA;;;AAGA;;;AAGA;;AAEA;;AAKA;;;;;;;;AAQA;AACA;;;;;AAKA;AACA;;;;;;;;AAQA;AACA;;;;AAIA;AACA;AACA;;;;;;;;;AASA;AACA;;;;AAIA;AACA;AACA;;;;;AAKA;;;AAGA;AACA;AACA;;;;AAIA;AACA;AACA;;;;;;;;AAQA;AACA;;;;AAIA;;AAEA;;;AAGA;;;;;AAKA;;;AAGA;;AAKA;AACA;AACA;;AAGA;;;AAGA;;;AAGA;AACA;;;AAGA;AACA;;;;;;AAMA;AACA;;;;AAIA;AACA;;;;AAIA;;AAEA;;;;;;;;;;AAUA;AACA;AACA;;;AAGA;;;AAGA;;;;AAIA;;;AAGA;AACA;;;;AAIA;AACA;AACA;;;;;;AAMA;AACA;;;;;;;;AAQA;;;;AAIA;;;;AAIA;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgeA;;;AAoFA;AACA;AACA;;;AARA;;;;;;AA4BA;AAoGA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;;AAKA;;;;;;;;;AAgBA;;;AAiGA;AACA;;;AAPA;;;;;;AA2BA;;AAmQA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA","sourceRoot":""}

View File

@@ -50,4 +50,4 @@
font-weight: bold;
}
`}}]}}),i.oi)}}]);
//# sourceMappingURL=chunk.2a461c1bd77195b530dc.js.map
//# sourceMappingURL=chunk.a20105fb68cb7a86b572.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.a20105fb68cb7a86b572.js","sources":["webpack://home-assistant-frontend/chunk.a20105fb68cb7a86b572.js"],"mappings":"AAAA;AAgPA;AACA;AACA;AANA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA","sourceRoot":""}

View File

@@ -1 +0,0 @@
{"version":3,"file":"chunk.a3793467e282c7745ce3.js","sources":["webpack://home-assistant-frontend/chunk.a3793467e282c7745ce3.js"],"mappings":"AAAA;;;AAiHA;AACA;;AAEA;;AATA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA","sourceRoot":""}

View File

@@ -48,4 +48,4 @@
}
}
`]}}]}}),n.oi)},1107:(e,t,r)=>{"use strict";r.d(t,{Ud:()=>p});const n=Symbol("Comlink.proxy"),i=Symbol("Comlink.endpoint"),o=Symbol("Comlink.releaseProxy"),a=Symbol("Comlink.thrown"),s=e=>"object"==typeof e&&null!==e||"function"==typeof e,l=new Map([["proxy",{canHandle:e=>s(e)&&e[n],serialize(e){const{port1:t,port2:r}=new MessageChannel;return c(e,t),[r,[r]]},deserialize:e=>(e.start(),p(e))}],["throw",{canHandle:e=>s(e)&&a in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function c(e,t=self){t.addEventListener("message",(function r(i){if(!i||!i.data)return;const{id:o,type:s,path:l}=Object.assign({path:[]},i.data),p=(i.data.argumentList||[]).map(v);let u;try{const t=l.slice(0,-1).reduce(((e,t)=>e[t]),e),r=l.reduce(((e,t)=>e[t]),e);switch(s){case 0:u=r;break;case 1:t[l.slice(-1)[0]]=v(i.data.value),u=!0;break;case 2:u=r.apply(t,p);break;case 3:u=function(e){return Object.assign(e,{[n]:!0})}(new r(...p));break;case 4:{const{port1:t,port2:r}=new MessageChannel;c(e,r),u=function(e,t){return m.set(e,t),e}(t,[t])}break;case 5:u=void 0}}catch(e){u={value:e,[a]:0}}Promise.resolve(u).catch((e=>({value:e,[a]:0}))).then((e=>{const[n,i]=y(e);t.postMessage(Object.assign(Object.assign({},n),{id:o}),i),5===s&&(t.removeEventListener("message",r),d(t))}))})),t.start&&t.start()}function d(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function p(e,t){return f(e,[],t)}function u(e){if(e)throw new Error("Proxy has been released and is not useable")}function f(e,t=[],r=function(){}){let n=!1;const a=new Proxy(r,{get(r,i){if(u(n),i===o)return()=>g(e,{type:5,path:t.map((e=>e.toString()))}).then((()=>{d(e),n=!0}));if("then"===i){if(0===t.length)return{then:()=>a};const r=g(e,{type:0,path:t.map((e=>e.toString()))}).then(v);return r.then.bind(r)}return f(e,[...t,i])},set(r,i,o){u(n);const[a,s]=y(o);return g(e,{type:1,path:[...t,i].map((e=>e.toString())),value:a},s).then(v)},apply(r,o,a){u(n);const s=t[t.length-1];if(s===i)return g(e,{type:4}).then(v);if("bind"===s)return f(e,t.slice(0,-1));const[l,c]=h(a);return g(e,{type:2,path:t.map((e=>e.toString())),argumentList:l},c).then(v)},construct(r,i){u(n);const[o,a]=h(i);return g(e,{type:3,path:t.map((e=>e.toString())),argumentList:o},a).then(v)}});return a}function h(e){const t=e.map(y);return[t.map((e=>e[0])),(r=t.map((e=>e[1])),Array.prototype.concat.apply([],r))];var r}const m=new WeakMap;function y(e){for(const[t,r]of l)if(r.canHandle(e)){const[n,i]=r.serialize(e);return[{type:3,name:t,value:n},i]}return[{type:0,value:e},m.get(e)||[]]}function v(e){switch(e.type){case 3:return l.get(e.name).deserialize(e.value);case 0:return e.value}}function g(e,t,r){return new Promise((n=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.addEventListener("message",(function t(r){r.data&&r.data.id&&r.data.id===i&&(e.removeEventListener("message",t),n(r.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:i},t),r)}))}}}]);
//# sourceMappingURL=chunk.a3793467e282c7745ce3.js.map
//# sourceMappingURL=chunk.c3f526690a29f2553fff.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"chunk.c3f526690a29f2553fff.js","sources":["webpack://home-assistant-frontend/chunk.c3f526690a29f2553fff.js"],"mappings":"AAAA;;;AAiHA;AACA;;AAEA;;AATA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA","sourceRoot":""}

Some files were not shown because too many files have changed in this diff Show More