@inpageedit/core 0.17.2 → 0.17.3

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.
Files changed (44) hide show
  1. package/dist/InPageEdit.js +1 -1
  2. package/dist/{PluginImagesUsed-bCsiMdd5.js → PluginImagesUsed-DWpe6M-r.js} +2 -2
  3. package/dist/{PluginImagesUsed-bCsiMdd5.js.map → PluginImagesUsed-DWpe6M-r.js.map} +1 -1
  4. package/dist/{PluginPrefSync-CjVsY-Ei.js → PluginPrefSync-CmVHL2wx.js} +2 -2
  5. package/dist/{PluginPrefSync-CjVsY-Ei.js.map → PluginPrefSync-CmVHL2wx.js.map} +1 -1
  6. package/dist/{PluginStoreApp-DKxtArs5.js → PluginStoreApp-CmLstT3F.js} +2 -2
  7. package/dist/{PluginStoreApp-DKxtArs5.js.map → PluginStoreApp-CmLstT3F.js.map} +1 -1
  8. package/dist/{PluginTemplatesUsed-CSrc0hi5.js → PluginTemplatesUsed-BjRYFXHz.js} +2 -2
  9. package/dist/{PluginTemplatesUsed-CSrc0hi5.js.map → PluginTemplatesUsed-BjRYFXHz.js.map} +1 -1
  10. package/dist/core.js +2 -2
  11. package/dist/{index-CkKY3iId.js → index-BVMm7Dix.js} +2 -2
  12. package/dist/{index-CkKY3iId.js.map → index-BVMm7Dix.js.map} +1 -1
  13. package/dist/{index-D78nVTYO.js → index-BYgh1HkH.js} +2 -2
  14. package/dist/{index-D78nVTYO.js.map → index-BYgh1HkH.js.map} +1 -1
  15. package/dist/{index-0iItkJyW.js → index-BbvMbIgz.js} +3 -3
  16. package/dist/{index-0iItkJyW.js.map → index-BbvMbIgz.js.map} +1 -1
  17. package/dist/{index-67KKEC1h.js → index-BlVSMvH-.js} +2 -2
  18. package/dist/{index-67KKEC1h.js.map → index-BlVSMvH-.js.map} +1 -1
  19. package/dist/{index-DRpv1zoB.js → index-CUDVeUEv.js} +2 -2
  20. package/dist/{index-DRpv1zoB.js.map → index-CUDVeUEv.js.map} +1 -1
  21. package/dist/{index-BonYcMRR.js → index-Ce-zc5RR.js} +2 -2
  22. package/dist/{index-BonYcMRR.js.map → index-Ce-zc5RR.js.map} +1 -1
  23. package/dist/{index-BPZDprsy.js → index-CkSdNy0U.js} +2 -2
  24. package/dist/{index-BPZDprsy.js.map → index-CkSdNy0U.js.map} +1 -1
  25. package/dist/{index-BGSq0cLS.js → index-D-8cyCdX.js} +28 -23
  26. package/dist/index-D-8cyCdX.js.map +1 -0
  27. package/dist/{index-CxckcdDI.js → index-DTU2DZU6.js} +14 -14
  28. package/dist/{index-CxckcdDI.js.map → index-DTU2DZU6.js.map} +1 -1
  29. package/dist/{index-CFwPBIwv.js → index-Dfdy54gH.js} +2 -2
  30. package/dist/{index-CFwPBIwv.js.map → index-Dfdy54gH.js.map} +1 -1
  31. package/dist/{index-Bf9sWKqX.js → index-DvFkW8lL.js} +2 -2
  32. package/dist/{index-Bf9sWKqX.js.map → index-DvFkW8lL.js.map} +1 -1
  33. package/dist/{index-wpZvFBVX.js → index-JvsrhizC.js} +3 -3
  34. package/dist/{index-wpZvFBVX.js.map → index-JvsrhizC.js.map} +1 -1
  35. package/dist/{index-DtXCZneF.js → index-LvMaeDQn.js} +2 -2
  36. package/dist/{index-DtXCZneF.js.map → index-LvMaeDQn.js.map} +1 -1
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +2 -2
  39. package/dist/plugins/index.js +12 -12
  40. package/dist/services/index.js +1 -1
  41. package/lib/index.umd.js +2 -2
  42. package/lib/index.umd.js.map +1 -1
  43. package/package.json +3 -3
  44. package/dist/index-BGSq0cLS.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { C as r, s as c, b as t, F as S, I as i, a as g, e as p, m, $ as f, M as L, S as d, c as l, d as n, f as C } from "./index-CxckcdDI.js";
1
+ import { C as r, s as c, b as t, F as S, I as i, a as g, e as p, m, $ as f, M as L, S as d, c as l, d as n, f as C } from "./index-DTU2DZU6.js";
2
2
  import "./Promise.withResolvers-C4chhLB1.js";
3
3
  import "./index-C0spLL-i.js";
