fundus 0.9.1 → 0.11.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 +64 -0
- package/build/client/_app/immutable/assets/2.6TBn1n3x.css +1 -0
- package/build/client/_app/immutable/assets/2.6TBn1n3x.css.br +0 -0
- package/build/client/_app/immutable/assets/2.6TBn1n3x.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.BuCXJbRG.css +1 -0
- package/build/client/_app/immutable/assets/3.BuCXJbRG.css.br +0 -0
- package/build/client/_app/immutable/assets/3.BuCXJbRG.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.C0QkCMQ4.css +1 -0
- package/build/client/_app/immutable/assets/4.C0QkCMQ4.css.br +0 -0
- package/build/client/_app/immutable/assets/4.C0QkCMQ4.css.gz +0 -0
- package/build/client/_app/immutable/assets/Popover.Et4sBRbI.css +1 -0
- package/build/client/_app/immutable/assets/Popover.Et4sBRbI.css.br +0 -0
- package/build/client/_app/immutable/assets/Popover.Et4sBRbI.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BAva9YXm.js +1 -0
- package/build/client/_app/immutable/chunks/BAva9YXm.js.br +0 -0
- package/build/client/_app/immutable/chunks/BAva9YXm.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BGAUmugt.js +1 -0
- package/build/client/_app/immutable/chunks/BGAUmugt.js.br +0 -0
- package/build/client/_app/immutable/chunks/BGAUmugt.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BMORe2Gb.js +3 -0
- package/build/client/_app/immutable/chunks/BMORe2Gb.js.br +0 -0
- package/build/client/_app/immutable/chunks/BMORe2Gb.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CBygkKLq.js +1 -0
- package/build/client/_app/immutable/chunks/CBygkKLq.js.br +0 -0
- package/build/client/_app/immutable/chunks/CBygkKLq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cil0r9BR.js +108 -0
- package/build/client/_app/immutable/chunks/Cil0r9BR.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cil0r9BR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D-p-QSzz.js +1 -0
- package/build/client/_app/immutable/chunks/D-p-QSzz.js.br +0 -0
- package/build/client/_app/immutable/chunks/D-p-QSzz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D15yxLq9.js +1 -0
- package/build/client/_app/immutable/chunks/D15yxLq9.js.br +0 -0
- package/build/client/_app/immutable/chunks/D15yxLq9.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DFRlZOKz.js +2 -0
- package/build/client/_app/immutable/chunks/DFRlZOKz.js.br +0 -0
- package/build/client/_app/immutable/chunks/DFRlZOKz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BFccgFID.js → DpFtnEPx.js} +1 -1
- package/build/client/_app/immutable/chunks/DpFtnEPx.js.br +4 -0
- package/build/client/_app/immutable/chunks/DpFtnEPx.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.BaP08B0_.js +2 -0
- package/build/client/_app/immutable/entry/app.BaP08B0_.js.br +0 -0
- package/build/client/_app/immutable/entry/app.BaP08B0_.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DntfygIK.js +1 -0
- package/build/client/_app/immutable/entry/start.DntfygIK.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DntfygIK.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.6A6JK0Xm.js +1 -0
- package/build/client/_app/immutable/nodes/0.6A6JK0Xm.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.6A6JK0Xm.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.8K7wLW9R.js +1 -0
- package/build/client/_app/immutable/nodes/1.8K7wLW9R.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.8K7wLW9R.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CB_PeUBC.js +3 -0
- package/build/client/_app/immutable/nodes/2.CB_PeUBC.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CB_PeUBC.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.qIkVQyP6.js +1 -0
- package/build/client/_app/immutable/nodes/3.qIkVQyP6.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.qIkVQyP6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.SmoVIy5D.js +2 -0
- package/build/client/_app/immutable/nodes/4.SmoVIy5D.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.SmoVIy5D.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 +7 -7
- package/build/index.js +7 -7
- package/build/server/chunks/chunks/{context.js-mXbNUDBD.js → context.js-BJfk3ZiR.js} +440 -6
- package/build/server/chunks/chunks/context.js-BJfk3ZiR.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-BCXeXDmU.js → contract.js-DRcxzb4o.js} +33 -13
- package/build/server/chunks/chunks/contract.js-DRcxzb4o.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-xvDCCOrG.js → exports.js-aVVdkXgn.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-xvDCCOrG.js.map → exports.js-aVVdkXgn.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-BHghHRmI.js → http.js-DMkgmpI5.js} +2 -2
- package/build/server/chunks/chunks/{http.js-BHghHRmI.js.map → http.js-DMkgmpI5.js.map} +1 -1
- package/build/server/chunks/chunks/{internal.js-Dqy56Bi9.js → internal.js-C6cIfe5d.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-Dqy56Bi9.js.map → internal.js-C6cIfe5d.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{shared.js-CHSvdnOT.js → shared.js-BNd0HSxp.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-CHSvdnOT.js.map → shared.js-BNd0HSxp.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-Chb8lDKD.js → utils.js-6HSqnONB.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-Chb8lDKD.js.map → utils.js-6HSqnONB.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CN1hcfLb.js → _server.ts.js-m2QGyBiV.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CN1hcfLb.js.map → _server.ts.js-m2QGyBiV.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-D_LU4nrh.js → _server.ts.js-eMNgdaf4.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-D_LU4nrh.js.map → _server.ts.js-eMNgdaf4.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BY9NgKmC.js → _server.ts.js-CEQd4Wxn.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BY9NgKmC.js.map → _server.ts.js-CEQd4Wxn.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-D2uPmOzD.js → _server.ts.js-B2JoGCzy.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-D2uPmOzD.js.map → _server.ts.js-B2JoGCzy.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CCsQkuSA.js → _server.ts.js-DTpkVywC.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CCsQkuSA.js.map → _server.ts.js-DTpkVywC.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CFVRCJTe.js → _server.ts.js-D6Z_pGEZ.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CFVRCJTe.js.map → _server.ts.js-D6Z_pGEZ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DTDSQlpi.js → _server.ts.js-CnDi9p0a.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DTDSQlpi.js.map → _server.ts.js-CnDi9p0a.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DrunH7kn.js → _server.ts.js-BCzuPX5Z.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DrunH7kn.js.map → _server.ts.js-BCzuPX5Z.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-jskTD8nZ.js → _server.ts.js-CGbYyJ6S.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-jskTD8nZ.js.map → _server.ts.js-CGbYyJ6S.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DEXkS6pQ.js → _server.ts.js-CL_89klb.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DEXkS6pQ.js.map → _server.ts.js-CL_89klb.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-baLtBCf4.js → _server.ts.js-DZUKtjz9.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-baLtBCf4.js.map → _server.ts.js-DZUKtjz9.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-1Cx7sbfQ.js → _server.ts.js-Dz25LG_P.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-1Cx7sbfQ.js.map → _server.ts.js-Dz25LG_P.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-Xc7glEPl.js → _server.ts.js-C-NuN3JJ.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-Xc7glEPl.js.map → _server.ts.js-C-NuN3JJ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-C7IxpaSj.js → _server.ts.js-CwL9UPh3.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-C7IxpaSj.js.map → _server.ts.js-CwL9UPh3.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DLZkdOrS.js → _server.ts.js-DanXYrj1.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DLZkdOrS.js.map → _server.ts.js-DanXYrj1.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-CSS2DDb1.js → _server.ts.js-BZrun0up.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-CSS2DDb1.js.map → _server.ts.js-BZrun0up.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-CrXh2YL-.js → _server.ts.js-DQOabHbS.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-CrXh2YL-.js.map → _server.ts.js-DQOabHbS.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-yT-0jHAT.js → _server.ts.js-k8Ueydx1.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-yT-0jHAT.js.map → _server.ts.js-k8Ueydx1.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/_server.ts.js-DmMmiFiu.js +82 -0
- package/build/server/chunks/entries/endpoints/api/usage/_server.ts.js-DmMmiFiu.js.map +1 -0
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DTZAlq3j.js → _server.ts.js-CT7yOdDS.js} +3 -3
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DTZAlq3j.js.map → _server.ts.js-CT7yOdDS.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-Cux6Dnfu.js → _server.ts.js-BQTC0OSC.js} +4 -4
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-Cux6Dnfu.js.map → _server.ts.js-BQTC0OSC.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BjcPFOHi.js → _server.ts.js-mv9cqSuS.js} +4 -4
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BjcPFOHi.js.map → _server.ts.js-mv9cqSuS.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-e6ugpMpo.js → hooks.server.js-BNQO3cZr.js} +3 -3
- package/build/server/chunks/entries/{hooks.server.js-e6ugpMpo.js.map → hooks.server.js-BNQO3cZr.js.map} +1 -1
- package/build/server/chunks/{handler-BT9ZZoXM.js → handler-rG16rikT.js} +5 -5
- package/build/server/chunks/{handler-BT9ZZoXM.js.map → handler-rG16rikT.js.map} +1 -1
- package/build/server/chunks/{index.js-Cvg0bLxz.js → index.js-DYK_SfL5.js} +5 -5
- package/build/server/chunks/{index.js-Cvg0bLxz.js.map → index.js-DYK_SfL5.js.map} +1 -1
- package/build/server/chunks/{manifest.js-CtTOK1ZJ.js → manifest.js-h2lDpEPs.js} +35 -28
- package/build/server/chunks/manifest.js-h2lDpEPs.js.map +1 -0
- package/build/server/chunks/nodes/{0.js-CyEDHDwU.js → 0.js-Db28RwnA.js} +2 -2
- package/build/server/chunks/nodes/{0.js-CyEDHDwU.js.map → 0.js-Db28RwnA.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-D26Uv3YT.js +7 -0
- package/build/server/chunks/nodes/{1.js-Cv0zPe22.js.map → 1.js-D26Uv3YT.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-BeRlEFid.js +7 -0
- package/build/server/chunks/nodes/{2.js-CAIMXiqt.js.map → 2.js-BeRlEFid.js.map} +1 -1
- package/build/server/chunks/nodes/3.js-BRUNmCyG.js +7 -0
- package/build/server/chunks/nodes/3.js-BRUNmCyG.js.map +1 -0
- package/build/server/chunks/nodes/4.js-CTHWqDf1.js +7 -0
- package/build/server/chunks/nodes/4.js-CTHWqDf1.js.map +1 -0
- package/dist/cli.js +6 -1
- package/dist/config.d.ts +1 -1
- package/dist/core/api-types.d.ts +36 -1
- package/dist/core/config.d.ts +35 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/manifest-entry.d.ts +11 -0
- package/dist/runtime/kind-handlers.d.ts +3 -2
- package/dist/runtime/kind-handlers.js +38 -10
- package/dist/runtime/manifest.d.ts +2 -1
- package/dist/runtime/manifest.js +13 -6
- package/dist/runtime/preload-registry.d.ts +1 -1
- package/dist/runtime/preload-registry.js +6 -3
- package/dist/server/check.d.ts +6 -0
- package/dist/server/check.js +4 -1
- package/dist/server/cli-commands.d.ts +3 -1
- package/dist/server/cli-commands.js +117 -2
- package/dist/server/codegen.d.ts +3 -0
- package/dist/server/codegen.js +19 -2
- package/dist/server/config-loader.d.ts +3 -1
- package/dist/server/config-loader.js +13 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +1 -1
- package/dist/server/operations.d.ts +7 -1
- package/dist/server/operations.js +85 -2
- package/dist/server/plugins/audio.js +1 -0
- package/dist/server/plugins/chroma-key-video.js +1 -0
- package/dist/server/plugins/image.js +1 -0
- package/dist/server/plugins/slice.js +1 -0
- package/dist/server/plugins/video.js +1 -0
- package/dist/server/start.d.ts +8 -0
- package/dist/server/start.js +24 -0
- package/dist/server/usage.d.ts +24 -0
- package/dist/server/usage.js +441 -0
- package/package.json +2 -2
- package/build/client/_app/immutable/assets/2.CK3PVkJ5.css +0 -1
- package/build/client/_app/immutable/assets/2.CK3PVkJ5.css.br +0 -0
- package/build/client/_app/immutable/assets/2.CK3PVkJ5.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.CmXD8k9d.css +0 -1
- package/build/client/_app/immutable/assets/3.CmXD8k9d.css.br +0 -0
- package/build/client/_app/immutable/assets/3.CmXD8k9d.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.p004hmEN.css +0 -1
- package/build/client/_app/immutable/assets/4.p004hmEN.css.br +0 -0
- package/build/client/_app/immutable/assets/4.p004hmEN.css.gz +0 -0
- package/build/client/_app/immutable/chunks/-scmOfVp.js +0 -108
- package/build/client/_app/immutable/chunks/-scmOfVp.js.br +0 -0
- package/build/client/_app/immutable/chunks/-scmOfVp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BD3hQKzV.js +0 -1
- package/build/client/_app/immutable/chunks/BD3hQKzV.js.br +0 -0
- package/build/client/_app/immutable/chunks/BD3hQKzV.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BFccgFID.js.br +0 -1
- package/build/client/_app/immutable/chunks/BFccgFID.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C3HGm51f.js +0 -1
- package/build/client/_app/immutable/chunks/C3HGm51f.js.br +0 -0
- package/build/client/_app/immutable/chunks/C3HGm51f.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C7OUKWnm.js +0 -1
- package/build/client/_app/immutable/chunks/C7OUKWnm.js.br +0 -0
- package/build/client/_app/immutable/chunks/C7OUKWnm.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DPZDGjcn.js +0 -1
- package/build/client/_app/immutable/chunks/DPZDGjcn.js.br +0 -0
- package/build/client/_app/immutable/chunks/DPZDGjcn.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DRjIin01.js +0 -1
- package/build/client/_app/immutable/chunks/DRjIin01.js.br +0 -0
- package/build/client/_app/immutable/chunks/DRjIin01.js.gz +0 -0
- package/build/client/_app/immutable/chunks/NblqapDQ.js +0 -3
- package/build/client/_app/immutable/chunks/NblqapDQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/NblqapDQ.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.SxIeroQ7.js +0 -2
- package/build/client/_app/immutable/entry/app.SxIeroQ7.js.br +0 -0
- package/build/client/_app/immutable/entry/app.SxIeroQ7.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BLJzoe4Q.js +0 -1
- package/build/client/_app/immutable/entry/start.BLJzoe4Q.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BLJzoe4Q.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.ZD2ILzva.js +0 -2
- package/build/client/_app/immutable/nodes/0.ZD2ILzva.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.ZD2ILzva.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DwuNSOrz.js +0 -1
- package/build/client/_app/immutable/nodes/1.DwuNSOrz.js.br +0 -1
- package/build/client/_app/immutable/nodes/1.DwuNSOrz.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Dq9XLv2P.js +0 -3
- package/build/client/_app/immutable/nodes/2.Dq9XLv2P.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Dq9XLv2P.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3._kFEQXPD.js +0 -1
- package/build/client/_app/immutable/nodes/3._kFEQXPD.js.br +0 -0
- package/build/client/_app/immutable/nodes/3._kFEQXPD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.B6dS2ueh.js +0 -2
- package/build/client/_app/immutable/nodes/4.B6dS2ueh.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.B6dS2ueh.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-mXbNUDBD.js.map +0 -1
- package/build/server/chunks/chunks/contract.js-BCXeXDmU.js.map +0 -1
- package/build/server/chunks/manifest.js-CtTOK1ZJ.js.map +0 -1
- package/build/server/chunks/nodes/1.js-Cv0zPe22.js +0 -7
- package/build/server/chunks/nodes/2.js-CAIMXiqt.js +0 -7
- package/build/server/chunks/nodes/3.js-CFifsujw.js +0 -7
- package/build/server/chunks/nodes/3.js-CFifsujw.js.map +0 -1
- package/build/server/chunks/nodes/4.js-BS8_mlOS.js +0 -7
- package/build/server/chunks/nodes/4.js-BS8_mlOS.js.map +0 -1
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { createHash, createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { isAbsolute } from 'node:path';
|
|
3
|
+
import { compareCodeUnits } from '../core/index.js';
|
|
4
|
+
const MAX_PATHS = 20;
|
|
5
|
+
const TOKEN_TTL_MS = 10 * 60 * 1000;
|
|
6
|
+
function locationKey(location) {
|
|
7
|
+
return `${location.file}\u0000${location.line}\u0000${location.column}`;
|
|
8
|
+
}
|
|
9
|
+
function compareLocations(left, right) {
|
|
10
|
+
return (compareCodeUnits(left.file, right.file) ||
|
|
11
|
+
left.line - right.line ||
|
|
12
|
+
left.column - right.column ||
|
|
13
|
+
compareCodeUnits(left.label ?? '', right.label ?? ''));
|
|
14
|
+
}
|
|
15
|
+
function validateLocation(value, context, allowLabel) {
|
|
16
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
17
|
+
throw new Error(`${context} must be an object.`);
|
|
18
|
+
}
|
|
19
|
+
const record = value;
|
|
20
|
+
if (typeof record.file !== 'string' || record.file.length === 0 || !isAbsolute(record.file)) {
|
|
21
|
+
throw new Error(`${context}.file must be an absolute path.`);
|
|
22
|
+
}
|
|
23
|
+
for (const key of ['line', 'column']) {
|
|
24
|
+
if (!Number.isSafeInteger(record[key]) || record[key] <= 0) {
|
|
25
|
+
throw new Error(`${context}.${key} must be a positive safe integer.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (allowLabel && record.label !== undefined && typeof record.label !== 'string') {
|
|
29
|
+
throw new Error(`${context}.label must be a string.`);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
file: record.file,
|
|
33
|
+
line: record.line,
|
|
34
|
+
column: record.column,
|
|
35
|
+
...(allowLabel && typeof record.label === 'string' ? { label: record.label } : {})
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function normalizeResult(value, target) {
|
|
39
|
+
const context = `fundus.config: usage.referenceProvider for ${target.manifest}.${target.assetId}`;
|
|
40
|
+
try {
|
|
41
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
42
|
+
throw new Error(`${context} must return an object.`);
|
|
43
|
+
}
|
|
44
|
+
const result = value;
|
|
45
|
+
if (result.status === 'unknown') {
|
|
46
|
+
if (result.reason !== undefined && typeof result.reason !== 'string') {
|
|
47
|
+
throw new Error(`${context} unknown reason must be a string.`);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
status: 'unknown',
|
|
51
|
+
...(typeof result.reason === 'string' ? { reason: result.reason } : {})
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (result.status !== 'resolved' || !Array.isArray(result.references)) {
|
|
55
|
+
throw new Error(`${context} must return resolved references or unknown.`);
|
|
56
|
+
}
|
|
57
|
+
const declarationKey = locationKey(target.declaration);
|
|
58
|
+
const references = result.references
|
|
59
|
+
.map((reference, index) => validateLocation(reference, `${context} references[${index}]`, true))
|
|
60
|
+
.filter((reference) => locationKey(reference) !== declarationKey)
|
|
61
|
+
.sort(compareLocations);
|
|
62
|
+
const deduplicated = [];
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
for (const reference of references) {
|
|
65
|
+
const key = locationKey(reference);
|
|
66
|
+
if (seen.has(key))
|
|
67
|
+
continue;
|
|
68
|
+
seen.add(key);
|
|
69
|
+
deduplicated.push(reference);
|
|
70
|
+
}
|
|
71
|
+
return { status: 'resolved', references: deduplicated };
|
|
72
|
+
}
|
|
73
|
+
catch (cause) {
|
|
74
|
+
return { status: 'unknown', reason: cause instanceof Error ? cause.message : String(cause) };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
class FifoLimiter {
|
|
78
|
+
#active = 0;
|
|
79
|
+
#queue = [];
|
|
80
|
+
async run(operation) {
|
|
81
|
+
if (this.#active >= 4)
|
|
82
|
+
await new Promise((resolve) => this.#queue.push(resolve));
|
|
83
|
+
this.#active++;
|
|
84
|
+
try {
|
|
85
|
+
return await operation();
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
this.#active--;
|
|
89
|
+
this.#queue.shift()?.();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export class FundusUsageAnalyzer {
|
|
94
|
+
#usage;
|
|
95
|
+
#secret = randomBytes(32);
|
|
96
|
+
#limiter = new FifoLimiter();
|
|
97
|
+
#inflight = new Map();
|
|
98
|
+
#freshGeneration = 0;
|
|
99
|
+
constructor(usage) {
|
|
100
|
+
this.#usage = usage;
|
|
101
|
+
}
|
|
102
|
+
async analyze(snapshot, options = {}) {
|
|
103
|
+
if (options.assetId && !Object.hasOwn(snapshot.library.assets, options.assetId)) {
|
|
104
|
+
throw new Error(`Unknown asset "${options.assetId}".`);
|
|
105
|
+
}
|
|
106
|
+
const rootsToAnalyze = options.assetId
|
|
107
|
+
? relevantRootsForAsset(snapshot, options.assetId)
|
|
108
|
+
: snapshot.roots;
|
|
109
|
+
const freshKey = options.forceFresh ? `fresh:${++this.#freshGeneration}` : 'normal';
|
|
110
|
+
const rootResults = new Map();
|
|
111
|
+
await Promise.all(rootsToAnalyze.map(async (root) => {
|
|
112
|
+
const key = rootKey(root);
|
|
113
|
+
if (!root.declaration) {
|
|
114
|
+
rootResults.set(key, {
|
|
115
|
+
status: 'unknown',
|
|
116
|
+
reason: root.declarationError ??
|
|
117
|
+
`Cannot locate generated declaration for ${root.manifest}.${root.assetId}.`
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const target = {
|
|
122
|
+
assetId: root.assetId,
|
|
123
|
+
manifest: root.manifest,
|
|
124
|
+
declaration: root.declaration
|
|
125
|
+
};
|
|
126
|
+
const inflightKey = `${snapshot.revision}|${locationKey(root.declaration)}|${freshKey}`;
|
|
127
|
+
let run = !options.forceFresh ? this.#inflight.get(inflightKey) : undefined;
|
|
128
|
+
if (!run) {
|
|
129
|
+
run = this.#limiter.run(async () => {
|
|
130
|
+
try {
|
|
131
|
+
return normalizeResult(await this.#usage.referenceProvider(target), target);
|
|
132
|
+
}
|
|
133
|
+
catch (cause) {
|
|
134
|
+
return {
|
|
135
|
+
status: 'unknown',
|
|
136
|
+
reason: `usage.referenceProvider failed for ${root.manifest}.${root.assetId}: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
if (!options.forceFresh) {
|
|
141
|
+
this.#inflight.set(inflightKey, run);
|
|
142
|
+
void run.finally(() => this.#inflight.delete(inflightKey));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
rootResults.set(key, await run);
|
|
146
|
+
}));
|
|
147
|
+
return this.#assemble(snapshot, rootResults, options.assetId);
|
|
148
|
+
}
|
|
149
|
+
stale(snapshot, assetId) {
|
|
150
|
+
const results = new Map();
|
|
151
|
+
for (const root of assetId ? relevantRootsForAsset(snapshot, assetId) : snapshot.roots) {
|
|
152
|
+
results.set(rootKey(root), {
|
|
153
|
+
status: 'unknown',
|
|
154
|
+
reason: 'The Fundus project changed repeatedly during usage analysis; refresh to retry.'
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return this.#assemble(snapshot, results, assetId);
|
|
158
|
+
}
|
|
159
|
+
async open(token) {
|
|
160
|
+
if (typeof token !== 'string' || token.length === 0) {
|
|
161
|
+
throw new Error('Usage location token must be a non-empty string.');
|
|
162
|
+
}
|
|
163
|
+
const [encoded, signature, extra] = token.split('.');
|
|
164
|
+
if (!encoded || !signature || extra !== undefined)
|
|
165
|
+
throw new Error('Invalid usage location token.');
|
|
166
|
+
const expected = createHmac('sha256', this.#secret).update(encoded).digest();
|
|
167
|
+
let received;
|
|
168
|
+
try {
|
|
169
|
+
received = Buffer.from(signature, 'base64url');
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
throw new Error('Invalid usage location token.');
|
|
173
|
+
}
|
|
174
|
+
if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
|
|
175
|
+
throw new Error('Invalid usage location token; refresh usage and try again.');
|
|
176
|
+
}
|
|
177
|
+
let payload;
|
|
178
|
+
try {
|
|
179
|
+
payload = JSON.parse(Buffer.from(encoded, 'base64url').toString('utf8'));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
throw new Error('Invalid usage location token.');
|
|
183
|
+
}
|
|
184
|
+
if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {
|
|
185
|
+
throw new Error('Invalid usage location token.');
|
|
186
|
+
}
|
|
187
|
+
const record = payload;
|
|
188
|
+
if (record.v !== 1 || typeof record.expiresAt !== 'number' || Date.now() > record.expiresAt) {
|
|
189
|
+
throw new Error('Usage location token expired; refresh usage and try again.');
|
|
190
|
+
}
|
|
191
|
+
const location = validateLocation(record.location, 'Usage location token', false);
|
|
192
|
+
const normalized = { file: location.file, line: location.line, column: location.column };
|
|
193
|
+
try {
|
|
194
|
+
await this.#usage.openLocation(normalized);
|
|
195
|
+
}
|
|
196
|
+
catch (cause) {
|
|
197
|
+
throw new Error(`Could not open ${normalized.file}:${normalized.line}:${normalized.column}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
#token(location) {
|
|
201
|
+
const encoded = Buffer.from(JSON.stringify({ v: 1, expiresAt: Date.now() + TOKEN_TTL_MS, location })).toString('base64url');
|
|
202
|
+
const signature = createHmac('sha256', this.#secret).update(encoded).digest('base64url');
|
|
203
|
+
return `${encoded}.${signature}`;
|
|
204
|
+
}
|
|
205
|
+
#assemble(snapshot, rootResults, requestedAssetId) {
|
|
206
|
+
const assetIds = requestedAssetId
|
|
207
|
+
? [requestedAssetId]
|
|
208
|
+
: Object.keys(snapshot.library.assets).sort(compareCodeUnits);
|
|
209
|
+
const analyzedRoots = snapshot.roots.filter((root) => rootResults.has(rootKey(root)));
|
|
210
|
+
const cyclicNodes = referenceCycleNodes(snapshot.referencesByAsset);
|
|
211
|
+
const cycleAncestors = reverseClosure(cyclicNodes, snapshot.referencesByAsset);
|
|
212
|
+
const adjustedResults = new Map();
|
|
213
|
+
for (const root of analyzedRoots) {
|
|
214
|
+
const result = rootResults.get(rootKey(root));
|
|
215
|
+
adjustedResults.set(rootKey(root), cycleAncestors.has(root.assetId) &&
|
|
216
|
+
result.status === 'resolved' &&
|
|
217
|
+
result.references.length === 0
|
|
218
|
+
? {
|
|
219
|
+
status: 'unknown',
|
|
220
|
+
reason: 'A reference cycle prevents complete usage analysis for this root.'
|
|
221
|
+
}
|
|
222
|
+
: result);
|
|
223
|
+
}
|
|
224
|
+
const usedAssets = referenceClosureFromSources(analyzedRoots
|
|
225
|
+
.filter((root) => {
|
|
226
|
+
const result = adjustedResults.get(rootKey(root));
|
|
227
|
+
return result?.status === 'resolved' && result.references.length > 0;
|
|
228
|
+
})
|
|
229
|
+
.map((root) => root.assetId), snapshot.referencesByAsset);
|
|
230
|
+
const unknownAssets = referenceClosureFromSources(analyzedRoots
|
|
231
|
+
.filter((root) => adjustedResults.get(rootKey(root))?.status === 'unknown')
|
|
232
|
+
.map((root) => root.assetId), snapshot.referencesByAsset);
|
|
233
|
+
const assets = assetIds.map((assetId) => {
|
|
234
|
+
const status = usedAssets.has(assetId)
|
|
235
|
+
? 'used'
|
|
236
|
+
: unknownAssets.has(assetId)
|
|
237
|
+
? 'unknown'
|
|
238
|
+
: 'unused';
|
|
239
|
+
if (!requestedAssetId) {
|
|
240
|
+
return { assetId, status, references: [], roots: [] };
|
|
241
|
+
}
|
|
242
|
+
const groups = [];
|
|
243
|
+
const pathCountMemo = new Map();
|
|
244
|
+
for (const root of analyzedRoots) {
|
|
245
|
+
const paths = pathsFromRoot(root.assetId, assetId, snapshot.referencesByAsset, pathCountMemo, cyclicNodes);
|
|
246
|
+
if (paths.count > 0n)
|
|
247
|
+
groups.push({ root, paths: paths.paths, count: paths.count });
|
|
248
|
+
}
|
|
249
|
+
const allReferences = [];
|
|
250
|
+
for (const group of groups) {
|
|
251
|
+
const result = adjustedResults.get(rootKey(group.root));
|
|
252
|
+
if (result?.status === 'resolved')
|
|
253
|
+
allReferences.push(...result.references);
|
|
254
|
+
}
|
|
255
|
+
allReferences.sort(compareLocations);
|
|
256
|
+
const uniqueReferences = [];
|
|
257
|
+
const referenceIdByKey = new Map();
|
|
258
|
+
for (const reference of allReferences) {
|
|
259
|
+
const key = locationKey(reference);
|
|
260
|
+
if (referenceIdByKey.has(key))
|
|
261
|
+
continue;
|
|
262
|
+
const id = `r${uniqueReferences.length}`;
|
|
263
|
+
referenceIdByKey.set(key, id);
|
|
264
|
+
uniqueReferences.push(reference);
|
|
265
|
+
}
|
|
266
|
+
const roots = groups.map(({ root, paths, count }) => {
|
|
267
|
+
const result = adjustedResults.get(rootKey(root)) ?? {
|
|
268
|
+
status: 'unknown',
|
|
269
|
+
reason: 'Usage analysis result is missing.'
|
|
270
|
+
};
|
|
271
|
+
const dtoResult = result.status === 'unknown'
|
|
272
|
+
? result
|
|
273
|
+
: {
|
|
274
|
+
status: 'resolved',
|
|
275
|
+
referenceIds: result.references
|
|
276
|
+
.map((reference) => referenceIdByKey.get(locationKey(reference)))
|
|
277
|
+
.filter((id) => id !== undefined)
|
|
278
|
+
};
|
|
279
|
+
return {
|
|
280
|
+
manifest: root.manifest,
|
|
281
|
+
rootAssetId: root.assetId,
|
|
282
|
+
paths,
|
|
283
|
+
pathsTruncated: count > BigInt(paths.length),
|
|
284
|
+
...(count > BigInt(paths.length)
|
|
285
|
+
? { additionalPathCount: (count - BigInt(paths.length)).toString() }
|
|
286
|
+
: {}),
|
|
287
|
+
declaration: root.declaration,
|
|
288
|
+
result: dtoResult
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
return {
|
|
292
|
+
assetId,
|
|
293
|
+
status,
|
|
294
|
+
references: uniqueReferences.map((reference, index) => ({
|
|
295
|
+
...reference,
|
|
296
|
+
id: `r${index}`,
|
|
297
|
+
openToken: this.#token(reference)
|
|
298
|
+
})),
|
|
299
|
+
roots
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
return { assets };
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function rootKey(root) {
|
|
306
|
+
return `${root.manifest}\u0000${root.assetId}`;
|
|
307
|
+
}
|
|
308
|
+
function relevantRootsForAsset(snapshot, assetId) {
|
|
309
|
+
const ancestors = reverseClosure(new Set([assetId]), snapshot.referencesByAsset);
|
|
310
|
+
return snapshot.roots.filter((root) => ancestors.has(root.assetId));
|
|
311
|
+
}
|
|
312
|
+
function reverseClosure(sources, referencesByAsset) {
|
|
313
|
+
const incoming = new Map();
|
|
314
|
+
for (const [source, references] of Object.entries(referencesByAsset)) {
|
|
315
|
+
for (const target of new Set(references.map((reference) => reference.assetId))) {
|
|
316
|
+
const sources = incoming.get(target);
|
|
317
|
+
if (sources)
|
|
318
|
+
sources.push(source);
|
|
319
|
+
else
|
|
320
|
+
incoming.set(target, [source]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const closure = new Set();
|
|
324
|
+
const pending = [...sources];
|
|
325
|
+
while (pending.length > 0) {
|
|
326
|
+
const current = pending.pop();
|
|
327
|
+
if (closure.has(current))
|
|
328
|
+
continue;
|
|
329
|
+
closure.add(current);
|
|
330
|
+
pending.push(...(incoming.get(current) ?? []));
|
|
331
|
+
}
|
|
332
|
+
return closure;
|
|
333
|
+
}
|
|
334
|
+
function referenceClosureFromSources(sources, referencesByAsset) {
|
|
335
|
+
const closure = new Set();
|
|
336
|
+
const pending = [...sources];
|
|
337
|
+
while (pending.length > 0) {
|
|
338
|
+
const current = pending.pop();
|
|
339
|
+
if (closure.has(current) || !Object.hasOwn(referencesByAsset, current))
|
|
340
|
+
continue;
|
|
341
|
+
closure.add(current);
|
|
342
|
+
for (const reference of referencesByAsset[current])
|
|
343
|
+
pending.push(reference.assetId);
|
|
344
|
+
}
|
|
345
|
+
return closure;
|
|
346
|
+
}
|
|
347
|
+
/** Tarjan SCC detection; singleton components count only when they self-reference. */
|
|
348
|
+
function referenceCycleNodes(referencesByAsset) {
|
|
349
|
+
let nextIndex = 0;
|
|
350
|
+
const indexByNode = new Map();
|
|
351
|
+
const lowLink = new Map();
|
|
352
|
+
const stack = [];
|
|
353
|
+
const onStack = new Set();
|
|
354
|
+
const cyclic = new Set();
|
|
355
|
+
const visit = (node) => {
|
|
356
|
+
indexByNode.set(node, nextIndex);
|
|
357
|
+
lowLink.set(node, nextIndex++);
|
|
358
|
+
stack.push(node);
|
|
359
|
+
onStack.add(node);
|
|
360
|
+
for (const target of new Set((referencesByAsset[node] ?? []).map((ref) => ref.assetId))) {
|
|
361
|
+
if (!Object.hasOwn(referencesByAsset, target))
|
|
362
|
+
continue;
|
|
363
|
+
if (!indexByNode.has(target)) {
|
|
364
|
+
visit(target);
|
|
365
|
+
lowLink.set(node, Math.min(lowLink.get(node), lowLink.get(target)));
|
|
366
|
+
}
|
|
367
|
+
else if (onStack.has(target)) {
|
|
368
|
+
lowLink.set(node, Math.min(lowLink.get(node), indexByNode.get(target)));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (lowLink.get(node) !== indexByNode.get(node))
|
|
372
|
+
return;
|
|
373
|
+
const component = [];
|
|
374
|
+
for (;;) {
|
|
375
|
+
const member = stack.pop();
|
|
376
|
+
onStack.delete(member);
|
|
377
|
+
component.push(member);
|
|
378
|
+
if (member === node)
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
if (component.length > 1 ||
|
|
382
|
+
(referencesByAsset[node] ?? []).some((reference) => reference.assetId === node)) {
|
|
383
|
+
for (const member of component)
|
|
384
|
+
cyclic.add(member);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
for (const node of Object.keys(referencesByAsset)) {
|
|
388
|
+
if (!indexByNode.has(node))
|
|
389
|
+
visit(node);
|
|
390
|
+
}
|
|
391
|
+
return cyclic;
|
|
392
|
+
}
|
|
393
|
+
function pathsFromRoot(root, target, referencesByAsset, countMemo = new Map(), cyclicNodes = referenceCycleNodes(referencesByAsset)) {
|
|
394
|
+
const count = (assetId, visiting) => {
|
|
395
|
+
if (assetId === target)
|
|
396
|
+
return 1n;
|
|
397
|
+
const visitedCyclicNodes = [...visiting]
|
|
398
|
+
.filter((id) => cyclicNodes.has(id))
|
|
399
|
+
.sort(compareCodeUnits);
|
|
400
|
+
const memoKey = JSON.stringify([assetId, visitedCyclicNodes]);
|
|
401
|
+
const cached = countMemo.get(memoKey);
|
|
402
|
+
if (cached !== undefined)
|
|
403
|
+
return cached;
|
|
404
|
+
if (visiting.has(assetId)) {
|
|
405
|
+
return 0n;
|
|
406
|
+
}
|
|
407
|
+
const nextVisiting = new Set(visiting).add(assetId);
|
|
408
|
+
let total = 0n;
|
|
409
|
+
const nextIds = [...new Set((referencesByAsset[assetId] ?? []).map((ref) => ref.assetId))].sort(compareCodeUnits);
|
|
410
|
+
for (const next of nextIds)
|
|
411
|
+
total += count(next, nextVisiting);
|
|
412
|
+
countMemo.set(memoKey, total);
|
|
413
|
+
return total;
|
|
414
|
+
};
|
|
415
|
+
const total = count(root, new Set());
|
|
416
|
+
const paths = [];
|
|
417
|
+
const collect = (assetId, path, visiting) => {
|
|
418
|
+
if (paths.length >= MAX_PATHS)
|
|
419
|
+
return;
|
|
420
|
+
if (assetId === target) {
|
|
421
|
+
paths.push(path);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (visiting.has(assetId))
|
|
425
|
+
return;
|
|
426
|
+
const nextVisiting = new Set(visiting).add(assetId);
|
|
427
|
+
const nextIds = [...new Set((referencesByAsset[assetId] ?? []).map((ref) => ref.assetId))].sort(compareCodeUnits);
|
|
428
|
+
for (const next of nextIds) {
|
|
429
|
+
if (count(next, nextVisiting) > 0n)
|
|
430
|
+
collect(next, [...path, next], nextVisiting);
|
|
431
|
+
if (paths.length >= MAX_PATHS)
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
if (total > 0n)
|
|
436
|
+
collect(root, [root], new Set());
|
|
437
|
+
return { paths, count: total };
|
|
438
|
+
}
|
|
439
|
+
export function usageSnapshotRevision(parts) {
|
|
440
|
+
return createHash('sha256').update(parts.join('\u0000')).digest('hex');
|
|
441
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fundus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=20.19.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"dev": "
|
|
36
|
+
"dev": "node scripts/dev.mjs",
|
|
37
37
|
"build:package": "svelte-package --input src/lib --output dist && node scripts/postbuild-package.mjs && publint",
|
|
38
38
|
"build:app": "vite build",
|
|
39
39
|
"build": "npm run build:package && npm run build:app",
|
|
@@ -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}.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}.selection-bar.svelte-1uha8ag,.filter-bar.svelte-1uha8ag{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.selection-bar.svelte-1uha8ag{margin-bottom:8px}.filter-bar.svelte-1uha8ag{margin-bottom:16px}.selection-summary.svelte-1uha8ag{color:var(--accent);white-space:nowrap;font-weight:600}.toggle.svelte-1uha8ag{color:var(--text-dim);align-items:center;gap:6px;display:inline-flex}.search.svelte-1uha8ag{border-radius:4px;align-items:center;gap:4px;width:220px;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}.import.svelte-1uha8ag{background:var(--accent);color:var(--text);margin-left:auto}.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{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;display:grid}.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:8px;padding:8px;display:flex;position:relative}.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:12px;left:12px}.card.svelte-1uha8ag:hover{border-color:var(--accent)}.thumbnail.svelte-1uha8ag{border-radius:var(--radius);justify-content:center;align-items:center;height:96px;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)}.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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.detail.svelte-xy8zsr{flex:1;grid-template-columns:224px 1fr 280px;min-height:0;display:grid}.center.svelte-xy8zsr{flex-direction:column;min-width:0;min-height:0;padding:12px 16px;display:flex}.center.empty.svelte-xy8zsr,.empty.svelte-xy8zsr{color:var(--text-dim);flex:1;justify-content:center;align-items:center;display:flex}.inspector.svelte-xy8zsr{background:var(--panel);border-left:1px solid var(--border);overflow-y:auto}.inspector.svelte-xy8zsr section:where(.svelte-xy8zsr){border-bottom:1px solid var(--border-soft);padding:12px}.inspector.svelte-xy8zsr h2:where(.svelte-xy8zsr){word-break:break-all;margin:0;font-size:13px}.raw.svelte-xy8zsr{color:var(--text-dim);word-break:break-all;margin:4px 0 0}.warning.svelte-xy8zsr{color:var(--warning);margin:8px 0 0;font-size:11px}.hint.svelte-xy8zsr{color:var(--text-faint);margin:0;font-size:11px}.inspector.svelte-xy8zsr h4:where(.svelte-xy8zsr){text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);margin:8px 0 4px;font-size:10px}.reference-row.svelte-xy8zsr{border-radius:var(--radius);color:var(--text-dim);align-items:center;gap:6px;min-width:0;padding:3px 4px;display:flex}.reference-row.svelte-xy8zsr:hover{background:var(--panel-raised);color:var(--text)}.reference-field.svelte-xy8zsr{color:var(--text-faint);font-size:11px}.reference-arrow.svelte-xy8zsr{color:var(--text-faint);flex:none}.reference-asset.svelte-xy8zsr{color:var(--accent);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.rename.svelte-xy8zsr{gap:8px;margin-bottom:8px;display:flex}.replace-raw.svelte-xy8zsr{width:100%;margin-bottom:8px}.source-label.svelte-xy8zsr{margin-bottom:8px}.source-field.svelte-xy8zsr{color:var(--text-dim);flex-direction:column;gap:4px;margin-bottom:8px;font-size:11px;display:flex}.source-field.svelte-xy8zsr .control:where(.svelte-xy8zsr){width:100%}.source-actions.svelte-xy8zsr{flex-direction:column;gap:6px;display:flex}.source-actions.svelte-xy8zsr .control:where(.svelte-xy8zsr){text-align:center;width:100%}.rename.svelte-xy8zsr input:where(.svelte-xy8zsr){flex:1;min-width:0}.danger.svelte-xy8zsr{width:100%}
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.popover-anchor.svelte-1rznwff{display:inline-flex;position:relative}.popover.svelte-1rznwff{z-index:10;background:var(--panel-raised);border:1px solid var(--border);border-radius:var(--radius);padding:8px;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 8px 24px #0006}.popover.right.svelte-1rznwff{left:auto;right:0}.controls.svelte-58t64l{align-items:center;gap:4px;display:inline-flex}.emoji-trigger.svelte-58t64l,.swatch-trigger.svelte-58t64l{border:1px solid var(--border);background:var(--panel-raised);cursor:pointer;justify-content:center;align-items:center;padding:0;display:inline-flex}.emoji-trigger.svelte-58t64l{border-radius:var(--radius-small);width:22px;height:22px;font-size:14px;line-height:1}.emoji-trigger.empty.svelte-58t64l{color:var(--text-faint)}.swatch-trigger.svelte-58t64l{background:var(--swatch);border-radius:50%;width:16px;height:16px}.swatch-trigger.empty.svelte-58t64l{background:0 0;position:relative}.swatch-trigger.empty.svelte-58t64l:after{content:"";background:var(--text-faint);height:1px;position:absolute;inset:50% 1px auto;transform:rotate(-45deg)}.emoji-trigger.active.svelte-58t64l,.swatch-trigger.active.svelte-58t64l{border-color:var(--accent)}.picker.svelte-58t64l{gap:4px;display:grid}.swatches.svelte-58t64l{grid-template-columns:repeat(7,18px)}.emojis.svelte-58t64l{grid-template-columns:repeat(8,24px)}.swatch.svelte-58t64l{border:1px solid var(--border);cursor:pointer;border-radius:50%;width:18px;height:18px;padding:0}.swatch.none.svelte-58t64l{background:0 0;position:relative}.swatch.none.svelte-58t64l:after{content:"";background:var(--text-faint);height:1px;position:absolute;inset:50% 1px auto;transform:rotate(-45deg)}.swatch.selected.svelte-58t64l{outline:2px solid var(--text);outline-offset:1px}.emoji.svelte-58t64l{border-radius:var(--radius-small);border:1px solid var(--border);background:var(--panel);cursor:pointer;width:24px;height:24px;padding:0;font-size:14px;line-height:1}.emoji.none.svelte-58t64l{color:var(--text-faint);font-size:12px}.emoji.selected.svelte-58t64l{border-color:var(--accent);background:var(--accent-soft)}.page.svelte-1k9wgg5{flex:1;min-height:0;padding:16px;overflow-y:auto}.create.svelte-1k9wgg5{align-items:center;gap:8px;margin-bottom:16px;display:flex}.create.svelte-1k9wgg5 input:where(.svelte-1k9wgg5){width:240px}.hint.svelte-1k9wgg5{color:var(--text-faint);font-size:11px}.empty.svelte-1k9wgg5{color:var(--text-dim);text-align:center;padding:48px}.list.svelte-1k9wgg5{flex-direction:column;gap:12px;max-width:640px;display:flex}.manifest.svelte-1k9wgg5{background:var(--panel);border:1px solid var(--manifest-color,var(--border-soft));border-radius:var(--radius-large);padding:12px}.manifest.svelte-1k9wgg5 header:where(.svelte-1k9wgg5){align-items:center;gap:12px;display:flex}.manifest.svelte-1k9wgg5 h2:where(.svelte-1k9wgg5){margin:0;font-size:13px}.size.svelte-1k9wgg5{color:var(--accent);font-variant-numeric:tabular-nums}.count.svelte-1k9wgg5{color:var(--text-dim);margin-left:auto}ul.svelte-1k9wgg5{margin:8px 0 0;padding:0;list-style:none}li.svelte-1k9wgg5 a:where(.svelte-1k9wgg5){border-radius:var(--radius);color:var(--text-dim);align-items:center;gap:12px;padding:4px 8px;display:flex}li.svelte-1k9wgg5 a:where(.svelte-1k9wgg5):hover{background:var(--panel-raised);color:var(--text)}.asset-id.svelte-1k9wgg5{color:var(--text);font-weight:600}.asset-type.svelte-1k9wgg5{border:1px solid var(--border);border-radius:4px;padding:0 5px;font-size:10px}.asset-size.svelte-1k9wgg5{font-variant-numeric:tabular-nums;margin-left:auto}.passive-member.svelte-1k9wgg5{margin-left:16px}.passive-member.svelte-1k9wgg5 a:where(.svelte-1k9wgg5),.passive-member.svelte-1k9wgg5 .asset-id:where(.svelte-1k9wgg5){color:var(--text-faint)}.passive-id.svelte-1k9wgg5{text-underline-offset:3px;font-weight:600;text-decoration-line:underline;text-decoration-style:dashed}.asset-via.svelte-1k9wgg5{color:var(--text-faint);font-size:11px}.dialog-text.svelte-1k9wgg5{color:var(--text-dim);margin:0 0 8px}.dialog-text.warn.svelte-1k9wgg5{color:var(--warning);font-size:11px}.dialog-row.svelte-1k9wgg5{align-items:center;gap:8px;margin-bottom:8px;display:flex}.dialog-label.svelte-1k9wgg5{color:var(--text-dim);flex:none}.dialog-row.svelte-1k9wgg5 input:where(.svelte-1k9wgg5){flex:1}
|
|
Binary file
|
|
Binary file
|