mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
ci: перепаковка кадров документации без потерь при съёмке
oxipng снимает с набора 19.4%: 2096 КБ становятся 1689 КБ, и все десять кадров остаются пиксельно идентичными — декодированные RGBA совпадают по sha256. Это выбор фильтров строки и уровня сжатия, а не квантование: визуального решения нет. Внутри съёмки, а не отдельным проходом по закоммиченным файлам: манифест хранит imageSha256 каждого кадра, поэтому жать их в репозитории руками нельзя — check-docs покраснеет; а если жать после подсчёта хешей, следующая съёмка вернёт неоптимизированные байты. Хеш считается после перепаковки. Версия oxipng попадает в манифест рядом с версией браузера и по той же причине: байты кадра зависят от того, чем жали. Отсюда же правка шага «Вердикт» — иначе он объявил бы «тот же браузер, а картинки изменились — изменился продукт», хотя изменился упаковщик. Пин версии и контрольной суммы вместо apt-get: пакет из образа раннера может пропасть, а падение шага съёмки стоит целого цикла приёмки (#175, #206). Проверено исполнением на прежней базе: съёмка прогнана целиком с подставным oxipng, 2096 -> 1689 КБ, хеши манифеста совпали с файлами, check-docs зелёный. Issue: #345 User-Visible: no
This commit is contained in:
@@ -48,6 +48,29 @@ jobs:
|
||||
run: npx playwright install chromium
|
||||
- name: Build the bundle the screenshots must come from
|
||||
run: npm run build
|
||||
# oxipng без потерь снимает с набора ~19% (замер в #345 на pyoxipng 9.1.1;
|
||||
# у 10.2.0 пресеты уровней перебалансированы, точная доля может отличаться,
|
||||
# но кадры остаются пиксельно идентичными в любой версии — это перепаковка).
|
||||
#
|
||||
# Пин версии и контрольной суммы намеренно, а не `apt-get install oxipng`:
|
||||
# пакет из образа раннера может пропасть или переехать, а падение шага
|
||||
# съёмки стоит целого цикла приёмки. Тот же урок, что с azure-зеркалом
|
||||
# Playwright (#175, #206).
|
||||
- name: Установить oxipng
|
||||
env:
|
||||
OXIPNG_VERSION: 10.2.0
|
||||
OXIPNG_SHA256: b33f84c73d42cb592bea5d84c431030b1e97784817693380dfcec7d9575f871e
|
||||
run: |
|
||||
set -euo pipefail
|
||||
asset="oxipng-${OXIPNG_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
|
||||
curl -fsSL -o "$asset" \
|
||||
"https://github.com/oxipng/oxipng/releases/download/v${OXIPNG_VERSION}/${asset}"
|
||||
echo "${OXIPNG_SHA256} ${asset}" | sha256sum -c -
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
tar -xzf "$asset" --strip-components=1 -C "$HOME/.local/bin" \
|
||||
"oxipng-${OXIPNG_VERSION}-x86_64-unknown-linux-gnu/oxipng"
|
||||
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||
"$HOME/.local/bin/oxipng" --version
|
||||
- name: Capture
|
||||
run: node demo/docs/capture.mjs
|
||||
# Вердикт до всякой приёмки. Само число изменившихся файлов ничего не
|
||||
@@ -58,16 +81,30 @@ jobs:
|
||||
# разницу рендеринга.
|
||||
- name: Вердикт
|
||||
run: |
|
||||
# Поле манифеста «до» — из закоммиченного состояния, «после» — из
|
||||
# свежего. Читается одинаково для браузера и для упаковщика: оба
|
||||
# переписывают все кадры сразу, и различить их причины обязан вердикт,
|
||||
# а не человек по памяти (#345).
|
||||
field() {
|
||||
node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{console.log(JSON.parse(s).$1||'')}catch{console.log('')}})"
|
||||
}
|
||||
git status --porcelain docs/images
|
||||
changed=$(git diff --name-only docs/images | grep -c png || true)
|
||||
before=$(git show HEAD:docs/images/screenshots.json | node -e \
|
||||
"let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{console.log(JSON.parse(s).chromium||'')}catch{console.log('')}})")
|
||||
before=$(git show HEAD:docs/images/screenshots.json | field chromium)
|
||||
after=$(node -e "console.log(require('./docs/images/screenshots.json').chromium)")
|
||||
packer_before=$(git show HEAD:docs/images/screenshots.json | field oxipng)
|
||||
packer_after=$(node -e "console.log(require('./docs/images/screenshots.json').oxipng || '')")
|
||||
echo "--- изменившихся PNG: $changed"
|
||||
echo "--- Chromium: было «${before:-не записан}», стало «$after»"
|
||||
if [ "$before" = "$after" ] && [ "$changed" -gt 0 ]; then
|
||||
echo "ВЕРДИКТ: тот же браузер, а картинки изменились — изменился продукт."
|
||||
echo "Смотрите на кадры: если изменение ожидаемое, принимайте."
|
||||
echo "--- oxipng: было «${packer_before:-не записан}», стало «${packer_after:-нет}»"
|
||||
if [ "$packer_before" != "$packer_after" ] && [ "$changed" -gt 0 ]; then
|
||||
echo "ВЕРДИКТ: изменился упаковщик, поэтому переписаны все кадры сразу."
|
||||
echo "Это перепаковка без потерь: пиксели те же, размер меньше на ~19%."
|
||||
echo "Ожидаемо один раз — при включении oxipng либо при смене его версии."
|
||||
echo "Проверить можно сравнением декодированных кадров, а не байтов."
|
||||
elif [ "$before" = "$after" ] && [ "$changed" -gt 0 ]; then
|
||||
echo "ВЕРДИКТ: тот же браузер и тот же упаковщик, а картинки изменились —"
|
||||
echo "изменился продукт. Смотрите на кадры: если изменение ожидаемое, принимайте."
|
||||
elif [ "$before" != "$after" ]; then
|
||||
echo "ВЕРДИКТ: браузер другой, поэтому переписаны все кадры сразу."
|
||||
echo "Это ожидаемо один раз — при переходе на канонический прогон."
|
||||
|
||||
@@ -1,96 +1,96 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc",
|
||||
"fingerprint": "e499c3cfebb07203abd2397b1303ed1a45286f24fcc9129f45917b8a99ba1479",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 255910,
|
||||
"initialViewGzipBytes": 255908,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyGzipBytes": 138425,
|
||||
"lazyGzipBytes": 138428,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 131779,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 7199,
|
||||
"lazyOnboardingGzipBytes": 7203,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/editor-MqqOS4sP.js",
|
||||
"sha256": "140369d29021c71a88b788224fca477b97fc4fc1d5254bbad9e68f01fee403c9",
|
||||
"path": "houseplan-assets/editor-DMlizeQy.js",
|
||||
"sha256": "7aeb38573980efdf90749280c7be4150f41bec4939919c9d84ecdf028185fd6a",
|
||||
"rawBytes": 3699,
|
||||
"gzipBytes": 1529,
|
||||
"gzipBytes": 1530,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"sha256": "66c490a5ab13cff53463d315b0d18c8dfd26f1caf150836de5559ac3df2aa82e",
|
||||
"path": "houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"sha256": "bbff295ebc0def9401caac0001245371490977fe612cc08c2402cfca5b827faf",
|
||||
"rawBytes": 910654,
|
||||
"gzipBytes": 255727,
|
||||
"gzipBytes": 255726,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"sha256": "0d2dd1b6cfc0c05a010e7b2345623f1063ed5e0fe0f9a95be9afb81e90c26e6b",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"sha256": "616d30f0d4a61a14f8c149c55e6a8d12647aa80bdd31c32b57d2803ba9c5653b",
|
||||
"rawBytes": 504952,
|
||||
"gzipBytes": 129697,
|
||||
"gzipBytes": 129695,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"sha256": "38044f0836917a8f91705b61b5d48fcf4c0ca72d41b919831d2b66a0a78e4ff9",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"sha256": "218d3b7f139f12bb842f7f888ba2e2fa97ca2f11b8bbfd6c2b9e16eff0647eef",
|
||||
"rawBytes": 26356,
|
||||
"gzipBytes": 6646,
|
||||
"gzipBytes": 6649,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/space-deletion-BxF_6aDU.js",
|
||||
"sha256": "137b0f78bc5e11c7b1e95c138c1fcf0f982f89013053a1cc648e6df52092401e",
|
||||
"path": "houseplan-assets/space-deletion-7mvB_XVT.js",
|
||||
"sha256": "ca7cdbe51f937d2cd53385204d3b7917ec18f50c51b5aef4eb3e273516b08747",
|
||||
"rawBytes": 911,
|
||||
"gzipBytes": 553,
|
||||
"gzipBytes": 554,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "3a1818c954f8d4a8a8cb143d7b9c39196a8a340a43c578fd6ca5b6fc01ac8065",
|
||||
"sha256": "45da1371d0ca2713a6a8f6108599c614bed0907f2c80556192375dbfdc741e2e",
|
||||
"rawBytes": 190,
|
||||
"gzipBytes": 183,
|
||||
"gzipBytes": 182,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";import{c as e,l as o,t,d2 as s,A as a,b as l}from"./houseplan-card-CdKyxHZ7.js";class i extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],l=this._floorToken;l&&a.push({value:l,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const i="string"==typeof this._config?.floor?this._config.floor:"";i&&!e.some(e=>e.value===i)&&a.push({value:i,label:i}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;this._loadSpaces();const e=this._lang,o={title:t(e,"editor.title"),floor:t(e,"editor.floor"),default_floor:t(e,"editor.default_floor"),language:t(e,"editor.language"),icon_size:t(e,"editor.icon_size"),show_temperature:t(e,"editor.show_temperature"),live_states:t(e,"editor.live_states"),show_signal:t(e,"editor.show_signal"),kiosk:t(e,"editor.kiosk"),cycle:t(e,"editor.cycle")},s=this._schema,i=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),n=e=>l`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>o[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return l`
|
||||
${n(s.slice(0,3))}
|
||||
${i?l`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(e,"editor.default_floor_missing",{id:i})}
|
||||
</div>`:a}
|
||||
${n(s.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}i.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",i);
|
||||
File diff suppressed because one or more lines are too long
-2572
File diff suppressed because one or more lines are too long
-217
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
function e(e,o){return{id:e,title:o,plan_url:null,view_box:[0,0,1,1],rooms:[],wall_segments:[]}}function o(e="file"){const o="draw"===e;return{source:e,showBorders:o,showNames:o,displayTouched:!1}}function r(e,o){if(e.displayTouched)return{...e,source:o};const r="draw"===o;return{...e,source:o,showBorders:r,showNames:r}}function s(e,o,r){return{...e,[o]:r,displayTouched:!0}}function t(e,o,r){const s=(e?.spaces||[]).find(e=>e?.id===r),t=new Set((s?.rooms||[]).map(e=>String(e?.id||"")).filter(Boolean)),n=[...new Set((e?.markers||[]).filter(e=>!0!==e?.removed&&"string"==typeof e?.id).filter(e=>e.space===r||"string"==typeof e.room_id&&t.has(e.room_id)||o?.[e.id]?.s===r).map(e=>e.id))].sort((e,o)=>e.localeCompare(o));return{markerIds:n,count:n.length}}globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";export{t as a,e as c,o as i,r as s,s as t};
|
||||
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";export{d3 as HouseplanCard}from"./houseplan-assets/houseplan-card-CdKyxHZ7.js";
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e499c3cfebb07203abd2397b1303ed1a45286f24fcc9129f45917b8a99ba1479";export{d3 as HouseplanCard}from"./houseplan-assets/houseplan-card-OQuczTJf.js";
|
||||
|
||||
+50
-2
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash } from 'node:crypto';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
@@ -18,6 +19,47 @@ const OUTPUT = resolve(ROOT, 'docs/images');
|
||||
const SCRIPT = fileURLToPath(import.meta.url);
|
||||
const sha256 = (value) => createHash('sha256').update(value).digest('hex');
|
||||
|
||||
/**
|
||||
* Перепаковка кадра без потерь (#345).
|
||||
*
|
||||
* Замер на этом наборе: 2096 КБ превращаются в 1689 КБ, минус 19.4%, и все
|
||||
* десять кадров остаются ПИКСЕЛЬНО идентичными — декодированные RGBA совпадают
|
||||
* по sha256. Это выбор фильтров строки и уровня сжатия, а не квантование:
|
||||
* визуального решения здесь нет вовсе.
|
||||
*
|
||||
* Почему внутри съёмки, а не отдельным проходом по закоммиченным файлам.
|
||||
* Манифест хранит `imageSha256` каждого кадра, поэтому оптимизировать файлы в
|
||||
* репозитории руками нельзя — `check-docs` покраснеет; а если жать после
|
||||
* подсчёта хешей, следующая же съёмка вернёт неоптимизированные байты.
|
||||
*
|
||||
* Отсутствие инструмента не ошибка: локальная съёмка и без него полезна для
|
||||
* глаз, а приёмка всё равно идёт только из артефакта CI, где `oxipng` стоит
|
||||
* пином (`.github/workflows/docs-screenshots.yml`). Но молчать об этом нельзя —
|
||||
* байты кадра зависят от того, был ли инструмент, поэтому его версия попадает
|
||||
* в манифест рядом с версией браузера, по той же причине.
|
||||
*/
|
||||
const oxipngVersion = (() => {
|
||||
const probe = spawnSync('oxipng', ['--version'], { encoding: 'utf8' });
|
||||
if (probe.status !== 0) {
|
||||
console.log('oxipng не найден: кадры пишутся как есть, без перепаковки');
|
||||
return null;
|
||||
}
|
||||
return String(probe.stdout || '').trim().split('\n')[0];
|
||||
})();
|
||||
|
||||
/** Пожать файл на месте и вернуть его новые байты. */
|
||||
const shrinkPng = (path, before) => {
|
||||
if (!oxipngVersion) return before;
|
||||
const run = spawnSync('oxipng', ['-o', '4', '--strip', 'safe', '--quiet', path]);
|
||||
if (run.status !== 0) {
|
||||
throw new Error(`oxipng не смог обработать ${path}: код ${run.status}`
|
||||
+ `${run.stderr ? ` · ${run.stderr}` : ''}`);
|
||||
}
|
||||
const after = readFileSync(path);
|
||||
console.log(` ${(before.length / 1024).toFixed(0)} КБ -> ${(after.length / 1024).toFixed(0)} КБ`);
|
||||
return after;
|
||||
};
|
||||
|
||||
|
||||
const roomCardClip = (page) => page.evaluate(() => {
|
||||
const card = window.__goldenCard;
|
||||
@@ -128,14 +170,18 @@ try {
|
||||
const image = await page.screenshot({
|
||||
...(clip ? { clip } : {}), animations: 'disabled', caret: 'hide', scale: 'css',
|
||||
});
|
||||
writeFileSync(resolve(OUTPUT, scenario.file), image);
|
||||
const imagePath = resolve(OUTPUT, scenario.file);
|
||||
writeFileSync(imagePath, image);
|
||||
// Хеш считается ПОСЛЕ перепаковки: манифест обязан описывать те байты,
|
||||
// которые лежат на диске, иначе приёмка отвергнет свой же кандидат.
|
||||
const stored = shrinkPng(imagePath, image);
|
||||
scenarios[scenario.id] = {
|
||||
file: scenario.file,
|
||||
viewport: scenario.viewport,
|
||||
theme: scenario.theme,
|
||||
language: scenario.language,
|
||||
sourceSha256: fingerprint,
|
||||
imageSha256: sha256(image),
|
||||
imageSha256: sha256(stored),
|
||||
};
|
||||
console.log(`captured ${scenario.id} -> docs/images/${scenario.file}`);
|
||||
}
|
||||
@@ -146,6 +192,8 @@ try {
|
||||
// Кто снимал. Смена браузера переписывает все картинки без содержательных
|
||||
// изменений (#246), поэтому окружение съёмки — часть доказательства.
|
||||
chromium: browser.version(),
|
||||
// Чем жали — тоже часть доказательства: без инструмента байты другие.
|
||||
oxipng: oxipngVersion,
|
||||
sourceFingerprint: fingerprint,
|
||||
captureScriptSha256: sha256(readFileSync(SCRIPT)),
|
||||
command: 'npm run build && node demo/docs/capture.mjs',
|
||||
|
||||
Vendored
+40
-40
@@ -1,96 +1,96 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc",
|
||||
"fingerprint": "e499c3cfebb07203abd2397b1303ed1a45286f24fcc9129f45917b8a99ba1479",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 255910,
|
||||
"initialViewGzipBytes": 255908,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyGzipBytes": 138425,
|
||||
"lazyGzipBytes": 138428,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 131779,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 7199,
|
||||
"lazyOnboardingGzipBytes": 7203,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/editor-MqqOS4sP.js",
|
||||
"sha256": "140369d29021c71a88b788224fca477b97fc4fc1d5254bbad9e68f01fee403c9",
|
||||
"path": "houseplan-assets/editor-DMlizeQy.js",
|
||||
"sha256": "7aeb38573980efdf90749280c7be4150f41bec4939919c9d84ecdf028185fd6a",
|
||||
"rawBytes": 3699,
|
||||
"gzipBytes": 1529,
|
||||
"gzipBytes": 1530,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"sha256": "66c490a5ab13cff53463d315b0d18c8dfd26f1caf150836de5559ac3df2aa82e",
|
||||
"path": "houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"sha256": "bbff295ebc0def9401caac0001245371490977fe612cc08c2402cfca5b827faf",
|
||||
"rawBytes": 910654,
|
||||
"gzipBytes": 255727,
|
||||
"gzipBytes": 255726,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/editor-MqqOS4sP.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js"
|
||||
"houseplan-assets/editor-DMlizeQy.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Bbmj7A6f.js",
|
||||
"sha256": "0d2dd1b6cfc0c05a010e7b2345623f1063ed5e0fe0f9a95be9afb81e90c26e6b",
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Bk__jFmU.js",
|
||||
"sha256": "616d30f0d4a61a14f8c149c55e6a8d12647aa80bdd31c32b57d2803ba9c5653b",
|
||||
"rawBytes": 504952,
|
||||
"gzipBytes": 129697,
|
||||
"gzipBytes": 129695,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C28J-NJP.js",
|
||||
"sha256": "38044f0836917a8f91705b61b5d48fcf4c0ca72d41b919831d2b66a0a78e4ff9",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-Dor16U6K.js",
|
||||
"sha256": "218d3b7f139f12bb842f7f888ba2e2fa97ca2f11b8bbfd6c2b9e16eff0647eef",
|
||||
"rawBytes": 26356,
|
||||
"gzipBytes": 6646,
|
||||
"gzipBytes": 6649,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js",
|
||||
"houseplan-assets/space-deletion-BxF_6aDU.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js",
|
||||
"houseplan-assets/space-deletion-7mvB_XVT.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/space-deletion-BxF_6aDU.js",
|
||||
"sha256": "137b0f78bc5e11c7b1e95c138c1fcf0f982f89013053a1cc648e6df52092401e",
|
||||
"path": "houseplan-assets/space-deletion-7mvB_XVT.js",
|
||||
"sha256": "ca7cdbe51f937d2cd53385204d3b7917ec18f50c51b5aef4eb3e273516b08747",
|
||||
"rawBytes": 911,
|
||||
"gzipBytes": 553,
|
||||
"gzipBytes": 554,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "3a1818c954f8d4a8a8cb143d7b9c39196a8a340a43c578fd6ca5b6fc01ac8065",
|
||||
"sha256": "45da1371d0ca2713a6a8f6108599c614bed0907f2c80556192375dbfdc741e2e",
|
||||
"rawBytes": 190,
|
||||
"gzipBytes": 183,
|
||||
"gzipBytes": 182,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-CdKyxHZ7.js"
|
||||
"houseplan-assets/houseplan-card-OQuczTJf.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";import{c as e,l as o,t,d2 as s,A as a,b as l}from"./houseplan-card-CdKyxHZ7.js";class i extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],l=this._floorToken;l&&a.push({value:l,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const i="string"==typeof this._config?.floor?this._config.floor:"";i&&!e.some(e=>e.value===i)&&a.push({value:i,label:i}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;this._loadSpaces();const e=this._lang,o={title:t(e,"editor.title"),floor:t(e,"editor.floor"),default_floor:t(e,"editor.default_floor"),language:t(e,"editor.language"),icon_size:t(e,"editor.icon_size"),show_temperature:t(e,"editor.show_temperature"),live_states:t(e,"editor.live_states"),show_signal:t(e,"editor.show_signal"),kiosk:t(e,"editor.kiosk"),cycle:t(e,"editor.cycle")},s=this._schema,i=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),n=e=>l`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>o[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return l`
|
||||
${n(s.slice(0,3))}
|
||||
${i?l`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(e,"editor.default_floor_missing",{id:i})}
|
||||
</div>`:a}
|
||||
${n(s.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}i.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",i);
|
||||
-5238
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
function e(e,o){return{id:e,title:o,plan_url:null,view_box:[0,0,1,1],rooms:[],wall_segments:[]}}function o(e="file"){const o="draw"===e;return{source:e,showBorders:o,showNames:o,displayTouched:!1}}function r(e,o){if(e.displayTouched)return{...e,source:o};const r="draw"===o;return{...e,source:o,showBorders:r,showNames:r}}function s(e,o,r){return{...e,[o]:r,displayTouched:!0}}function t(e,o,r){const s=(e?.spaces||[]).find(e=>e?.id===r),t=new Set((s?.rooms||[]).map(e=>String(e?.id||"")).filter(Boolean)),n=[...new Set((e?.markers||[]).filter(e=>!0!==e?.removed&&"string"==typeof e?.id).filter(e=>e.space===r||"string"==typeof e.room_id&&t.has(e.room_id)||o?.[e.id]?.s===r).map(e=>e.id))].sort((e,o)=>e.localeCompare(o));return{markerIds:n,count:n.length}}globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";export{t as a,e as c,o as i,r as s,s as t};
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="edcb61bd3c2c9a6056c747c366bbd7c73f1678dce2c656f631b56a4241a4b8dc";export{d3 as HouseplanCard}from"./houseplan-assets/houseplan-card-CdKyxHZ7.js";
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="e499c3cfebb07203abd2397b1303ed1a45286f24fcc9129f45917b8a99ba1479";export{d3 as HouseplanCard}from"./houseplan-assets/houseplan-card-OQuczTJf.js";
|
||||
|
||||
Reference in New Issue
Block a user