fundus 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -1
- package/build/client/_app/immutable/assets/2.X44Wyac-.css +1 -0
- package/build/client/_app/immutable/assets/2.X44Wyac-.css.br +0 -0
- package/build/client/_app/immutable/assets/2.X44Wyac-.css.gz +0 -0
- package/build/client/_app/immutable/assets/{3.C6xo25uI.css → 3.66PJT3JC.css} +1 -1
- package/build/client/_app/immutable/assets/3.66PJT3JC.css.br +0 -0
- package/build/client/_app/immutable/assets/3.66PJT3JC.css.gz +0 -0
- package/build/client/_app/immutable/assets/{AssetSourceMenu.IjDdjx3o.css → AssetSourceMenu.Buj2UxUg.css} +1 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.Buj2UxUg.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.Buj2UxUg.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{VX-Uq_b9.js → 5fq8ySvR.js} +1 -1
- package/build/client/_app/immutable/chunks/5fq8ySvR.js.br +0 -0
- package/build/client/_app/immutable/chunks/5fq8ySvR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js +1 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js +2 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js.br +0 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js.gz +0 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js +108 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{-8MKoIIe.js → jEVVu5G9.js} +1 -1
- package/build/client/_app/immutable/chunks/jEVVu5G9.js.br +0 -0
- package/build/client/_app/immutable/chunks/jEVVu5G9.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CJpgt8H5.js → app.Z9n2k33I.js} +2 -2
- package/build/client/_app/immutable/entry/app.Z9n2k33I.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Z9n2k33I.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js +1 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js +1 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.D6OhgXcC.js → 1.rgoSlmPu.js} +1 -1
- package/build/client/_app/immutable/nodes/1.rgoSlmPu.js.br +2 -0
- package/build/client/_app/immutable/nodes/1.rgoSlmPu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js +3 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js +1 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.js +2 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +8 -7
- package/build/handler.js.map +1 -1
- package/build/index.js +8 -7
- package/build/index.js.map +1 -1
- package/build/server/chunks/chunks/{context.js-CVuTSPjH.js → context.js-Dh0ibRIF.js} +818 -136
- package/build/server/chunks/chunks/context.js-Dh0ibRIF.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-itFN0Gon.js → contract.js-_LTMZBo2.js} +156 -58
- package/build/server/chunks/chunks/contract.js-_LTMZBo2.js.map +1 -0
- package/build/server/chunks/chunks/{core.js-CABVXpby.js → core.js-CTyKR4bu.js} +145 -156
- package/build/server/chunks/chunks/core.js-CTyKR4bu.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-VRV1_yEb.js → exports.js-gz2aNXzz.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-VRV1_yEb.js.map → exports.js-gz2aNXzz.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-ChQRRKfZ.js → http.js-BiqUcAuu.js} +3 -2
- package/build/server/chunks/chunks/http.js-BiqUcAuu.js.map +1 -0
- package/build/server/chunks/chunks/{internal.js-qXxDe7VN.js → internal.js-DoH0cN5N.js} +5 -3
- package/build/server/chunks/chunks/internal.js-DoH0cN5N.js.map +1 -0
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{manifest-membership.js-BnSECWpJ.js → manifest-membership.js-at1ixQdW.js} +10 -3
- package/build/server/chunks/chunks/manifest-membership.js-at1ixQdW.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation.js-ZEOCk_jA.js → raw-reconciliation.js-CUH8IIJx.js} +3 -3
- package/build/server/chunks/chunks/raw-reconciliation.js-CUH8IIJx.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CscuoBC2.js → raw-reconciliation2.js-z4xl5zw2.js} +2 -2
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CscuoBC2.js.map → raw-reconciliation2.js-z4xl5zw2.js.map} +1 -1
- package/build/server/chunks/chunks/{shared.js-DnEOHbgT.js → shared.js-CI-ZkPQn.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-DnEOHbgT.js.map → shared.js-CI-ZkPQn.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-lNH0hKSx.js → utils.js-gXYLxRG9.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-lNH0hKSx.js.map → utils.js-gXYLxRG9.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-z988EDp2.js → _server.ts.js-CdDjuW0r.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-z988EDp2.js.map → _server.ts.js-CdDjuW0r.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-C68ru6gS.js → _server.ts.js-OWM1eORG.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-C68ru6gS.js.map → _server.ts.js-OWM1eORG.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-C0tk6RFk.js → _server.ts.js-DoG-7ZpZ.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-C0tk6RFk.js.map → _server.ts.js-DoG-7ZpZ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-I03oZuo8.js → _server.ts.js-CAWjVeGd.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-I03oZuo8.js.map → _server.ts.js-CAWjVeGd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/_server.ts.js-CqS4aALY.js +38 -0
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/_server.ts.js-CqS4aALY.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-BsQB8YDq.js → _server.ts.js-Bo_EsYXJ.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-BsQB8YDq.js.map → _server.ts.js-Bo_EsYXJ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CJuFE6Fb.js → _server.ts.js-DW4w0XAr.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CJuFE6Fb.js.map → _server.ts.js-DW4w0XAr.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DuOZRRiA.js → _server.ts.js-_MiNPnSy.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DuOZRRiA.js.map → _server.ts.js-_MiNPnSy.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DGzYpQbv.js → _server.ts.js-DwbrQnBc.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DGzYpQbv.js.map → _server.ts.js-DwbrQnBc.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-B045QoCA.js → _server.ts.js-CEnHQf3b.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-B045QoCA.js.map → _server.ts.js-CEnHQf3b.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-HUkVdz19.js → _server.ts.js-BZDuJZtF.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-HUkVdz19.js.map → _server.ts.js-BZDuJZtF.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-ry509mom.js → _server.ts.js-DRgdpKKd.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-ry509mom.js.map → _server.ts.js-DRgdpKKd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DU0J7U25.js → _server.ts.js-CP5QyIhz.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DU0J7U25.js.map → _server.ts.js-CP5QyIhz.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AZIV2PIn.js → _server.ts.js-BKEvt065.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AZIV2PIn.js.map → _server.ts.js-BKEvt065.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CDL0hCfM.js → _server.ts.js-C_zihkDS.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CDL0hCfM.js.map → _server.ts.js-C_zihkDS.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-B13c17fq.js → _server.ts.js-watkBmy6.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-B13c17fq.js.map → _server.ts.js-watkBmy6.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-BCxjyAGC.js → _server.ts.js-YtumLIou.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-BCxjyAGC.js.map → _server.ts.js-YtumLIou.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-BveeMZc2.js → _server.ts.js-Dkouuu-M.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-BveeMZc2.js.map → _server.ts.js-Dkouuu-M.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-BZjTd9a0.js → _server.ts.js-DwsEQeuf.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-BZjTd9a0.js.map → _server.ts.js-DwsEQeuf.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BbTfPvC9.js → _server.ts.js-CdQxfhV3.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BbTfPvC9.js.map → _server.ts.js-CdQxfhV3.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-8VPJMLBk.js → _server.ts.js-DDdMocWj.js} +6 -6
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-8VPJMLBk.js.map → _server.ts.js-DDdMocWj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqR2J2sB.js → _server.ts.js-DbzjbH32.js} +9 -7
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqR2J2sB.js.map → _server.ts.js-DbzjbH32.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-DbA28dCY.js → _server.ts.js-K_JbXZsU.js} +9 -7
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-DbA28dCY.js.map → _server.ts.js-K_JbXZsU.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-9PBc_3Jh.js → hooks.server.js-DgZAVFbQ.js} +8 -6
- package/build/server/chunks/entries/{hooks.server.js-9PBc_3Jh.js.map → hooks.server.js-DgZAVFbQ.js.map} +1 -1
- package/build/server/chunks/{handler-BHt7eOOX.js → handler-CFkKak8t.js} +5 -5
- package/build/server/chunks/{handler-BHt7eOOX.js.map → handler-CFkKak8t.js.map} +1 -1
- package/build/server/chunks/{index.js-DcVaL-Ja.js → index.js-B1IroJH5.js} +5 -5
- package/build/server/chunks/{index.js-DcVaL-Ja.js.map → index.js-B1IroJH5.js.map} +1 -1
- package/build/server/chunks/{manifest.js-DgjSU4wg.js → manifest.js-DNDBsrEU.js} +36 -29
- package/build/server/chunks/manifest.js-DNDBsrEU.js.map +1 -0
- package/build/server/chunks/nodes/{0.js-BgTB-_Zt.js → 0.js-CZ3mZUZl.js} +2 -2
- package/build/server/chunks/nodes/{0.js-BgTB-_Zt.js.map → 0.js-CZ3mZUZl.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-BmDzLKxV.js +7 -0
- package/build/server/chunks/nodes/{1.js-DNabcIPP.js.map → 1.js-BmDzLKxV.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-Dirm-bY-.js +7 -0
- package/build/server/chunks/nodes/2.js-Dirm-bY-.js.map +1 -0
- package/build/server/chunks/nodes/3.js-DOqHmSWt.js +7 -0
- package/build/server/chunks/nodes/3.js-DOqHmSWt.js.map +1 -0
- package/build/server/chunks/nodes/4.js-C8pmF8IP.js +7 -0
- package/build/server/chunks/nodes/{4.js-BE7ZG9vA.js.map → 4.js-C8pmF8IP.js.map} +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +2 -2
- package/dist/core/api-types.d.ts +24 -3
- package/dist/core/config.d.ts +84 -0
- package/dist/core/config.js +9 -0
- package/dist/core/index.d.ts +10 -5
- package/dist/core/index.js +5 -2
- package/dist/core/ingest.d.ts +1 -6
- package/dist/core/ingest.js +4 -21
- package/dist/core/library-validation.d.ts +13 -0
- package/dist/core/library-validation.js +48 -0
- package/dist/core/library.d.ts +19 -0
- package/dist/core/library.js +4 -4
- package/dist/core/manifest-membership.d.ts +2 -2
- package/dist/core/package-declaration.d.ts +43 -0
- package/dist/core/package-declaration.js +80 -0
- package/dist/core/package-merge.d.ts +65 -0
- package/dist/core/package-merge.js +173 -0
- package/dist/core/propose-asset-id.d.ts +10 -0
- package/dist/core/propose-asset-id.js +25 -0
- package/dist/core/reference-graph.d.ts +3 -3
- package/dist/server/build.js +26 -11
- package/dist/server/check.d.ts +13 -3
- package/dist/server/check.js +112 -24
- package/dist/server/cli-commands.d.ts +2 -2
- package/dist/server/cli-commands.js +213 -29
- package/dist/server/codegen.d.ts +3 -1
- package/dist/server/codegen.js +18 -0
- package/dist/server/config-loader.d.ts +36 -1
- package/dist/server/config-loader.js +190 -4
- package/dist/server/http.js +1 -0
- package/dist/server/importers/figma.d.ts +26 -3
- package/dist/server/importers/figma.js +114 -1
- package/dist/server/library-store.d.ts +20 -1
- package/dist/server/library-store.js +121 -60
- package/dist/server/operations.d.ts +12 -0
- package/dist/server/operations.js +283 -48
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css +0 -1
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.br +0 -0
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.C6xo25uI.css.br +0 -0
- package/build/client/_app/immutable/assets/3.C6xo25uI.css.gz +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.IjDdjx3o.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.IjDdjx3o.css.gz +0 -0
- package/build/client/_app/immutable/chunks/-8MKoIIe.js.br +0 -0
- package/build/client/_app/immutable/chunks/-8MKoIIe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D1wFzWdi.js +0 -108
- package/build/client/_app/immutable/chunks/D1wFzWdi.js.br +0 -0
- package/build/client/_app/immutable/chunks/D1wFzWdi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DmQb0SN8.js +0 -2
- package/build/client/_app/immutable/chunks/DmQb0SN8.js.br +0 -0
- package/build/client/_app/immutable/chunks/DmQb0SN8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/N1X6Qzcl.js +0 -1
- package/build/client/_app/immutable/chunks/N1X6Qzcl.js.br +0 -0
- package/build/client/_app/immutable/chunks/N1X6Qzcl.js.gz +0 -0
- package/build/client/_app/immutable/chunks/VX-Uq_b9.js.br +0 -1
- package/build/client/_app/immutable/chunks/VX-Uq_b9.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CJpgt8H5.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CJpgt8H5.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DToPJitz.js +0 -1
- package/build/client/_app/immutable/entry/start.DToPJitz.js.br +0 -1
- package/build/client/_app/immutable/entry/start.DToPJitz.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.Co4Hh8k6.js +0 -1
- package/build/client/_app/immutable/nodes/0.Co4Hh8k6.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.Co4Hh8k6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.D6OhgXcC.js.br +0 -3
- package/build/client/_app/immutable/nodes/1.D6OhgXcC.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.sBDjyIQu.js +0 -3
- package/build/client/_app/immutable/nodes/2.sBDjyIQu.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.sBDjyIQu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.DDt73kMC.js +0 -1
- package/build/client/_app/immutable/nodes/3.DDt73kMC.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DDt73kMC.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.FsXXhVSP.js +0 -2
- package/build/client/_app/immutable/nodes/4.FsXXhVSP.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.FsXXhVSP.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-CVuTSPjH.js.map +0 -1
- package/build/server/chunks/chunks/contract.js-itFN0Gon.js.map +0 -1
- package/build/server/chunks/chunks/core.js-CABVXpby.js.map +0 -1
- package/build/server/chunks/chunks/http.js-ChQRRKfZ.js.map +0 -1
- package/build/server/chunks/chunks/internal.js-qXxDe7VN.js.map +0 -1
- package/build/server/chunks/chunks/manifest-membership.js-BnSECWpJ.js.map +0 -1
- package/build/server/chunks/chunks/raw-reconciliation.js-ZEOCk_jA.js.map +0 -1
- package/build/server/chunks/manifest.js-DgjSU4wg.js.map +0 -1
- package/build/server/chunks/nodes/1.js-DNabcIPP.js +0 -7
- package/build/server/chunks/nodes/2.js-CcVBvLSR.js +0 -7
- package/build/server/chunks/nodes/2.js-CcVBvLSR.js.map +0 -1
- package/build/server/chunks/nodes/3.js-DreG5rig.js +0 -7
- package/build/server/chunks/nodes/3.js-DreG5rig.js.map +0 -1
- package/build/server/chunks/nodes/4.js-BE7ZG9vA.js +0 -7
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { readFile } from 'node:fs/promises';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
-
import { assetIdError, allDeliveredAssetIds, canonicalizeParameters, collectAllReferences, compareCodeUnits, computeLibraryMembership, folderOfRawPath, normalizeFolderPath, parentFolderPath, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, serializeLibrary, typesForFileName } from '../core/index.js';
|
|
10
|
+
import { assetIdError, allDeliveredAssetIds, canonicalizeParameters, collectAllReferences, compareCodeUnits, computeLibraryMembership, flatLibraryIssues, folderOfRawPath, materializeLibrary, mergePackages, normalizeFolderPath, parentFolderPath, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, serializeLibrary, typesForFileName } from '../core/index.js';
|
|
11
11
|
import { LibraryStore } from './library-store.js';
|
|
12
|
-
import { generateManifestModules, locateGeneratedAssetDeclaration, manifestModuleFileName } from './codegen.js';
|
|
12
|
+
import { generateManifestModules, locateGeneratedAssetDeclaration, manifestModuleCollisionIssues, manifestModuleFileName } from './codegen.js';
|
|
13
|
+
import { packageSlotFindings } from './check.js';
|
|
13
14
|
import { descriptorsByType, serverPluginForType, serverPluginsByType } from './plugins.js';
|
|
14
15
|
import { processAssets, readCurrentProxy } from './processing/processor.js';
|
|
15
16
|
import { encodeRelativePathForUrl } from './folder-filesystem.js';
|
|
@@ -52,6 +53,18 @@ function figmaSlicePixelRatio(raw, type) {
|
|
|
52
53
|
return undefined;
|
|
53
54
|
return validateFigmaSourceParameters(raw.importSource.parameters).scale;
|
|
54
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* The Fundus tag of a Figma tag-mode import source, else null. In tag mode the
|
|
58
|
+
* tag IS the asset id, so this is the single seam that ties provenance to
|
|
59
|
+
* identity — used to assert id equality on import/reimport and to forbid
|
|
60
|
+
* renaming a tag-referenced asset. Only Figma sources are inspected.
|
|
61
|
+
*/
|
|
62
|
+
function figmaTagOf(importSource) {
|
|
63
|
+
if (importSource?.importer !== 'figma')
|
|
64
|
+
return null;
|
|
65
|
+
const params = validateFigmaSourceParameters(importSource.parameters);
|
|
66
|
+
return params.mode === 'tag' ? params.fundusTag : null;
|
|
67
|
+
}
|
|
55
68
|
export class FundusOperations {
|
|
56
69
|
#config;
|
|
57
70
|
#registry;
|
|
@@ -358,6 +371,10 @@ export class FundusOperations {
|
|
|
358
371
|
});
|
|
359
372
|
return this.#enqueueOperation(async () => {
|
|
360
373
|
this.#validateImportedRaw(raw, options.importer);
|
|
374
|
+
const tag = figmaTagOf(raw.importSource);
|
|
375
|
+
if (tag !== null && tag !== options.id) {
|
|
376
|
+
throw new SourceImportError('invalid-input', `A Figma tag import must use its tag as the asset id: the tag is "${tag}", not "${options.id}".`);
|
|
377
|
+
}
|
|
361
378
|
return this.#createImportedAsset(raw, options);
|
|
362
379
|
});
|
|
363
380
|
}
|
|
@@ -398,6 +415,10 @@ export class FundusOperations {
|
|
|
398
415
|
}
|
|
399
416
|
return this.#enqueueOperation(async () => {
|
|
400
417
|
this.#validateImportedRaw(raw, snapshot.importer.kind);
|
|
418
|
+
const tag = figmaTagOf(raw.importSource);
|
|
419
|
+
if (tag !== null && tag !== id) {
|
|
420
|
+
throw new SourceImportError('invalid-input', `A Figma tag reimport may not retarget asset "${id}" to a different tag "${tag}".`);
|
|
421
|
+
}
|
|
401
422
|
const plugin = serverPluginForType(snapshot.expected.type, this.#registry);
|
|
402
423
|
if (!plugin.descriptor.accepts.includes(raw.extension)) {
|
|
403
424
|
throw new SourceImportError('invalid-response', `The ${snapshot.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
@@ -457,6 +478,10 @@ export class FundusOperations {
|
|
|
457
478
|
const importSource = raw.importSource;
|
|
458
479
|
return this.#enqueueOperation(async () => {
|
|
459
480
|
this.#validateImportedRaw(raw, preflight.importer.kind);
|
|
481
|
+
const tag = figmaTagOf(importSource);
|
|
482
|
+
if (tag !== null && tag !== id) {
|
|
483
|
+
throw new SourceImportError('invalid-input', `A Figma tag replacement must use its own tag as the asset id: the tag is "${tag}", not "${id}".`);
|
|
484
|
+
}
|
|
460
485
|
const plugin = serverPluginForType(preflight.expected.type, this.#registry);
|
|
461
486
|
if (!plugin.descriptor.accepts.includes(raw.extension)) {
|
|
462
487
|
throw new SourceImportError('invalid-response', `The ${preflight.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
@@ -485,40 +510,155 @@ export class FundusOperations {
|
|
|
485
510
|
}
|
|
486
511
|
});
|
|
487
512
|
}
|
|
513
|
+
/**
|
|
514
|
+
* Edit a Figma tag asset's tag, fileKey, and/or scale in place. Because in tag
|
|
515
|
+
* mode the tag IS the asset id, changing the tag renames the asset (moves the
|
|
516
|
+
* library key); changing only fileKey/scale is an in-place re-point. Mirrors
|
|
517
|
+
* `reimportAsset`'s three phases: preflight in the queue, materialize outside
|
|
518
|
+
* it, then commit atomically through `store.repointTagAsset`.
|
|
519
|
+
*/
|
|
520
|
+
async retagFigmaAsset(id, input) {
|
|
521
|
+
const snapshot = await this.#enqueueOperation(async () => {
|
|
522
|
+
const library = await this.#store.read();
|
|
523
|
+
this.#requireAsset(library, id);
|
|
524
|
+
const record = library.assets[id];
|
|
525
|
+
const currentTag = figmaTagOf(record.importSource);
|
|
526
|
+
if (currentTag === null || !record.importSource) {
|
|
527
|
+
throw new SourceImportError('invalid-input', `Asset "${id}" is not a Figma tag import.`);
|
|
528
|
+
}
|
|
529
|
+
const current = validateFigmaSourceParameters(record.importSource.parameters);
|
|
530
|
+
const newTag = input.tag ?? currentTag;
|
|
531
|
+
const fileKey = input.fileKey ?? current.fileKey;
|
|
532
|
+
const scale = input.scale ?? current.scale;
|
|
533
|
+
if (newTag !== id) {
|
|
534
|
+
const problem = assetIdError(newTag);
|
|
535
|
+
if (problem)
|
|
536
|
+
throw new SourceImportError('invalid-input', problem);
|
|
537
|
+
if (Object.hasOwn(library.assets, newTag)) {
|
|
538
|
+
throw new SourceImportError('invalid-input', `An asset with id "${newTag}" already exists.`);
|
|
539
|
+
}
|
|
540
|
+
// A tag change renames the asset; reject one that would dangle references.
|
|
541
|
+
const candidate = structuredClone(library);
|
|
542
|
+
candidate.assets[newTag] = candidate.assets[id];
|
|
543
|
+
delete candidate.assets[id];
|
|
544
|
+
await this.#assertNoIntroducedIssues(library, candidate);
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
await verifyStableRawFile(join(this.#config.rawDir, record.raw), record.rawHash);
|
|
548
|
+
}
|
|
549
|
+
catch {
|
|
550
|
+
throw new SourceImportError('stale-import', 'The local raw file changed. Apply or discard that edit before retagging.');
|
|
551
|
+
}
|
|
552
|
+
const importer = this.#importers.require('figma');
|
|
553
|
+
return {
|
|
554
|
+
importer,
|
|
555
|
+
input: importer.validateInput({ mode: 'tag', tag: newTag, fileKey, scale, format: 'png' }),
|
|
556
|
+
newTag,
|
|
557
|
+
expected: {
|
|
558
|
+
raw: record.raw,
|
|
559
|
+
rawHash: record.rawHash,
|
|
560
|
+
type: record.type,
|
|
561
|
+
canonicalSource: canonicalizeParameters(record.importSource)
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
});
|
|
565
|
+
const raw = await snapshot.importer.importRaw(snapshot.input, {
|
|
566
|
+
config: this.#config,
|
|
567
|
+
fetch: globalThis.fetch
|
|
568
|
+
});
|
|
569
|
+
if (!raw.importSource) {
|
|
570
|
+
throw new SourceImportError('invalid-response', 'The Figma importer did not return provenance for the retagged source.');
|
|
571
|
+
}
|
|
572
|
+
const importSource = raw.importSource;
|
|
573
|
+
return this.#enqueueOperation(async () => {
|
|
574
|
+
this.#validateImportedRaw(raw, snapshot.importer.kind);
|
|
575
|
+
if (figmaTagOf(importSource) !== snapshot.newTag) {
|
|
576
|
+
throw new SourceImportError('invalid-response', `The Figma importer resolved a different tag than "${snapshot.newTag}".`);
|
|
577
|
+
}
|
|
578
|
+
const plugin = serverPluginForType(snapshot.expected.type, this.#registry);
|
|
579
|
+
if (!plugin.descriptor.accepts.includes(raw.extension)) {
|
|
580
|
+
throw new SourceImportError('invalid-response', `The ${snapshot.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
581
|
+
}
|
|
582
|
+
// A retag may change the export scale, so always sync a slice's pixel ratio.
|
|
583
|
+
const pixelRatio = figmaSlicePixelRatio(raw, snapshot.expected.type);
|
|
584
|
+
let library;
|
|
585
|
+
try {
|
|
586
|
+
library = await this.#store.repointTagAsset(id, snapshot.newTag, raw.bytes, snapshot.expected, importSource, pixelRatio === undefined
|
|
587
|
+
? undefined
|
|
588
|
+
: (parameters) => plugin.descriptor.validateParameters(mergeParameterPatch(parameters, { pixelRatio })));
|
|
589
|
+
}
|
|
590
|
+
catch (cause) {
|
|
591
|
+
if (cause instanceof Error && cause.message === 'stale-import') {
|
|
592
|
+
throw new SourceImportError('stale-import', 'The asset or local raw file changed while Figma was exporting. Nothing was changed.');
|
|
593
|
+
}
|
|
594
|
+
throw cause;
|
|
595
|
+
}
|
|
596
|
+
return this.#afterMutation(library);
|
|
597
|
+
});
|
|
598
|
+
}
|
|
488
599
|
async #createImportedAsset(raw, options) {
|
|
489
600
|
this.#validateImportedRaw(raw);
|
|
490
601
|
const fileName = raw.suggestedFileName ?? `${options.id}.${raw.extension}`;
|
|
491
602
|
const plugin = serverPluginForType(options.type, this.#registry);
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (plugin.seedIngestParameters) {
|
|
503
|
-
const seeded = await plugin.seedIngestParameters({
|
|
504
|
-
rawPath,
|
|
505
|
-
rawFileName,
|
|
506
|
-
parameters: next,
|
|
507
|
-
config: this.#config
|
|
508
|
-
});
|
|
509
|
-
if (seeded !== undefined)
|
|
510
|
-
next = seeded;
|
|
511
|
-
}
|
|
512
|
-
// Source scale is a default: an explicit parametersPatch below still wins.
|
|
603
|
+
// Filling a Package slot writes a host override that inherits the Package's
|
|
604
|
+
// parameters via the deep merge, so the override is partial. Byte-derived
|
|
605
|
+
// fields the Package can't author — the slice pixelRatio from the import
|
|
606
|
+
// scale — must still be supplied here; an explicit patch then wins.
|
|
607
|
+
const packageBase = this.#packageBase(await this.#store.read(), options.id);
|
|
608
|
+
if (packageBase && packageBase.type !== options.type) {
|
|
609
|
+
throw new SourceImportError('invalid-input', `Filling slot "${options.id}" requires the package type "${packageBase.type}", not "${options.type}".`);
|
|
610
|
+
}
|
|
611
|
+
let slotOverride = {};
|
|
612
|
+
if (packageBase) {
|
|
513
613
|
const pixelRatio = figmaSlicePixelRatio(raw, options.type);
|
|
514
614
|
if (pixelRatio !== undefined) {
|
|
515
|
-
|
|
615
|
+
slotOverride = mergeParameterPatch(slotOverride, { pixelRatio });
|
|
516
616
|
}
|
|
517
617
|
if (options.parametersPatch !== undefined) {
|
|
518
|
-
|
|
618
|
+
slotOverride = mergeParameterPatch(slotOverride, options.parametersPatch);
|
|
519
619
|
}
|
|
520
|
-
|
|
521
|
-
|
|
620
|
+
}
|
|
621
|
+
const library = packageBase
|
|
622
|
+
? await this.#store.createAsset({
|
|
623
|
+
fileName,
|
|
624
|
+
bytes: raw.bytes,
|
|
625
|
+
type: options.type,
|
|
626
|
+
id: options.id,
|
|
627
|
+
folder: options.folder,
|
|
628
|
+
manifests: options.manifests,
|
|
629
|
+
importSource: raw.importSource,
|
|
630
|
+
parametersOverride: slotOverride
|
|
631
|
+
})
|
|
632
|
+
: await this.#store.createAsset({
|
|
633
|
+
fileName,
|
|
634
|
+
bytes: raw.bytes,
|
|
635
|
+
type: options.type,
|
|
636
|
+
id: options.id,
|
|
637
|
+
folder: options.folder,
|
|
638
|
+
manifests: options.manifests,
|
|
639
|
+
importSource: raw.importSource
|
|
640
|
+
}, async ({ rawPath, rawFileName, parameters }) => {
|
|
641
|
+
let next = parameters;
|
|
642
|
+
if (plugin.seedIngestParameters) {
|
|
643
|
+
const seeded = await plugin.seedIngestParameters({
|
|
644
|
+
rawPath,
|
|
645
|
+
rawFileName,
|
|
646
|
+
parameters: next,
|
|
647
|
+
config: this.#config
|
|
648
|
+
});
|
|
649
|
+
if (seeded !== undefined)
|
|
650
|
+
next = seeded;
|
|
651
|
+
}
|
|
652
|
+
// Source scale is a default: an explicit parametersPatch below still wins.
|
|
653
|
+
const pixelRatio = figmaSlicePixelRatio(raw, options.type);
|
|
654
|
+
if (pixelRatio !== undefined) {
|
|
655
|
+
next = mergeParameterPatch(next, { pixelRatio });
|
|
656
|
+
}
|
|
657
|
+
if (options.parametersPatch !== undefined) {
|
|
658
|
+
next = mergeParameterPatch(next, options.parametersPatch);
|
|
659
|
+
}
|
|
660
|
+
return plugin.descriptor.validateParameters(next);
|
|
661
|
+
});
|
|
522
662
|
return this.#afterMutation(library);
|
|
523
663
|
}
|
|
524
664
|
#validateImportTarget(options, library) {
|
|
@@ -543,8 +683,10 @@ export class FundusOperations {
|
|
|
543
683
|
options.manifests.some((value) => typeof value !== 'string'))) {
|
|
544
684
|
throw new SourceImportError('invalid-input', 'Import manifests must be an array of strings.');
|
|
545
685
|
}
|
|
686
|
+
// A placement may target a Package-introduced manifest (host + package union).
|
|
687
|
+
const validManifests = this.#effectiveOf(library).effective.manifests;
|
|
546
688
|
for (const manifest of new Set(options.manifests ?? [])) {
|
|
547
|
-
if (!Object.hasOwn(
|
|
689
|
+
if (!Object.hasOwn(validManifests, manifest)) {
|
|
548
690
|
throw new SourceImportError('invalid-input', `Unknown manifest "${manifest}".`);
|
|
549
691
|
}
|
|
550
692
|
}
|
|
@@ -568,7 +710,9 @@ export class FundusOperations {
|
|
|
568
710
|
}
|
|
569
711
|
async #patchAsset(id, body) {
|
|
570
712
|
let library = await this.#store.read();
|
|
571
|
-
|
|
713
|
+
// A pure Package asset is read-only; fill/override it by importing bytes
|
|
714
|
+
// with its id. Host assets and existing overrides patch normally.
|
|
715
|
+
this.#assertHostAsset(library, id, 'editing it');
|
|
572
716
|
if (body.parameters !== undefined) {
|
|
573
717
|
library = await this.#store.updateParameters(id, body.parameters);
|
|
574
718
|
}
|
|
@@ -689,6 +833,9 @@ export class FundusOperations {
|
|
|
689
833
|
async #renameAsset(id, newId) {
|
|
690
834
|
const library = await this.#store.read();
|
|
691
835
|
this.#requireAsset(library, id);
|
|
836
|
+
if (figmaTagOf(library.assets[id].importSource) !== null) {
|
|
837
|
+
throw new SourceImportError('invalid-input', 'This asset is referenced by a Figma tag and cannot be renamed; re-import with a new tag instead.');
|
|
838
|
+
}
|
|
692
839
|
// A collision or invalid new id is the store's own (clearer) error; the
|
|
693
840
|
// candidate check covers what the store cannot see: broken references.
|
|
694
841
|
if (newId !== id && !Object.hasOwn(library.assets, newId)) {
|
|
@@ -787,12 +934,19 @@ export class FundusOperations {
|
|
|
787
934
|
async #runAfterMutation(library) {
|
|
788
935
|
const pipelineIssues = [];
|
|
789
936
|
const classification = await this.#classifyRawDirectory(library);
|
|
790
|
-
const
|
|
937
|
+
const { effective, provenance, mergeFindings } = this.#effectiveOf(library);
|
|
938
|
+
const materialized = materializeLibrary(effective);
|
|
939
|
+
const ordinaryIssues = [
|
|
940
|
+
...(await this.#store.validate(library, { flatSpace: false })),
|
|
941
|
+
...this.#flatIssues(effective, provenance, mergeFindings)
|
|
942
|
+
];
|
|
791
943
|
const safetyIssues = this.#rawSafetyIssues(library, classification);
|
|
792
944
|
if (ordinaryIssues.length === 0 && safetyIssues.length === 0) {
|
|
793
945
|
try {
|
|
794
|
-
|
|
795
|
-
|
|
946
|
+
// Codegen runs over the merged, materialized library so the dev server
|
|
947
|
+
// writes the same modules `fundus build`/`fundus check` expect.
|
|
948
|
+
const report = await processAssets(this.#config, materialized, this.#registry);
|
|
949
|
+
await generateManifestModules(this.#config, materialized, report.proxies, this.#registry);
|
|
796
950
|
}
|
|
797
951
|
catch (cause) {
|
|
798
952
|
pipelineIssues.push({
|
|
@@ -808,13 +962,15 @@ export class FundusOperations {
|
|
|
808
962
|
state: await this.#snapshotState(latestLibrary, latestClassification, pipelineIssues)
|
|
809
963
|
};
|
|
810
964
|
}
|
|
811
|
-
async #buildState(library, issues, classification) {
|
|
965
|
+
async #buildState(host, library, provenance, issues, classification) {
|
|
812
966
|
const [gitBranch, changedGitAssets] = await Promise.all([
|
|
813
967
|
currentGitBranch(this.#config.projectRoot),
|
|
814
|
-
|
|
968
|
+
// Git diff over the host library only — Package assets are not host-owned
|
|
969
|
+
// and would otherwise all read as "new".
|
|
970
|
+
gitAssetChanges(this.#config.projectRoot, this.#config.library, host)
|
|
815
971
|
]);
|
|
816
972
|
const referencesByAsset = collectAllReferences(library, descriptorsByType(this.#registry));
|
|
817
|
-
const duplicatesByAsset = await this.#duplicateDetector.find(
|
|
973
|
+
const duplicatesByAsset = await this.#duplicateDetector.find(host, this.#config.rawDir);
|
|
818
974
|
const membershipByManifest = computeLibraryMembership(library, referencesByAsset);
|
|
819
975
|
const delivered = allDeliveredAssetIds(membershipByManifest);
|
|
820
976
|
// Per asset: the manifests it is a passive member of, with attribution.
|
|
@@ -837,6 +993,14 @@ export class FundusOperations {
|
|
|
837
993
|
const assets = [];
|
|
838
994
|
for (const assetId of Object.keys(library.assets).sort(compareCodeUnits)) {
|
|
839
995
|
const record = library.assets[assetId];
|
|
996
|
+
const prov = provenance[assetId] ?? { source: 'host' };
|
|
997
|
+
const origin = prov.source === 'host'
|
|
998
|
+
? { kind: 'host' }
|
|
999
|
+
: prov.source === 'package'
|
|
1000
|
+
? { kind: 'package', origin: prov.origin }
|
|
1001
|
+
: { kind: 'override', origin: prov.origin };
|
|
1002
|
+
// An unfilled Package slot carries no bytes.
|
|
1003
|
+
const isSlot = record.raw === undefined;
|
|
840
1004
|
const warnings = [];
|
|
841
1005
|
for (const issue of issues) {
|
|
842
1006
|
if (issue.assetId === assetId)
|
|
@@ -844,8 +1008,9 @@ export class FundusOperations {
|
|
|
844
1008
|
}
|
|
845
1009
|
// Unreachable: no explicit membership AND no passive membership in any
|
|
846
1010
|
// manifest — nothing delivers the asset. A passively delivered asset is
|
|
847
|
-
// fine (it ships inlined into its referrers) and must not warn.
|
|
848
|
-
|
|
1011
|
+
// fine (it ships inlined into its referrers) and must not warn. An inert
|
|
1012
|
+
// unfilled Package slot is not a host mistake and must not warn.
|
|
1013
|
+
if (record.manifests.length === 0 && !delivered.has(assetId) && !isSlot) {
|
|
849
1014
|
warnings.push('In no manifest and not referenced by any delivered asset — ' +
|
|
850
1015
|
'nothing is processed or generated for it.');
|
|
851
1016
|
}
|
|
@@ -853,7 +1018,7 @@ export class FundusOperations {
|
|
|
853
1018
|
warnings.push(`Importer "${record.importSource.importer}" is unavailable; the local raw file remains usable.`);
|
|
854
1019
|
}
|
|
855
1020
|
let proxy = null;
|
|
856
|
-
if (delivered.has(assetId)) {
|
|
1021
|
+
if (delivered.has(assetId) && !isSlot) {
|
|
857
1022
|
try {
|
|
858
1023
|
const currentProxy = await readCurrentProxy(assetId, record, this.#config, this.#registry);
|
|
859
1024
|
if (currentProxy) {
|
|
@@ -871,13 +1036,17 @@ export class FundusOperations {
|
|
|
871
1036
|
warnings.push(cause instanceof Error ? cause.message : String(cause));
|
|
872
1037
|
}
|
|
873
1038
|
}
|
|
1039
|
+
const raw = record.raw ?? '';
|
|
1040
|
+
const rawHash = record.rawHash ?? '';
|
|
874
1041
|
assets.push({
|
|
875
1042
|
id: assetId,
|
|
876
1043
|
type: record.type,
|
|
877
|
-
raw
|
|
878
|
-
folder: folderOfRawPath(
|
|
879
|
-
rawUrl:
|
|
880
|
-
|
|
1044
|
+
raw,
|
|
1045
|
+
folder: folderOfRawPath(raw),
|
|
1046
|
+
rawUrl: isSlot
|
|
1047
|
+
? ''
|
|
1048
|
+
: `/files/raw/${encodeRelativePathForUrl(raw)}?v=${rawHash.slice(0, 12)}`,
|
|
1049
|
+
rawHash,
|
|
881
1050
|
gitStatus: changedGitAssets.get(assetId) ?? null,
|
|
882
1051
|
importSource: record.importSource,
|
|
883
1052
|
parameters: record.parameters,
|
|
@@ -892,7 +1061,9 @@ export class FundusOperations {
|
|
|
892
1061
|
assetId: reference.assetId
|
|
893
1062
|
})),
|
|
894
1063
|
incoming: incomingByAsset.get(assetId) ?? []
|
|
895
|
-
}
|
|
1064
|
+
},
|
|
1065
|
+
origin,
|
|
1066
|
+
overridden: origin.kind === 'override'
|
|
896
1067
|
});
|
|
897
1068
|
}
|
|
898
1069
|
// Per manifest: the membership picture for the manifests view, and the
|
|
@@ -923,18 +1094,26 @@ export class FundusOperations {
|
|
|
923
1094
|
presetNames[type] = names;
|
|
924
1095
|
presetCapabilities[type] = Object.fromEntries(names.map((name) => [name, plugin.presetCapabilities?.(presets[name]) ?? {}]));
|
|
925
1096
|
}
|
|
926
|
-
const rawIngestionQueue = this.#buildRawIngestionQueue(
|
|
1097
|
+
const rawIngestionQueue = this.#buildRawIngestionQueue(host, classification);
|
|
927
1098
|
return {
|
|
928
1099
|
gitBranch,
|
|
929
1100
|
library,
|
|
930
1101
|
assets,
|
|
931
|
-
importDefaults: {
|
|
1102
|
+
importDefaults: {
|
|
1103
|
+
figma: {
|
|
1104
|
+
scale: this.#config.import.figma.defaults.scale,
|
|
1105
|
+
...(this.#config.import.figma.defaultFileKey !== undefined
|
|
1106
|
+
? { defaultFileKey: this.#config.import.figma.defaultFileKey }
|
|
1107
|
+
: {})
|
|
1108
|
+
}
|
|
1109
|
+
},
|
|
932
1110
|
issues,
|
|
933
1111
|
presetNames,
|
|
934
1112
|
presetCapabilities,
|
|
935
1113
|
manifestMemberships,
|
|
936
1114
|
manifestDeliveredBytes,
|
|
937
|
-
rawIngestionQueue
|
|
1115
|
+
rawIngestionQueue,
|
|
1116
|
+
packageOrigins: this.#config.packages.map((pkg) => pkg.origin).sort(compareCodeUnits)
|
|
938
1117
|
};
|
|
939
1118
|
}
|
|
940
1119
|
#compatibleTypes(path) {
|
|
@@ -947,8 +1126,10 @@ export class FundusOperations {
|
|
|
947
1126
|
return rawSafetyIssues(library, classification, (path) => this.#compatibleTypes(path));
|
|
948
1127
|
}
|
|
949
1128
|
async #snapshotState(library, classification, extraIssues = []) {
|
|
1129
|
+
const { effective, provenance, mergeFindings } = this.#effectiveOf(library);
|
|
950
1130
|
const issues = [
|
|
951
|
-
...(await this.#store.validate(library)),
|
|
1131
|
+
...(await this.#store.validate(library, { flatSpace: false })),
|
|
1132
|
+
...this.#flatIssues(effective, provenance, mergeFindings),
|
|
952
1133
|
...this.#rawSafetyIssues(library, classification),
|
|
953
1134
|
...extraIssues
|
|
954
1135
|
];
|
|
@@ -960,7 +1141,7 @@ export class FundusOperations {
|
|
|
960
1141
|
seen.add(key);
|
|
961
1142
|
return true;
|
|
962
1143
|
});
|
|
963
|
-
return this.#buildState(library, uniqueIssues, classification);
|
|
1144
|
+
return this.#buildState(library, effective, provenance, uniqueIssues, classification);
|
|
964
1145
|
}
|
|
965
1146
|
#canAutoReconcile(classification, retry = false) {
|
|
966
1147
|
return (classification.complete &&
|
|
@@ -1066,6 +1247,60 @@ export class FundusOperations {
|
|
|
1066
1247
|
throw new Error(`Unknown asset "${id}".`);
|
|
1067
1248
|
}
|
|
1068
1249
|
}
|
|
1250
|
+
/** Merge the configured Packages under the host library (host wins). */
|
|
1251
|
+
#effectiveOf(host) {
|
|
1252
|
+
const { library, provenance, findings } = mergePackages(host, this.#config.packages ?? []);
|
|
1253
|
+
return { effective: library, provenance, mergeFindings: findings };
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* The Package base record for `id` when `id` is a read-only Package asset the
|
|
1257
|
+
* host has not yet filled — i.e. this create is a *slot fill*. Returns null
|
|
1258
|
+
* for a plain new host asset.
|
|
1259
|
+
*/
|
|
1260
|
+
#packageBase(host, id) {
|
|
1261
|
+
if (Object.hasOwn(host.assets, id))
|
|
1262
|
+
return null;
|
|
1263
|
+
const { effective, provenance } = this.#effectiveOf(host);
|
|
1264
|
+
if (provenance[id]?.source === 'package')
|
|
1265
|
+
return { type: effective.assets[id].type };
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Flat-space validation over the effective library: merge errors, id/type/
|
|
1270
|
+
* parameter/membership/appearance/reference checks, module collisions, and
|
|
1271
|
+
* delivered-slot findings. Disk/host checks stay in `store.validate(host,
|
|
1272
|
+
* { flatSpace: false })`.
|
|
1273
|
+
*/
|
|
1274
|
+
#flatIssues(effective, provenance, mergeFindings) {
|
|
1275
|
+
const referencesByAsset = collectAllReferences(effective, descriptorsByType(this.#registry));
|
|
1276
|
+
const membership = computeLibraryMembership(effective, referencesByAsset);
|
|
1277
|
+
return [
|
|
1278
|
+
...mergeFindings
|
|
1279
|
+
.filter((finding) => finding.kind !== 'package-overridden')
|
|
1280
|
+
.map((finding) => ({ assetId: finding.assetId, message: finding.message })),
|
|
1281
|
+
...flatLibraryIssues(effective, descriptorsByType(this.#registry)),
|
|
1282
|
+
...manifestModuleCollisionIssues(effective.manifests),
|
|
1283
|
+
...packageSlotFindings(effective, provenance, membership).map((finding) => ({
|
|
1284
|
+
assetId: finding.assetId,
|
|
1285
|
+
message: finding.message
|
|
1286
|
+
}))
|
|
1287
|
+
];
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Whether an id is a read-only Package asset the host has not overridden.
|
|
1291
|
+
* Such ids can be filled/overridden (write a host record) but not mutated,
|
|
1292
|
+
* renamed, moved, or deleted in place.
|
|
1293
|
+
*/
|
|
1294
|
+
#assertHostAsset(host, id, action) {
|
|
1295
|
+
if (Object.hasOwn(host.assets, id))
|
|
1296
|
+
return;
|
|
1297
|
+
const { provenance } = this.#effectiveOf(host);
|
|
1298
|
+
const prov = provenance[id];
|
|
1299
|
+
if (prov && prov.source !== 'host') {
|
|
1300
|
+
throw new Error(`Asset "${id}" is provided by package "${prov.origin}"; ${action} is not available. Override it by importing or uploading bytes with this id.`);
|
|
1301
|
+
}
|
|
1302
|
+
throw new Error(`Unknown asset "${id}".`);
|
|
1303
|
+
}
|
|
1069
1304
|
/**
|
|
1070
1305
|
* Apply a CLI asset change to the store, validating the resulting library
|
|
1071
1306
|
* on an in-memory candidate first — nothing is persisted when the change
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.submenu-anchor.svelte-13hq4tl{position:relative}button.svelte-13hq4tl{width:100%;color:var(--text);font:inherit;text-align:left;white-space:nowrap;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-13hq4tl:hover,button.svelte-13hq4tl:focus-visible{background:var(--accent-soft);outline:none}.submenu-anchor.svelte-13hq4tl:has(.submenu:where(.svelte-13hq4tl))>.submenu-trigger:where(.svelte-13hq4tl){background:var(--accent-soft);outline:none}button.svelte-13hq4tl:disabled{color:var(--text-faint);background:0 0}.submenu-trigger.svelte-13hq4tl{justify-content:space-between;align-items:center;gap:12px;display:flex}.arrow.svelte-13hq4tl{color:var(--text-faint);font-size:16px;line-height:12px}.submenu.svelte-13hq4tl{z-index:1;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;min-width:168px;max-width:320px;padding:4px;position:absolute;top:-5px;left:calc(100% - 4px);overflow-y:auto;box-shadow:0 8px 24px #00000073}.submenu.opens-left.svelte-13hq4tl{left:auto;right:calc(100% - 4px)}.submenu.svelte-13hq4tl button:where(.svelte-13hq4tl){text-overflow:ellipsis;overflow:hidden}hr.svelte-13hq4tl{background:var(--border);border:0;height:1px;margin:4px 8px}.context-menu.svelte-109nkvw{z-index:200;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;width:168px;padding:4px;position:fixed;box-shadow:0 8px 24px #00000073}button.svelte-109nkvw{width:100%;color:var(--text);font:inherit;text-align:left;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-109nkvw:hover,button.svelte-109nkvw:focus-visible{background:var(--accent-soft);outline:none}button.danger.svelte-109nkvw{color:var(--danger)}hr.svelte-109nkvw{background:var(--border);border:0;height:1px;margin:4px 8px}.manifest-label.svelte-1b4m5oj{align-items:center;gap:4px;min-width:0;display:inline-flex}.emoji.svelte-1b4m5oj{flex:none;line-height:1}.name.svelte-1b4m5oj{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.chip.svelte-1b4m5oj{background:color-mix(in srgb, var(--manifest-color) 20%, transparent);color:var(--manifest-color);border-radius:4px;padding:0 5px;font-size:10px}.chip.passive.svelte-1b4m5oj{border:1px dashed var(--manifest-color);background:0 0}.browse-select.svelte-dr99ka{border-radius:4px;align-items:center;min-width:0;height:24px;padding:0 6px 0 0;display:inline-flex}.browse-select.svelte-dr99ka:focus-within{border-color:var(--accent)}.browse-select.filter-active.svelte-dr99ka{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}.browse-select.filter-active.svelte-dr99ka .icon-slot:where(.svelte-dr99ka){color:var(--accent)}.icon-slot.svelte-dr99ka{width:24px;height:24px;color:var(--text-dim);-webkit-user-select:none;user-select:none;flex:none;justify-content:center;align-items:center;display:flex}select.svelte-dr99ka{background:0 0;border:0;outline:none;min-width:0;height:100%;margin:0;padding:0 6px 0 0}.filter-field .popover-anchor{width:100%}.multi-select-trigger.svelte-1yxb8yh{text-align:left;border-radius:4px;align-items:center;gap:5px;width:100%;min-width:0;height:24px;padding:0 6px 0 0;display:flex}.multi-select-trigger.filter-active.svelte-1yxb8yh{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}.icon-slot.svelte-1yxb8yh{width:24px;height:24px;color:var(--text-dim);flex:none;place-items:center;display:grid}.filter-active.svelte-1yxb8yh .icon-slot:where(.svelte-1yxb8yh){color:var(--accent)}.summary.svelte-1yxb8yh{min-width:0;color:var(--text);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.filter-active.svelte-1yxb8yh .summary:where(.svelte-1yxb8yh){color:var(--accent)}.selected-count.svelte-1yxb8yh{background:var(--accent);min-width:15px;height:15px;color:var(--text);border-radius:999px;flex:none;place-items:center;padding:0 4px;font-size:9px;font-weight:700;display:grid}.multi-select-menu.svelte-1yxb8yh{width:max(160px, var(--multi-select-width,100%));min-width:160px}.menu-header.svelte-1yxb8yh{border-bottom:1px solid var(--border-soft);color:var(--text-dim);justify-content:space-between;align-items:center;gap:12px;padding:1px 4px 6px;font-size:10px;display:flex}.menu-header.svelte-1yxb8yh button:where(.svelte-1yxb8yh){color:var(--accent);font:inherit;background:0 0;border:0;padding:1px 2px}.menu-header.svelte-1yxb8yh button:where(.svelte-1yxb8yh):disabled{opacity:.4;cursor:default}.options.svelte-1yxb8yh{max-height:224px;padding-top:4px;overflow-y:auto}.options.svelte-1yxb8yh label:where(.svelte-1yxb8yh){border-radius:var(--radius-small);min-width:0;height:26px;color:var(--text);cursor:pointer;align-items:center;gap:7px;padding:0 5px;display:flex}.options.svelte-1yxb8yh label:where(.svelte-1yxb8yh):hover,.options.svelte-1yxb8yh label:where(.svelte-1yxb8yh):focus-within{background:var(--accent-soft)}.options.svelte-1yxb8yh label.selected:where(.svelte-1yxb8yh){color:var(--accent)}.options.svelte-1yxb8yh input:where(.svelte-1yxb8yh){width:12px;height:12px;accent-color:var(--accent);flex:none;margin:0}.options.svelte-1yxb8yh span:where(.svelte-1yxb8yh){text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.browse-checkbox.svelte-sa6meb{cursor:pointer;align-items:center;min-width:0;height:24px;display:inline-flex}.browse-checkbox.svelte-sa6meb:focus-within .value:where(.svelte-sa6meb){color:var(--accent)}.icon-slot.svelte-sa6meb{-webkit-user-select:none;user-select:none;flex:none;justify-content:center;align-items:center;width:24px;height:24px;display:flex}.value.svelte-sa6meb{min-width:0;color:var(--text);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:11px;line-height:14px;overflow:hidden}input.svelte-sa6meb{width:12px;height:12px;accent-color:var(--accent);margin:0}.library-view.svelte-1uha8ag{flex:1;min-height:0;display:flex}.page.svelte-1uha8ag{flex:1;min-height:0;padding:16px;position:relative;overflow-y:auto}.library-toolbar.svelte-1uha8ag{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:16px;display:flex}.library-toolbar.svelte-1uha8ag .control{border-radius:var(--radius-small);height:24px}.selection-controls.svelte-1uha8ag{align-items:center;gap:8px;display:inline-flex}.selection-action.svelte-1uha8ag:disabled{opacity:.45;cursor:default}.selection-action.svelte-1uha8ag{justify-content:center;align-items:center;display:inline-flex}.selection-summary.svelte-1uha8ag{color:var(--accent);white-space:nowrap;font-weight:600}.preview-size-control.svelte-1uha8ag{height:24px;color:var(--text-dim);cursor:default;align-items:center;gap:6px;margin-left:auto;padding:0 7px;display:inline-flex}.preview-size-icon.svelte-1uha8ag{fill:currentColor;flex:none;width:14px;height:14px}.preview-size-icon.dense.svelte-1uha8ag{color:var(--text-faint)}.preview-size-icon.dense.svelte-1uha8ag rect:where(.svelte-1uha8ag){rx:.75px;width:3px;height:3px}.preview-size-icon.roomy.svelte-1uha8ag rect:where(.svelte-1uha8ag){rx:1.25px}.preview-size-range.svelte-1uha8ag{appearance:none;cursor:pointer;background:0 0;flex:none;width:104px;height:14px;margin:0;padding:0}.preview-size-range.svelte-1uha8ag::-webkit-slider-runnable-track{background:linear-gradient(to right, var(--accent) 0 var(--preview-size-progress), var(--border) var(--preview-size-progress) 100%);border-radius:999px;height:3px}.preview-size-range.svelte-1uha8ag::-moz-range-track{background:var(--border);border-radius:999px;height:3px}.preview-size-range.svelte-1uha8ag::-moz-range-progress{background:var(--accent);border-radius:999px;height:3px}.preview-size-range.svelte-1uha8ag::-webkit-slider-thumb{border:2px solid var(--panel-raised);appearance:none;background:var(--accent);width:12px;height:12px;box-shadow:0 0 0 1px var(--accent);border-radius:50%;margin-top:-4.5px}.preview-size-range.svelte-1uha8ag::-moz-range-thumb{border:2px solid var(--panel-raised);background:var(--accent);width:8px;height:8px;box-shadow:0 0 0 1px var(--accent);border-radius:50%}.preview-size-range.svelte-1uha8ag:focus-visible{outline:none}.preview-size-range.svelte-1uha8ag:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 1px var(--accent), 0 0 0 4px var(--accent-soft)}.preview-size-range.svelte-1uha8ag:focus-visible::-moz-range-thumb{box-shadow:0 0 0 1px var(--accent), 0 0 0 4px var(--accent-soft)}.search.svelte-1uha8ag{flex:0 0 240px;align-items:center;gap:4px;width:240px;min-width:200px;height:24px;padding:0 6px 0 0;display:flex}.search.svelte-1uha8ag:focus-within{border-color:var(--accent)}.search.filter-active.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft)}.search.filter-active.svelte-1uha8ag .search-icon-slot:where(.svelte-1uha8ag),.search.filter-active.svelte-1uha8ag kbd:where(.svelte-1uha8ag){color:var(--accent)}.search.filter-active.svelte-1uha8ag kbd:where(.svelte-1uha8ag){border-color:var(--accent)}.search-icon-slot.svelte-1uha8ag{width:24px;height:24px;color:var(--text-dim);flex:none;justify-content:center;align-items:center;display:flex}.search-icon.svelte-1uha8ag{fill:none;stroke:currentColor;stroke-width:1.5px;stroke-linecap:round;flex:none;width:14px;height:14px}.search-input.svelte-1uha8ag{min-width:0;height:100%;color:var(--text);font:inherit;background:0 0;border:0;outline:none;flex:1;padding:0}.search-input.svelte-1uha8ag::-webkit-search-cancel-button{appearance:none;background:var(--text-dim);cursor:pointer;width:12px;height:12px;margin:0;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='m3 3 8 8m0-8-8 8' fill='none' stroke='black' stroke-linecap='round' stroke-width='2.25'/%3E%3C/svg%3E") 50%/12px 12px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='m3 3 8 8m0-8-8 8' fill='none' stroke='black' stroke-linecap='round' stroke-width='2.25'/%3E%3C/svg%3E") 50%/12px 12px no-repeat}.search.filter-active.svelte-1uha8ag .search-input:where(.svelte-1uha8ag)::-webkit-search-cancel-button{background:var(--accent)}.search.svelte-1uha8ag kbd:where(.svelte-1uha8ag){border:1px solid var(--border);color:var(--text-faint);border-radius:3px;flex:none;padding:1px 4px;font:9px/14px system-ui,sans-serif}.toolbar-button.svelte-1uha8ag,.import-trigger.svelte-1uha8ag{white-space:nowrap;justify-content:center;align-items:center;gap:6px;display:inline-flex}.toolbar-button.active.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}.filter-count.svelte-1uha8ag{background:var(--accent);min-width:16px;height:16px;color:var(--text);border-radius:999px;place-items:center;padding:0 4px;font-size:10px;font-weight:700;display:inline-grid}.filters-popover.svelte-1uha8ag{width:min(480px,100vw - 24px)}.popover-header.svelte-1uha8ag{border-bottom:1px solid var(--border-soft);justify-content:space-between;align-items:center;gap:16px;padding:2px 2px 10px;display:flex}.popover-header.svelte-1uha8ag strong:where(.svelte-1uha8ag){color:var(--text);font-size:11px;font-weight:400}.clear-filters.svelte-1uha8ag{color:var(--accent);font:inherit;background:0 0;border:0;padding:2px 4px;font-size:11px}.clear-filters.svelte-1uha8ag:disabled{opacity:.4;cursor:default}.filter-grid.svelte-1uha8ag{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;padding:10px 2px;display:grid}.filter-field.svelte-1uha8ag{flex-direction:column;gap:4px;min-width:0;display:flex}.filter-field.svelte-1uha8ag>span:where(.svelte-1uha8ag){color:#ffffffb2;letter-spacing:.27px;-webkit-user-select:none;user-select:none;font-size:9px;font-weight:500;line-height:14px}.filter-field.svelte-1uha8ag .browse-select,.filter-field.svelte-1uha8ag .browse-checkbox{width:100%}.filter-field.svelte-1uha8ag .browse-select select{flex:1;width:100%}.filter-options-grid.svelte-1uha8ag{padding-top:0;padding-bottom:2px}.filter-options-grid.svelte-1uha8ag .browse-checkbox,.filter-options-grid.svelte-1uha8ag .browse-checkbox .icon-slot{height:14px}.filter-options-grid.svelte-1uha8ag .browse-checkbox .icon-slot{justify-content:flex-start;align-items:flex-start;width:18px}@media (width<=560px){.filter-grid.svelte-1uha8ag{grid-template-columns:1fr}}@media (width<=1056px){.search.svelte-1uha8ag{flex-basis:100%;order:10;width:100%}}.section.svelte-1uha8ag{margin-bottom:24px}.section.svelte-1uha8ag:last-child{margin-bottom:0}.section-emoji.svelte-1uha8ag{margin-right:6px}.grid.svelte-1uha8ag,.folder-grid.svelte-1uha8ag{gap:8px;display:grid}.grid.svelte-1uha8ag{grid-template-columns:repeat(auto-fill, minmax(min(100%, var(--preview-card-width)), 1fr))}.folder-grid.svelte-1uha8ag{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}.folder-card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);min-width:0;height:60px;color:var(--text);text-align:left;border-radius:8px;align-items:center;gap:10px;padding:8px 10px;display:flex}.folder-card.svelte-1uha8ag:hover,.folder-card.svelte-1uha8ag:focus-visible{border-color:var(--accent);outline:none}.folder-card.drop-target.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent)}.folder-card.dragging-folder.svelte-1uha8ag{opacity:.55}.folder-card-icon.svelte-1uha8ag{color:var(--text-dim);flex:none;align-items:center;display:flex}.folder-card-details.svelte-1uha8ag{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.folder-card-details.svelte-1uha8ag strong:where(.svelte-1uha8ag){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.folder-card-details.svelte-1uha8ag span:where(.svelte-1uha8ag),.folder-card-arrow.svelte-1uha8ag{color:var(--text-faint)}.folder-card-arrow.svelte-1uha8ag{flex:none;font-size:18px}.card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);border-radius:8px;flex-direction:column;gap:clamp(4px,5cqi,8px);padding:clamp(4px,5cqi,8px);display:flex;position:relative;container-type:inline-size}.card.selected.svelte-1uha8ag{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.asset-select.svelte-1uha8ag{z-index:1;width:16px;height:16px;accent-color:var(--accent);position:absolute;top:clamp(6px,8cqi,12px);left:clamp(6px,8cqi,12px)}.card.svelte-1uha8ag:hover{border-color:var(--accent)}.thumbnail.svelte-1uha8ag{width:100%;height:min(var(--preview-card-height), 66.667cqi);border-radius:var(--radius);justify-content:center;align-items:center;display:flex;overflow:hidden}.meta.svelte-1uha8ag{align-items:center;gap:6px;min-width:0;display:flex}.id.svelte-1uha8ag{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.type-badge.svelte-1uha8ag{color:var(--text-dim);border:1px solid var(--border);border-radius:4px;flex:none;margin-left:auto;padding:0 5px;font-size:10px}.badges.svelte-1uha8ag{flex-wrap:wrap;gap:4px;min-height:16px;display:flex}.badge.svelte-1uha8ag{border-radius:4px;padding:0 5px;font-size:10px}.badge.warning.svelte-1uha8ag{background:var(--warning-soft);color:var(--warning)}@container (width<=109px){.type-badge.svelte-1uha8ag{display:none}.badges.svelte-1uha8ag{flex-wrap:nowrap;overflow:hidden}}@container (width<=79px){.card.svelte-1uha8ag>.overlay{background:var(--accent);border:0;width:6px;height:6px;padding:0;font-size:0;top:5px;left:auto;right:5px;transform:none}.card.svelte-1uha8ag>.overlay.edited{background:var(--warning)}.asset-select.svelte-1uha8ag{width:8px;height:8px;top:0;left:0;transform:translate(-8%,8%)}.meta.svelte-1uha8ag,.badges.svelte-1uha8ag{display:none}}.empty.svelte-1uha8ag{color:var(--text-dim);text-align:center;padding:48px}.dialog-row.svelte-1uha8ag{align-items:center;gap:8px;display:flex}.dialog-row.svelte-1uha8ag span:where(.svelte-1uha8ag){width:44px;color:var(--text-dim)}.dialog-row.svelte-1uha8ag input:where(.svelte-1uha8ag){flex:1}.dialog-text.svelte-1uha8ag,.dialog-warning.svelte-1uha8ag{margin:8px 0 0}.dialog-warning.svelte-1uha8ag{color:var(--warning)}.drop-hint.svelte-1uha8ag{border:2px dashed var(--accent);color:var(--accent);pointer-events:none;background:#0d99ff14;border-radius:12px;justify-content:center;align-items:center;font-size:14px;display:flex;position:fixed;inset:48px 8px 8px}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|