4
4
  export {
@@ -1,5 +1,5 @@
1
1
  import { j as c } from "./Promise.withResolvers-C4chhLB1.js";
2
- import { a as y } from "./index-CxckcdDI.js";
2
+ import { a as y } from "./index-DTU2DZU6.js";
3
3
  import { BasePlugin as I } from "./core.js";
4
4
  var U = Object.create, g = Object.defineProperty, j = Object.getOwnPropertyDescriptor, k = (e, t) => (t = Symbol[e]) ? t : /* @__PURE__ */ Symbol.for("Symbol." + e), f = (e) => {
5
5
  throw TypeError(e);
@@ -87,4 +87,4 @@ O(h, 1, _);
87
87
  export {
88
88
  _ as PluginImagesUsed
89
89
  };
90
- //# sourceMappingURL=PluginImagesUsed-bCsiMdd5.js.map
90
+ //# sourceMappingURL=PluginImagesUsed-DWpe6M-r.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluginImagesUsed-bCsiMdd5.js","sources":["../src/plugins/quick-usage/PluginImagesUsed.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/index.js'\nimport { QuickEditEventPayload } from '../quick-edit/index.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n imagesUsed: PluginImagesUsed\n }\n}\n\nexport interface PluginTemplatesUsedOptions {\n wikiPage?: IWikiPage\n title?: string\n pageId?: number\n revision?: number\n}\n\n@Inject(['modal', '$'])\nexport class PluginImagesUsed extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'images-used')\n }\n\n protected async start() {\n this.ctx.on('quick-edit/wiki-page', this.injectQuickEdit.bind(this))\n }\n\n injectQuickEdit(payload: QuickEditEventPayload) {\n const { $ } = this.ctx\n const { wikiPage, modal } = payload\n if (!wikiPage || !wikiPage.pageid) return\n const wrapper = this.ctx.quickUsage.getWrapperForQuickEdit(modal)\n const link = (\n <a\n href={`#ipe://quick-usage/images?title=${wikiPage.title}`}\n onClick={async (e) => {\n e.preventDefault()\n const usageModal = await this.showModal({ wikiPage })\n if (usageModal) {\n modal.on(modal.Event.Close, () => {\n usageModal.destroy()\n })\n }\n }}\n >{$`Images Used`}</a>\n )\n wrapper.appendChild(link)\n }\n\n async showModal(options: PluginTemplatesUsedOptions = {}) {\n const { $ } = this.ctx\n\n const wikiPage = options.wikiPage || (await this.ctx.wikiPage.WikiPage.newFromAnyKind(options))\n if (!wikiPage || !wikiPage.pageid) return\n\n const modal = this.ctx.modal.show({\n title: $`Images Used`,\n content: (\n <section className=\"ipe-quickUsage__images\">\n <ol>\n {wikiPage.images.map((image) => {\n const src = this.ctx.wikiFile.getFileUrl(image.title)\n return (\n <li key={image.title}>\n <a\n href={this.ctx.wiki.getUrl(image.title)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {image.title}\n </a>{' '}\n (\n <a\n href={src}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => {\n e.preventDefault()\n this.ctx.quickPreview.previewFile(src, image.title)\n }}\n >{$`Preview`}</a>\n )\n </li>\n )\n })}\n </ol>\n </section>\n ),\n sizeClass: 'dialog',\n draggable: true,\n backdrop: false,\n })\n\n this.ctx.emit('analytics/event', { feature: 'quick-usage', subtype: 'images-used' })\n\n return modal\n }\n}\n"],"names":["_PluginImagesUsed_decorators","_init","_a","Inject","PluginImagesUsed","BasePlugin","ctx","payload","$","wikiPage","modal","wrapper","link","jsx","e","usageModal","options","image","src","__decoratorStart","__decorateElement","__runInitializers"],"mappings":";;;;;;;;;;;;;;GAAAA,GAAAC,GAAAC;AAiBAF,IAAA,CAACG,EAAO,CAAC,SAAS,GAAG,CAAC,CAAA;AACf,MAAMC,WAAyBF,IAAAG,GAAW;AAAA,EAC/C,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,aAAa,GADX,KAAA,MAAAA;AAAA,EAEnB;AAAA,EAEA,MAAgB,QAAQ;AACtB,SAAK,IAAI,GAAG,wBAAwB,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EACrE;AAAA,EAEA,gBAAgBC,GAAgC;AAC9C,UAAM,EAAE,GAAAC,MAAM,KAAK,KACb,EAAE,UAAAC,GAAU,OAAAC,EAAA,IAAUH;AAC5B,QAAI,CAACE,KAAY,CAACA,EAAS,OAAQ;AACnC,UAAME,IAAU,KAAK,IAAI,WAAW,uBAAuBD,CAAK,GAC1DE,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM,mCAAmCJ,EAAS,KAAK;AAAA,QACvD,SAAS,OAAOK,MAAM;AACpB,UAAAA,EAAE,eAAA;AACF,gBAAMC,IAAa,MAAM,KAAK,UAAU,EAAE,UAAAN,GAAU;AACpD,UAAIM,KACFL,EAAM,GAAGA,EAAM,MAAM,OAAO,MAAM;AAChC,YAAAK,EAAW,QAAA;AAAA,UACb,CAAC;AAAA,QAEL;AAAA,QACA,UAAAP;AAAA,MAAA;AAAA,IAAA;AAEJ,IAAAG,EAAQ,YAAYC,CAAI;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAUI,IAAsC,IAAI;AACxD,UAAM,EAAE,GAAAR,MAAM,KAAK,KAEbC,IAAWO,EAAQ,YAAa,MAAM,KAAK,IAAI,SAAS,SAAS,eAAeA,CAAO;AAC7F,QAAI,CAACP,KAAY,CAACA,EAAS,OAAQ;AAEnC,UAAMC,IAAQ,KAAK,IAAI,MAAM,KAAK;AAAA,MAChC,OAAOF;AAAA,MACP,SACE,gBAAAK,EAAC,WAAA,EAAQ,WAAU,0BACjB,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAJ,EAAS,OAAO,IAAI,CAACQ,MAAU;AAC9B,cAAMC,IAAM,KAAK,IAAI,SAAS,WAAWD,EAAM,KAAK;AACpD,iCACG,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,KAAK,IAAI,KAAK,OAAOI,EAAM,KAAK;AAAA,cACtC,QAAO;AAAA,cACP,KAAI;AAAA,cAEH,UAAAA,EAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UACJ;AAAA,UAAI;AAAA,UAET,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAMK;AAAA,cACN,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,SAAS,CAACJ,MAAM;AACd,gBAAAA,EAAE,eAAA,GACF,KAAK,IAAI,aAAa,YAAYI,GAAKD,EAAM,KAAK;AAAA,cACpD;AAAA,cACA,UAAAT;AAAA,YAAA;AAAA,UAAA;AAAA,UAAe;AAAA,QAAA,EAAA,GAjBVS,EAAM,KAmBf;AAAA,MAEJ,CAAC,GACH,GACF;AAAA,MAEF,WAAW;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,IAAA,CACX;AAED,gBAAK,IAAI,KAAK,mBAAmB,EAAE,SAAS,eAAe,SAAS,eAAe,GAE5EP;AAAA,EACT;AACF;AA/EOT,IAAAkB,EAAAjB,CAAA;AAAME,IAANgB,4BADPpB,GACaI,CAAA;AAANiB,EAAApB,GAAA,GAAMG,CAAA;"}
1
+ {"version":3,"file":"PluginImagesUsed-DWpe6M-r.js","sources":["../src/plugins/quick-usage/PluginImagesUsed.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/index.js'\nimport { QuickEditEventPayload } from '../quick-edit/index.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n imagesUsed: PluginImagesUsed\n }\n}\n\nexport interface PluginTemplatesUsedOptions {\n wikiPage?: IWikiPage\n title?: string\n pageId?: number\n revision?: number\n}\n\n@Inject(['modal', '$'])\nexport class PluginImagesUsed extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'images-used')\n }\n\n protected async start() {\n this.ctx.on('quick-edit/wiki-page', this.injectQuickEdit.bind(this))\n }\n\n injectQuickEdit(payload: QuickEditEventPayload) {\n const { $ } = this.ctx\n const { wikiPage, modal } = payload\n if (!wikiPage || !wikiPage.pageid) return\n const wrapper = this.ctx.quickUsage.getWrapperForQuickEdit(modal)\n const link = (\n <a\n href={`#ipe://quick-usage/images?title=${wikiPage.title}`}\n onClick={async (e) => {\n e.preventDefault()\n const usageModal = await this.showModal({ wikiPage })\n if (usageModal) {\n modal.on(modal.Event.Close, () => {\n usageModal.destroy()\n })\n }\n }}\n >{$`Images Used`}</a>\n )\n wrapper.appendChild(link)\n }\n\n async showModal(options: PluginTemplatesUsedOptions = {}) {\n const { $ } = this.ctx\n\n const wikiPage = options.wikiPage || (await this.ctx.wikiPage.WikiPage.newFromAnyKind(options))\n if (!wikiPage || !wikiPage.pageid) return\n\n const modal = this.ctx.modal.show({\n title: $`Images Used`,\n content: (\n <section className=\"ipe-quickUsage__images\">\n <ol>\n {wikiPage.images.map((image) => {\n const src = this.ctx.wikiFile.getFileUrl(image.title)\n return (\n <li key={image.title}>\n <a\n href={this.ctx.wiki.getUrl(image.title)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {image.title}\n </a>{' '}\n (\n <a\n href={src}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => {\n e.preventDefault()\n this.ctx.quickPreview.previewFile(src, image.title)\n }}\n >{$`Preview`}</a>\n )\n </li>\n )\n })}\n </ol>\n </section>\n ),\n sizeClass: 'dialog',\n draggable: true,\n backdrop: false,\n })\n\n this.ctx.emit('analytics/event', { feature: 'quick-usage', subtype: 'images-used' })\n\n return modal\n }\n}\n"],"names":["_PluginImagesUsed_decorators","_init","_a","Inject","PluginImagesUsed","BasePlugin","ctx","payload","$","wikiPage","modal","wrapper","link","jsx","e","usageModal","options","image","src","__decoratorStart","__decorateElement","__runInitializers"],"mappings":";;;;;;;;;;;;;;GAAAA,GAAAC,GAAAC;AAiBAF,IAAA,CAACG,EAAO,CAAC,SAAS,GAAG,CAAC,CAAA;AACf,MAAMC,WAAyBF,IAAAG,GAAW;AAAA,EAC/C,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,aAAa,GADX,KAAA,MAAAA;AAAA,EAEnB;AAAA,EAEA,MAAgB,QAAQ;AACtB,SAAK,IAAI,GAAG,wBAAwB,KAAK,gBAAgB,KAAK,IAAI,CAAC;AAAA,EACrE;AAAA,EAEA,gBAAgBC,GAAgC;AAC9C,UAAM,EAAE,GAAAC,MAAM,KAAK,KACb,EAAE,UAAAC,GAAU,OAAAC,EAAA,IAAUH;AAC5B,QAAI,CAACE,KAAY,CAACA,EAAS,OAAQ;AACnC,UAAME,IAAU,KAAK,IAAI,WAAW,uBAAuBD,CAAK,GAC1DE,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM,mCAAmCJ,EAAS,KAAK;AAAA,QACvD,SAAS,OAAOK,MAAM;AACpB,UAAAA,EAAE,eAAA;AACF,gBAAMC,IAAa,MAAM,KAAK,UAAU,EAAE,UAAAN,GAAU;AACpD,UAAIM,KACFL,EAAM,GAAGA,EAAM,MAAM,OAAO,MAAM;AAChC,YAAAK,EAAW,QAAA;AAAA,UACb,CAAC;AAAA,QAEL;AAAA,QACA,UAAAP;AAAA,MAAA;AAAA,IAAA;AAEJ,IAAAG,EAAQ,YAAYC,CAAI;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAUI,IAAsC,IAAI;AACxD,UAAM,EAAE,GAAAR,MAAM,KAAK,KAEbC,IAAWO,EAAQ,YAAa,MAAM,KAAK,IAAI,SAAS,SAAS,eAAeA,CAAO;AAC7F,QAAI,CAACP,KAAY,CAACA,EAAS,OAAQ;AAEnC,UAAMC,IAAQ,KAAK,IAAI,MAAM,KAAK;AAAA,MAChC,OAAOF;AAAA,MACP,SACE,gBAAAK,EAAC,WAAA,EAAQ,WAAU,0BACjB,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAJ,EAAS,OAAO,IAAI,CAACQ,MAAU;AAC9B,cAAMC,IAAM,KAAK,IAAI,SAAS,WAAWD,EAAM,KAAK;AACpD,iCACG,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,KAAK,IAAI,KAAK,OAAOI,EAAM,KAAK;AAAA,cACtC,QAAO;AAAA,cACP,KAAI;AAAA,cAEH,UAAAA,EAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UACJ;AAAA,UAAI;AAAA,UAET,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAMK;AAAA,cACN,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,SAAS,CAACJ,MAAM;AACd,gBAAAA,EAAE,eAAA,GACF,KAAK,IAAI,aAAa,YAAYI,GAAKD,EAAM,KAAK;AAAA,cACpD;AAAA,cACA,UAAAT;AAAA,YAAA;AAAA,UAAA;AAAA,UAAe;AAAA,QAAA,EAAA,GAjBVS,EAAM,KAmBf;AAAA,MAEJ,CAAC,GACH,GACF;AAAA,MAEF,WAAW;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,IAAA,CACX;AAED,gBAAK,IAAI,KAAK,mBAAmB,EAAE,SAAS,eAAe,SAAS,eAAe,GAE5EP;AAAA,EACT;AACF;AA/EOT,IAAAkB,EAAAjB,CAAA;AAAME,IAANgB,4BADPpB,GACaI,CAAA;AAANiB,EAAApB,GAAA,GAAMG,CAAA;"}
@@ -1,5 +1,5 @@
1
1
  import { j as r } from "./Promise.withResolvers-C4chhLB1.js";
2
- import { a as k } from "./index-CxckcdDI.js";
2
+ import { a as k } from "./index-DTU2DZU6.js";
3
3
  import { WatchlistAction as I } from "./models/index.js";
4
4
  import { BasePlugin as U } from "./core.js";
5
5
  import { A as f } from "./ActionButton-B6OUgtHx.js";
@@ -334,4 +334,4 @@ O(y, 1, m);
334
334
  export {
335
335
  m as PluginPrefSync
336
336
  };
337
- //# sourceMappingURL=PluginPrefSync-CjVsY-Ei.js.map
337
+ //# sourceMappingURL=PluginPrefSync-CmVHL2wx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluginPrefSync-CjVsY-Ei.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit.js'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction.js'\nimport { IWikiTitle } from '@/models/WikiTitle/index.js'\n\ndeclare module '@/InPageEdit' {\n export interface InPageEdit {\n prefSync: PluginPrefSync\n }\n}\n\n@Inject(['preferences', 'wiki', 'wikiPage', 'wikiTitle', 'modal', 'preferencesUI', '$'])\nexport class PluginPrefSync extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'pref-sync')\n ctx.set('prefSync', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n const $ = ctx.$\n ctx.preferences.defineCategory({\n name: 'pref-sync',\n label: $`Sync`,\n description: $`Import and export preferences`,\n index: 98,\n customRenderer: () => {\n const userPageTitle = this.getUserPrefsPageTitle()\n return (\n <div className=\"theme-ipe-prose\">\n {userPageTitle && (\n <section>\n <h3>{$`Backup your preferences via user page`}</h3>\n <p>\n <a href={userPageTitle?.getURL().toString()} target=\"_blank\">\n {userPageTitle?.getPrefixedText()} →\n </a>\n </p>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n type=\"primary\"\n onClick={(e) => {\n e.preventDefault()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n this.exportToUserPage()\n .then((title) => {\n ctx.modal.notify('success', {\n title: $`Preferences Exported`,\n content: (\n <p>\n Your preferences have been exported to{' '}\n <a href={title.getURL().toString()} target=\"_blank\">\n {title.getPrefixedText()}\n </a>\n .\n </p>\n ),\n })\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-up\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.57 .811 3.128 1.986\" />\n <path d=\"M19 22v-6\" />\n <path d=\"M22 19l-3 -3l-3 3\" />\n </svg>{' '}\n {$`Backup`}\n </ActionButton>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n modal?.setLoadingState(true)\n this.importFromUserPage()\n .then((record) => {\n this.notifyImportSuccess(record)\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-down\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.573 .813 3.13 1.99\" />\n <path d=\"M19 16v6\" />\n <path d=\"M22 19l-3 3l-3 -3\" />\n </svg>{' '}\n {$`Restore`}\n </ActionButton>\n </div>\n </section>\n )}\n <section>\n <h3>{$`Import and export preferences`}</h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = 'application/json'\n // Mobile Safari (and some older browsers) do not fire a 'cancel' event when\n // the file picker is dismissed without selecting a file. We use a\n // window 'focus' listener as a heuristic: once the picker closes\n // the window regains focus; if no file was chosen we treat it as cancel.\n // Fuck you Apple\n let handled = false\n const onDialogClose = () => {\n // If change handler did not run, treat as cancel\n if (!handled) {\n modal?.setLoadingState(false)\n }\n window.removeEventListener('focus', onDialogClose)\n }\n window.addEventListener('focus', onDialogClose, { once: true })\n\n input.addEventListener('change', async (e) => {\n handled = true\n try {\n const file = (e.target as HTMLInputElement).files?.[0]\n if (!file) {\n return\n }\n const record = await this.importFromFile(file)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n })\n input.click()\n }}\n >\n {$`Import from file`}\n </ActionButton>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const input = (\n <input type=\"url\" style={{ width: '100%' }}></input>\n ) as HTMLInputElement\n const modal = ctx.preferencesUI.getCurrentModal()\n ctx.modal.confirm(\n {\n title: $`Import from URL`,\n content: (\n <div className=\"ipe-input-box\">\n <label htmlFor=\"url-input\">\n {$`Enter the URL of the preferences JSON file:`}\n </label>\n {input}\n </div>\n ),\n },\n async (result) => {\n const url = input.value.trim()\n if (!result || !url) {\n return\n }\n try {\n modal?.setLoadingState(true)\n const record = await this.importFromUrl(url)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n }\n )\n }}\n >\n {$`Import from URL`}\n </ActionButton>\n <ActionButton\n onClick={async (e) => {\n e.preventDefault()\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n const data = await ctx.preferences.getExportableRecord()\n const json = JSON.stringify(data, null, 2)\n ctx.modal.dialog(\n {\n title: $`Save to file`,\n content: (\n <div>\n <label htmlFor=\"data\">{$`Your InPageEdit preferences:`}</label>\n <textarea\n name=\"data\"\n id=\"data\"\n rows={10}\n value={json}\n readOnly\n style={{ width: '100%' }}\n ></textarea>\n </div>\n ),\n buttons: [\n {\n label: 'Copy',\n method: (_, m) => {\n navigator.clipboard.writeText(json)\n ctx.modal.notify('success', {\n content: $`Copied to clipboard`,\n })\n m.close()\n },\n },\n {\n label: $`Download`,\n method: (_, m) => {\n const a = document.createElement('a')\n a.href = `data:text/json;charset=utf-8,${encodeURIComponent(json)}`\n a.download = `ipe-prefs-${new Date().toISOString()}.json`\n a.click()\n m.close()\n },\n },\n ],\n },\n () => {}\n )\n }}\n >\n {$`Save as file`}\n </ActionButton>\n </div>\n </section>\n </div>\n )\n },\n })\n }\n\n protected stop(): Promise<void> | void {}\n\n /**\n * 获取用户页配置文件的标题\n */\n private getUserPrefsPageTitle(): IWikiTitle | null {\n try {\n const userName = this.ctx.wiki?.userInfo?.name\n if (!userName) {\n return null\n }\n // 使用 User: 命名空间\n return this.ctx.wikiTitle.newTitle(`User:${userName}/ipe-prefs.json`, 2)\n } catch {\n return null\n }\n }\n\n /**\n * 从用户页加载配置\n */\n async importFromUserPage(): Promise<Record<string, unknown>> {\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n this.logger.debug('Cannot get user page title, skipping load')\n return {}\n }\n\n try {\n // 使用 raw action 获取 JSON 内容\n const rawUrl = title.getURL({ action: 'raw', ctype: 'application/json' })\n const changed = await this.importFromUrl(rawUrl.toString())\n this.logger.info('Loaded preferences from user page:', title)\n return changed\n } catch (error) {\n this.logger.error('Failed to load preferences from user page:', error)\n return {}\n }\n }\n\n /**\n * 导出配置到用户页\n */\n async exportToUserPage(): Promise<IWikiTitle> {\n const ctx = this.ctx\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n throw new Error('Cannot get user page title')\n }\n\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n\n const json = await ctx.preferences.getExportableRecord()\n const text = JSON.stringify(json, null, 2)\n\n try {\n const page = this.ctx.wikiPage.newBlankPage({\n title: title.toString(),\n ns: 2, // User namespace\n })\n await page.edit({\n text,\n summary: 'Update InPageEdit preferences',\n watchlist: WatchlistAction.nochange,\n })\n\n this.logger.info('Exported preferences to user page:', title)\n return title\n } catch (error) {\n this.logger.error('Failed to export preferences to user page:', error)\n throw error\n }\n }\n\n async importFromUrl(input: string): Promise<Record<string, unknown>> {\n const response = await fetch(input)\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n const blob = await response.blob()\n const changed = await this.importFromFile(blob)\n return changed\n }\n\n async importFromFile(input: Blob): Promise<Record<string, unknown>> {\n const text = await input.text()\n const data = JSON.parse(text)\n const changed = await this.ctx.preferences.setMany(data)\n return changed\n }\n\n private notifyImportSuccess(configs?: Record<string, unknown>) {\n const { $ } = this.ctx\n const keys = Object.keys(configs ?? {})\n const count = keys.length\n return this.ctx.modal.notify('success', {\n title: $`Preferences Imported`,\n content: (\n <section>\n <p>\n {$({\n count,\n })`Successfully imported {{ count }} {{ count > 1 ? \"settings\" : \"setting\" }}:`}\n </p>\n <ol style={{ listStyle: 'auto', paddingLeft: '1em' }}>\n {keys.map((key) => (\n <li key={key}>{key}</li>\n ))}\n </ol>\n </section>\n ),\n })\n }\n}\n"],"names":["_PluginPrefSync_decorators","_init","_a","Inject","PluginPrefSync","BasePlugin","ctx","$","userPageTitle","jsxs","jsx","ActionButton","e","btn","modal","title","record","input","handled","onDialogClose","file","result","url","data","json","_","m","a","userName","rawUrl","changed","error","text","WatchlistAction","response","blob","configs","keys","count","key","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
1
+ {"version":3,"file":"PluginPrefSync-CmVHL2wx.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit.js'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction.js'\nimport { IWikiTitle } from '@/models/WikiTitle/index.js'\n\ndeclare module '@/InPageEdit' {\n export interface InPageEdit {\n prefSync: PluginPrefSync\n }\n}\n\n@Inject(['preferences', 'wiki', 'wikiPage', 'wikiTitle', 'modal', 'preferencesUI', '$'])\nexport class PluginPrefSync extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'pref-sync')\n ctx.set('prefSync', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n const $ = ctx.$\n ctx.preferences.defineCategory({\n name: 'pref-sync',\n label: $`Sync`,\n description: $`Import and export preferences`,\n index: 98,\n customRenderer: () => {\n const userPageTitle = this.getUserPrefsPageTitle()\n return (\n <div className=\"theme-ipe-prose\">\n {userPageTitle && (\n <section>\n <h3>{$`Backup your preferences via user page`}</h3>\n <p>\n <a href={userPageTitle?.getURL().toString()} target=\"_blank\">\n {userPageTitle?.getPrefixedText()} →\n </a>\n </p>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n type=\"primary\"\n onClick={(e) => {\n e.preventDefault()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n this.exportToUserPage()\n .then((title) => {\n ctx.modal.notify('success', {\n title: $`Preferences Exported`,\n content: (\n <p>\n Your preferences have been exported to{' '}\n <a href={title.getURL().toString()} target=\"_blank\">\n {title.getPrefixedText()}\n </a>\n .\n </p>\n ),\n })\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-up\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.57 .811 3.128 1.986\" />\n <path d=\"M19 22v-6\" />\n <path d=\"M22 19l-3 -3l-3 3\" />\n </svg>{' '}\n {$`Backup`}\n </ActionButton>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n modal?.setLoadingState(true)\n this.importFromUserPage()\n .then((record) => {\n this.notifyImportSuccess(record)\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-down\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.573 .813 3.13 1.99\" />\n <path d=\"M19 16v6\" />\n <path d=\"M22 19l-3 3l-3 -3\" />\n </svg>{' '}\n {$`Restore`}\n </ActionButton>\n </div>\n </section>\n )}\n <section>\n <h3>{$`Import and export preferences`}</h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = 'application/json'\n // Mobile Safari (and some older browsers) do not fire a 'cancel' event when\n // the file picker is dismissed without selecting a file. We use a\n // window 'focus' listener as a heuristic: once the picker closes\n // the window regains focus; if no file was chosen we treat it as cancel.\n // Fuck you Apple\n let handled = false\n const onDialogClose = () => {\n // If change handler did not run, treat as cancel\n if (!handled) {\n modal?.setLoadingState(false)\n }\n window.removeEventListener('focus', onDialogClose)\n }\n window.addEventListener('focus', onDialogClose, { once: true })\n\n input.addEventListener('change', async (e) => {\n handled = true\n try {\n const file = (e.target as HTMLInputElement).files?.[0]\n if (!file) {\n return\n }\n const record = await this.importFromFile(file)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n })\n input.click()\n }}\n >\n {$`Import from file`}\n </ActionButton>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const input = (\n <input type=\"url\" style={{ width: '100%' }}></input>\n ) as HTMLInputElement\n const modal = ctx.preferencesUI.getCurrentModal()\n ctx.modal.confirm(\n {\n title: $`Import from URL`,\n content: (\n <div className=\"ipe-input-box\">\n <label htmlFor=\"url-input\">\n {$`Enter the URL of the preferences JSON file:`}\n </label>\n {input}\n </div>\n ),\n },\n async (result) => {\n const url = input.value.trim()\n if (!result || !url) {\n return\n }\n try {\n modal?.setLoadingState(true)\n const record = await this.importFromUrl(url)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n }\n )\n }}\n >\n {$`Import from URL`}\n </ActionButton>\n <ActionButton\n onClick={async (e) => {\n e.preventDefault()\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n const data = await ctx.preferences.getExportableRecord()\n const json = JSON.stringify(data, null, 2)\n ctx.modal.dialog(\n {\n title: $`Save to file`,\n content: (\n <div>\n <label htmlFor=\"data\">{$`Your InPageEdit preferences:`}</label>\n <textarea\n name=\"data\"\n id=\"data\"\n rows={10}\n value={json}\n readOnly\n style={{ width: '100%' }}\n ></textarea>\n </div>\n ),\n buttons: [\n {\n label: 'Copy',\n method: (_, m) => {\n navigator.clipboard.writeText(json)\n ctx.modal.notify('success', {\n content: $`Copied to clipboard`,\n })\n m.close()\n },\n },\n {\n label: $`Download`,\n method: (_, m) => {\n const a = document.createElement('a')\n a.href = `data:text/json;charset=utf-8,${encodeURIComponent(json)}`\n a.download = `ipe-prefs-${new Date().toISOString()}.json`\n a.click()\n m.close()\n },\n },\n ],\n },\n () => {}\n )\n }}\n >\n {$`Save as file`}\n </ActionButton>\n </div>\n </section>\n </div>\n )\n },\n })\n }\n\n protected stop(): Promise<void> | void {}\n\n /**\n * 获取用户页配置文件的标题\n */\n private getUserPrefsPageTitle(): IWikiTitle | null {\n try {\n const userName = this.ctx.wiki?.userInfo?.name\n if (!userName) {\n return null\n }\n // 使用 User: 命名空间\n return this.ctx.wikiTitle.newTitle(`User:${userName}/ipe-prefs.json`, 2)\n } catch {\n return null\n }\n }\n\n /**\n * 从用户页加载配置\n */\n async importFromUserPage(): Promise<Record<string, unknown>> {\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n this.logger.debug('Cannot get user page title, skipping load')\n return {}\n }\n\n try {\n // 使用 raw action 获取 JSON 内容\n const rawUrl = title.getURL({ action: 'raw', ctype: 'application/json' })\n const changed = await this.importFromUrl(rawUrl.toString())\n this.logger.info('Loaded preferences from user page:', title)\n return changed\n } catch (error) {\n this.logger.error('Failed to load preferences from user page:', error)\n return {}\n }\n }\n\n /**\n * 导出配置到用户页\n */\n async exportToUserPage(): Promise<IWikiTitle> {\n const ctx = this.ctx\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n throw new Error('Cannot get user page title')\n }\n\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n\n const json = await ctx.preferences.getExportableRecord()\n const text = JSON.stringify(json, null, 2)\n\n try {\n const page = this.ctx.wikiPage.newBlankPage({\n title: title.toString(),\n ns: 2, // User namespace\n })\n await page.edit({\n text,\n summary: 'Update InPageEdit preferences',\n watchlist: WatchlistAction.nochange,\n })\n\n this.logger.info('Exported preferences to user page:', title)\n return title\n } catch (error) {\n this.logger.error('Failed to export preferences to user page:', error)\n throw error\n }\n }\n\n async importFromUrl(input: string): Promise<Record<string, unknown>> {\n const response = await fetch(input)\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n const blob = await response.blob()\n const changed = await this.importFromFile(blob)\n return changed\n }\n\n async importFromFile(input: Blob): Promise<Record<string, unknown>> {\n const text = await input.text()\n const data = JSON.parse(text)\n const changed = await this.ctx.preferences.setMany(data)\n return changed\n }\n\n private notifyImportSuccess(configs?: Record<string, unknown>) {\n const { $ } = this.ctx\n const keys = Object.keys(configs ?? {})\n const count = keys.length\n return this.ctx.modal.notify('success', {\n title: $`Preferences Imported`,\n content: (\n <section>\n <p>\n {$({\n count,\n })`Successfully imported {{ count }} {{ count > 1 ? \"settings\" : \"setting\" }}:`}\n </p>\n <ol style={{ listStyle: 'auto', paddingLeft: '1em' }}>\n {keys.map((key) => (\n <li key={key}>{key}</li>\n ))}\n </ol>\n </section>\n ),\n })\n }\n}\n"],"names":["_PluginPrefSync_decorators","_init","_a","Inject","PluginPrefSync","BasePlugin","ctx","$","userPageTitle","jsxs","jsx","ActionButton","e","btn","modal","title","record","input","handled","onDialogClose","file","result","url","data","json","_","m","a","userName","rawUrl","changed","error","text","WatchlistAction","response","blob","configs","keys","count","key","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { a as K, l as P, e as d, h as u, y as U, C as te, k as G, r as w, f as q, q as i, D as L, z as c, B as p, E as Y, G as J, H as D, I as F, F as Q, x as W, v as A, g as ie } from "./vueHooks-Bs93iP61.js";
2
2
  import { c as T } from "./Promise.withResolvers-C4chhLB1.js";
3
- import { E as re } from "./index-CxckcdDI.js";
3
+ import { E as re } from "./index-DTU2DZU6.js";
4
4
  import { _ as O } from "./_plugin-vue_export-helper-CHgC5LLL.js";
5
5
  const H = /* @__PURE__ */ K({
6
6
  __name: "UIBaseButton",
@@ -454,4 +454,4 @@ ${e.join(`
454
454
  export {
455
455
  Ze as default
456
456
  };
457
- //# sourceMappingURL=PluginStoreApp-DKxtArs5.js.map
457
+ //# sourceMappingURL=PluginStoreApp-CmLstT3F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluginStoreApp-DKxtArs5.js","sources":["../src/plugins/plugin-store/components/ui/UIBaseButton.vue","../src/plugins/plugin-store/components/RegistryManager.vue","../src/plugins/plugin-store/components/PluginInstallManager.vue"],"sourcesContent":["<template lang=\"pug\">\nbutton.ipeps-button(:class='buttonClass')\n slot\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { computed } from 'vue'\n\nconst props = withDefaults(\n defineProps<{\n variant?: 'neutral' | 'primary' | 'danger' | 'ghost' | 'accent'\n active?: boolean\n }>(),\n {\n variant: 'neutral',\n active: false,\n }\n)\n\nconst buttonClass = computed(() => ({\n 'is-active': props.active,\n 'is-danger': props.variant === 'danger',\n 'is-primary': props.variant === 'primary',\n 'is-ghost': props.variant === 'ghost',\n 'is-accent': props.variant === 'accent',\n}))\n</script>\n","<template lang=\"pug\">\n#ipe-registry-manager\n .ipeps-header\n .ipeps-header-title {{ $`Registries` }}\n .ipeps-input-wrapper\n input.ipeps-input.with-icon(\n v-model.trim='inputValue',\n type='url',\n :placeholder='$`Add registry URL` + ` (https://...)`',\n :disabled='isAdding'\n )\n .ipeps-input-icon 📦\n UIBaseButton(@click='onAddRegistry', :disabled='isAdding || !inputValue', variant='primary') {{ isAdding ? $`Adding...` : $`Add` }}\n\n .ipeps-list(v-if='registries.length')\n .ipeps-item(v-for='reg in registries', :key='reg.registryUrl')\n .registry-info\n .item-name {{ reg.label }}\n .item-desc\n .homepage: a(v-if='reg.homepage', :href='reg.homepage', target='_blank') {{ reg.homepage }}\n .url {{ reg.registryUrl }}\n .item-meta {{ reg.packages.length }} packages\n .ipeps-actions\n UIBaseButton(@click='onRemoveRegistry(reg.registryUrl)', variant='danger') {{ $`Remove` }}\n .ipeps-empty(v-else)\n .icon 🗂️\n .text {{ $`No registries configured` }}\n .description\n UIBaseButton(\n @click='onAddOfficialRegistry',\n variant='primary',\n style='padding: 0.25rem 0.5rem'\n ) {{ $`Setup default registry` }}\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { onMounted, ref } from 'vue'\nimport { h } from 'jsx-dom'\nimport type { PluginStoreRegistry } from '../schema.js'\nimport UIBaseButton from './ui/UIBaseButton.vue'\n\nconst ctx = useIPE()\nconst $ = ctx.$\nconst $$ = ctx.$$\n\ninterface RegistryViewModel extends PluginStoreRegistry {\n registryUrl: string\n label: string\n}\n\nconst registries = ref<RegistryViewModel[]>([])\nconst inputValue = ref('')\nconst isAdding = ref(false)\n\nconst urlToLabel = (u: string) => {\n try {\n return new URL(u).hostname\n } catch {\n return u\n }\n}\n\nasync function loadRegistries() {\n const urls = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n const results = await Promise.allSettled(\n urls.map(async (url) => {\n const info = await ctx.store.getRegistryInfo(url)\n return {\n registryUrl: url,\n label: urlToLabel(url),\n ...info,\n } as RegistryViewModel\n })\n )\n registries.value = results\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryViewModel>).value)\n}\n\nasync function onAddRegistry() {\n const url = inputValue.value.trim()\n if (!url) return\n if (registries.value.some((r) => r.registryUrl === url)) {\n ctx.modal.notify('info', { content: 'Registry already exists.' })\n return\n }\n isAdding.value = true\n try {\n // try load immediately\n const info = await ctx.store.getRegistryInfo(url, 'online_manifest', true)\n if (!info) {\n throw new Error('Invalid registry or unreachable')\n }\n const current = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n current.push(url)\n await ctx.preferences.set('pluginStore.registries', current)\n registries.value.push({\n registryUrl: url,\n label: urlToLabel(url),\n ...info,\n })\n inputValue.value = ''\n ctx.modal.notify('success', { content: 'Registry added.' })\n } catch (e) {\n ctx.modal.notify('error', {\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n isAdding.value = false\n }\n}\n\nasync function removeRegistryUrl(url: string) {\n const current = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n const next = current.filter((u) => u !== url)\n await ctx.preferences.set('pluginStore.registries', next)\n registries.value = registries.value.filter((r) => r.registryUrl !== url)\n}\n\nasync function onRemoveRegistry(url: string) {\n const installed =\n (await ctx.preferences.get<{ registry: string; id: string }[]>('pluginStore.plugins')) || []\n const installedOfReg = installed.filter((p) => p.registry === url)\n if (installedOfReg.length === 0) {\n ctx.modal.confirm(\n {\n title: $$`plugin-store.remove-registry.title`,\n content: $$`plugin-store.remove-registry.tip-content` + `\\n${url}`,\n cancelBtn: {\n label: $`Cancel`,\n className: 'is-ghost',\n },\n okBtn: {\n label: $`Remove`,\n className: 'is-danger',\n },\n },\n async (ok) => {\n if (!ok) return\n await removeRegistryUrl(url)\n ctx.modal.notify('success', { content: $$`plugin-store.remove-registry.remove-success` })\n }\n )\n return\n }\n\n ctx.modal.dialog(\n {\n title: $$`plugin-store.remove-registry.title`,\n content: h('div', { class: 'theme-ipe-prose' }, [\n h(\n 'p',\n {},\n $$({ count: installedOfReg.length })`plugin-store.remove-registry.confirm-content`\n ),\n h(\n 'ul',\n {},\n installedOfReg.map((p) => h('li', {}, p.id))\n ),\n ]),\n buttons: [\n {\n label: $$`plugin-store.remove-registry.buttons.remove-only`,\n className: 'is-danger is-ghost',\n method: async (_, m) => {\n await removeRegistryUrl(url)\n ctx.modal.notify('success', {\n content: $$`plugin-store.remove-registry.remove-success`,\n })\n m.close()\n },\n },\n {\n label: $$`plugin-store.remove-registry.buttons.remove-and-uninstall`,\n className: 'is-danger',\n method: async (_, m) => {\n await removeRegistryUrl(url)\n for (const p of installedOfReg) {\n try {\n await ctx.store.uninstallAndRemovePreference(p.registry, p.id)\n } catch (e) {\n // best-effort; notify but continue\n ctx.modal.notify('error', {\n content:\n e instanceof Error\n ? `Failed to uninstall ${p.id}: ${e.message}`\n : `Failed to uninstall ${p.id}`,\n })\n }\n }\n ctx.modal.notify('success', {\n content: $$({\n $1: installedOfReg.length,\n })`plugin-store.remove-registry.remove-with-plugins-success`,\n })\n m.close()\n },\n },\n ],\n },\n () => {}\n )\n}\n\nfunction onPreferencesChanged(payload: { changes: Record<string, unknown> }) {\n const regs = payload.changes['pluginStore.registries'] as string[]\n if (Array.isArray(regs)) {\n loadRegistries()\n }\n}\n\nfunction onAddOfficialRegistry() {\n const url = Endpoints.PLUGIN_REGISTRY_URL\n inputValue.value = url\n onAddRegistry()\n}\n\nonMounted(() => {\n loadRegistries()\n ctx.on('preferences/changed', onPreferencesChanged)\n})\n</script>\n\n<style scoped lang=\"scss\">\n@use './style.scss' as *;\n\n.registry-info {\n flex: 1;\n min-width: 0;\n .homepage {\n margin-top: 0.25rem;\n a {\n color: var(--ipe-modal-accent);\n text-decoration: none;\n font-size: 0.8125rem;\n transition: all 0.2s ease;\n &:hover {\n color: color-mix(in srgb, var(--ipe-modal-accent) 80%, var(--ipe-modal-text));\n text-decoration: underline;\n }\n }\n }\n .url {\n font-family: monospace;\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n margin-top: 0.125rem;\n word-break: break-all;\n }\n}\n</style>\n","<template lang=\"pug\">\n#ipe-plugin-install-manager\n .ipeps-header\n .ipeps-header-title {{ $`Plugins` }}\n .ipeps-input-wrapper\n input.ipeps-input.with-icon(\n v-model.trim='searchInput',\n type='text',\n :placeholder='$`Search plugins...`',\n :disabled='!pluginsFromRegistries.length'\n )\n .ipeps-input-icon 🔍\n button.ipeps-button(\n @click='refreshRegistries',\n :disabled='isRefreshing || !hasRegistries',\n :class='{ refreshing: isRefreshing }',\n variant='primary'\n ) {{ isRefreshing ? $`Refreshing...` : $`Refresh` }}\n\n .ipeps-loading(v-if='!hasRegistries && !firstInit')\n .loading-spinner\n .loading-text {{ $`Loading...` }}\n\n .ipeps-list(v-else-if='allPluginsToDisplay.length')\n .ipeps-item(\n v-for='plugin in allPluginsToDisplay',\n :key='plugin._key',\n :class='{ installed: isInstalledKey(plugin._key), broken: plugin.isBroken }'\n )\n .plugin-info\n .plugin-header\n .item-name {{ plugin.name || plugin.id }}\n span.ipeps-badge(\n v-if='isInstalledKey(plugin._key) || plugin.isBroken',\n :class='{ \"is-installed\": isInstalledKey(plugin._key), \"is-broken\": plugin.isBroken }'\n ) {{ plugin.isBroken ? $$`plugin-store.tags.broken` : $$`plugin-store.tags.installed` }}\n .ipeps-tags\n a.ipeps-tag.registry-tag(\n v-if='plugin.registryHomepage && !plugin.isRegistryMissing',\n :href='plugin.registryHomepage',\n target='_blank',\n :title='plugin.registryLabel'\n ) {{ plugin.registryLabel }}\n span.ipeps-tag.registry-tag(\n v-else,\n :title='plugin.registryLabel',\n :class='{ broken: plugin.isRegistryMissing }'\n ) {{ plugin.registryLabel }}\n .plugin-id.ipeps-tag(:class='{ broken: plugin.isBroken && !plugin.isRegistryMissing }') {{ plugin.id }}\n .plugin-desc(:class='{ \"broken-desc\": plugin.isBroken }') {{ getDesc(plugin) }}\n .plugin-meta\n span.version(v-if='plugin.version') v{{ plugin.version }}\n span.author(v-if='plugin.author') 👤 {{ plugin.author }}\n span.license(v-if='plugin.license') 📜 {{ plugin.license }}\n UIBaseButton(\n :active='isInstalledKey(plugin._key)',\n :variant='isInstalledKey(plugin._key) ? \"danger\" : \"primary\"',\n @click='togglePluginByKey(plugin)'\n ) {{ isInstalledKey(plugin._key) ? $`Remove` : $`Install` }}\n\n .ipeps-empty(v-else)\n .plugin-empty-icon 📦\n .plugin-empty-text {{ $`No matching plugins found` }}\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport type { PluginStorePackage, PluginStoreRegistry } from '../schema.js'\nimport UIBaseButton from './ui/UIBaseButton.vue'\n\ninterface RegistryWithUrl extends PluginStoreRegistry {\n registryUrl: string\n}\ninterface PluginIdentifier {\n registry: string\n id: string\n}\n\ninterface PluginViewModel extends PluginStorePackage {\n _key: string\n registry: string\n registryHomepage: string\n registryLabel: string\n isBroken: boolean\n isRegistryMissing: boolean\n}\n\n// --- state ---\nconst ctx = useIPE()\nconst $ = ctx.$\nconst $$ = ctx.$$\nconst registryInfos = ref<RegistryWithUrl[]>([])\nconst installedPlugins = ref<PluginIdentifier[]>([])\nconst searchInput = ref('')\nconst isRefreshing = ref(false)\n\n// helpers\nconst makeKey = (r: string, id: string) => `${r}\\n${id}` // stable + O(1)\n\nconst installedKeySet = computed(\n () => new Set(installedPlugins.value.map((p) => makeKey(p.registry, p.id)))\n)\nconst isInstalledKey = (key: string) => installedKeySet.value.has(key)\n\nconst urlToLabel = (registryUrl: string) => {\n try {\n return new URL(registryUrl).hostname\n } catch {\n return registryUrl\n }\n}\n\nconst firstInit = ref(false)\nconst hasRegistries = computed(() => registryInfos.value.length > 0)\n\nconst pluginsFromRegistries = computed<PluginViewModel[]>(\n () =>\n registryInfos.value.flatMap((reg) =>\n (reg.packages || []).map((pkg) => ({\n ...pkg,\n _key: makeKey(reg.registryUrl, pkg.id),\n registry: reg.registryUrl,\n registryHomepage: reg.homepage,\n registryLabel: urlToLabel(reg.registryUrl),\n isBroken: false,\n isRegistryMissing: false,\n }))\n ) as PluginViewModel[]\n)\n\n// merge normal + broken, and normalize once here\nconst normalizedPlugins = computed(() => {\n const q = searchInput.value.trim().toLowerCase()\n\n const all: Array<any> = pluginsFromRegistries.value\n\n // broken installed plugins (installed but not available now)\n const availableKeys = new Set(all.map((p) => p._key))\n const availableRegs = new Set(registryInfos.value.map((r) => r.registryUrl))\n\n const broken = installedPlugins.value\n .filter((p) => !availableKeys.has(makeKey(p.registry, p.id)))\n .map((p) => {\n const regInfo = registryInfos.value.find((r) => r.registryUrl === p.registry)\n return {\n id: p.id,\n name: undefined,\n description: undefined,\n version: undefined,\n author: undefined,\n license: undefined,\n _key: makeKey(p.registry, p.id),\n registry: p.registry,\n registryHomepage: regInfo?.homepage,\n registryLabel: urlToLabel(p.registry),\n isBroken: true,\n isRegistryMissing: !availableRegs.has(p.registry),\n }\n })\n\n const filtered = (list: any[]) => {\n if (!q) return list\n return list.filter(\n (p) =>\n (p.name && p.name.toLowerCase().includes(q)) ||\n (p.id && p.id.toLowerCase().includes(q)) ||\n (p.description && p.description.toLowerCase().includes(q)) ||\n (p.author && p.author.toLowerCase().includes(q)) ||\n (p.registry && p.registry.toLowerCase().includes(q))\n )\n }\n\n // broken on top\n return [...filtered(broken), ...filtered(all)]\n})\n\nconst allPluginsToDisplay = computed(() => normalizedPlugins.value)\n\nconst getDesc = (p: any) => {\n if (p.description) return p.description\n if (!p.isBroken) return ''\n return p.isRegistryMissing\n ? $$`plugin-store.broken.registry-unavailable`\n : $$`plugin-store.broken.plugin-removed`\n}\n\n// actions\nconst enablePlugin = async (registry: string, id: string) => {\n ctx.store.installAndSetPreference(registry, id)\n}\nconst disablePlugin = async (registry: string, id: string) => {\n ctx.store.uninstallAndRemovePreference(registry, id)\n}\nconst togglePlugin = (registry: string, id: string) =>\n isInstalledKey(makeKey(registry, id)) ? disablePlugin(registry, id) : enablePlugin(registry, id)\nconst togglePluginByKey = (p: any) => togglePlugin(p.registry, p.id)\n\nconst refreshRegistries = async () => {\n if (isRefreshing.value) return\n if (registryInfos.value.length === 0) {\n ctx.modal.notify('info', {\n content: 'No registry configured. Please add a registry first.',\n })\n return\n }\n\n isRefreshing.value = true\n const results = await ctx.store.refreshAllRegistryCaches()\n const okResults = Object.entries(results).filter(([_, r]) => r !== null)\n registryInfos.value = okResults.map(([url, r]) => ({\n ...r!,\n registryUrl: url,\n }))\n const failedUrls = Object.entries(results)\n .filter(([_, r]) => r === null)\n .map(([url]) => url)\n isRefreshing.value = false\n\n if (okResults.length === 0) {\n ctx.modal.notify('error', {\n content: 'All registries failed to refresh',\n })\n } else {\n ctx.modal.notify('success', {\n content: `${okResults.length} ${okResults.length === 1 ? 'registry' : 'registries'} refreshed successfully.`,\n })\n if (failedUrls.length > 0) {\n ctx.modal.notify('warning', {\n content: `${failedUrls.length} ${failedUrls.length === 1 ? 'registry' : 'registries'} failed to refresh:\\n${failedUrls.join('\\n')}`,\n })\n }\n }\n}\n\n// init\nconst init = async () => {\n firstInit.value = false\n const urls = (await ctx.store.ctx.preferences.get('pluginStore.registries')) || []\n const regResults = await Promise.allSettled(\n urls.map(async (url: string) => ({\n ...(await ctx.store.getRegistryInfo(url)),\n registryUrl: url,\n }))\n )\n registryInfos.value = regResults\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryWithUrl>).value)\n\n installedPlugins.value = (await ctx.preferences.get('pluginStore.plugins')) || []\n\n firstInit.value = true\n}\n\nfunction onPreferencesChanged(payload: { changes: Record<string, unknown> }) {\n const regs = payload.changes['pluginStore.registries'] as string[]\n const plugins = payload.changes['pluginStore.plugins'] as PluginIdentifier[]\n if (Array.isArray(plugins)) installedPlugins.value = plugins\n if (Array.isArray(regs)) {\n init()\n }\n}\n\nonMounted(() => {\n init()\n ctx.on('preferences/changed', onPreferencesChanged)\n})\nonBeforeUnmount(() => {})\n</script>\n\n<style scoped lang=\"scss\">\n@use './style.scss' as *;\n\n.plugin-info {\n flex: 1;\n min-width: 0;\n}\n.plugin-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.375rem;\n}\n.registry-tag {\n color: var(--ipe-modal-accent);\n background: color-mix(in srgb, var(--ipe-modal-accent) 8%, transparent);\n border: 1px solid color-mix(in srgb, var(--ipe-modal-accent) 18%, transparent);\n text-decoration: none;\n transition: all 0.2s ease;\n &:hover {\n background: color-mix(in srgb, var(--ipe-modal-accent) 12%, transparent);\n border-color: color-mix(in srgb, var(--ipe-modal-accent) 30%, transparent);\n }\n &.broken {\n text-decoration: line-through;\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n.plugin-id {\n &.broken {\n opacity: 0.65;\n text-decoration: line-through;\n }\n}\n.plugin-desc {\n font-size: 0.8125rem;\n color: var(--ipe-modal-muted);\n margin-bottom: 0.5rem;\n line-height: 1.6;\n &.broken-desc {\n color: color-mix(in srgb, var(--ipe-modal-warning) 80%, var(--ipe-modal-text));\n font-style: italic;\n }\n}\n.plugin-meta {\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n display: flex;\n gap: 1rem;\n align-items: center;\n .version {\n font-family: monospace;\n font-weight: 500;\n color: color-mix(in srgb, var(--ipe-modal-text) 80%, var(--ipe-modal-muted));\n }\n .author {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n .license {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n}\n</style>\n"],"names":["props","__props","buttonClass","computed","ctx","useIPE","$","$$","registries","ref","inputValue","isAdding","urlToLabel","u","loadRegistries","urls","results","url","info","r","onAddRegistry","current","e","removeRegistryUrl","next","onRemoveRegistry","installedOfReg","p","ok","h","_","m","onPreferencesChanged","payload","regs","onAddOfficialRegistry","Endpoints","onMounted","registryInfos","installedPlugins","searchInput","isRefreshing","makeKey","id","installedKeySet","isInstalledKey","key","registryUrl","firstInit","hasRegistries","pluginsFromRegistries","reg","pkg","normalizedPlugins","q","all","availableKeys","availableRegs","broken","regInfo","filtered","list","allPluginsToDisplay","getDesc","enablePlugin","registry","disablePlugin","togglePlugin","togglePluginByKey","refreshRegistries","okResults","failedUrls","init","regResults","plugins","onBeforeUnmount"],"mappings":"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"}
1
+ {"version":3,"file":"PluginStoreApp-CmLstT3F.js","sources":["../src/plugins/plugin-store/components/ui/UIBaseButton.vue","../src/plugins/plugin-store/components/RegistryManager.vue","../src/plugins/plugin-store/components/PluginInstallManager.vue"],"sourcesContent":["<template lang=\"pug\">\nbutton.ipeps-button(:class='buttonClass')\n slot\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { computed } from 'vue'\n\nconst props = withDefaults(\n defineProps<{\n variant?: 'neutral' | 'primary' | 'danger' | 'ghost' | 'accent'\n active?: boolean\n }>(),\n {\n variant: 'neutral',\n active: false,\n }\n)\n\nconst buttonClass = computed(() => ({\n 'is-active': props.active,\n 'is-danger': props.variant === 'danger',\n 'is-primary': props.variant === 'primary',\n 'is-ghost': props.variant === 'ghost',\n 'is-accent': props.variant === 'accent',\n}))\n</script>\n","<template lang=\"pug\">\n#ipe-registry-manager\n .ipeps-header\n .ipeps-header-title {{ $`Registries` }}\n .ipeps-input-wrapper\n input.ipeps-input.with-icon(\n v-model.trim='inputValue',\n type='url',\n :placeholder='$`Add registry URL` + ` (https://...)`',\n :disabled='isAdding'\n )\n .ipeps-input-icon 📦\n UIBaseButton(@click='onAddRegistry', :disabled='isAdding || !inputValue', variant='primary') {{ isAdding ? $`Adding...` : $`Add` }}\n\n .ipeps-list(v-if='registries.length')\n .ipeps-item(v-for='reg in registries', :key='reg.registryUrl')\n .registry-info\n .item-name {{ reg.label }}\n .item-desc\n .homepage: a(v-if='reg.homepage', :href='reg.homepage', target='_blank') {{ reg.homepage }}\n .url {{ reg.registryUrl }}\n .item-meta {{ reg.packages.length }} packages\n .ipeps-actions\n UIBaseButton(@click='onRemoveRegistry(reg.registryUrl)', variant='danger') {{ $`Remove` }}\n .ipeps-empty(v-else)\n .icon 🗂️\n .text {{ $`No registries configured` }}\n .description\n UIBaseButton(\n @click='onAddOfficialRegistry',\n variant='primary',\n style='padding: 0.25rem 0.5rem'\n ) {{ $`Setup default registry` }}\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { onMounted, ref } from 'vue'\nimport { h } from 'jsx-dom'\nimport type { PluginStoreRegistry } from '../schema.js'\nimport UIBaseButton from './ui/UIBaseButton.vue'\n\nconst ctx = useIPE()\nconst $ = ctx.$\nconst $$ = ctx.$$\n\ninterface RegistryViewModel extends PluginStoreRegistry {\n registryUrl: string\n label: string\n}\n\nconst registries = ref<RegistryViewModel[]>([])\nconst inputValue = ref('')\nconst isAdding = ref(false)\n\nconst urlToLabel = (u: string) => {\n try {\n return new URL(u).hostname\n } catch {\n return u\n }\n}\n\nasync function loadRegistries() {\n const urls = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n const results = await Promise.allSettled(\n urls.map(async (url) => {\n const info = await ctx.store.getRegistryInfo(url)\n return {\n registryUrl: url,\n label: urlToLabel(url),\n ...info,\n } as RegistryViewModel\n })\n )\n registries.value = results\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryViewModel>).value)\n}\n\nasync function onAddRegistry() {\n const url = inputValue.value.trim()\n if (!url) return\n if (registries.value.some((r) => r.registryUrl === url)) {\n ctx.modal.notify('info', { content: 'Registry already exists.' })\n return\n }\n isAdding.value = true\n try {\n // try load immediately\n const info = await ctx.store.getRegistryInfo(url, 'online_manifest', true)\n if (!info) {\n throw new Error('Invalid registry or unreachable')\n }\n const current = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n current.push(url)\n await ctx.preferences.set('pluginStore.registries', current)\n registries.value.push({\n registryUrl: url,\n label: urlToLabel(url),\n ...info,\n })\n inputValue.value = ''\n ctx.modal.notify('success', { content: 'Registry added.' })\n } catch (e) {\n ctx.modal.notify('error', {\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n isAdding.value = false\n }\n}\n\nasync function removeRegistryUrl(url: string) {\n const current = (await ctx.preferences.get<string[]>('pluginStore.registries')) || []\n const next = current.filter((u) => u !== url)\n await ctx.preferences.set('pluginStore.registries', next)\n registries.value = registries.value.filter((r) => r.registryUrl !== url)\n}\n\nasync function onRemoveRegistry(url: string) {\n const installed =\n (await ctx.preferences.get<{ registry: string; id: string }[]>('pluginStore.plugins')) || []\n const installedOfReg = installed.filter((p) => p.registry === url)\n if (installedOfReg.length === 0) {\n ctx.modal.confirm(\n {\n title: $$`plugin-store.remove-registry.title`,\n content: $$`plugin-store.remove-registry.tip-content` + `\\n${url}`,\n cancelBtn: {\n label: $`Cancel`,\n className: 'is-ghost',\n },\n okBtn: {\n label: $`Remove`,\n className: 'is-danger',\n },\n },\n async (ok) => {\n if (!ok) return\n await removeRegistryUrl(url)\n ctx.modal.notify('success', { content: $$`plugin-store.remove-registry.remove-success` })\n }\n )\n return\n }\n\n ctx.modal.dialog(\n {\n title: $$`plugin-store.remove-registry.title`,\n content: h('div', { class: 'theme-ipe-prose' }, [\n h(\n 'p',\n {},\n $$({ count: installedOfReg.length })`plugin-store.remove-registry.confirm-content`\n ),\n h(\n 'ul',\n {},\n installedOfReg.map((p) => h('li', {}, p.id))\n ),\n ]),\n buttons: [\n {\n label: $$`plugin-store.remove-registry.buttons.remove-only`,\n className: 'is-danger is-ghost',\n method: async (_, m) => {\n await removeRegistryUrl(url)\n ctx.modal.notify('success', {\n content: $$`plugin-store.remove-registry.remove-success`,\n })\n m.close()\n },\n },\n {\n label: $$`plugin-store.remove-registry.buttons.remove-and-uninstall`,\n className: 'is-danger',\n method: async (_, m) => {\n await removeRegistryUrl(url)\n for (const p of installedOfReg) {\n try {\n await ctx.store.uninstallAndRemovePreference(p.registry, p.id)\n } catch (e) {\n // best-effort; notify but continue\n ctx.modal.notify('error', {\n content:\n e instanceof Error\n ? `Failed to uninstall ${p.id}: ${e.message}`\n : `Failed to uninstall ${p.id}`,\n })\n }\n }\n ctx.modal.notify('success', {\n content: $$({\n $1: installedOfReg.length,\n })`plugin-store.remove-registry.remove-with-plugins-success`,\n })\n m.close()\n },\n },\n ],\n },\n () => {}\n )\n}\n\nfunction onPreferencesChanged(payload: { changes: Record<string, unknown> }) {\n const regs = payload.changes['pluginStore.registries'] as string[]\n if (Array.isArray(regs)) {\n loadRegistries()\n }\n}\n\nfunction onAddOfficialRegistry() {\n const url = Endpoints.PLUGIN_REGISTRY_URL\n inputValue.value = url\n onAddRegistry()\n}\n\nonMounted(() => {\n loadRegistries()\n ctx.on('preferences/changed', onPreferencesChanged)\n})\n</script>\n\n<style scoped lang=\"scss\">\n@use './style.scss' as *;\n\n.registry-info {\n flex: 1;\n min-width: 0;\n .homepage {\n margin-top: 0.25rem;\n a {\n color: var(--ipe-modal-accent);\n text-decoration: none;\n font-size: 0.8125rem;\n transition: all 0.2s ease;\n &:hover {\n color: color-mix(in srgb, var(--ipe-modal-accent) 80%, var(--ipe-modal-text));\n text-decoration: underline;\n }\n }\n }\n .url {\n font-family: monospace;\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n margin-top: 0.125rem;\n word-break: break-all;\n }\n}\n</style>\n","<template lang=\"pug\">\n#ipe-plugin-install-manager\n .ipeps-header\n .ipeps-header-title {{ $`Plugins` }}\n .ipeps-input-wrapper\n input.ipeps-input.with-icon(\n v-model.trim='searchInput',\n type='text',\n :placeholder='$`Search plugins...`',\n :disabled='!pluginsFromRegistries.length'\n )\n .ipeps-input-icon 🔍\n button.ipeps-button(\n @click='refreshRegistries',\n :disabled='isRefreshing || !hasRegistries',\n :class='{ refreshing: isRefreshing }',\n variant='primary'\n ) {{ isRefreshing ? $`Refreshing...` : $`Refresh` }}\n\n .ipeps-loading(v-if='!hasRegistries && !firstInit')\n .loading-spinner\n .loading-text {{ $`Loading...` }}\n\n .ipeps-list(v-else-if='allPluginsToDisplay.length')\n .ipeps-item(\n v-for='plugin in allPluginsToDisplay',\n :key='plugin._key',\n :class='{ installed: isInstalledKey(plugin._key), broken: plugin.isBroken }'\n )\n .plugin-info\n .plugin-header\n .item-name {{ plugin.name || plugin.id }}\n span.ipeps-badge(\n v-if='isInstalledKey(plugin._key) || plugin.isBroken',\n :class='{ \"is-installed\": isInstalledKey(plugin._key), \"is-broken\": plugin.isBroken }'\n ) {{ plugin.isBroken ? $$`plugin-store.tags.broken` : $$`plugin-store.tags.installed` }}\n .ipeps-tags\n a.ipeps-tag.registry-tag(\n v-if='plugin.registryHomepage && !plugin.isRegistryMissing',\n :href='plugin.registryHomepage',\n target='_blank',\n :title='plugin.registryLabel'\n ) {{ plugin.registryLabel }}\n span.ipeps-tag.registry-tag(\n v-else,\n :title='plugin.registryLabel',\n :class='{ broken: plugin.isRegistryMissing }'\n ) {{ plugin.registryLabel }}\n .plugin-id.ipeps-tag(:class='{ broken: plugin.isBroken && !plugin.isRegistryMissing }') {{ plugin.id }}\n .plugin-desc(:class='{ \"broken-desc\": plugin.isBroken }') {{ getDesc(plugin) }}\n .plugin-meta\n span.version(v-if='plugin.version') v{{ plugin.version }}\n span.author(v-if='plugin.author') 👤 {{ plugin.author }}\n span.license(v-if='plugin.license') 📜 {{ plugin.license }}\n UIBaseButton(\n :active='isInstalledKey(plugin._key)',\n :variant='isInstalledKey(plugin._key) ? \"danger\" : \"primary\"',\n @click='togglePluginByKey(plugin)'\n ) {{ isInstalledKey(plugin._key) ? $`Remove` : $`Install` }}\n\n .ipeps-empty(v-else)\n .plugin-empty-icon 📦\n .plugin-empty-text {{ $`No matching plugins found` }}\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport type { PluginStorePackage, PluginStoreRegistry } from '../schema.js'\nimport UIBaseButton from './ui/UIBaseButton.vue'\n\ninterface RegistryWithUrl extends PluginStoreRegistry {\n registryUrl: string\n}\ninterface PluginIdentifier {\n registry: string\n id: string\n}\n\ninterface PluginViewModel extends PluginStorePackage {\n _key: string\n registry: string\n registryHomepage: string\n registryLabel: string\n isBroken: boolean\n isRegistryMissing: boolean\n}\n\n// --- state ---\nconst ctx = useIPE()\nconst $ = ctx.$\nconst $$ = ctx.$$\nconst registryInfos = ref<RegistryWithUrl[]>([])\nconst installedPlugins = ref<PluginIdentifier[]>([])\nconst searchInput = ref('')\nconst isRefreshing = ref(false)\n\n// helpers\nconst makeKey = (r: string, id: string) => `${r}\\n${id}` // stable + O(1)\n\nconst installedKeySet = computed(\n () => new Set(installedPlugins.value.map((p) => makeKey(p.registry, p.id)))\n)\nconst isInstalledKey = (key: string) => installedKeySet.value.has(key)\n\nconst urlToLabel = (registryUrl: string) => {\n try {\n return new URL(registryUrl).hostname\n } catch {\n return registryUrl\n }\n}\n\nconst firstInit = ref(false)\nconst hasRegistries = computed(() => registryInfos.value.length > 0)\n\nconst pluginsFromRegistries = computed<PluginViewModel[]>(\n () =>\n registryInfos.value.flatMap((reg) =>\n (reg.packages || []).map((pkg) => ({\n ...pkg,\n _key: makeKey(reg.registryUrl, pkg.id),\n registry: reg.registryUrl,\n registryHomepage: reg.homepage,\n registryLabel: urlToLabel(reg.registryUrl),\n isBroken: false,\n isRegistryMissing: false,\n }))\n ) as PluginViewModel[]\n)\n\n// merge normal + broken, and normalize once here\nconst normalizedPlugins = computed(() => {\n const q = searchInput.value.trim().toLowerCase()\n\n const all: Array<any> = pluginsFromRegistries.value\n\n // broken installed plugins (installed but not available now)\n const availableKeys = new Set(all.map((p) => p._key))\n const availableRegs = new Set(registryInfos.value.map((r) => r.registryUrl))\n\n const broken = installedPlugins.value\n .filter((p) => !availableKeys.has(makeKey(p.registry, p.id)))\n .map((p) => {\n const regInfo = registryInfos.value.find((r) => r.registryUrl === p.registry)\n return {\n id: p.id,\n name: undefined,\n description: undefined,\n version: undefined,\n author: undefined,\n license: undefined,\n _key: makeKey(p.registry, p.id),\n registry: p.registry,\n registryHomepage: regInfo?.homepage,\n registryLabel: urlToLabel(p.registry),\n isBroken: true,\n isRegistryMissing: !availableRegs.has(p.registry),\n }\n })\n\n const filtered = (list: any[]) => {\n if (!q) return list\n return list.filter(\n (p) =>\n (p.name && p.name.toLowerCase().includes(q)) ||\n (p.id && p.id.toLowerCase().includes(q)) ||\n (p.description && p.description.toLowerCase().includes(q)) ||\n (p.author && p.author.toLowerCase().includes(q)) ||\n (p.registry && p.registry.toLowerCase().includes(q))\n )\n }\n\n // broken on top\n return [...filtered(broken), ...filtered(all)]\n})\n\nconst allPluginsToDisplay = computed(() => normalizedPlugins.value)\n\nconst getDesc = (p: any) => {\n if (p.description) return p.description\n if (!p.isBroken) return ''\n return p.isRegistryMissing\n ? $$`plugin-store.broken.registry-unavailable`\n : $$`plugin-store.broken.plugin-removed`\n}\n\n// actions\nconst enablePlugin = async (registry: string, id: string) => {\n ctx.store.installAndSetPreference(registry, id)\n}\nconst disablePlugin = async (registry: string, id: string) => {\n ctx.store.uninstallAndRemovePreference(registry, id)\n}\nconst togglePlugin = (registry: string, id: string) =>\n isInstalledKey(makeKey(registry, id)) ? disablePlugin(registry, id) : enablePlugin(registry, id)\nconst togglePluginByKey = (p: any) => togglePlugin(p.registry, p.id)\n\nconst refreshRegistries = async () => {\n if (isRefreshing.value) return\n if (registryInfos.value.length === 0) {\n ctx.modal.notify('info', {\n content: 'No registry configured. Please add a registry first.',\n })\n return\n }\n\n isRefreshing.value = true\n const results = await ctx.store.refreshAllRegistryCaches()\n const okResults = Object.entries(results).filter(([_, r]) => r !== null)\n registryInfos.value = okResults.map(([url, r]) => ({\n ...r!,\n registryUrl: url,\n }))\n const failedUrls = Object.entries(results)\n .filter(([_, r]) => r === null)\n .map(([url]) => url)\n isRefreshing.value = false\n\n if (okResults.length === 0) {\n ctx.modal.notify('error', {\n content: 'All registries failed to refresh',\n })\n } else {\n ctx.modal.notify('success', {\n content: `${okResults.length} ${okResults.length === 1 ? 'registry' : 'registries'} refreshed successfully.`,\n })\n if (failedUrls.length > 0) {\n ctx.modal.notify('warning', {\n content: `${failedUrls.length} ${failedUrls.length === 1 ? 'registry' : 'registries'} failed to refresh:\\n${failedUrls.join('\\n')}`,\n })\n }\n }\n}\n\n// init\nconst init = async () => {\n firstInit.value = false\n const urls = (await ctx.store.ctx.preferences.get('pluginStore.registries')) || []\n const regResults = await Promise.allSettled(\n urls.map(async (url: string) => ({\n ...(await ctx.store.getRegistryInfo(url)),\n registryUrl: url,\n }))\n )\n registryInfos.value = regResults\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryWithUrl>).value)\n\n installedPlugins.value = (await ctx.preferences.get('pluginStore.plugins')) || []\n\n firstInit.value = true\n}\n\nfunction onPreferencesChanged(payload: { changes: Record<string, unknown> }) {\n const regs = payload.changes['pluginStore.registries'] as string[]\n const plugins = payload.changes['pluginStore.plugins'] as PluginIdentifier[]\n if (Array.isArray(plugins)) installedPlugins.value = plugins\n if (Array.isArray(regs)) {\n init()\n }\n}\n\nonMounted(() => {\n init()\n ctx.on('preferences/changed', onPreferencesChanged)\n})\nonBeforeUnmount(() => {})\n</script>\n\n<style scoped lang=\"scss\">\n@use './style.scss' as *;\n\n.plugin-info {\n flex: 1;\n min-width: 0;\n}\n.plugin-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.375rem;\n}\n.registry-tag {\n color: var(--ipe-modal-accent);\n background: color-mix(in srgb, var(--ipe-modal-accent) 8%, transparent);\n border: 1px solid color-mix(in srgb, var(--ipe-modal-accent) 18%, transparent);\n text-decoration: none;\n transition: all 0.2s ease;\n &:hover {\n background: color-mix(in srgb, var(--ipe-modal-accent) 12%, transparent);\n border-color: color-mix(in srgb, var(--ipe-modal-accent) 30%, transparent);\n }\n &.broken {\n text-decoration: line-through;\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n.plugin-id {\n &.broken {\n opacity: 0.65;\n text-decoration: line-through;\n }\n}\n.plugin-desc {\n font-size: 0.8125rem;\n color: var(--ipe-modal-muted);\n margin-bottom: 0.5rem;\n line-height: 1.6;\n &.broken-desc {\n color: color-mix(in srgb, var(--ipe-modal-warning) 80%, var(--ipe-modal-text));\n font-style: italic;\n }\n}\n.plugin-meta {\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n display: flex;\n gap: 1rem;\n align-items: center;\n .version {\n font-family: monospace;\n font-weight: 500;\n color: color-mix(in srgb, var(--ipe-modal-text) 80%, var(--ipe-modal-muted));\n }\n .author {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n .license {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n}\n</style>\n"],"names":["props","__props","buttonClass","computed","ctx","useIPE","$","$$","registries","ref","inputValue","isAdding","urlToLabel","u","loadRegistries","urls","results","url","info","r","onAddRegistry","current","e","removeRegistryUrl","next","onRemoveRegistry","installedOfReg","p","ok","h","_","m","onPreferencesChanged","payload","regs","onAddOfficialRegistry","Endpoints","onMounted","registryInfos","installedPlugins","searchInput","isRefreshing","makeKey","id","installedKeySet","isInstalledKey","key","registryUrl","firstInit","hasRegistries","pluginsFromRegistries","reg","pkg","normalizedPlugins","q","all","availableKeys","availableRegs","broken","regInfo","filtered","list","allPluginsToDisplay","getDesc","enablePlugin","registry","disablePlugin","togglePlugin","togglePluginByKey","refreshRegistries","okResults","failedUrls","init","regResults","plugins","onBeforeUnmount"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { j as d } from "./Promise.withResolvers-C4chhLB1.js";
2
- import { a as y } from "./index-CxckcdDI.js";
2
+ import { a as y } from "./index-DTU2DZU6.js";
3
3
  import { BasePlugin as E } from "./core.js";
4
4
  var S = Object.create, m = Object.defineProperty, U = Object.getOwnPropertyDescriptor, k = (e, t) => (t = Symbol[e]) ? t : /* @__PURE__ */ Symbol.for("Symbol." + e), f = (e) => {
5
5
  throw TypeError(e);
@@ -73,4 +73,4 @@ F(h, 1, _);
73
73
  export {
74
74
  _ as PluginTemplatesUsed
75
75
  };
76
- //# sourceMappingURL=PluginTemplatesUsed-CSrc0hi5.js.map
76
+ //# sourceMappingURL=PluginTemplatesUsed-BjRYFXHz.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluginTemplatesUsed-CSrc0hi5.js","sources":["../src/plugins/quick-usage/PluginTemplatesUsed.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/index.js'\nimport { QuickEditEventPayload } from '../quick-edit/index.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n templatesUsed: PluginTemplatesUsed\n }\n}\n\nexport interface PluginTemplatesUsedOptions {\n wikiPage?: IWikiPage\n title?: string\n pageId?: number\n revision?: number\n}\n\n@Inject(['modal', '$'])\nexport class PluginTemplatesUsed extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'templates-used')\n ctx.set('templatesUsed', this)\n }\n\n protected async start() {\n this.ctx.on('quick-edit/wiki-page', this._injectQuickEdit.bind(this))\n }\n\n private _injectQuickEdit(payload: QuickEditEventPayload) {\n const { $ } = this.ctx\n const { wikiPage, modal } = payload\n if (!wikiPage || !wikiPage.pageid) return\n const wrapper = this.ctx.quickUsage.getWrapperForQuickEdit(modal)\n const link = (\n <a\n href={`#ipe://quick-usage/templates?title=${wikiPage.title}`}\n onClick={async (e) => {\n e.preventDefault()\n const usageModal = await this.showModal({ wikiPage })\n if (usageModal) {\n modal.on(modal.Event.Close, () => {\n usageModal.destroy()\n })\n }\n }}\n >{$`Templates Used`}</a>\n )\n wrapper.appendChild(link)\n }\n\n async showModal(options: PluginTemplatesUsedOptions = {}) {\n const { $ } = this.ctx\n\n const wikiPage = options.wikiPage || (await this.ctx.wikiPage.WikiPage.newFromAnyKind(options))\n if (!wikiPage || !wikiPage.pageid) return\n\n const modal = this.ctx.modal.show({\n title: $`Templates Used`,\n content: (\n <section className=\"ipe-quickUsage__templates\">\n <ol>\n {wikiPage.templates.map((template) => {\n const title = this.ctx.wikiTitle.newTitle(template.title, template.ns)\n const quickEditButton = this.ctx.quickEdit.createQuickEditButton(\n {\n title: title.toString(),\n },\n { label: '' }\n )\n return (\n <li key={title.toString()}>\n <a href={title.getURL().toString()} target=\"_blank\" rel=\"noopener noreferrer\">\n {title.toString()}\n </a>{' '}\n ({quickEditButton})\n </li>\n )\n })}\n </ol>\n </section>\n ),\n sizeClass: 'dialog',\n draggable: true,\n backdrop: false,\n })\n\n this.ctx.emit('analytics/event', { feature: 'quick-usage', subtype: 'templates-used' })\n\n return modal\n }\n}\n"],"names":["_PluginTemplatesUsed_decorators","_init","_a","Inject","PluginTemplatesUsed","BasePlugin","ctx","payload","$","wikiPage","modal","wrapper","link","jsx","e","usageModal","options","template","title","quickEditButton","__decoratorStart","__decorateElement","__runInitializers"],"mappings":";;;;;;;;;;;;;;GAAAA,GAAAC,GAAAC;AAiBAF,IAAA,CAACG,EAAO,CAAC,SAAS,GAAG,CAAC,CAAA;AACf,MAAMC,WAA4BF,IAAAG,GAAW;AAAA,EAClD,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,gBAAgB,GADd,KAAA,MAAAA,GAEjBA,EAAI,IAAI,iBAAiB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAgB,QAAQ;AACtB,SAAK,IAAI,GAAG,wBAAwB,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAAA,EACtE;AAAA,EAEQ,iBAAiBC,GAAgC;AACvD,UAAM,EAAE,GAAAC,MAAM,KAAK,KACb,EAAE,UAAAC,GAAU,OAAAC,EAAA,IAAUH;AAC5B,QAAI,CAACE,KAAY,CAACA,EAAS,OAAQ;AACnC,UAAME,IAAU,KAAK,IAAI,WAAW,uBAAuBD,CAAK,GAC1DE,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM,sCAAsCJ,EAAS,KAAK;AAAA,QAC1D,SAAS,OAAOK,MAAM;AACpB,UAAAA,EAAE,eAAA;AACF,gBAAMC,IAAa,MAAM,KAAK,UAAU,EAAE,UAAAN,GAAU;AACpD,UAAIM,KACFL,EAAM,GAAGA,EAAM,MAAM,OAAO,MAAM;AAChC,YAAAK,EAAW,QAAA;AAAA,UACb,CAAC;AAAA,QAEL;AAAA,QACA,UAAAP;AAAA,MAAA;AAAA,IAAA;AAEJ,IAAAG,EAAQ,YAAYC,CAAI;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAUI,IAAsC,IAAI;AACxD,UAAM,EAAE,GAAAR,MAAM,KAAK,KAEbC,IAAWO,EAAQ,YAAa,MAAM,KAAK,IAAI,SAAS,SAAS,eAAeA,CAAO;AAC7F,QAAI,CAACP,KAAY,CAACA,EAAS,OAAQ;AAEnC,UAAMC,IAAQ,KAAK,IAAI,MAAM,KAAK;AAAA,MAChC,OAAOF;AAAA,MACP,SACE,gBAAAK,EAAC,WAAA,EAAQ,WAAU,6BACjB,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAJ,EAAS,UAAU,IAAI,CAACQ,MAAa;AACpC,cAAMC,IAAQ,KAAK,IAAI,UAAU,SAASD,EAAS,OAAOA,EAAS,EAAE,GAC/DE,IAAkB,KAAK,IAAI,UAAU;AAAA,UACzC;AAAA,YACE,OAAOD,EAAM,SAAA;AAAA,UAAS;AAAA,UAExB,EAAE,OAAO,GAAA;AAAA,QAAG;AAEd,iCACG,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAL,EAAC,KAAA,EAAE,MAAMK,EAAM,OAAA,EAAS,SAAA,GAAY,QAAO,UAAS,KAAI,uBACrD,UAAAA,EAAM,YACT;AAAA,UAAK;AAAA,UAAI;AAAA,UACPC;AAAA,UAAgB;AAAA,QAAA,KAJXD,EAAM,UAKf;AAAA,MAEJ,CAAC,GACH,GACF;AAAA,MAEF,WAAW;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,IAAA,CACX;AAED,gBAAK,IAAI,KAAK,mBAAmB,EAAE,SAAS,eAAe,SAAS,kBAAkB,GAE/ER;AAAA,EACT;AACF;AAxEOT,IAAAmB,EAAAlB,CAAA;AAAME,IAANiB,+BADPrB,GACaI,CAAA;AAANkB,EAAArB,GAAA,GAAMG,CAAA;"}
1
+ {"version":3,"file":"PluginTemplatesUsed-BjRYFXHz.js","sources":["../src/plugins/quick-usage/PluginTemplatesUsed.tsx"],"sourcesContent":["import { Inject, InPageEdit } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/index.js'\nimport { QuickEditEventPayload } from '../quick-edit/index.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n templatesUsed: PluginTemplatesUsed\n }\n}\n\nexport interface PluginTemplatesUsedOptions {\n wikiPage?: IWikiPage\n title?: string\n pageId?: number\n revision?: number\n}\n\n@Inject(['modal', '$'])\nexport class PluginTemplatesUsed extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'templates-used')\n ctx.set('templatesUsed', this)\n }\n\n protected async start() {\n this.ctx.on('quick-edit/wiki-page', this._injectQuickEdit.bind(this))\n }\n\n private _injectQuickEdit(payload: QuickEditEventPayload) {\n const { $ } = this.ctx\n const { wikiPage, modal } = payload\n if (!wikiPage || !wikiPage.pageid) return\n const wrapper = this.ctx.quickUsage.getWrapperForQuickEdit(modal)\n const link = (\n <a\n href={`#ipe://quick-usage/templates?title=${wikiPage.title}`}\n onClick={async (e) => {\n e.preventDefault()\n const usageModal = await this.showModal({ wikiPage })\n if (usageModal) {\n modal.on(modal.Event.Close, () => {\n usageModal.destroy()\n })\n }\n }}\n >{$`Templates Used`}</a>\n )\n wrapper.appendChild(link)\n }\n\n async showModal(options: PluginTemplatesUsedOptions = {}) {\n const { $ } = this.ctx\n\n const wikiPage = options.wikiPage || (await this.ctx.wikiPage.WikiPage.newFromAnyKind(options))\n if (!wikiPage || !wikiPage.pageid) return\n\n const modal = this.ctx.modal.show({\n title: $`Templates Used`,\n content: (\n <section className=\"ipe-quickUsage__templates\">\n <ol>\n {wikiPage.templates.map((template) => {\n const title = this.ctx.wikiTitle.newTitle(template.title, template.ns)\n const quickEditButton = this.ctx.quickEdit.createQuickEditButton(\n {\n title: title.toString(),\n },\n { label: '' }\n )\n return (\n <li key={title.toString()}>\n <a href={title.getURL().toString()} target=\"_blank\" rel=\"noopener noreferrer\">\n {title.toString()}\n </a>{' '}\n ({quickEditButton})\n </li>\n )\n })}\n </ol>\n </section>\n ),\n sizeClass: 'dialog',\n draggable: true,\n backdrop: false,\n })\n\n this.ctx.emit('analytics/event', { feature: 'quick-usage', subtype: 'templates-used' })\n\n return modal\n }\n}\n"],"names":["_PluginTemplatesUsed_decorators","_init","_a","Inject","PluginTemplatesUsed","BasePlugin","ctx","payload","$","wikiPage","modal","wrapper","link","jsx","e","usageModal","options","template","title","quickEditButton","__decoratorStart","__decorateElement","__runInitializers"],"mappings":";;;;;;;;;;;;;;GAAAA,GAAAC,GAAAC;AAiBAF,IAAA,CAACG,EAAO,CAAC,SAAS,GAAG,CAAC,CAAA;AACf,MAAMC,WAA4BF,IAAAG,GAAW;AAAA,EAClD,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,gBAAgB,GADd,KAAA,MAAAA,GAEjBA,EAAI,IAAI,iBAAiB,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAgB,QAAQ;AACtB,SAAK,IAAI,GAAG,wBAAwB,KAAK,iBAAiB,KAAK,IAAI,CAAC;AAAA,EACtE;AAAA,EAEQ,iBAAiBC,GAAgC;AACvD,UAAM,EAAE,GAAAC,MAAM,KAAK,KACb,EAAE,UAAAC,GAAU,OAAAC,EAAA,IAAUH;AAC5B,QAAI,CAACE,KAAY,CAACA,EAAS,OAAQ;AACnC,UAAME,IAAU,KAAK,IAAI,WAAW,uBAAuBD,CAAK,GAC1DE,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM,sCAAsCJ,EAAS,KAAK;AAAA,QAC1D,SAAS,OAAOK,MAAM;AACpB,UAAAA,EAAE,eAAA;AACF,gBAAMC,IAAa,MAAM,KAAK,UAAU,EAAE,UAAAN,GAAU;AACpD,UAAIM,KACFL,EAAM,GAAGA,EAAM,MAAM,OAAO,MAAM;AAChC,YAAAK,EAAW,QAAA;AAAA,UACb,CAAC;AAAA,QAEL;AAAA,QACA,UAAAP;AAAA,MAAA;AAAA,IAAA;AAEJ,IAAAG,EAAQ,YAAYC,CAAI;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAUI,IAAsC,IAAI;AACxD,UAAM,EAAE,GAAAR,MAAM,KAAK,KAEbC,IAAWO,EAAQ,YAAa,MAAM,KAAK,IAAI,SAAS,SAAS,eAAeA,CAAO;AAC7F,QAAI,CAACP,KAAY,CAACA,EAAS,OAAQ;AAEnC,UAAMC,IAAQ,KAAK,IAAI,MAAM,KAAK;AAAA,MAChC,OAAOF;AAAA,MACP,SACE,gBAAAK,EAAC,WAAA,EAAQ,WAAU,6BACjB,UAAA,gBAAAA,EAAC,MAAA,EACE,UAAAJ,EAAS,UAAU,IAAI,CAACQ,MAAa;AACpC,cAAMC,IAAQ,KAAK,IAAI,UAAU,SAASD,EAAS,OAAOA,EAAS,EAAE,GAC/DE,IAAkB,KAAK,IAAI,UAAU;AAAA,UACzC;AAAA,YACE,OAAOD,EAAM,SAAA;AAAA,UAAS;AAAA,UAExB,EAAE,OAAO,GAAA;AAAA,QAAG;AAEd,iCACG,MAAA,EACC,UAAA;AAAA,UAAA,gBAAAL,EAAC,KAAA,EAAE,MAAMK,EAAM,OAAA,EAAS,SAAA,GAAY,QAAO,UAAS,KAAI,uBACrD,UAAAA,EAAM,YACT;AAAA,UAAK;AAAA,UAAI;AAAA,UACPC;AAAA,UAAgB;AAAA,QAAA,KAJXD,EAAM,UAKf;AAAA,MAEJ,CAAC,GACH,GACF;AAAA,MAEF,WAAW;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,IAAA,CACX;AAED,gBAAK,IAAI,KAAK,mBAAmB,EAAE,SAAS,eAAe,SAAS,kBAAkB,GAE/ER;AAAA,EACT;AACF;AAxEOT,IAAAmB,EAAAlB,CAAA;AAAME,IAANiB,+BADPrB,GACaI,CAAA;AAANkB,EAAArB,GAAA,GAAMG,CAAA;"}
package/dist/core.js CHANGED
@@ -1,5 +1,5 @@
1
- import { i as n } from "./index-CxckcdDI.js";
2
- import { C as u, s as S, b as x, E as H, F as v, I as y, a as E, e as b, m as C, $ as L, M as j, R as k, S as I, c as M, d as P, f as R } from "./index-CxckcdDI.js";
1
+ import { i as n } from "./index-DTU2DZU6.js";
2
+ import { C as u, s as S, b as x, E as H, F as v, I as y, a as E, e as b, m as C, $ as L, M as j, R as k, S as I, c as M, d as P, f as R } from "./index-DTU2DZU6.js";
3
3
  import { p as h } from "./Promise.withResolvers-C4chhLB1.js";
4
4
  class l {
5
5
  constructor(e, t = void 0, c) {
@@ -1,5 +1,5 @@
1
1
  import { j as i, F as E, P as Q } from "./Promise.withResolvers-C4chhLB1.js";
2
- import { a as R, R as $, S as d } from "./index-CxckcdDI.js";
2
+ import { a as R, R as $, S as d } from "./index-DTU2DZU6.js";
3
3
  import { WatchlistAction as f } from "./models/index.js";
4
4
  import { m as U } from "./makeCallable-Cg4zUG4c.js";
5
5
  import { BasePlugin as W } from "./core.js";
@@ -426,4 +426,4 @@ let ge = S;
426
426
  export {
427
427
  ge as PluginQuickEdit
428
428
  };
429
- //# sourceMappingURL=index-CkKY3iId.js.map
429
+ //# sourceMappingURL=index-BVMm7Dix.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CkKY3iId.js","sources":["../src/utils/sleep.ts","../src/plugins/quick-edit/index.tsx"],"sourcesContent":["export const sleep = (ms: number = 0) =>\n new Promise((resolve) => setTimeout(resolve, ms))\n","import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/WikiPage'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction'\nimport { IPEModal } from '@inpageedit/modal'\nimport { ReactNode } from 'jsx-dom'\nimport { makeCallable } from '@/utils/makeCallable.js'\nimport { MediaWikiApiError } from 'wiki-saikou'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickEdit: PluginQuickEdit & {\n (...args: Parameters<PluginQuickEdit['showModal']>): ReturnType<PluginQuickEdit['showModal']>\n }\n }\n interface Events {\n 'quick-edit/init-options'(payload: Omit<QuickEditEventPayload, 'modal' | 'wikiPage'>): void\n 'quick-edit/show-modal'(payload: Omit<QuickEditEventPayload, 'wikiPage'>): void\n 'quick-edit/wiki-page'(payload: QuickEditEventPayload): void\n 'quick-edit/edit-notice'(payload: QuickEditEventPayload & { editNotices: ReactNode[] }): void\n 'quick-edit/submit'(payload: QuickEditSubmitPayload & { ctx: InPageEdit }): void\n }\n interface PreferencesMap {\n 'quickEdit.editSummary': string\n 'quickEdit.editMinor': boolean\n 'quickEdit.outSideClose': boolean\n 'quickEdit.watchList': WatchlistAction\n 'quickEdit.keyshortcut.save': string\n 'quickEdit.editFont': string\n }\n}\n\nexport interface QuickEditOptions {\n title: string\n pageId: number\n revision: number\n /**\n * - `undefined` for full article edit\n * - `0` for the first section\n * - `\"new\"` for a new section\n */\n section: number | 'new' | undefined\n editMinor: boolean\n editSummary: string\n createOnly: boolean\n reloadAfterSave: boolean\n}\n\nexport interface QuickEditEventPayload {\n ctx: InPageEdit\n options: QuickEditOptions\n modal: IPEModal\n wikiPage: IWikiPage\n}\n\nexport interface QuickEditSubmitPayload {\n wikiPage: IWikiPage\n text?: string\n summary?: string\n section?: number | 'new' | undefined\n minor?: boolean\n createonly?: boolean\n recreate?: boolean\n watchlist?: WatchlistAction\n}\n\n@Inject(['api', 'wikiPage', 'wikiTitle', 'currentPage', 'wiki', 'modal', 'preferences', '$'])\n@RegisterPreferences(\n Schema.object({\n 'quickEdit.editSummary': Schema.string()\n .description('Default edit summary for quick edits')\n .default('[IPE-NEXT] Quick edit'),\n 'quickEdit.editMinor': Schema.boolean()\n .description('Default to checking \"minor edit\" option')\n .default(false),\n 'quickEdit.outSideClose': Schema.boolean()\n .description('Close editor modal by clicking outside')\n .default(true),\n 'quickEdit.watchList': Schema.union([\n Schema.const(WatchlistAction.preferences).description('Follow MW preferences'),\n Schema.const(WatchlistAction.nochange).description('Keep the current watchlist status'),\n Schema.const(WatchlistAction.watch).description('Add the page to watchlist'),\n Schema.const(WatchlistAction.unwatch).description('Remove the page from watchlist'),\n ])\n .description('Watchlist options')\n .default(WatchlistAction.preferences),\n 'quickEdit.keyshortcut.save': Schema.string()\n .default('ctrl-s')\n .role('keyshortcut')\n .description('save button key shortcut (blank to disable)'),\n 'quickEdit.editFont': Schema.union([\n Schema.const('preferences').description('Follow MW preferences'),\n Schema.const('monospace').description('Monospace'),\n Schema.const('sans-serif').description('Sans-serif'),\n Schema.const('serif').description('Serif'),\n Schema.string().description('Custom font (same as CSS `font-family` property)').default(''),\n ])\n .description(\"Font to use in quick edit's textarea\")\n .default('preferences'),\n })\n .description('Quick edit options')\n .extra('category', 'editor')\n)\nexport class PluginQuickEdit extends BasePlugin {\n private readonly DEFAULT_OPTIONS: QuickEditOptions = {\n title: '',\n pageId: 0,\n revision: 0,\n section: undefined,\n editMinor: false,\n editSummary: '',\n createOnly: false,\n reloadAfterSave: true,\n }\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-edit')\n this.ctx.root.set('quickEdit', makeCallable(this, 'showModal'))\n }\n\n protected start(): Promise<void> | void {\n this.ctx.inject(['toolbox'], (ctx) => {\n this.injectToolbox(ctx)\n ctx.on('dispose', () => {\n this.removeToolbox(ctx)\n })\n })\n }\n\n async showModal(payload?: string | Partial<QuickEditOptions>) {\n const { $ } = this.ctx\n if (typeof payload === 'undefined') {\n payload = {}\n } else if (typeof payload === 'string') {\n payload = {\n title: payload,\n } as Partial<QuickEditOptions>\n }\n\n // @ts-expect-error legacy `page` option\n if (payload?.page) {\n // @ts-expect-error\n payload.title = payload.page\n // @ts-expect-error\n delete payload.page\n }\n\n if (!payload.title && !payload.pageId && !payload.revision) {\n this.logger.warn('None of the title, pageId or revision provided. Using defaults.')\n const searchParams = new URLSearchParams(window.location.search)\n const title = this.ctx.currentPage.wikiTitle\n payload = {\n ...payload,\n title: title?.getPrefixedDBKey(),\n revision: searchParams.has('oldid') ? Number(searchParams.get('oldid')) : undefined,\n pageId: searchParams.has('curid') ? Number(searchParams.get('curid')) : undefined,\n }\n }\n\n if (!payload.revision && !payload.pageId && payload.title) {\n const realTarget = this.ctx.wikiTitle.resolveSpecialPageTarget(payload.title)\n if (realTarget && realTarget.title.getNamespaceId() >= 0) {\n payload.title = realTarget.title.getPrefixedDBKey()\n payload.section ??= realTarget.section\n }\n }\n\n const outSideClose = (await this.ctx.preferences.get('quickEdit.outSideClose'))!\n const watchList = (await this.ctx.preferences.get('quickEdit.watchList'))!\n const editSummary =\n typeof payload.editSummary === 'string'\n ? payload.editSummary\n : (await this.ctx.preferences.get('quickEdit.editSummary'))!\n const editMinor =\n typeof payload.editMinor === 'boolean'\n ? payload.editMinor\n : (await this.ctx.preferences.get('quickEdit.editMinor'))!\n const fontOptions = await this.getEditFontOptions()\n\n const options: QuickEditOptions = {\n ...this.DEFAULT_OPTIONS,\n editSummary,\n editMinor,\n ...payload,\n }\n if (!options.editSummary) {\n options.editSummary = (await this.ctx.preferences.get('quickEdit.editSummary')) || ''\n }\n this.ctx.emit('quick-edit/init-options', { ctx: this.ctx, options })\n\n const modal = this.ctx.modal\n .createObject({\n className: 'ipe-quickEdit',\n sizeClass: 'large',\n // backdrop: false,\n // draggable: true,\n center: false,\n outSideClose,\n })\n .init()\n modal.setTitle(\n (\n <>\n Loading: <u>{options.title}</u>\n </>\n ) as HTMLElement\n )\n modal.setContent(\n (\n <section\n className=\"ipe-quickEdit-loading\"\n style={{\n height: '70vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <ProgressBar />\n </section>\n ) as HTMLElement\n )\n modal.addButton({\n side: 'right',\n type: 'button',\n className: 'is-danger is-ghost',\n label: $`Cancel`,\n method() {\n modal.close()\n },\n })\n modal.show()\n this.ctx.emit('quick-edit/show-modal', { ctx: this.ctx, modal, options })\n\n let wikiPage: IWikiPage\n try {\n wikiPage = await this.getWikiPageFromPayload(options)\n if (wikiPage.pageInfo.special) {\n throw new Error($`Special page is not editable.`)\n }\n } catch (e) {\n modal.off(modal.Event.Close)\n modal.close()\n this.ctx.modal.notify('error', {\n content: e instanceof Error ? e.message : String(e),\n })\n return\n }\n\n const edittingContent = options.section === 'new' ? '' : wikiPage.revisions[0]?.content || ''\n const edittingRevId = wikiPage.revisions[0]?.revid\n const isEdittingOld = edittingRevId && edittingRevId !== wikiPage.lastrevid\n const isCreatingNewSection = options.section === 'new'\n const isCreatingNewPage = wikiPage.pageid === 0\n\n modal.setTitle(\n (\n <>\n {isCreatingNewSection\n ? $`New Section`\n : $`Quick ${isCreatingNewPage ? 'Create' : 'Edit'}`}\n : <u>{wikiPage.pageInfo.title}</u>\n {isEdittingOld ? ` (${$`Revision`} ${edittingRevId})` : ''}\n </>\n ) as HTMLElement\n )\n\n const editNotices = [] as ReactNode[]\n // Page not exists\n if (isCreatingNewPage) {\n editNotices.push(\n <MBox title={$`Attention`} type=\"important\">\n <p>{$`This page does not exist.`}</p>\n </MBox>\n )\n }\n // Edit based on old revision\n if (isEdittingOld) {\n editNotices.push(\n <MBox title={$`Attention`} type=\"warning\">\n <p\n innerHTML={$`You are editing a <em>historical version</em>; the content is not the latest!`}\n ></p>\n </MBox>\n )\n }\n this.ctx.emit('quick-edit/edit-notice', {\n ctx: this.ctx,\n options,\n modal,\n wikiPage,\n editNotices,\n })\n\n const editForm = (\n <form className=\"ipe-quickEdit__form\">\n <div className=\"ipe-quickEdit__notices\">{editNotices}</div>\n <div\n className=\"ipe-quickEdit__content\"\n style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}\n >\n {options.section === 'new' && (\n <>\n <InputBox\n label={$`Section title`}\n id=\"summary\"\n name=\"summary\"\n value={''}\n inputProps={{ placeholder: $`Topic for new section, this will be the h2 heading` }}\n />\n </>\n )}\n <textarea\n className={`ipe-quickEdit__textarea ${fontOptions.className}`}\n style={{ fontFamily: fontOptions.fontFamily }}\n name=\"text\"\n id=\"wpTextbox1\"\n >\n {edittingContent}\n </textarea>\n </div>\n <div\n class=\"ipe-quickEdit__options\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n marginTop: '1rem',\n }}\n >\n {!isCreatingNewSection && (\n <InputBox label={$`Summary`} id=\"summary\" name=\"summary\" value={options.editSummary} />\n )}\n <div className=\"ipe-input-box\">\n <label htmlFor=\"watchlist\" style={{ display: 'block' }}>\n {$`Watchlist`}\n </label>\n <div style={{ display: 'flex', gap: '1rem', whiteSpace: 'nowrap', overflowX: 'auto' }}>\n {[\n WatchlistAction.preferences,\n WatchlistAction.nochange,\n WatchlistAction.watch,\n WatchlistAction.unwatch,\n ].map((action) => (\n <RadioBox\n key={action}\n name=\"watchlist\"\n value={action}\n inputProps={{\n checked: watchList === action,\n onChange: (e) => {\n e.target &&\n (e.target as HTMLElement).closest('label')?.scrollIntoView({\n behavior: 'smooth',\n inline: 'center',\n })\n },\n }}\n >\n {$`watchlist.${action}`}\n </RadioBox>\n ))}\n </div>\n </div>\n <div style={{ display: 'flex', gap: '1rem' }}>\n <CheckBox name=\"minor\" id=\"minor\" checked={options.editMinor}>\n {$`Minor edit`}\n </CheckBox>\n <CheckBox name=\"reloadAfterSave\" id=\"reloadAfterSave\" checked={options.reloadAfterSave}>\n {$`Reload after save`}\n </CheckBox>\n </div>\n </div>\n {/* Debug Info */}\n {import.meta.env.DEV && (\n <div className=\"debug\" style={{ marginTop: '1rem' }}>\n <details>\n <pre>{JSON.stringify(wikiPage.pageInfo, null, 2)}</pre>\n </details>\n </div>\n )}\n </form>\n ) as HTMLFormElement\n modal.setContent(editForm)\n\n let dismissWarnings = false\n modal.addButton(\n {\n side: 'left',\n className: 'is-primary submit-btn',\n label: $`Submit`,\n keyPress: (await this.ctx.preferences.get('quickEdit.keyshortcut.save')) || undefined,\n method: async () => {\n const formData = new FormData(editForm)\n console.info(wikiPage, editForm, {\n text: formData.get('text') as string,\n summary: formData.get('summary') as string,\n minor: formData.get('minor') === 'on',\n })\n modal.setLoadingState(true)\n\n try {\n await this.handleSubmit({\n wikiPage,\n text: formData.get('text') as string,\n summary: formData.get('summary') as string,\n minor: formData.get('minor') === 'on',\n section: options.section,\n watchlist: watchList,\n // 如果无视风险,那么就不再尝试解决冲突,直接重建页面\n createonly: wikiPage.pageid === 0 && !dismissWarnings,\n recreate: wikiPage.pageid === 0 && dismissWarnings,\n })\n\n modal.setOptions({\n beforeClose: noop,\n })\n modal.close()\n\n this.ctx.modal.notify('success', {\n title: $`Submission Successful`,\n content: $`Your changes have been saved.`,\n })\n\n if (formData.get('reloadAfterSave')) {\n await sleep(500)\n location.reload()\n }\n } catch (error) {\n modal.setLoadingState(false)\n\n if (MediaWikiApiError.is(error)) {\n if (\n error.code === 'pagedeleted' ||\n error.code === 'editconflict' ||\n error.code === 'articleexists'\n ) {\n dismissWarnings = true\n this.ctx.modal.notify('warning', {\n title: $`Submission Error`,\n content: (\n <div>\n <p>\n <strong>{error.message}</strong>\n </p>\n <p>{$`You can try to submit again to dismiss the warnings.`}</p>\n </div>\n ),\n closeAfter: 15 * 1000,\n })\n return // can be dismissed by re-submission\n }\n }\n\n // Errors not handled above\n this.ctx.modal.notify('error', {\n title: $`Submission Error`,\n content: error instanceof Error ? error.message : String(error),\n })\n }\n },\n },\n 0\n )\n modal.setOptions({\n beforeClose: () => {\n const oldStr = wikiPage.revisions[0]?.content || ''\n const newStr = editForm.querySelector('textarea')?.value || ''\n if (newStr === oldStr) {\n return true\n } else {\n this.ctx.modal.confirm(\n {\n className: 'is-primary',\n title: $`Unsaved Changes`,\n content: $`All edit contents will be lost after closing the modal. Are you sure you want to close?`,\n center: true,\n okBtn: {\n label: $`Give Up`,\n className: 'is-danger is-ghost',\n },\n cancelBtn: {\n label: $`Continue Editing`,\n className: 'is-primary is-ghost',\n },\n },\n (confirmed) => {\n if (confirmed) {\n modal.setOptions({\n beforeClose: noop,\n })\n modal.close()\n }\n return true\n }\n )\n return false\n }\n },\n })\n this.ctx.emit('quick-edit/wiki-page', {\n ctx: this.ctx,\n options,\n modal,\n wikiPage,\n })\n\n const beforeUnload = (e: BeforeUnloadEvent) => {\n if (editForm.querySelector('textarea')?.value === edittingContent) {\n return true\n }\n e.preventDefault()\n return $`You have unsaved changes. Are you sure you want to leave?`\n }\n window.addEventListener('beforeunload', beforeUnload)\n modal.on(modal.Event.Close, () => {\n window.removeEventListener('beforeunload', beforeUnload)\n })\n }\n\n async handleSubmit(payload: QuickEditSubmitPayload) {\n const { wikiPage, ...rest } = payload\n\n this.ctx.emit('quick-edit/submit', {\n ctx: this.ctx,\n wikiPage,\n ...rest,\n })\n\n return wikiPage.edit({\n ...rest,\n })\n }\n\n static readonly BUILT_IN_FONT_OPTIONS = ['preferences', 'monospace', 'sans-serif', 'serif']\n async getEditFontOptions() {\n const prefEditFont = (await this.ctx.preferences.get('quickEdit.editFont'))!\n if (PluginQuickEdit.BUILT_IN_FONT_OPTIONS.includes(prefEditFont)) {\n const editfont =\n prefEditFont === 'preferences'\n ? this.ctx.wiki.userOptions?.editfont || 'monospace'\n : prefEditFont\n return {\n className: `mw-editfont-${editfont}`,\n fontFamily: '',\n }\n } else {\n return {\n className: 'mw-editfont-custom',\n fontFamily: prefEditFont,\n }\n }\n }\n\n async getWikiPageFromPayload(payload: Partial<QuickEditOptions>) {\n if (payload.revision) {\n return this.ctx.wikiPage.newFromRevision(payload.revision, payload.section)\n } else if (payload.pageId) {\n return this.ctx.wikiPage.newFromPageId(payload.pageId, payload.section)\n } else if (payload.title) {\n return this.ctx.wikiPage.newFromTitle(payload.title, false, payload.section)\n }\n throw new Error('Invalid payload')\n }\n\n private async injectToolbox(ctx: InPageEdit) {\n const { $ } = this.ctx\n const title = this.ctx.currentPage.wikiTitle\n const canEdit = title && title.getNamespaceId() >= 0\n ctx.toolbox.addButton({\n id: 'quick-edit',\n group: 'group1',\n index: 0,\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-edit\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1\" />\n <path d=\"M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z\" />\n <path d=\"M16 5l3 3\" />\n </svg>\n ) as HTMLElement,\n buttonProps: {\n disabled: !canEdit,\n },\n tooltip: () => (canEdit ? $`Quick Edit` : $`Not editable`),\n onClick: () => {\n const revision = new URLSearchParams(window.location.search).get('oldid')\n this.showModal({\n title: title?.getPrefixedText(),\n revision: revision ? Number(revision) : undefined,\n })\n },\n })\n }\n\n protected removeToolbox(ctx: InPageEdit) {\n ctx.toolbox.removeButton('quick-edit')\n }\n\n createQuickEditButton(\n payload: Partial<QuickEditOptions>,\n options?: {\n icon?: ReactNode\n label?: ReactNode\n }\n ) {\n const { $ } = this.ctx\n const icon = options?.icon ?? <IconQuickEdit className=\"ipe-icon\" />\n const label = options?.label ?? $`Quick Edit`\n return (\n <a\n href={`#ipe://quick-edit/`}\n dataset={payload as any}\n className={`ipe-quick-edit ${payload.createOnly ? 'ipe-quick-edit--create-only' : ''}`}\n style={{\n userSelect: 'none',\n marginLeft: '0.2em',\n }}\n onClick={(e) => {\n e.preventDefault()\n this.showModal(payload)\n }}\n >\n {icon}\n {label}\n </a>\n ) as HTMLAnchorElement\n }\n}\n"],"names":["sleep","ms","resolve","_PluginQuickEdit_decorators","_init","_a","Inject","RegisterPreferences","Schema","WatchlistAction","_PluginQuickEdit","BasePlugin","ctx","makeCallable","payload","$","searchParams","title","realTarget","outSideClose","watchList","editSummary","editMinor","fontOptions","options","modal","jsxs","Fragment","jsx","ProgressBar","wikiPage","e","edittingContent","edittingRevId","isEdittingOld","isCreatingNewSection","isCreatingNewPage","editNotices","MBox","editForm","InputBox","action","RadioBox","CheckBox","dismissWarnings","formData","noop","error","MediaWikiApiError","oldStr","confirmed","beforeUnload","rest","prefEditFont","canEdit","revision","icon","IconQuickEdit","label","__decoratorStart","__decorateElement","__runInitializers","PluginQuickEdit"],"mappings":"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"}
1
+ {"version":3,"file":"index-BVMm7Dix.js","sources":["../src/utils/sleep.ts","../src/plugins/quick-edit/index.tsx"],"sourcesContent":["export const sleep = (ms: number = 0) =>\n new Promise((resolve) => setTimeout(resolve, ms))\n","import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { IWikiPage } from '@/models/WikiPage'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction'\nimport { IPEModal } from '@inpageedit/modal'\nimport { ReactNode } from 'jsx-dom'\nimport { makeCallable } from '@/utils/makeCallable.js'\nimport { MediaWikiApiError } from 'wiki-saikou'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickEdit: PluginQuickEdit & {\n (...args: Parameters<PluginQuickEdit['showModal']>): ReturnType<PluginQuickEdit['showModal']>\n }\n }\n interface Events {\n 'quick-edit/init-options'(payload: Omit<QuickEditEventPayload, 'modal' | 'wikiPage'>): void\n 'quick-edit/show-modal'(payload: Omit<QuickEditEventPayload, 'wikiPage'>): void\n 'quick-edit/wiki-page'(payload: QuickEditEventPayload): void\n 'quick-edit/edit-notice'(payload: QuickEditEventPayload & { editNotices: ReactNode[] }): void\n 'quick-edit/submit'(payload: QuickEditSubmitPayload & { ctx: InPageEdit }): void\n }\n interface PreferencesMap {\n 'quickEdit.editSummary': string\n 'quickEdit.editMinor': boolean\n 'quickEdit.outSideClose': boolean\n 'quickEdit.watchList': WatchlistAction\n 'quickEdit.keyshortcut.save': string\n 'quickEdit.editFont': string\n }\n}\n\nexport interface QuickEditOptions {\n title: string\n pageId: number\n revision: number\n /**\n * - `undefined` for full article edit\n * - `0` for the first section\n * - `\"new\"` for a new section\n */\n section: number | 'new' | undefined\n editMinor: boolean\n editSummary: string\n createOnly: boolean\n reloadAfterSave: boolean\n}\n\nexport interface QuickEditEventPayload {\n ctx: InPageEdit\n options: QuickEditOptions\n modal: IPEModal\n wikiPage: IWikiPage\n}\n\nexport interface QuickEditSubmitPayload {\n wikiPage: IWikiPage\n text?: string\n summary?: string\n section?: number | 'new' | undefined\n minor?: boolean\n createonly?: boolean\n recreate?: boolean\n watchlist?: WatchlistAction\n}\n\n@Inject(['api', 'wikiPage', 'wikiTitle', 'currentPage', 'wiki', 'modal', 'preferences', '$'])\n@RegisterPreferences(\n Schema.object({\n 'quickEdit.editSummary': Schema.string()\n .description('Default edit summary for quick edits')\n .default('[IPE-NEXT] Quick edit'),\n 'quickEdit.editMinor': Schema.boolean()\n .description('Default to checking \"minor edit\" option')\n .default(false),\n 'quickEdit.outSideClose': Schema.boolean()\n .description('Close editor modal by clicking outside')\n .default(true),\n 'quickEdit.watchList': Schema.union([\n Schema.const(WatchlistAction.preferences).description('Follow MW preferences'),\n Schema.const(WatchlistAction.nochange).description('Keep the current watchlist status'),\n Schema.const(WatchlistAction.watch).description('Add the page to watchlist'),\n Schema.const(WatchlistAction.unwatch).description('Remove the page from watchlist'),\n ])\n .description('Watchlist options')\n .default(WatchlistAction.preferences),\n 'quickEdit.keyshortcut.save': Schema.string()\n .default('ctrl-s')\n .role('keyshortcut')\n .description('save button key shortcut (blank to disable)'),\n 'quickEdit.editFont': Schema.union([\n Schema.const('preferences').description('Follow MW preferences'),\n Schema.const('monospace').description('Monospace'),\n Schema.const('sans-serif').description('Sans-serif'),\n Schema.const('serif').description('Serif'),\n Schema.string().description('Custom font (same as CSS `font-family` property)').default(''),\n ])\n .description(\"Font to use in quick edit's textarea\")\n .default('preferences'),\n })\n .description('Quick edit options')\n .extra('category', 'editor')\n)\nexport class PluginQuickEdit extends BasePlugin {\n private readonly DEFAULT_OPTIONS: QuickEditOptions = {\n title: '',\n pageId: 0,\n revision: 0,\n section: undefined,\n editMinor: false,\n editSummary: '',\n createOnly: false,\n reloadAfterSave: true,\n }\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-edit')\n this.ctx.root.set('quickEdit', makeCallable(this, 'showModal'))\n }\n\n protected start(): Promise<void> | void {\n this.ctx.inject(['toolbox'], (ctx) => {\n this.injectToolbox(ctx)\n ctx.on('dispose', () => {\n this.removeToolbox(ctx)\n })\n })\n }\n\n async showModal(payload?: string | Partial<QuickEditOptions>) {\n const { $ } = this.ctx\n if (typeof payload === 'undefined') {\n payload = {}\n } else if (typeof payload === 'string') {\n payload = {\n title: payload,\n } as Partial<QuickEditOptions>\n }\n\n // @ts-expect-error legacy `page` option\n if (payload?.page) {\n // @ts-expect-error\n payload.title = payload.page\n // @ts-expect-error\n delete payload.page\n }\n\n if (!payload.title && !payload.pageId && !payload.revision) {\n this.logger.warn('None of the title, pageId or revision provided. Using defaults.')\n const searchParams = new URLSearchParams(window.location.search)\n const title = this.ctx.currentPage.wikiTitle\n payload = {\n ...payload,\n title: title?.getPrefixedDBKey(),\n revision: searchParams.has('oldid') ? Number(searchParams.get('oldid')) : undefined,\n pageId: searchParams.has('curid') ? Number(searchParams.get('curid')) : undefined,\n }\n }\n\n if (!payload.revision && !payload.pageId && payload.title) {\n const realTarget = this.ctx.wikiTitle.resolveSpecialPageTarget(payload.title)\n if (realTarget && realTarget.title.getNamespaceId() >= 0) {\n payload.title = realTarget.title.getPrefixedDBKey()\n payload.section ??= realTarget.section\n }\n }\n\n const outSideClose = (await this.ctx.preferences.get('quickEdit.outSideClose'))!\n const watchList = (await this.ctx.preferences.get('quickEdit.watchList'))!\n const editSummary =\n typeof payload.editSummary === 'string'\n ? payload.editSummary\n : (await this.ctx.preferences.get('quickEdit.editSummary'))!\n const editMinor =\n typeof payload.editMinor === 'boolean'\n ? payload.editMinor\n : (await this.ctx.preferences.get('quickEdit.editMinor'))!\n const fontOptions = await this.getEditFontOptions()\n\n const options: QuickEditOptions = {\n ...this.DEFAULT_OPTIONS,\n editSummary,\n editMinor,\n ...payload,\n }\n if (!options.editSummary) {\n options.editSummary = (await this.ctx.preferences.get('quickEdit.editSummary')) || ''\n }\n this.ctx.emit('quick-edit/init-options', { ctx: this.ctx, options })\n\n const modal = this.ctx.modal\n .createObject({\n className: 'ipe-quickEdit',\n sizeClass: 'large',\n // backdrop: false,\n // draggable: true,\n center: false,\n outSideClose,\n })\n .init()\n modal.setTitle(\n (\n <>\n Loading: <u>{options.title}</u>\n </>\n ) as HTMLElement\n )\n modal.setContent(\n (\n <section\n className=\"ipe-quickEdit-loading\"\n style={{\n height: '70vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <ProgressBar />\n </section>\n ) as HTMLElement\n )\n modal.addButton({\n side: 'right',\n type: 'button',\n className: 'is-danger is-ghost',\n label: $`Cancel`,\n method() {\n modal.close()\n },\n })\n modal.show()\n this.ctx.emit('quick-edit/show-modal', { ctx: this.ctx, modal, options })\n\n let wikiPage: IWikiPage\n try {\n wikiPage = await this.getWikiPageFromPayload(options)\n if (wikiPage.pageInfo.special) {\n throw new Error($`Special page is not editable.`)\n }\n } catch (e) {\n modal.off(modal.Event.Close)\n modal.close()\n this.ctx.modal.notify('error', {\n content: e instanceof Error ? e.message : String(e),\n })\n return\n }\n\n const edittingContent = options.section === 'new' ? '' : wikiPage.revisions[0]?.content || ''\n const edittingRevId = wikiPage.revisions[0]?.revid\n const isEdittingOld = edittingRevId && edittingRevId !== wikiPage.lastrevid\n const isCreatingNewSection = options.section === 'new'\n const isCreatingNewPage = wikiPage.pageid === 0\n\n modal.setTitle(\n (\n <>\n {isCreatingNewSection\n ? $`New Section`\n : $`Quick ${isCreatingNewPage ? 'Create' : 'Edit'}`}\n : <u>{wikiPage.pageInfo.title}</u>\n {isEdittingOld ? ` (${$`Revision`} ${edittingRevId})` : ''}\n </>\n ) as HTMLElement\n )\n\n const editNotices = [] as ReactNode[]\n // Page not exists\n if (isCreatingNewPage) {\n editNotices.push(\n <MBox title={$`Attention`} type=\"important\">\n <p>{$`This page does not exist.`}</p>\n </MBox>\n )\n }\n // Edit based on old revision\n if (isEdittingOld) {\n editNotices.push(\n <MBox title={$`Attention`} type=\"warning\">\n <p\n innerHTML={$`You are editing a <em>historical version</em>; the content is not the latest!`}\n ></p>\n </MBox>\n )\n }\n this.ctx.emit('quick-edit/edit-notice', {\n ctx: this.ctx,\n options,\n modal,\n wikiPage,\n editNotices,\n })\n\n const editForm = (\n <form className=\"ipe-quickEdit__form\">\n <div className=\"ipe-quickEdit__notices\">{editNotices}</div>\n <div\n className=\"ipe-quickEdit__content\"\n style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}\n >\n {options.section === 'new' && (\n <>\n <InputBox\n label={$`Section title`}\n id=\"summary\"\n name=\"summary\"\n value={''}\n inputProps={{ placeholder: $`Topic for new section, this will be the h2 heading` }}\n />\n </>\n )}\n <textarea\n className={`ipe-quickEdit__textarea ${fontOptions.className}`}\n style={{ fontFamily: fontOptions.fontFamily }}\n name=\"text\"\n id=\"wpTextbox1\"\n >\n {edittingContent}\n </textarea>\n </div>\n <div\n class=\"ipe-quickEdit__options\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n marginTop: '1rem',\n }}\n >\n {!isCreatingNewSection && (\n <InputBox label={$`Summary`} id=\"summary\" name=\"summary\" value={options.editSummary} />\n )}\n <div className=\"ipe-input-box\">\n <label htmlFor=\"watchlist\" style={{ display: 'block' }}>\n {$`Watchlist`}\n </label>\n <div style={{ display: 'flex', gap: '1rem', whiteSpace: 'nowrap', overflowX: 'auto' }}>\n {[\n WatchlistAction.preferences,\n WatchlistAction.nochange,\n WatchlistAction.watch,\n WatchlistAction.unwatch,\n ].map((action) => (\n <RadioBox\n key={action}\n name=\"watchlist\"\n value={action}\n inputProps={{\n checked: watchList === action,\n onChange: (e) => {\n e.target &&\n (e.target as HTMLElement).closest('label')?.scrollIntoView({\n behavior: 'smooth',\n inline: 'center',\n })\n },\n }}\n >\n {$`watchlist.${action}`}\n </RadioBox>\n ))}\n </div>\n </div>\n <div style={{ display: 'flex', gap: '1rem' }}>\n <CheckBox name=\"minor\" id=\"minor\" checked={options.editMinor}>\n {$`Minor edit`}\n </CheckBox>\n <CheckBox name=\"reloadAfterSave\" id=\"reloadAfterSave\" checked={options.reloadAfterSave}>\n {$`Reload after save`}\n </CheckBox>\n </div>\n </div>\n {/* Debug Info */}\n {import.meta.env.DEV && (\n <div className=\"debug\" style={{ marginTop: '1rem' }}>\n <details>\n <pre>{JSON.stringify(wikiPage.pageInfo, null, 2)}</pre>\n </details>\n </div>\n )}\n </form>\n ) as HTMLFormElement\n modal.setContent(editForm)\n\n let dismissWarnings = false\n modal.addButton(\n {\n side: 'left',\n className: 'is-primary submit-btn',\n label: $`Submit`,\n keyPress: (await this.ctx.preferences.get('quickEdit.keyshortcut.save')) || undefined,\n method: async () => {\n const formData = new FormData(editForm)\n console.info(wikiPage, editForm, {\n text: formData.get('text') as string,\n summary: formData.get('summary') as string,\n minor: formData.get('minor') === 'on',\n })\n modal.setLoadingState(true)\n\n try {\n await this.handleSubmit({\n wikiPage,\n text: formData.get('text') as string,\n summary: formData.get('summary') as string,\n minor: formData.get('minor') === 'on',\n section: options.section,\n watchlist: watchList,\n // 如果无视风险,那么就不再尝试解决冲突,直接重建页面\n createonly: wikiPage.pageid === 0 && !dismissWarnings,\n recreate: wikiPage.pageid === 0 && dismissWarnings,\n })\n\n modal.setOptions({\n beforeClose: noop,\n })\n modal.close()\n\n this.ctx.modal.notify('success', {\n title: $`Submission Successful`,\n content: $`Your changes have been saved.`,\n })\n\n if (formData.get('reloadAfterSave')) {\n await sleep(500)\n location.reload()\n }\n } catch (error) {\n modal.setLoadingState(false)\n\n if (MediaWikiApiError.is(error)) {\n if (\n error.code === 'pagedeleted' ||\n error.code === 'editconflict' ||\n error.code === 'articleexists'\n ) {\n dismissWarnings = true\n this.ctx.modal.notify('warning', {\n title: $`Submission Error`,\n content: (\n <div>\n <p>\n <strong>{error.message}</strong>\n </p>\n <p>{$`You can try to submit again to dismiss the warnings.`}</p>\n </div>\n ),\n closeAfter: 15 * 1000,\n })\n return // can be dismissed by re-submission\n }\n }\n\n // Errors not handled above\n this.ctx.modal.notify('error', {\n title: $`Submission Error`,\n content: error instanceof Error ? error.message : String(error),\n })\n }\n },\n },\n 0\n )\n modal.setOptions({\n beforeClose: () => {\n const oldStr = wikiPage.revisions[0]?.content || ''\n const newStr = editForm.querySelector('textarea')?.value || ''\n if (newStr === oldStr) {\n return true\n } else {\n this.ctx.modal.confirm(\n {\n className: 'is-primary',\n title: $`Unsaved Changes`,\n content: $`All edit contents will be lost after closing the modal. Are you sure you want to close?`,\n center: true,\n okBtn: {\n label: $`Give Up`,\n className: 'is-danger is-ghost',\n },\n cancelBtn: {\n label: $`Continue Editing`,\n className: 'is-primary is-ghost',\n },\n },\n (confirmed) => {\n if (confirmed) {\n modal.setOptions({\n beforeClose: noop,\n })\n modal.close()\n }\n return true\n }\n )\n return false\n }\n },\n })\n this.ctx.emit('quick-edit/wiki-page', {\n ctx: this.ctx,\n options,\n modal,\n wikiPage,\n })\n\n const beforeUnload = (e: BeforeUnloadEvent) => {\n if (editForm.querySelector('textarea')?.value === edittingContent) {\n return true\n }\n e.preventDefault()\n return $`You have unsaved changes. Are you sure you want to leave?`\n }\n window.addEventListener('beforeunload', beforeUnload)\n modal.on(modal.Event.Close, () => {\n window.removeEventListener('beforeunload', beforeUnload)\n })\n }\n\n async handleSubmit(payload: QuickEditSubmitPayload) {\n const { wikiPage, ...rest } = payload\n\n this.ctx.emit('quick-edit/submit', {\n ctx: this.ctx,\n wikiPage,\n ...rest,\n })\n\n return wikiPage.edit({\n ...rest,\n })\n }\n\n static readonly BUILT_IN_FONT_OPTIONS = ['preferences', 'monospace', 'sans-serif', 'serif']\n async getEditFontOptions() {\n const prefEditFont = (await this.ctx.preferences.get('quickEdit.editFont'))!\n if (PluginQuickEdit.BUILT_IN_FONT_OPTIONS.includes(prefEditFont)) {\n const editfont =\n prefEditFont === 'preferences'\n ? this.ctx.wiki.userOptions?.editfont || 'monospace'\n : prefEditFont\n return {\n className: `mw-editfont-${editfont}`,\n fontFamily: '',\n }\n } else {\n return {\n className: 'mw-editfont-custom',\n fontFamily: prefEditFont,\n }\n }\n }\n\n async getWikiPageFromPayload(payload: Partial<QuickEditOptions>) {\n if (payload.revision) {\n return this.ctx.wikiPage.newFromRevision(payload.revision, payload.section)\n } else if (payload.pageId) {\n return this.ctx.wikiPage.newFromPageId(payload.pageId, payload.section)\n } else if (payload.title) {\n return this.ctx.wikiPage.newFromTitle(payload.title, false, payload.section)\n }\n throw new Error('Invalid payload')\n }\n\n private async injectToolbox(ctx: InPageEdit) {\n const { $ } = this.ctx\n const title = this.ctx.currentPage.wikiTitle\n const canEdit = title && title.getNamespaceId() >= 0\n ctx.toolbox.addButton({\n id: 'quick-edit',\n group: 'group1',\n index: 0,\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-edit\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1\" />\n <path d=\"M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z\" />\n <path d=\"M16 5l3 3\" />\n </svg>\n ) as HTMLElement,\n buttonProps: {\n disabled: !canEdit,\n },\n tooltip: () => (canEdit ? $`Quick Edit` : $`Not editable`),\n onClick: () => {\n const revision = new URLSearchParams(window.location.search).get('oldid')\n this.showModal({\n title: title?.getPrefixedText(),\n revision: revision ? Number(revision) : undefined,\n })\n },\n })\n }\n\n protected removeToolbox(ctx: InPageEdit) {\n ctx.toolbox.removeButton('quick-edit')\n }\n\n createQuickEditButton(\n payload: Partial<QuickEditOptions>,\n options?: {\n icon?: ReactNode\n label?: ReactNode\n }\n ) {\n const { $ } = this.ctx\n const icon = options?.icon ?? <IconQuickEdit className=\"ipe-icon\" />\n const label = options?.label ?? $`Quick Edit`\n return (\n <a\n href={`#ipe://quick-edit/`}\n dataset={payload as any}\n className={`ipe-quick-edit ${payload.createOnly ? 'ipe-quick-edit--create-only' : ''}`}\n style={{\n userSelect: 'none',\n marginLeft: '0.2em',\n }}\n onClick={(e) => {\n e.preventDefault()\n this.showModal(payload)\n }}\n >\n {icon}\n {label}\n </a>\n ) as HTMLAnchorElement\n }\n}\n"],"names":["sleep","ms","resolve","_PluginQuickEdit_decorators","_init","_a","Inject","RegisterPreferences","Schema","WatchlistAction","_PluginQuickEdit","BasePlugin","ctx","makeCallable","payload","$","searchParams","title","realTarget","outSideClose","watchList","editSummary","editMinor","fontOptions","options","modal","jsxs","Fragment","jsx","ProgressBar","wikiPage","e","edittingContent","edittingRevId","isEdittingOld","isCreatingNewSection","isCreatingNewPage","editNotices","MBox","editForm","InputBox","action","RadioBox","CheckBox","dismissWarnings","formData","noop","error","MediaWikiApiError","oldStr","confirmed","beforeUnload","rest","prefEditFont","canEdit","revision","icon","IconQuickEdit","label","__decoratorStart","__decorateElement","__runInitializers","PluginQuickEdit"],"mappings":";;;;;;;;;;;AAAO,MAAMA,IAAQ,CAACC,IAAa,MACjC,IAAI,QAAQ,CAACC,MAAY,WAAWA,GAASD,CAAE,CAAC;;;;;;;;;;;;GCDlDE,GAAAC,GAAAC;AAiEAF,IAAA,CAACG,EAAO,CAAC,OAAO,YAAY,aAAa,eAAe,QAAQ,SAAS,eAAe,GAAG,CAAC,GAC3FC;AAAA,EACCC,EAAO,OAAO;AAAA,IACZ,yBAAyBA,EAAO,OAAA,EAC7B,YAAY,sCAAsC,EAClD,QAAQ,uBAAuB;AAAA,IAClC,uBAAuBA,EAAO,QAAA,EAC3B,YAAY,yCAAyC,EACrD,QAAQ,EAAK;AAAA,IAChB,0BAA0BA,EAAO,QAAA,EAC9B,YAAY,wCAAwC,EACpD,QAAQ,EAAI;AAAA,IACf,uBAAuBA,EAAO,MAAM;AAAA,MAClCA,EAAO,MAAMC,EAAgB,WAAW,EAAE,YAAY,uBAAuB;AAAA,MAC7ED,EAAO,MAAMC,EAAgB,QAAQ,EAAE,YAAY,mCAAmC;AAAA,MACtFD,EAAO,MAAMC,EAAgB,KAAK,EAAE,YAAY,2BAA2B;AAAA,MAC3ED,EAAO,MAAMC,EAAgB,OAAO,EAAE,YAAY,gCAAgC;AAAA,IAAA,CACnF,EACE,YAAY,mBAAmB,EAC/B,QAAQA,EAAgB,WAAW;AAAA,IACtC,8BAA8BD,EAAO,OAAA,EAClC,QAAQ,QAAQ,EAChB,KAAK,aAAa,EAClB,YAAY,6CAA6C;AAAA,IAC5D,sBAAsBA,EAAO,MAAM;AAAA,MACjCA,EAAO,MAAM,aAAa,EAAE,YAAY,uBAAuB;AAAA,MAC/DA,EAAO,MAAM,WAAW,EAAE,YAAY,WAAW;AAAA,MACjDA,EAAO,MAAM,YAAY,EAAE,YAAY,YAAY;AAAA,MACnDA,EAAO,MAAM,OAAO,EAAE,YAAY,OAAO;AAAA,MACzCA,EAAO,OAAA,EAAS,YAAY,kDAAkD,EAAE,QAAQ,EAAE;AAAA,IAAA,CAC3F,EACE,YAAY,sCAAsC,EAClD,QAAQ,aAAa;AAAA,EAAA,CACzB,EACE,YAAY,oBAAoB,EAChC,MAAM,YAAY,QAAQ;AAC/B,CAAA;AACO,IAAME,IAAN,MAAMA,WAAwBL,IAAAM,GAAW;AAAA,EAY9C,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,YAAY,GADV,KAAA,MAAAA,GAXnB,KAAiB,kBAAoC;AAAA,MACnD,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,iBAAiB;AAAA,IAAA,GAKjB,KAAK,IAAI,KAAK,IAAI,aAAaC,EAAa,MAAM,WAAW,CAAC;AAAA,EAChE;AAAA,EAEU,QAA8B;AACtC,SAAK,IAAI,OAAO,CAAC,SAAS,GAAG,CAACD,MAAQ;AACpC,WAAK,cAAcA,CAAG,GACtBA,EAAI,GAAG,WAAW,MAAM;AACtB,aAAK,cAAcA,CAAG;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAUE,GAA8C;AAC5D,UAAM,EAAE,GAAAC,MAAM,KAAK;AAiBnB,QAhBI,OAAOD,IAAY,MACrBA,IAAU,CAAA,IACD,OAAOA,KAAY,aAC5BA,IAAU;AAAA,MACR,OAAOA;AAAA,IAAA,IAKPA,GAAS,SAEXA,EAAQ,QAAQA,EAAQ,MAExB,OAAOA,EAAQ,OAGb,CAACA,EAAQ,SAAS,CAACA,EAAQ,UAAU,CAACA,EAAQ,UAAU;AAC1D,WAAK,OAAO,KAAK,iEAAiE;AAClF,YAAME,IAAe,IAAI,gBAAgB,OAAO,SAAS,MAAM,GACzDC,IAAQ,KAAK,IAAI,YAAY;AACnC,MAAAH,IAAU;AAAA,QACR,GAAGA;AAAA,QACH,OAAOG,GAAO,iBAAA;AAAA,QACd,UAAUD,EAAa,IAAI,OAAO,IAAI,OAAOA,EAAa,IAAI,OAAO,CAAC,IAAI;AAAA,QAC1E,QAAQA,EAAa,IAAI,OAAO,IAAI,OAAOA,EAAa,IAAI,OAAO,CAAC,IAAI;AAAA,MAAA;AAAA,IAE5E;AAEA,QAAI,CAACF,EAAQ,YAAY,CAACA,EAAQ,UAAUA,EAAQ,OAAO;AACzD,YAAMI,IAAa,KAAK,IAAI,UAAU,yBAAyBJ,EAAQ,KAAK;AAC5E,MAAII,KAAcA,EAAW,MAAM,eAAA,KAAoB,MACrDJ,EAAQ,QAAQI,EAAW,MAAM,iBAAA,GACjCJ,EAAQ,YAAYI,EAAW;AAAA,IAEnC;AAEA,UAAMC,IAAgB,MAAM,KAAK,IAAI,YAAY,IAAI,wBAAwB,GACvEC,IAAa,MAAM,KAAK,IAAI,YAAY,IAAI,qBAAqB,GACjEC,IACJ,OAAOP,EAAQ,eAAgB,WAC3BA,EAAQ,cACP,MAAM,KAAK,IAAI,YAAY,IAAI,uBAAuB,GACvDQ,IACJ,OAAOR,EAAQ,aAAc,YACzBA,EAAQ,YACP,MAAM,KAAK,IAAI,YAAY,IAAI,qBAAqB,GACrDS,IAAc,MAAM,KAAK,mBAAA,GAEzBC,IAA4B;AAAA,MAChC,GAAG,KAAK;AAAA,MACR,aAAAH;AAAA,MACA,WAAAC;AAAA,MACA,GAAGR;AAAA,IAAA;AAEL,IAAKU,EAAQ,gBACXA,EAAQ,cAAe,MAAM,KAAK,IAAI,YAAY,IAAI,uBAAuB,KAAM,KAErF,KAAK,IAAI,KAAK,2BAA2B,EAAE,KAAK,KAAK,KAAK,SAAAA,GAAS;AAEnE,UAAMC,IAAQ,KAAK,IAAI,MACpB,aAAa;AAAA,MACZ,WAAW;AAAA,MACX,WAAW;AAAA;AAAA;AAAA,MAGX,QAAQ;AAAA,MACR,cAAAN;AAAA,IAAA,CACD,EACA,KAAA;AACH,IAAAM,EAAM;AAAA,MAEFC,gBAAAA,EAAAC,GAAA,EAAE,UAAA;AAAA,QAAA;AAAA,0BACU,KAAA,EAAG,UAAAH,EAAQ,OAAM;AAAA,MAAA,GAC7B;AAAA,IAAA,GAGJC,EAAM;AAAA,MAEF,gBAAAG;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,eAAe;AAAA,YACf,gBAAgB;AAAA,YAChB,YAAY;AAAA,UAAA;AAAA,UAGd,4BAACC,GAAA,CAAA,CAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACf,GAGJJ,EAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAOV;AAAA,MACP,SAAS;AACP,QAAAU,EAAM,MAAA;AAAA,MACR;AAAA,IAAA,CACD,GACDA,EAAM,KAAA,GACN,KAAK,IAAI,KAAK,yBAAyB,EAAE,KAAK,KAAK,KAAK,OAAAA,GAAO,SAAAD,GAAS;AAExE,QAAIM;AACJ,QAAI;AAEF,UADAA,IAAW,MAAM,KAAK,uBAAuBN,CAAO,GAChDM,EAAS,SAAS;AACpB,cAAM,IAAI,MAAMf,gCAAgC;AAAA,IAEpD,SAASgB,GAAG;AACV,MAAAN,EAAM,IAAIA,EAAM,MAAM,KAAK,GAC3BA,EAAM,MAAA,GACN,KAAK,IAAI,MAAM,OAAO,SAAS;AAAA,QAC7B,SAASM,aAAa,QAAQA,EAAE,UAAU,OAAOA,CAAC;AAAA,MAAA,CACnD;AACD;AAAA,IACF;AAEA,UAAMC,IAAkBR,EAAQ,YAAY,QAAQ,KAAKM,EAAS,UAAU,CAAC,GAAG,WAAW,IACrFG,IAAgBH,EAAS,UAAU,CAAC,GAAG,OACvCI,IAAgBD,KAAiBA,MAAkBH,EAAS,WAC5DK,IAAuBX,EAAQ,YAAY,OAC3CY,IAAoBN,EAAS,WAAW;AAE9C,IAAAL,EAAM;AAAA,MAEFC,gBAAAA,EAAAC,GAAA,EACG,UAAA;AAAA,QAAAQ,IACGpB,iBACAA,UAAUqB,IAAoB,WAAW,MAAM;AAAA,QAAG;AAAA,0BACnD,KAAA,EAAG,UAAAN,EAAS,SAAS,OAAM;AAAA,QAC7BI,IAAgB,KAAKnB,WAAW,IAAIkB,CAAa,MAAM;AAAA,MAAA,GAC1D;AAAA,IAAA;AAIJ,UAAMI,IAAc,CAAA;AAEpB,IAAID,KACFC,EAAY;AAAA,MACV,gBAAAT,EAACU,KAAK,OAAOvB,cAAc,MAAK,aAC9B,UAAA,gBAAAa,EAAC,KAAA,EAAG,UAAAb,6BAAA,CAA6B,GACnC;AAAA,IAAA,GAIAmB,KACFG,EAAY;AAAA,wBACTC,GAAA,EAAK,OAAOvB,cAAc,MAAK,WAC9B,UAAA,gBAAAa;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWb;AAAA,QAAA;AAAA,MAAA,GAEf;AAAA,IAAA,GAGJ,KAAK,IAAI,KAAK,0BAA0B;AAAA,MACtC,KAAK,KAAK;AAAA,MACV,SAAAS;AAAA,MACA,OAAAC;AAAA,MACA,UAAAK;AAAA,MACA,aAAAO;AAAA,IAAA,CACD;AAED,UAAME,IACJb,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACd,UAAA;AAAA,wBAAC,OAAA,EAAI,WAAU,0BAA0B,UAAAW,GAAY;AAAA,MACrDX,gBAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,OAAA;AAAA,UAEvD,UAAA;AAAA,YAAAF,EAAQ,YAAY,SACnB,gBAAAI,EAAAD,GAAA,EACE,UAAA,gBAAAC;AAAA,cAACY;AAAA,cAAA;AAAA,gBACC,OAAOzB;AAAA,gBACP,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,YAAY,EAAE,aAAaA,sDAAA;AAAA,cAAsD;AAAA,YAAA,GAErF;AAAA,YAEF,gBAAAa;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAW,2BAA2BL,EAAY,SAAS;AAAA,gBAC3D,OAAO,EAAE,YAAYA,EAAY,WAAA;AAAA,gBACjC,MAAK;AAAA,gBACL,IAAG;AAAA,gBAEF,UAAAS;AAAA,cAAA;AAAA,YAAA;AAAA,UACH;AAAA,QAAA;AAAA,MAAA;AAAA,MAEFN,gBAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO;AAAA,YACL,SAAS;AAAA,YACT,eAAe;AAAA,YACf,KAAK;AAAA,YACL,WAAW;AAAA,UAAA;AAAA,UAGZ,UAAA;AAAA,YAAA,CAACS,KACA,gBAAAP,EAACY,GAAA,EAAS,OAAOzB,YAAY,IAAG,WAAU,MAAK,WAAU,OAAOS,EAAQ,aAAa;AAAA,YAEvFE,gBAAAA,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,cAAA,gBAAAE,EAAC,SAAA,EAAM,SAAQ,aAAY,OAAO,EAAE,SAAS,QAAA,GAC1C,UAAAb,aAAA,CACH;AAAA,cACA,gBAAAa,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,QAAQ,YAAY,UAAU,WAAW,OAAA,GAC1E,UAAA;AAAA,gBACCnB,EAAgB;AAAA,gBAChBA,EAAgB;AAAA,gBAChBA,EAAgB;AAAA,gBAChBA,EAAgB;AAAA,cAAA,EAChB,IAAI,CAACgC,MACL,gBAAAb;AAAA,gBAACc;AAAA,gBAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,OAAOD;AAAA,kBACP,YAAY;AAAA,oBACV,SAASrB,MAAcqB;AAAA,oBACvB,UAAU,CAACV,MAAM;AACf,sBAAAA,EAAE,UACCA,EAAE,OAAuB,QAAQ,OAAO,GAAG,eAAe;AAAA,wBACzD,UAAU;AAAA,wBACV,QAAQ;AAAA,sBAAA,CACT;AAAA,oBACL;AAAA,kBAAA;AAAA,kBAGD,wBAAcU,CAAM;AAAA,gBAAA;AAAA,gBAdhBA;AAAA,cAAA,CAgBR,GACH;AAAA,YAAA,GACF;AAAA,YACAf,gBAAAA,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,OAAA,GAClC,UAAA;AAAA,cAAA,gBAAAE,EAACe,GAAA,EAAS,MAAK,SAAQ,IAAG,SAAQ,SAASnB,EAAQ,WAChD,UAAAT,cAAA,CACH;AAAA,cACA,gBAAAa,EAACe,KAAS,MAAK,mBAAkB,IAAG,mBAAkB,SAASnB,EAAQ,iBACpE,UAAAT,qBAAA,CACH;AAAA,YAAA,GACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD;AAAA,IAAA,GAOH;AAEF,IAAAU,EAAM,WAAWc,CAAQ;AAEzB,QAAIK,IAAkB;AACtB,IAAAnB,EAAM;AAAA,MACJ;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,OAAOV;AAAA,QACP,UAAW,MAAM,KAAK,IAAI,YAAY,IAAI,4BAA4B,KAAM;AAAA,QAC5E,QAAQ,YAAY;AAClB,gBAAM8B,IAAW,IAAI,SAASN,CAAQ;AAMtC,UAAAd,EAAM,gBAAgB,EAAI;AAE1B,cAAI;AACF,kBAAM,KAAK,aAAa;AAAA,cACtB,UAAAK;AAAA,cACA,MAAMe,EAAS,IAAI,MAAM;AAAA,cACzB,SAASA,EAAS,IAAI,SAAS;AAAA,cAC/B,OAAOA,EAAS,IAAI,OAAO,MAAM;AAAA,cACjC,SAASrB,EAAQ;AAAA,cACjB,WAAWJ;AAAA;AAAA,cAEX,YAAYU,EAAS,WAAW,KAAK,CAACc;AAAA,cACtC,UAAUd,EAAS,WAAW,KAAKc;AAAA,YAAA,CACpC,GAEDnB,EAAM,WAAW;AAAA,cACf,aAAaqB;AAAA,YAAA,CACd,GACDrB,EAAM,MAAA,GAEN,KAAK,IAAI,MAAM,OAAO,WAAW;AAAA,cAC/B,OAAOV;AAAA,cACP,SAASA;AAAA,YAAA,CACV,GAEG8B,EAAS,IAAI,iBAAiB,MAChC,MAAM7C,EAAM,GAAG,GACf,SAAS,OAAA;AAAA,UAEb,SAAS+C,GAAO;AAGd,gBAFAtB,EAAM,gBAAgB,EAAK,GAEvBuB,EAAkB,GAAGD,CAAK,MAE1BA,EAAM,SAAS,iBACfA,EAAM,SAAS,kBACfA,EAAM,SAAS,kBACf;AACA,cAAAH,IAAkB,IAClB,KAAK,IAAI,MAAM,OAAO,WAAW;AAAA,gBAC/B,OAAO7B;AAAA,gBACP,2BACG,OAAA,EACC,UAAA;AAAA,kBAAA,gBAAAa,EAAC,KAAA,EACC,UAAA,gBAAAA,EAAC,UAAA,EAAQ,UAAAmB,EAAM,QAAA,CAAQ,GACzB;AAAA,kBACA,gBAAAnB,EAAC,OAAG,UAAAb,yDAAwD;AAAA,gBAAA,GAC9D;AAAA,gBAEF,YAAY,KAAK;AAAA,cAAA,CAClB;AACD;AAAA,YACF;AAIF,iBAAK,IAAI,MAAM,OAAO,SAAS;AAAA,cAC7B,OAAOA;AAAA,cACP,SAASgC,aAAiB,QAAQA,EAAM,UAAU,OAAOA,CAAK;AAAA,YAAA,CAC/D;AAAA,UACH;AAAA,QACF;AAAA,MAAA;AAAA,MAEF;AAAA,IAAA,GAEFtB,EAAM,WAAW;AAAA,MACf,aAAa,MAAM;AACjB,cAAMwB,IAASnB,EAAS,UAAU,CAAC,GAAG,WAAW;AAEjD,gBADeS,EAAS,cAAc,UAAU,GAAG,SAAS,QAC7CU,IACN,MAEP,KAAK,IAAI,MAAM;AAAA,UACb;AAAA,YACE,WAAW;AAAA,YACX,OAAOlC;AAAA,YACP,SAASA;AAAA,YACT,QAAQ;AAAA,YACR,OAAO;AAAA,cACL,OAAOA;AAAA,cACP,WAAW;AAAA,YAAA;AAAA,YAEb,WAAW;AAAA,cACT,OAAOA;AAAA,cACP,WAAW;AAAA,YAAA;AAAA,UACb;AAAA,UAEF,CAACmC,OACKA,MACFzB,EAAM,WAAW;AAAA,YACf,aAAaqB;AAAA,UAAA,CACd,GACDrB,EAAM,MAAA,IAED;AAAA,QACT,GAEK;AAAA,MAEX;AAAA,IAAA,CACD,GACD,KAAK,IAAI,KAAK,wBAAwB;AAAA,MACpC,KAAK,KAAK;AAAA,MACV,SAAAD;AAAA,MACA,OAAAC;AAAA,MACA,UAAAK;AAAA,IAAA,CACD;AAED,UAAMqB,IAAe,CAACpB,MAChBQ,EAAS,cAAc,UAAU,GAAG,UAAUP,IACzC,MAETD,EAAE,eAAA,GACKhB;AAET,WAAO,iBAAiB,gBAAgBoC,CAAY,GACpD1B,EAAM,GAAGA,EAAM,MAAM,OAAO,MAAM;AAChC,aAAO,oBAAoB,gBAAgB0B,CAAY;AAAA,IACzD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAarC,GAAiC;AAClD,UAAM,EAAE,UAAAgB,GAAU,GAAGsB,EAAA,IAAStC;AAE9B,gBAAK,IAAI,KAAK,qBAAqB;AAAA,MACjC,KAAK,KAAK;AAAA,MACV,UAAAgB;AAAA,MACA,GAAGsB;AAAA,IAAA,CACJ,GAEMtB,EAAS,KAAK;AAAA,MACnB,GAAGsB;AAAA,IAAA,CACJ;AAAA,EACH;AAAA,EAEA,OAAA;AAAA,SAAgB,wBAAwB,CAAC,eAAe,aAAa,cAAc,OAAO;AAAA,EAAA;AAAA,EAC1F,MAAM,qBAAqB;AACzB,UAAMC,IAAgB,MAAM,KAAK,IAAI,YAAY,IAAI,oBAAoB;AACzE,WAAI3C,EAAgB,sBAAsB,SAAS2C,CAAY,IAKtD;AAAA,MACL,WAAW,eAJXA,MAAiB,gBACb,KAAK,IAAI,KAAK,aAAa,YAAY,cACvCA,CAE8B;AAAA,MAClC,YAAY;AAAA,IAAA,IAGP;AAAA,MACL,WAAW;AAAA,MACX,YAAYA;AAAA,IAAA;AAAA,EAGlB;AAAA,EAEA,MAAM,uBAAuBvC,GAAoC;AAC/D,QAAIA,EAAQ;AACV,aAAO,KAAK,IAAI,SAAS,gBAAgBA,EAAQ,UAAUA,EAAQ,OAAO;AAC5E,QAAWA,EAAQ;AACjB,aAAO,KAAK,IAAI,SAAS,cAAcA,EAAQ,QAAQA,EAAQ,OAAO;AACxE,QAAWA,EAAQ;AACjB,aAAO,KAAK,IAAI,SAAS,aAAaA,EAAQ,OAAO,IAAOA,EAAQ,OAAO;AAE7E,UAAM,IAAI,MAAM,iBAAiB;AAAA,EACnC;AAAA,EAEA,MAAc,cAAcF,GAAiB;AAC3C,UAAM,EAAE,GAAAG,MAAM,KAAK,KACbE,IAAQ,KAAK,IAAI,YAAY,WAC7BqC,IAAUrC,KAASA,EAAM,eAAA,KAAoB;AACnD,IAAAL,EAAI,QAAQ,UAAU;AAAA,MACpB,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MACEc,gBAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAM;AAAA,UACN,QAAO;AAAA,UACP,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,QAAO;AAAA,UACP,gBAAa;AAAA,UACb,kBAAe;AAAA,UACf,mBAAgB;AAAA,UAChB,OAAM;AAAA,UAEN,UAAA;AAAA,YAAA,gBAAAE,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,YAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,8DAA6D;AAAA,YACrE,gBAAAA,EAAC,QAAA,EAAK,GAAE,0EAAyE;AAAA,YACjF,gBAAAA,EAAC,QAAA,EAAK,GAAE,aAAY;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGxB,aAAa;AAAA,QACX,UAAU,CAAC0B;AAAA,MAAA;AAAA,MAEb,SAAS,MAAOA,IAAUvC,gBAAgBA;AAAA,MAC1C,SAAS,MAAM;AACb,cAAMwC,IAAW,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,OAAO;AACxE,aAAK,UAAU;AAAA,UACb,OAAOtC,GAAO,gBAAA;AAAA,UACd,UAAUsC,IAAW,OAAOA,CAAQ,IAAI;AAAA,QAAA,CACzC;AAAA,MACH;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEU,cAAc3C,GAAiB;AACvC,IAAAA,EAAI,QAAQ,aAAa,YAAY;AAAA,EACvC;AAAA,EAEA,sBACEE,GACAU,GAIA;AACA,UAAM,EAAE,GAAAT,MAAM,KAAK,KACbyC,IAAOhC,GAAS,QAAQ,gBAAAI,EAAC6B,GAAA,EAAc,WAAU,YAAW,GAC5DC,IAAQlC,GAAS,SAAST;AAChC,WACEW,gBAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,SAASZ;AAAA,QACT,WAAW,kBAAkBA,EAAQ,aAAa,gCAAgC,EAAE;AAAA,QACpF,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,YAAY;AAAA,QAAA;AAAA,QAEd,SAAS,CAACiB,MAAM;AACd,UAAAA,EAAE,eAAA,GACF,KAAK,UAAUjB,CAAO;AAAA,QACxB;AAAA,QAEC,UAAA;AAAA,UAAA0C;AAAA,UACAE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAzhBOtD,IAAAuD,EAAAtD,CAAA;AAAMK,IAANkD,4BArCPzD,GAqCaO,CAAA;AAANmD,GAAAzD,GAAA,GAAMM,CAAA;AAAN,IAAMoD,KAANpD;"}