dsh-plugin-shop 0.7.1 → 0.7.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +374 -318
- package/lib/index.js +10 -1
- package/lib/typert.host.js +11 -10
- package/lib/typert.remote-client.js +10 -9
- package/lib/types/client/locales.d.ts +6 -0
- package/lib/types/client/present.d.ts +1 -13
- package/lib/types/host/catalog.d.ts +5 -0
- package/lib/types/host/index.d.ts +3 -0
- package/lib/types/shared/shop-like.d.ts +32 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -4318,6 +4318,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4318
4318
|
"detail": string(),
|
|
4319
4319
|
"replacement": union([_undefined(), string()]).optional()
|
|
4320
4320
|
})),
|
|
4321
|
+
"notAShop": union([_undefined(), array(string())]).optional(),
|
|
4321
4322
|
"stars": record(string(), number()),
|
|
4322
4323
|
"incompatible": record(string(), array(string()))
|
|
4323
4324
|
});
|
|
@@ -4436,7 +4437,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4436
4437
|
},
|
|
4437
4438
|
sourceLocation: {
|
|
4438
4439
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4439
|
-
"line":
|
|
4440
|
+
"line": 577,
|
|
4440
4441
|
"column": 9
|
|
4441
4442
|
}
|
|
4442
4443
|
},
|
|
@@ -4454,7 +4455,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4454
4455
|
},
|
|
4455
4456
|
sourceLocation: {
|
|
4456
4457
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4457
|
-
"line":
|
|
4458
|
+
"line": 763,
|
|
4458
4459
|
"column": 9
|
|
4459
4460
|
}
|
|
4460
4461
|
},
|
|
@@ -4482,7 +4483,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4482
4483
|
},
|
|
4483
4484
|
sourceLocation: {
|
|
4484
4485
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4485
|
-
"line":
|
|
4486
|
+
"line": 628,
|
|
4486
4487
|
"column": 9
|
|
4487
4488
|
}
|
|
4488
4489
|
},
|
|
@@ -4509,7 +4510,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4509
4510
|
},
|
|
4510
4511
|
sourceLocation: {
|
|
4511
4512
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4512
|
-
"line":
|
|
4513
|
+
"line": 752,
|
|
4513
4514
|
"column": 3
|
|
4514
4515
|
}
|
|
4515
4516
|
},
|
|
@@ -4527,7 +4528,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4527
4528
|
},
|
|
4528
4529
|
sourceLocation: {
|
|
4529
4530
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4530
|
-
"line":
|
|
4531
|
+
"line": 913,
|
|
4531
4532
|
"column": 9
|
|
4532
4533
|
}
|
|
4533
4534
|
},
|
|
@@ -4554,7 +4555,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4554
4555
|
},
|
|
4555
4556
|
sourceLocation: {
|
|
4556
4557
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4557
|
-
"line":
|
|
4558
|
+
"line": 469,
|
|
4558
4559
|
"column": 9
|
|
4559
4560
|
}
|
|
4560
4561
|
},
|
|
@@ -4582,7 +4583,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4582
4583
|
},
|
|
4583
4584
|
sourceLocation: {
|
|
4584
4585
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4585
|
-
"line":
|
|
4586
|
+
"line": 855,
|
|
4586
4587
|
"column": 9
|
|
4587
4588
|
}
|
|
4588
4589
|
},
|
|
@@ -4609,7 +4610,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4609
4610
|
},
|
|
4610
4611
|
sourceLocation: {
|
|
4611
4612
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4612
|
-
"line":
|
|
4613
|
+
"line": 981,
|
|
4613
4614
|
"column": 9
|
|
4614
4615
|
}
|
|
4615
4616
|
},
|
|
@@ -4627,13 +4628,87 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4627
4628
|
},
|
|
4628
4629
|
sourceLocation: {
|
|
4629
4630
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4630
|
-
"line":
|
|
4631
|
+
"line": 964,
|
|
4631
4632
|
"column": 9
|
|
4632
4633
|
}
|
|
4633
4634
|
}
|
|
4634
4635
|
]
|
|
4635
4636
|
};
|
|
4636
4637
|
//#endregion
|
|
4638
|
+
//#region src/shared/shop-like.ts
|
|
4639
|
+
/**
|
|
4640
|
+
* Whether a package name reads as a competing plugin marketplace.
|
|
4641
|
+
*
|
|
4642
|
+
* Shared on purpose. The registry needs it to pick which newly harvested names
|
|
4643
|
+
* to send for a market verdict, and the client needs it to hide the ones no
|
|
4644
|
+
* verdict has reached yet. When each had a copy they drifted — that is exactly
|
|
4645
|
+
* how the shelf came to disagree with its own count — so there is one.
|
|
4646
|
+
*
|
|
4647
|
+
* It lives under the published package rather than beside the registry because
|
|
4648
|
+
* the dependency can only point this way: the package's tsconfig pins
|
|
4649
|
+
* `rootDir: "src"`, so nothing outside it can be imported, while the registry
|
|
4650
|
+
* scripts are internal and may reach in.
|
|
4651
|
+
*
|
|
4652
|
+
* This is a NAME heuristic and nothing more. It cannot tell a plugin that
|
|
4653
|
+
* stores tea from one that sells plugins — on the live catalog it caught 73
|
|
4654
|
+
* names of which 20 were innocent — so `registry/markets.yml` carries the
|
|
4655
|
+
* verdict per name and overrides it either way.
|
|
4656
|
+
*
|
|
4657
|
+
* @module shared/shop-like
|
|
4658
|
+
*/
|
|
4659
|
+
const SHOP_KEYWORDS = [
|
|
4660
|
+
"store",
|
|
4661
|
+
"market",
|
|
4662
|
+
"mall",
|
|
4663
|
+
"shop",
|
|
4664
|
+
"marketplace"
|
|
4665
|
+
];
|
|
4666
|
+
/**
|
|
4667
|
+
* Competing plugin marketplaces whose names carry no store/market keyword
|
|
4668
|
+
* and so escape the pattern rules below (spec §7.2). Each is a real npm
|
|
4669
|
+
* package that presents its own catalog of dsh plugins inside the Harness:
|
|
4670
|
+
* `dsh-plugin` is the npm package of github.com/dshplugin/dsh-plugin-hub,
|
|
4671
|
+
* `dsh-plugin-hub` and `@lanbaolu/dsh-plugin-hub` are app-store packages,
|
|
4672
|
+
* and `@mutocenew/dsh-plugin-catalog` ships a plugin directory with agent
|
|
4673
|
+
* query tools. Exact names only — nothing here is a pattern.
|
|
4674
|
+
*/
|
|
4675
|
+
const SHOP_LIKE_NAMES = [
|
|
4676
|
+
"dsh-plugin",
|
|
4677
|
+
"dsh-plugin-hub",
|
|
4678
|
+
"@lanbaolu/dsh-plugin-hub",
|
|
4679
|
+
"@mutocenew/dsh-plugin-catalog"
|
|
4680
|
+
];
|
|
4681
|
+
/**
|
|
4682
|
+
* Whether a package name reads as a plugin shop (a marketplace for dsh
|
|
4683
|
+
* plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
|
|
4684
|
+
* tab hides these so the market does not list competing markets.
|
|
4685
|
+
*
|
|
4686
|
+
* Precision over recall: a name merely CONTAINING a keyword segment without
|
|
4687
|
+
* a plugin qualifier or a keyword ending (`market-data-provider`,
|
|
4688
|
+
* `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
|
|
4689
|
+
* match on the substring "store". The keyword list keeps "store" on purpose:
|
|
4690
|
+
* it matches other people's package names, not ours.
|
|
4691
|
+
*/
|
|
4692
|
+
function isShopLike(name) {
|
|
4693
|
+
if (SHOP_LIKE_NAMES.includes(name.toLowerCase())) return true;
|
|
4694
|
+
const segments = name.toLowerCase().split(/[-_.]+/);
|
|
4695
|
+
const hasPlugin = segments.includes("plugin");
|
|
4696
|
+
if (segments.some((segment) => /plugin(store|market|mall|shop|marketplace)/.test(segment) || /(store|market|mall|shop|marketplace)plugin/.test(segment))) return true;
|
|
4697
|
+
if (segments.some((segment) => segment.startsWith("dsh") && SHOP_KEYWORDS.some((keyword) => segment === `dsh${keyword}`))) return true;
|
|
4698
|
+
if (segments.length >= 2 && (segments[0] === "dsh" || segments[0]?.endsWith("/dsh") === true) && SHOP_KEYWORDS.includes(segments[1]) && (segments.length === 2 || segments[2] !== void 0 && [
|
|
4699
|
+
"plus",
|
|
4700
|
+
"pro",
|
|
4701
|
+
"hub",
|
|
4702
|
+
"center",
|
|
4703
|
+
"centre",
|
|
4704
|
+
"max",
|
|
4705
|
+
"free",
|
|
4706
|
+
"lite"
|
|
4707
|
+
].includes(segments[2]))) return true;
|
|
4708
|
+
if (segments.filter((segment) => SHOP_KEYWORDS.includes(segment)).length === 0) return false;
|
|
4709
|
+
return hasPlugin || SHOP_KEYWORDS.includes(segments.at(-1));
|
|
4710
|
+
}
|
|
4711
|
+
//#endregion
|
|
4637
4712
|
//#region src/client/present.ts
|
|
4638
4713
|
/** Hot-mount reason code → locale key, so the notice reads in the language
|
|
4639
4714
|
* the person set in dsh. An absent (or unrecognized) reason keeps the generic
|
|
@@ -4750,58 +4825,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4750
4825
|
}
|
|
4751
4826
|
}
|
|
4752
4827
|
}
|
|
4753
|
-
const SHOP_KEYWORDS = [
|
|
4754
|
-
"store",
|
|
4755
|
-
"market",
|
|
4756
|
-
"mall",
|
|
4757
|
-
"shop",
|
|
4758
|
-
"marketplace"
|
|
4759
|
-
];
|
|
4760
|
-
/**
|
|
4761
|
-
* Competing plugin marketplaces whose names carry no store/market keyword
|
|
4762
|
-
* and so escape the pattern rules below (spec §7.2). Each is a real npm
|
|
4763
|
-
* package that presents its own catalog of dsh plugins inside the Harness:
|
|
4764
|
-
* `dsh-plugin` is the npm package of github.com/dshplugin/dsh-plugin-hub,
|
|
4765
|
-
* `dsh-plugin-hub` and `@lanbaolu/dsh-plugin-hub` are app-store packages,
|
|
4766
|
-
* and `@mutocenew/dsh-plugin-catalog` ships a plugin directory with agent
|
|
4767
|
-
* query tools. Exact names only — nothing here is a pattern.
|
|
4768
|
-
*/
|
|
4769
|
-
const SHOP_LIKE_NAMES = [
|
|
4770
|
-
"dsh-plugin",
|
|
4771
|
-
"dsh-plugin-hub",
|
|
4772
|
-
"@lanbaolu/dsh-plugin-hub",
|
|
4773
|
-
"@mutocenew/dsh-plugin-catalog"
|
|
4774
|
-
];
|
|
4775
|
-
/**
|
|
4776
|
-
* Whether a package name reads as a plugin shop (a marketplace for dsh
|
|
4777
|
-
* plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
|
|
4778
|
-
* tab hides these so the market does not list competing markets.
|
|
4779
|
-
*
|
|
4780
|
-
* Precision over recall: a name merely CONTAINING a keyword segment without
|
|
4781
|
-
* a plugin qualifier or a keyword ending (`market-data-provider`,
|
|
4782
|
-
* `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
|
|
4783
|
-
* match on the substring "store". The keyword list keeps "store" on purpose:
|
|
4784
|
-
* it matches other people's package names, not ours.
|
|
4785
|
-
*/
|
|
4786
|
-
function isShopLike(name) {
|
|
4787
|
-
if (SHOP_LIKE_NAMES.includes(name.toLowerCase())) return true;
|
|
4788
|
-
const segments = name.toLowerCase().split(/[-_.]+/);
|
|
4789
|
-
const hasPlugin = segments.includes("plugin");
|
|
4790
|
-
if (segments.some((segment) => /plugin(store|market|mall|shop|marketplace)/.test(segment) || /(store|market|mall|shop|marketplace)plugin/.test(segment))) return true;
|
|
4791
|
-
if (segments.some((segment) => segment.startsWith("dsh") && SHOP_KEYWORDS.some((keyword) => segment === `dsh${keyword}`))) return true;
|
|
4792
|
-
if (segments.length >= 2 && (segments[0] === "dsh" || segments[0]?.endsWith("/dsh") === true) && SHOP_KEYWORDS.includes(segments[1]) && (segments.length === 2 || segments[2] !== void 0 && [
|
|
4793
|
-
"plus",
|
|
4794
|
-
"pro",
|
|
4795
|
-
"hub",
|
|
4796
|
-
"center",
|
|
4797
|
-
"centre",
|
|
4798
|
-
"max",
|
|
4799
|
-
"free",
|
|
4800
|
-
"lite"
|
|
4801
|
-
].includes(segments[2]))) return true;
|
|
4802
|
-
if (segments.filter((segment) => SHOP_KEYWORDS.includes(segment)).length === 0) return false;
|
|
4803
|
-
return hasPlugin || SHOP_KEYWORDS.includes(segments.at(-1));
|
|
4804
|
-
}
|
|
4805
4828
|
const CATEGORY_KEYS = {
|
|
4806
4829
|
tool: "categoryTool",
|
|
4807
4830
|
provider: "categoryProvider",
|
|
@@ -4993,6 +5016,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4993
5016
|
installFailed: "安装失败",
|
|
4994
5017
|
installTransportFailed: "安装请求未能送达。请稍后重试。",
|
|
4995
5018
|
refresh: "刷新",
|
|
5019
|
+
refreshing: "刷新中…",
|
|
5020
|
+
refreshFailed: "刷新失败,仍显示上次的目录",
|
|
4996
5021
|
staleLabel: "显示 {date} 的快照",
|
|
4997
5022
|
showing: "显示前 {shown} 个(共 {total})· 继续滚动加载",
|
|
4998
5023
|
repository: "仓库",
|
|
@@ -5031,6 +5056,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5031
5056
|
updateFailed: "更新失败",
|
|
5032
5057
|
updateTransportFailed: "更新请求未能送达。请稍后重试。",
|
|
5033
5058
|
checkUpdate: "检查更新",
|
|
5059
|
+
checkUpdateTitle: "检查更新",
|
|
5034
5060
|
upToDate: "已是最新版本",
|
|
5035
5061
|
github: "GitHub",
|
|
5036
5062
|
enabledSwitch: "启用",
|
|
@@ -5081,6 +5107,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5081
5107
|
installFailed: "Install failed",
|
|
5082
5108
|
installTransportFailed: "The install request could not be delivered. Please retry.",
|
|
5083
5109
|
refresh: "Refresh",
|
|
5110
|
+
refreshing: "Refreshing…",
|
|
5111
|
+
refreshFailed: "Reload failed; still showing the last catalog",
|
|
5084
5112
|
staleLabel: "showing {date}",
|
|
5085
5113
|
showing: "showing first {shown} of {total} — scroll to load more",
|
|
5086
5114
|
repository: "Repository",
|
|
@@ -5118,7 +5146,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5118
5146
|
restartDisabledNotice: "This dsh process runs as a systemd service, so the shop cannot restart it safely. Restart the service manually, or set allowRestart: true in the shop row config.",
|
|
5119
5147
|
updateFailed: "Update failed",
|
|
5120
5148
|
updateTransportFailed: "The update request could not be delivered. Please retry.",
|
|
5121
|
-
checkUpdate: "Check
|
|
5149
|
+
checkUpdate: "Check",
|
|
5150
|
+
checkUpdateTitle: "Check for updates",
|
|
5122
5151
|
upToDate: "Up to date",
|
|
5123
5152
|
github: "GitHub",
|
|
5124
5153
|
enabledSwitch: "Enable",
|
|
@@ -5274,108 +5303,110 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5274
5303
|
};
|
|
5275
5304
|
}
|
|
5276
5305
|
//#endregion
|
|
5277
|
-
//#region \0dsh-plugin-shop-css:
|
|
5278
|
-
const css = "/* Shop tab styles — a market shelf inside the settings surface. The visual\n * language is the dsh theme's alias tokens ONLY (the four tokens the previous\n * styles referenced that do not exist — bg-layer-3, interactive-bg-hover,\n * state-error, state-success — are corrected to bg-layer-2 and the\n * state-*-primary set). The signature is the category spine: one HUE per\n * category (seven fixed hues, not the brand token — the brand resolves to\n * near-black in the light theme, so seven brand opacities read as seven\n * shades of gray), with the category name as the cover label in the same hue. Class names are mapped to content-derived names at bundle time\n * (tsdown.sfae5fa_client.se9da7d_config.se722f1_ts) and stubbed in tests; only the keys are relied\n * on.\n *\n * One token rule the theme forces: the background LAYERS do not carry\n * contrast. In the light theme bg-base, bg-layer-1, bg-layer-2 and\n * bg-layer-3 all resolve to the same white; only the dark theme spreads them\n * (950/875/850/800). So a layer-2 fill on a layer-1 ground is invisible for\n * half of all users, and anything whose fill is its ONLY affordance — the\n * loading skeleton, the borderless capability chips — derives its fill from\n * label-primary instead, which inverts with the theme by construction.\n * Elements that also carry a border or text may keep a layer fill.\n * `css-tokens.sfae5fa_client.s2f7a8b_spec.se722f1_ts` pins this. */\n\n.s99b207_panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n /* The shelf never scrolls sideways: a card too wide for its track wraps\n * its badges rather than widening the panel.\n *\n * `clip` rather than `hidden`, with a margin, because `.se23a0e_searchInput` sits\n * at exactly (0, 0) of this box — it is the first child of `.s27ad76_toolbar`,\n * itself the first child here, and this rule carries no padding — so its\n * focus ring paints ENTIRELY outside the panel. `hidden` clipped it at the\n * padding edge, and because the spec forbids one axis being `hidden` while\n * the other is `visible`, it silently promoted overflow-y to `auto` and\n * clipped the ring top and bottom as well; all that survived was a stray\n * arc on the right, where the 280px input stops short of the panel. `clip`\n * does not coerce the other axis, so overflow-y stays `visible`, and\n * `overflow-clip-margin` buys back the 3px the ring reaches sideways.\n * `hidden` stays as the first declaration, the fallback for engines\n * without `clip`; there the ring is clipped as before, never worse. */\n overflow-x: hidden;\n overflow-x: clip;\n overflow-clip-margin: 3px;\n}\n\n.s2abe0f_stateLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* Visually hidden but screen-reader readable (the loading copy while the\n * skeleton stands in visually). */\n.sfb85e5_srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n}\n\n/* The loading shelf: ghost cards with the same geometry as the real grid, so\n * the swap to content is a same-shape handoff instead of a jump. */\n.s728a01_skeletonGrid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 8px;\n}\n\n.s33d002_skeletonCard {\n position: relative;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n}\n\n/* The shimmer sweep: one gradient band travels across each ghost card while\n * the bars breathe, so the loading state reads as \"the shelf is scanning\". */\n.s33d002_skeletonCard::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 100deg,\n transparent 25%,\n color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent) 50%,\n transparent 75%\n );\n transform: translateX(-100%);\n animation: dshShopSkeletonSweep 1.4s ease-in-out infinite;\n pointer-events: none;\n}\n\n@keyframes dshShopSkeletonSweep {\n to { transform: translateX(100%); }\n}\n\n.s46e666_skeletonName {\n width: 55%;\n height: 14px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s2a467d_skeletonSummary {\n width: 92%;\n height: 12px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s232601_skeletonSummaryShort {\n width: 68%;\n height: 12px;\n margin: 6px 12px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n/* The ghost of the action line, right where the real buttons land. */\n.sde9b0c_skeletonActions {\n display: block;\n width: 84px;\n height: 24px;\n margin: 0 12px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s33d002_skeletonCard span {\n animation: dshShopSkeletonPulse 1.6s ease-in-out infinite;\n}\n\n@keyframes dshShopSkeletonPulse {\n 0%, 100% { opacity: 0.5; }\n 50% { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s33d002_skeletonCard span { animation: none; opacity: 0.75; }\n .s33d002_skeletonCard::after { content: none; }\n}\n\n.sb632c0_actionButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.sb632c0_actionButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.sb632c0_actionButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s27ad76_toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.saba3c3_toolbarRight {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* The shop's own version, right of the search box: `v0.4.4`, plus the\n * update button when the version check found a newer release. */\n.s6736c0_versionBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.s2dff04_versionText {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s40b16e_updateSelfButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-brand-primary);\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.s40b16e_updateSelfButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 20%, transparent);\n}\n\n.s40b16e_updateSelfButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The on-demand re-check next to the version number: a quiet pill; the\n * border and text carry it in the light theme where bg layers are white. */\n.secd6a2_checkUpdateButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.secd6a2_checkUpdateButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n color: var(--dsw-alias-label-primary);\n}\n\n.secd6a2_checkUpdateButton:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n.secd6a2_checkUpdateButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The project's GitHub mark, right of the version row: a quiet icon link.\n * The octocat carries itself — color shift on hover, no text, no border. */\n.s5e1ce3_githubLink {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 3px;\n border-radius: 6px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s5e1ce3_githubLink:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.s5e1ce3_githubLink:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The self-update's expanded states (running log / done + restart /\n * failure detail) sit under the toolbar, above the category bar. */\n.s798348_selfUpdatePanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n\n.se23a0e_searchInput {\n width: min(280px, 100%);\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n.se23a0e_searchInput:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s82b1d4_staleBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.see2588_staleBadge {\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n color: var(--dsw-alias-state-warn-primary);\n font-size: 12px;\n}\n\n.se67e0b_categoryBar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.s8c06a0_categoryButton {\n padding: 3px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s8c06a0_categoryButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s65a55a_categoryButtonOn {\n border-color: var(--dsw-alias-brand-primary);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-weight: 600;\n}\n\n.s8c06a0_categoryButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sb6cdd6_catalogHeading {\n margin: 2px 0 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-primary);\n}\n\n.s38a33e_catalogStats {\n margin: 6px 0 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.se3ba96_emptyLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* The shelf: a responsive grid of cards. */\n/* Single-line rows: one full-width column, one plugin per line. */\n.sb41fe1_cards {\n display: grid;\n grid-template-columns: 1fr;\n max-width: 100%;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n animation: dshShopCardsIn 220ms ease;\n}\n\n@keyframes dshShopCardsIn {\n from { opacity: 0; transform: translateY(3px); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sb41fe1_cards { animation: none; }\n}\n\n.sfcd584_card {\n position: relative;\n display: flex;\n flex-direction: column;\n /* A grid item's min-width is auto by default: its content would widen the\n * 1fr track past the panel and overflow horizontally. */\n min-width: 0;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;\n /* Off-screen cards skip layout and paint; the placeholder keeps scrollbar\n * estimation sane before the browser has measured the real height. */\n content-visibility: auto;\n contain-intrinsic-size: auto 140px;\n}\n\n/* The sentinel that triggers the next shelf batch: zero visual footprint. */\n.sf2d932_cardsSentry {\n height: 1px;\n margin: 0;\n padding: 0;\n}\n\n.s947694_showingLine {\n margin: 0;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sfcd584_card:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l1));\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sfcd584_card { transition: none; }\n .sfcd584_card:hover { transform: none; }\n}\n\n/* The signature: a spine and cover in the category's own hue. The hues are\n * fixed mid-bright colors that read on both themes; `other` deliberately\n * stays a neutral gray so the fallback category does not compete. */\n.sfc4028_cardSpine {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 3px;\n background: var(--spine-hue, #8B8E96);\n}\n\n.sfcd584_card[data-category='tool'] { --spine-hue: #4C8DFF; }\n.sfcd584_card[data-category='provider'] { --spine-hue: #A78BFA; }\n.sfcd584_card[data-category='ui'] { --spine-hue: #2DD4BF; }\n.sfcd584_card[data-category='workflow'] { --spine-hue: #F59E0B; }\n.sfcd584_card[data-category='integration'] { --spine-hue: #34D399; }\n.sfcd584_card[data-category='theme'] { --spine-hue: #F472B6; }\n.sfcd584_card[data-category='other'] { --spine-hue: #8B8E96; }\n\n/* The category sits in the badge row as a quiet chip in the category's own\n * hue — the border carries it where the light theme's white layers cannot\n * (the same lesson as the check button). */\n.sb94610_categoryBadge {\n padding: 1px 7px;\n border: 1px solid color-mix(in srgb, var(--spine-hue, #8B8E96) 45%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--spine-hue, #8B8E96);\n white-space: nowrap;\n}\n\n.s50a94e_entryHeader {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px 2px;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.s50a94e_entryHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* The name fills the row and truncates rather than wraps; the badges stay\n * intact beside it. */\n.sfdbf47_name {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n flex: 1 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--dsw-alias-label-primary);\n}\n\n.s28e55e_badges {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* The action line: buttons side by side; an active install/uninstall flow\n * (gate, log, notices) takes the full width below them. */\n.s9359c0_cardActions {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 10px;\n}\n\n.s9359c0_cardActions > .s549462_gate,\n.s9359c0_cardActions > .s20fbe0_installPanel,\n.s9359c0_cardActions > .s94517f_installedActions {\n flex-basis: 100%;\n}\n\n/* The entry's version, always visible on the card (the expanded detail\n * repeats it in the version row) — the same quiet mono as the toolbar. */\n.sc54e24_cardVersion {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The octocat marking a github-sourced entry, beside its short commit. */\n.s623bee_sourceBadge {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sf9a12c_tierBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 1.6;\n}\n\n.sf9a12c_tierBadge[data-tier='verified'] {\n color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent);\n}\n\n.sf9a12c_tierBadge[data-tier='verified-stale'] {\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.sf9a12c_tierBadge[data-tier='community'] {\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n border: 1px solid var(--dsw-alias-border-l2);\n}\n\n.s671f97_incompatibleBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.s963e5c_starsBadge {\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sbb5739_chevron, .s4e56e8_chevronOpen {\n color: var(--dsw-alias-label-secondary);\n transition: transform 120ms ease;\n}\n\n.s4e56e8_chevronOpen { transform: rotate(180deg); }\n\n@media (prefers-reduced-motion: reduce) {\n .sbb5739_chevron, .s4e56e8_chevronOpen { transition: none; }\n}\n\n.sf9a60a_body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 12px;\n}\n\n.sfd2791_summary {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.s69ed84_summaryZh {\n margin: -4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Expanded cards show the full summary: the clamp is lifted, never raised —\n * a higher number would still truncate the author's text, just later. */\n.s83c8c8_summaryExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.s20b5b9_summaryZhExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.s45793c_incompatibleDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s551fd2_capabilitiesBlock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sb1f0de_capabilitiesNote {\n margin: 0;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s9a5379_capabilities {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s9a5379_capabilities li {\n padding: 1px 6px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s9e0e76_detail {\n border-top: 1px solid var(--dsw-alias-border-l1);\n padding-top: 8px;\n}\n\n.s41121d_detailRows {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 0;\n}\n\n.s852a05_detailRow {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: 12px;\n}\n\n.s852a05_detailRow dt {\n color: var(--dsw-alias-label-secondary);\n}\n\n.s852a05_detailRow dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n overflow-wrap: anywhere;\n text-align: right;\n color: var(--dsw-alias-label-primary);\n}\n\n.s852a05_detailRow a {\n color: var(--dsw-alias-brand-primary);\n text-decoration: none;\n}\n\n.s852a05_detailRow a:hover {\n text-decoration: underline;\n}\n\n.s852a05_detailRow a:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The publishing account, beside the npm link. Secondary label colour and a\n * middot separator carry the distinction — never a background fill, which is\n * invisible in the light theme where every bg-layer token is the same white. */\n/* Who published the entry, at the right edge of the action row. `margin-left:\n * auto` is what pushes it there; the row is a wrapping flex, so an active\n * install flow (which claims the full width) drops this to the next line\n * rather than squeezing it. */\n.s367f3b_author {\n margin-left: auto;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n\n.s2f9e91_reviewedLine {\n margin: 8px 0 0;\n padding: 6px 8px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n font-size: 12px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n/* Install flow. */\n.s20fbe0_installPanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 2px;\n}\n\n.s89d599_installButton, .s7b4348_confirmButton, .s20b00b_cancelButton {\n align-self: flex-start;\n padding: 5px 14px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.s89d599_installButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.s89d599_installButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.s7b4348_confirmButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.s7b4348_confirmButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.s20b00b_cancelButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n}\n\n.s20b00b_cancelButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.s89d599_installButton:focus-visible, .s7b4348_confirmButton:focus-visible, .s20b00b_cancelButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The shelf card of a plugin that is installed and current carries this\n * non-interactive label instead of an install button. Border + text do the\n * work in the light theme, where every bg-layer token resolves to white. */\n.s1e55fb_installedLabel {\n align-self: flex-start;\n margin: 0;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n/* An installed card's controls: the installed label or the update button,\n * plus the uninstall button. The install panel's running/failed states are\n * column layouts and sit as one item of this row. */\n.s94517f_installedActions {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n/* Uninstall revokes privilege; the quiet outline keeps it from competing\n * with the primary action, and the error tint says \"removes\". */\n.s432016_uninstallButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 55%, transparent);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s432016_uninstallButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n.s432016_uninstallButton:focus-visible {\n outline: 2px solid var(--dsw-alias-state-error-primary);\n outline-offset: 1px;\n}\n\n/* The restart dsh button on a done install: quiet outline, same rank as\n * the other secondary actions. */\n.s5c0f5a_restartButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s5c0f5a_restartButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.s5c0f5a_restartButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s549462_gate {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n border: 1px solid var(--dsw-alias-state-warn-primary);\n border-radius: 8px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n.sed2c7d_gateTitle {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.sdce129_gateBody {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.sfae869_gateWarning {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.sae8426_gateActions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.s260a62_installing {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sba0b9c_log {\n max-height: 160px;\n overflow: auto;\n margin: 0;\n padding: 8px;\n border-radius: 6px;\n background: var(--dsw-alias-bg-base);\n border: 1px solid var(--dsw-alias-border-l1);\n list-style: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n line-height: 1.5;\n}\n\n.s5c7c9d_logLine {\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sebdc74_notice {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-state-success-primary);\n}\n\n.s2672db_failedHeading {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.s3a9748_failedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.sc1144d_rejectedCode {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.s2209a3_rejectedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n/* Installed section. */\n.sb4abbb_outdatedSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 6px;\n}\n\n.sbca39c_outdatedList {\n display: flex;\n flex-direction: column;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s1abd04_outdatedRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.s10dca9_outdatedInfo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.s10dca9_outdatedInfo strong {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n word-break: break-all;\n color: var(--dsw-alias-label-primary);\n}\n\n.sb04966_outdatedVersions {\n /* Two inline labels with nothing between them in the markup ran together as\n * `installed v1.0.0latest v2.0.0`: JSX drops the whitespace-only line, and\n * the per-label class the markup asked for was never defined (singular\n * against this rule's plural). The container owns the gap, the same idiom\n * as .s28e55e_badges — the labels need no class of their own. */\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.see54bf_outdatedActions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* The enable/disable switch. */\n.sa65b66_switch {\n position: relative;\n width: 32px;\n height: 18px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.s50b82f_switchOn {\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 55%, transparent);\n}\n\n.sbbb39a_switchKnob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n border-radius: 999px;\n background: var(--dsw-alias-label-primary);\n transition: transform 120ms ease, background 120ms ease;\n}\n\n.s50b82f_switchOn .sbbb39a_switchKnob {\n transform: translateX(14px);\n background: var(--dsw-alias-bg-base);\n}\n\n.sa65b66_switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sa65b66_switch, .sbbb39a_switchKnob { transition: none; }\n}\n\n/* The hot enable/disable switch on installed rows: the knob button plus the\n * §8 hot-apply / failure notices rendered beside it. */\n.s24b48c_switchWrap {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n";
|
|
5279
|
-
if (typeof document !== "undefined" && !document.querySelector("style[data-plugin-css=\"
|
|
5306
|
+
//#region \0dsh-plugin-shop-css:e3675a89
|
|
5307
|
+
const css = "/* Shop tab styles — a market shelf inside the settings surface. The visual\n * language is the dsh theme's alias tokens ONLY (the four tokens the previous\n * styles referenced that do not exist — bg-layer-3, interactive-bg-hover,\n * state-error, state-success — are corrected to bg-layer-2 and the\n * state-*-primary set). The signature is the category spine: one HUE per\n * category (seven fixed hues, not the brand token — the brand resolves to\n * near-black in the light theme, so seven brand opacities read as seven\n * shades of gray), with the category name as the cover label in the same hue. Class names are mapped to content-derived names at bundle time\n * (tsdown.s8583e3_client.s942a79_config.s5f67aa_ts) and stubbed in tests; only the keys are relied\n * on.\n *\n * One token rule the theme forces: the background LAYERS do not carry\n * contrast. In the light theme bg-base, bg-layer-1, bg-layer-2 and\n * bg-layer-3 all resolve to the same white; only the dark theme spreads them\n * (950/875/850/800). So a layer-2 fill on a layer-1 ground is invisible for\n * half of all users, and anything whose fill is its ONLY affordance — the\n * loading skeleton, the borderless capability chips — derives its fill from\n * label-primary instead, which inverts with the theme by construction.\n * Elements that also carry a border or text may keep a layer fill.\n * `css-tokens.s8583e3_client.sfd9d8a_spec.s5f67aa_ts` pins this. */\n\n.s255e5a_panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n /* The shelf never scrolls sideways: a card too wide for its track wraps\n * its badges rather than widening the panel.\n *\n * Clipped on BOTH axes, with a margin, because `.s232ec4_searchInput` sits at\n * exactly (0, 0) of this box — it is the first child of `.s646509_toolbar`, itself\n * the first child here, and this rule carries no padding — so its focus\n * ring paints ENTIRELY outside the panel.\n *\n * Both axes is the load-bearing part: `overflow-clip-margin` is inert\n * unless the element clips on both. Clipping x alone left the margin doing\n * nothing — measured against the live app on 0.7.1, the ring reached 0 of\n * its 3px on the left at every device pixel ratio (1, 1.25, 1.5, 2), while\n * keeping the full 3px on the right, where the 280px input stops short of\n * the panel and never meets the clip edge. Raising the margin to 6px\n * changed nothing; clipping both axes with the SAME 3px restored the whole\n * ring. A test that reads declarations cannot see that difference, which is\n * why the first attempt at this shipped broken.\n *\n * `clip` is not a scroll container, so this does not bring back the\n * accidental scrolling `hidden` caused by coercing the other axis to\n * `auto`. Nothing is lost vertically: the panel's scrollHeight equals its\n * height and no descendant paints outside the clip rect (measured).\n * `overflow-x: hidden` stays as the fallback for engines without `clip`,\n * where the ring is clipped as it was before, never worse. */\n overflow-x: hidden;\n overflow: clip;\n overflow-clip-margin: 3px;\n}\n\n.s44a3ec_stateLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* Visually hidden but screen-reader readable (the loading copy while the\n * skeleton stands in visually). */\n.s3a0ece_srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n}\n\n/* The loading shelf: ghost cards with the same geometry as the real grid, so\n * the swap to content is a same-shape handoff instead of a jump. */\n.se0c3b4_skeletonGrid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 8px;\n}\n\n.s520416_skeletonCard {\n position: relative;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n}\n\n/* The shimmer sweep: one gradient band travels across each ghost card while\n * the bars breathe, so the loading state reads as \"the shelf is scanning\". */\n.s520416_skeletonCard::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 100deg,\n transparent 25%,\n color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent) 50%,\n transparent 75%\n );\n transform: translateX(-100%);\n animation: dshShopSkeletonSweep 1.4s ease-in-out infinite;\n pointer-events: none;\n}\n\n@keyframes dshShopSkeletonSweep {\n to { transform: translateX(100%); }\n}\n\n.s8c7d6f_skeletonName {\n width: 55%;\n height: 14px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sf5179e_skeletonSummary {\n width: 92%;\n height: 12px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sbb0d25_skeletonSummaryShort {\n width: 68%;\n height: 12px;\n margin: 6px 12px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n/* The ghost of the action line, right where the real buttons land. */\n.s96e910_skeletonActions {\n display: block;\n width: 84px;\n height: 24px;\n margin: 0 12px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s520416_skeletonCard span {\n animation: dshShopSkeletonPulse 1.6s ease-in-out infinite;\n}\n\n@keyframes dshShopSkeletonPulse {\n 0%, 100% { opacity: 0.5; }\n 50% { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s520416_skeletonCard span { animation: none; opacity: 0.75; }\n .s520416_skeletonCard::after { content: none; }\n}\n\n.s73242a_actionButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s73242a_actionButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s73242a_actionButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s646509_toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.s745e3c_toolbarRight {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* The shop's own version, right of the search box: `v0.4.4`, plus the\n * update button when the version check found a newer release. */\n.s4fe61f_versionBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sb9b924_versionText {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa04455_updateSelfButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-brand-primary);\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.sa04455_updateSelfButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 20%, transparent);\n}\n\n.sa04455_updateSelfButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The on-demand re-check next to the version number: a quiet pill; the\n * border and text carry it in the light theme where bg layers are white. */\n.s614a38_checkUpdateButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s614a38_checkUpdateButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n color: var(--dsw-alias-label-primary);\n}\n\n.s614a38_checkUpdateButton:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n.s614a38_checkUpdateButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The project's GitHub mark, right of the version row: a quiet icon link.\n * The octocat carries itself — color shift on hover, no text, no border. */\n.sa987f7_githubLink {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 3px;\n border-radius: 6px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa987f7_githubLink:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sa987f7_githubLink:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The self-update's expanded states (running log / done + restart /\n * failure detail) sit under the toolbar, above the category bar. */\n.sb81ba5_selfUpdatePanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n\n.s232ec4_searchInput {\n width: min(280px, 100%);\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n.s232ec4_searchInput:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s3946f1_staleBadge {\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n color: var(--dsw-alias-state-warn-primary);\n font-size: 12px;\n}\n\n.sb2c859_categoryBar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.s26d58e_categoryButton {\n padding: 3px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s26d58e_categoryButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s5f68c4_categoryButtonOn {\n border-color: var(--dsw-alias-brand-primary);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-weight: 600;\n}\n\n.s26d58e_categoryButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s668774_catalogHeading {\n margin: 2px 0 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-primary);\n}\n\n.seb0a1e_catalogStatsRow {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 6px 0 0;\n}\n\n.sccc4d1_catalogStats {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* Sits beside the 12px stats caption, so it is quieter than `.s73242a_actionButton`:\n * this is an affordance, not a call to action — the catalog reloads on its\n * own at mount and the shelf is already usable without it. */\n.s64a5ff_reloadButton {\n padding: 1px 9px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n line-height: 17px;\n cursor: pointer;\n}\n\n.s64a5ff_reloadButton:hover:not(:disabled) {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s64a5ff_reloadButton:disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.s64a5ff_reloadButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s4453f3_reloadFailed {\n font-size: 11px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s6de1ab_emptyLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* The shelf: a responsive grid of cards. */\n/* Single-line rows: one full-width column, one plugin per line. */\n.sf657f5_cards {\n display: grid;\n grid-template-columns: 1fr;\n max-width: 100%;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n animation: dshShopCardsIn 220ms ease;\n}\n\n@keyframes dshShopCardsIn {\n from { opacity: 0; transform: translateY(3px); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sf657f5_cards { animation: none; }\n}\n\n.s65f383_card {\n position: relative;\n display: flex;\n flex-direction: column;\n /* A grid item's min-width is auto by default: its content would widen the\n * 1fr track past the panel and overflow horizontally. */\n min-width: 0;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;\n /* Off-screen cards skip layout and paint; the placeholder keeps scrollbar\n * estimation sane before the browser has measured the real height. */\n content-visibility: auto;\n contain-intrinsic-size: auto 140px;\n}\n\n/* The sentinel that triggers the next shelf batch: zero visual footprint. */\n.sd7ee01_cardsSentry {\n height: 1px;\n margin: 0;\n padding: 0;\n}\n\n.s705cc6_showingLine {\n margin: 0;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s65f383_card:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l1));\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s65f383_card { transition: none; }\n .s65f383_card:hover { transform: none; }\n}\n\n/* The signature: a spine and cover in the category's own hue. The hues are\n * fixed mid-bright colors that read on both themes; `other` deliberately\n * stays a neutral gray so the fallback category does not compete. */\n.s4ce25d_cardSpine {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 3px;\n background: var(--spine-hue, #8B8E96);\n}\n\n.s65f383_card[data-category='tool'] { --spine-hue: #4C8DFF; }\n.s65f383_card[data-category='provider'] { --spine-hue: #A78BFA; }\n.s65f383_card[data-category='ui'] { --spine-hue: #2DD4BF; }\n.s65f383_card[data-category='workflow'] { --spine-hue: #F59E0B; }\n.s65f383_card[data-category='integration'] { --spine-hue: #34D399; }\n.s65f383_card[data-category='theme'] { --spine-hue: #F472B6; }\n.s65f383_card[data-category='other'] { --spine-hue: #8B8E96; }\n\n/* The category sits in the badge row as a quiet chip in the category's own\n * hue — the border carries it where the light theme's white layers cannot\n * (the same lesson as the check button). */\n.s9c8eaa_categoryBadge {\n padding: 1px 7px;\n border: 1px solid color-mix(in srgb, var(--spine-hue, #8B8E96) 45%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--spine-hue, #8B8E96);\n white-space: nowrap;\n}\n\n.sa97234_entryHeader {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px 2px;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.sa97234_entryHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* The name fills the row and truncates rather than wraps; the badges stay\n * intact beside it. */\n.sc3f149_name {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n flex: 1 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--dsw-alias-label-primary);\n}\n\n.s513026_badges {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* The action line: buttons side by side; an active install/uninstall flow\n * (gate, log, notices) takes the full width below them. */\n.s9b5048_cardActions {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 10px;\n}\n\n.s9b5048_cardActions > .sc4f2ac_gate,\n.s9b5048_cardActions > .s4d374c_installPanel,\n.s9b5048_cardActions > .sf53ca0_installedActions {\n flex-basis: 100%;\n}\n\n/* The entry's version, always visible on the card (the expanded detail\n * repeats it in the version row) — the same quiet mono as the toolbar. */\n.sc6ec6e_cardVersion {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The octocat marking a github-sourced entry, beside its short commit. */\n.s71f10f_sourceBadge {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s5e82cb_tierBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 1.6;\n}\n\n.s5e82cb_tierBadge[data-tier='verified'] {\n color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='verified-stale'] {\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='community'] {\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n border: 1px solid var(--dsw-alias-border-l2);\n}\n\n.s4bbe02_incompatibleBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.sff43b4_starsBadge {\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s73f7fb_chevron, .s61393c_chevronOpen {\n color: var(--dsw-alias-label-secondary);\n transition: transform 120ms ease;\n}\n\n.s61393c_chevronOpen { transform: rotate(180deg); }\n\n@media (prefers-reduced-motion: reduce) {\n .s73f7fb_chevron, .s61393c_chevronOpen { transition: none; }\n}\n\n.s820ebf_body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 12px;\n}\n\n.sb8fbc8_summary {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.se507db_summaryZh {\n margin: -4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Expanded cards show the full summary: the clamp is lifted, never raised —\n * a higher number would still truncate the author's text, just later. */\n.s10baf0_summaryExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.sb9dba9_summaryZhExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.s6eca19_incompatibleDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s9d2029_capabilitiesBlock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.s3bdbd5_capabilitiesNote {\n margin: 0;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s441702_capabilities {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s441702_capabilities li {\n padding: 1px 6px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sde3f0c_detail {\n border-top: 1px solid var(--dsw-alias-border-l1);\n padding-top: 8px;\n}\n\n.se98179_detailRows {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 0;\n}\n\n.sfb4d2f_detailRow {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: 12px;\n}\n\n.sfb4d2f_detailRow dt {\n color: var(--dsw-alias-label-secondary);\n}\n\n.sfb4d2f_detailRow dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n overflow-wrap: anywhere;\n text-align: right;\n color: var(--dsw-alias-label-primary);\n}\n\n.sfb4d2f_detailRow a {\n color: var(--dsw-alias-brand-primary);\n text-decoration: none;\n}\n\n.sfb4d2f_detailRow a:hover {\n text-decoration: underline;\n}\n\n.sfb4d2f_detailRow a:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The publishing account, beside the npm link. Secondary label colour and a\n * middot separator carry the distinction — never a background fill, which is\n * invisible in the light theme where every bg-layer token is the same white. */\n/* Who published the entry, at the right edge of the action row. `margin-left:\n * auto` is what pushes it there; the row is a wrapping flex, so an active\n * install flow (which claims the full width) drops this to the next line\n * rather than squeezing it. */\n.s1ff66f_author {\n margin-left: auto;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n}\n\n.sd58c6d_reviewedLine {\n margin: 8px 0 0;\n padding: 6px 8px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n font-size: 12px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n/* Install flow. */\n.s4d374c_installPanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 2px;\n}\n\n.se7aaed_installButton, .sb43a49_confirmButton, .s6e45d1_cancelButton {\n align-self: flex-start;\n padding: 5px 14px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.se7aaed_installButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.se7aaed_installButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.sb43a49_confirmButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.sb43a49_confirmButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.s6e45d1_cancelButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n}\n\n.s6e45d1_cancelButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.se7aaed_installButton:focus-visible, .sb43a49_confirmButton:focus-visible, .s6e45d1_cancelButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The shelf card of a plugin that is installed and current carries this\n * non-interactive label instead of an install button. Border + text do the\n * work in the light theme, where every bg-layer token resolves to white. */\n.sb6fc74_installedLabel {\n align-self: flex-start;\n margin: 0;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n/* An installed card's controls: the installed label or the update button,\n * plus the uninstall button. The install panel's running/failed states are\n * column layouts and sit as one item of this row. */\n.sf53ca0_installedActions {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n/* Uninstall revokes privilege; the quiet outline keeps it from competing\n * with the primary action, and the error tint says \"removes\". */\n.s96967f_uninstallButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 55%, transparent);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s96967f_uninstallButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n.s96967f_uninstallButton:focus-visible {\n outline: 2px solid var(--dsw-alias-state-error-primary);\n outline-offset: 1px;\n}\n\n/* The restart dsh button on a done install: quiet outline, same rank as\n * the other secondary actions. */\n.s6ac237_restartButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s6ac237_restartButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.s6ac237_restartButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sc4f2ac_gate {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n border: 1px solid var(--dsw-alias-state-warn-primary);\n border-radius: 8px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n.s559c38_gateTitle {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s3c0ace_gateBody {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.sc323e5_gateWarning {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s4b2373_gateActions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.s52b5a5_installing {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s64ab71_log {\n max-height: 160px;\n overflow: auto;\n margin: 0;\n padding: 8px;\n border-radius: 6px;\n background: var(--dsw-alias-bg-base);\n border: 1px solid var(--dsw-alias-border-l1);\n list-style: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n line-height: 1.5;\n}\n\n.s1531a8_logLine {\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sf20dda_notice {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-state-success-primary);\n}\n\n.seb9b08_failedHeading {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.sfd3021_failedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.s50ba35_rejectedCode {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.se75489_rejectedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n/* Installed section. */\n.sa276cf_outdatedSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 6px;\n}\n\n.sceae6e_outdatedList {\n display: flex;\n flex-direction: column;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s8d2072_outdatedRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.s5c2545_outdatedInfo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.s5c2545_outdatedInfo strong {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n word-break: break-all;\n color: var(--dsw-alias-label-primary);\n}\n\n.s877c68_outdatedVersions {\n /* Two inline labels with nothing between them in the markup ran together as\n * `installed v1.0.0latest v2.0.0`: JSX drops the whitespace-only line, and\n * the per-label class the markup asked for was never defined (singular\n * against this rule's plural). The container owns the gap, the same idiom\n * as .s513026_badges — the labels need no class of their own. */\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa1f556_outdatedActions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* The enable/disable switch. */\n.s11c019_switch {\n position: relative;\n width: 32px;\n height: 18px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.s7580e8_switchOn {\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 55%, transparent);\n}\n\n.saab2b3_switchKnob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n border-radius: 999px;\n background: var(--dsw-alias-label-primary);\n transition: transform 120ms ease, background 120ms ease;\n}\n\n.s7580e8_switchOn .saab2b3_switchKnob {\n transform: translateX(14px);\n background: var(--dsw-alias-bg-base);\n}\n\n.s11c019_switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s11c019_switch, .saab2b3_switchKnob { transition: none; }\n}\n\n/* The hot enable/disable switch on installed rows: the knob button plus the\n * §8 hot-apply / failure notices rendered beside it. */\n.sd9f9e4_switchWrap {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n";
|
|
5308
|
+
if (typeof document !== "undefined" && !document.querySelector("style[data-plugin-css=\"e3675a89\"]")) {
|
|
5280
5309
|
const tag = document.createElement("style");
|
|
5281
|
-
tag.dataset.pluginCss = "
|
|
5310
|
+
tag.dataset.pluginCss = "e3675a89";
|
|
5282
5311
|
tag.textContent = css;
|
|
5283
5312
|
document.head.appendChild(tag);
|
|
5284
5313
|
}
|
|
5285
|
-
var
|
|
5286
|
-
"client": "
|
|
5287
|
-
"config": "
|
|
5288
|
-
"ts": "
|
|
5289
|
-
"spec": "
|
|
5290
|
-
"panel": "
|
|
5291
|
-
"searchInput": "
|
|
5292
|
-
"toolbar": "
|
|
5293
|
-
"stateLine": "
|
|
5294
|
-
"srOnly": "
|
|
5295
|
-
"skeletonGrid": "
|
|
5296
|
-
"skeletonCard": "
|
|
5297
|
-
"skeletonName": "
|
|
5298
|
-
"skeletonSummary": "
|
|
5299
|
-
"skeletonSummaryShort": "
|
|
5300
|
-
"skeletonActions": "
|
|
5301
|
-
"actionButton": "
|
|
5302
|
-
"toolbarRight": "
|
|
5303
|
-
"versionBlock": "
|
|
5304
|
-
"versionText": "
|
|
5305
|
-
"updateSelfButton": "
|
|
5306
|
-
"checkUpdateButton": "
|
|
5307
|
-
"githubLink": "
|
|
5308
|
-
"selfUpdatePanel": "
|
|
5309
|
-
"
|
|
5310
|
-
"
|
|
5311
|
-
"
|
|
5312
|
-
"
|
|
5313
|
-
"
|
|
5314
|
-
"
|
|
5315
|
-
"catalogStats": "
|
|
5316
|
-
"
|
|
5317
|
-
"
|
|
5318
|
-
"
|
|
5319
|
-
"
|
|
5320
|
-
"
|
|
5321
|
-
"
|
|
5322
|
-
"
|
|
5323
|
-
"
|
|
5324
|
-
"
|
|
5325
|
-
"
|
|
5326
|
-
"
|
|
5327
|
-
"
|
|
5328
|
-
"
|
|
5329
|
-
"
|
|
5330
|
-
"
|
|
5331
|
-
"
|
|
5332
|
-
"
|
|
5333
|
-
"
|
|
5334
|
-
"
|
|
5335
|
-
"
|
|
5336
|
-
"
|
|
5337
|
-
"
|
|
5338
|
-
"
|
|
5339
|
-
"
|
|
5340
|
-
"
|
|
5341
|
-
"
|
|
5342
|
-
"
|
|
5343
|
-
"
|
|
5344
|
-
"
|
|
5345
|
-
"
|
|
5346
|
-
"
|
|
5347
|
-
"
|
|
5348
|
-
"
|
|
5349
|
-
"
|
|
5350
|
-
"
|
|
5351
|
-
"
|
|
5352
|
-
"
|
|
5353
|
-
"
|
|
5354
|
-
"
|
|
5355
|
-
"
|
|
5356
|
-
"
|
|
5357
|
-
"
|
|
5358
|
-
"
|
|
5359
|
-
"
|
|
5360
|
-
"
|
|
5361
|
-
"
|
|
5362
|
-
"
|
|
5363
|
-
"
|
|
5364
|
-
"
|
|
5365
|
-
"
|
|
5366
|
-
"
|
|
5367
|
-
"
|
|
5368
|
-
"
|
|
5369
|
-
"
|
|
5370
|
-
"
|
|
5371
|
-
"
|
|
5372
|
-
"
|
|
5373
|
-
"
|
|
5374
|
-
"
|
|
5375
|
-
"
|
|
5376
|
-
"
|
|
5377
|
-
"
|
|
5378
|
-
"
|
|
5314
|
+
var _dsh_plugin_shop_css_e3675a89_default = {
|
|
5315
|
+
"client": "s8583e3_client",
|
|
5316
|
+
"config": "s942a79_config",
|
|
5317
|
+
"ts": "s5f67aa_ts",
|
|
5318
|
+
"spec": "sfd9d8a_spec",
|
|
5319
|
+
"panel": "s255e5a_panel",
|
|
5320
|
+
"searchInput": "s232ec4_searchInput",
|
|
5321
|
+
"toolbar": "s646509_toolbar",
|
|
5322
|
+
"stateLine": "s44a3ec_stateLine",
|
|
5323
|
+
"srOnly": "s3a0ece_srOnly",
|
|
5324
|
+
"skeletonGrid": "se0c3b4_skeletonGrid",
|
|
5325
|
+
"skeletonCard": "s520416_skeletonCard",
|
|
5326
|
+
"skeletonName": "s8c7d6f_skeletonName",
|
|
5327
|
+
"skeletonSummary": "sf5179e_skeletonSummary",
|
|
5328
|
+
"skeletonSummaryShort": "sbb0d25_skeletonSummaryShort",
|
|
5329
|
+
"skeletonActions": "s96e910_skeletonActions",
|
|
5330
|
+
"actionButton": "s73242a_actionButton",
|
|
5331
|
+
"toolbarRight": "s745e3c_toolbarRight",
|
|
5332
|
+
"versionBlock": "s4fe61f_versionBlock",
|
|
5333
|
+
"versionText": "sb9b924_versionText",
|
|
5334
|
+
"updateSelfButton": "sa04455_updateSelfButton",
|
|
5335
|
+
"checkUpdateButton": "s614a38_checkUpdateButton",
|
|
5336
|
+
"githubLink": "sa987f7_githubLink",
|
|
5337
|
+
"selfUpdatePanel": "sb81ba5_selfUpdatePanel",
|
|
5338
|
+
"staleBadge": "s3946f1_staleBadge",
|
|
5339
|
+
"categoryBar": "sb2c859_categoryBar",
|
|
5340
|
+
"categoryButton": "s26d58e_categoryButton",
|
|
5341
|
+
"categoryButtonOn": "s5f68c4_categoryButtonOn",
|
|
5342
|
+
"catalogHeading": "s668774_catalogHeading",
|
|
5343
|
+
"catalogStatsRow": "seb0a1e_catalogStatsRow",
|
|
5344
|
+
"catalogStats": "sccc4d1_catalogStats",
|
|
5345
|
+
"reloadButton": "s64a5ff_reloadButton",
|
|
5346
|
+
"reloadFailed": "s4453f3_reloadFailed",
|
|
5347
|
+
"emptyLine": "s6de1ab_emptyLine",
|
|
5348
|
+
"cards": "sf657f5_cards",
|
|
5349
|
+
"card": "s65f383_card",
|
|
5350
|
+
"cardsSentry": "sd7ee01_cardsSentry",
|
|
5351
|
+
"showingLine": "s705cc6_showingLine",
|
|
5352
|
+
"cardSpine": "s4ce25d_cardSpine",
|
|
5353
|
+
"categoryBadge": "s9c8eaa_categoryBadge",
|
|
5354
|
+
"entryHeader": "sa97234_entryHeader",
|
|
5355
|
+
"name": "sc3f149_name",
|
|
5356
|
+
"badges": "s513026_badges",
|
|
5357
|
+
"cardActions": "s9b5048_cardActions",
|
|
5358
|
+
"gate": "sc4f2ac_gate",
|
|
5359
|
+
"installPanel": "s4d374c_installPanel",
|
|
5360
|
+
"installedActions": "sf53ca0_installedActions",
|
|
5361
|
+
"cardVersion": "sc6ec6e_cardVersion",
|
|
5362
|
+
"sourceBadge": "s71f10f_sourceBadge",
|
|
5363
|
+
"tierBadge": "s5e82cb_tierBadge",
|
|
5364
|
+
"incompatibleBadge": "s4bbe02_incompatibleBadge",
|
|
5365
|
+
"starsBadge": "sff43b4_starsBadge",
|
|
5366
|
+
"chevron": "s73f7fb_chevron",
|
|
5367
|
+
"chevronOpen": "s61393c_chevronOpen",
|
|
5368
|
+
"body": "s820ebf_body",
|
|
5369
|
+
"summary": "sb8fbc8_summary",
|
|
5370
|
+
"summaryZh": "se507db_summaryZh",
|
|
5371
|
+
"summaryExpanded": "s10baf0_summaryExpanded",
|
|
5372
|
+
"summaryZhExpanded": "sb9dba9_summaryZhExpanded",
|
|
5373
|
+
"incompatibleDetail": "s6eca19_incompatibleDetail",
|
|
5374
|
+
"capabilitiesBlock": "s9d2029_capabilitiesBlock",
|
|
5375
|
+
"capabilitiesNote": "s3bdbd5_capabilitiesNote",
|
|
5376
|
+
"capabilities": "s441702_capabilities",
|
|
5377
|
+
"detail": "sde3f0c_detail",
|
|
5378
|
+
"detailRows": "se98179_detailRows",
|
|
5379
|
+
"detailRow": "sfb4d2f_detailRow",
|
|
5380
|
+
"author": "s1ff66f_author",
|
|
5381
|
+
"reviewedLine": "sd58c6d_reviewedLine",
|
|
5382
|
+
"installButton": "se7aaed_installButton",
|
|
5383
|
+
"confirmButton": "sb43a49_confirmButton",
|
|
5384
|
+
"cancelButton": "s6e45d1_cancelButton",
|
|
5385
|
+
"installedLabel": "sb6fc74_installedLabel",
|
|
5386
|
+
"uninstallButton": "s96967f_uninstallButton",
|
|
5387
|
+
"restartButton": "s6ac237_restartButton",
|
|
5388
|
+
"gateTitle": "s559c38_gateTitle",
|
|
5389
|
+
"gateBody": "s3c0ace_gateBody",
|
|
5390
|
+
"gateWarning": "sc323e5_gateWarning",
|
|
5391
|
+
"gateActions": "s4b2373_gateActions",
|
|
5392
|
+
"installing": "s52b5a5_installing",
|
|
5393
|
+
"log": "s64ab71_log",
|
|
5394
|
+
"logLine": "s1531a8_logLine",
|
|
5395
|
+
"notice": "sf20dda_notice",
|
|
5396
|
+
"failedHeading": "seb9b08_failedHeading",
|
|
5397
|
+
"failedDetail": "sfd3021_failedDetail",
|
|
5398
|
+
"rejectedCode": "s50ba35_rejectedCode",
|
|
5399
|
+
"rejectedDetail": "se75489_rejectedDetail",
|
|
5400
|
+
"outdatedSection": "sa276cf_outdatedSection",
|
|
5401
|
+
"outdatedList": "sceae6e_outdatedList",
|
|
5402
|
+
"outdatedRow": "s8d2072_outdatedRow",
|
|
5403
|
+
"outdatedInfo": "s5c2545_outdatedInfo",
|
|
5404
|
+
"outdatedVersions": "s877c68_outdatedVersions",
|
|
5405
|
+
"outdatedActions": "sa1f556_outdatedActions",
|
|
5406
|
+
"switch": "s11c019_switch",
|
|
5407
|
+
"switchOn": "s7580e8_switchOn",
|
|
5408
|
+
"switchKnob": "saab2b3_switchKnob",
|
|
5409
|
+
"switchWrap": "sd9f9e4_switchWrap"
|
|
5379
5410
|
};
|
|
5380
5411
|
//#endregion
|
|
5381
5412
|
//#region src/client/ShopTab.tsx
|
|
@@ -5392,7 +5423,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5392
5423
|
width: "14",
|
|
5393
5424
|
height: "14",
|
|
5394
5425
|
"aria-hidden": "true",
|
|
5395
|
-
className: open ?
|
|
5426
|
+
className: open ? _dsh_plugin_shop_css_e3675a89_default.chevronOpen : _dsh_plugin_shop_css_e3675a89_default.chevron,
|
|
5396
5427
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
5397
5428
|
fill: "currentColor",
|
|
5398
5429
|
d: "M3.5 6 8 10.5 12.5 6l1 1L8 12.5 2.5 7l1-1Z"
|
|
@@ -5413,32 +5444,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5413
5444
|
const author = authorOf(entry);
|
|
5414
5445
|
const category = entry.catalog?.category ?? "other";
|
|
5415
5446
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5416
|
-
className:
|
|
5447
|
+
className: _dsh_plugin_shop_css_e3675a89_default.card,
|
|
5417
5448
|
"data-shop-entry": entry.name,
|
|
5418
5449
|
"data-category": category,
|
|
5419
5450
|
children: [
|
|
5420
5451
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5421
|
-
className:
|
|
5452
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cardSpine,
|
|
5422
5453
|
"aria-hidden": "true"
|
|
5423
5454
|
}),
|
|
5424
5455
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
5425
5456
|
type: "button",
|
|
5426
|
-
className:
|
|
5457
|
+
className: _dsh_plugin_shop_css_e3675a89_default.entryHeader,
|
|
5427
5458
|
"aria-expanded": open,
|
|
5428
5459
|
"aria-controls": detailId,
|
|
5429
5460
|
onClick: () => setOpen((current) => !current),
|
|
5430
5461
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5431
|
-
className:
|
|
5462
|
+
className: _dsh_plugin_shop_css_e3675a89_default.name,
|
|
5432
5463
|
children: entry.name
|
|
5433
5464
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5434
|
-
className:
|
|
5465
|
+
className: _dsh_plugin_shop_css_e3675a89_default.badges,
|
|
5435
5466
|
children: [
|
|
5436
5467
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5437
|
-
className:
|
|
5468
|
+
className: _dsh_plugin_shop_css_e3675a89_default.categoryBadge,
|
|
5438
5469
|
children: t(categoryKey(entry))
|
|
5439
5470
|
}),
|
|
5440
5471
|
entry.source === "npm" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5441
|
-
className:
|
|
5472
|
+
className: _dsh_plugin_shop_css_e3675a89_default.sourceBadge,
|
|
5442
5473
|
"data-shop-source-npm": true,
|
|
5443
5474
|
role: "img",
|
|
5444
5475
|
"aria-label": t("npmSource"),
|
|
@@ -5455,7 +5486,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5455
5486
|
})
|
|
5456
5487
|
}),
|
|
5457
5488
|
hasGithubHome(entry) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5458
|
-
className:
|
|
5489
|
+
className: _dsh_plugin_shop_css_e3675a89_default.sourceBadge,
|
|
5459
5490
|
"data-shop-source-github": true,
|
|
5460
5491
|
role: "img",
|
|
5461
5492
|
"aria-label": t("githubSource"),
|
|
@@ -5469,23 +5500,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5469
5500
|
})
|
|
5470
5501
|
}),
|
|
5471
5502
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5472
|
-
className:
|
|
5503
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cardVersion,
|
|
5473
5504
|
"data-card-version": true,
|
|
5474
5505
|
children: ["v", displayVersion(entry)]
|
|
5475
5506
|
}),
|
|
5476
5507
|
entry.tier !== "community" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5477
|
-
className:
|
|
5508
|
+
className: _dsh_plugin_shop_css_e3675a89_default.tierBadge,
|
|
5478
5509
|
"data-tier": entry.tier,
|
|
5479
5510
|
children: t(tierKey(entry.tier))
|
|
5480
5511
|
}),
|
|
5481
5512
|
missing.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5482
|
-
className:
|
|
5513
|
+
className: _dsh_plugin_shop_css_e3675a89_default.incompatibleBadge,
|
|
5483
5514
|
"data-shop-incompatible": true,
|
|
5484
5515
|
title: t("incompatibleDetail", { modules: missing.join(", ") }),
|
|
5485
5516
|
children: t("incompatibleBadge")
|
|
5486
5517
|
}),
|
|
5487
5518
|
stars !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5488
|
-
className:
|
|
5519
|
+
className: _dsh_plugin_shop_css_e3675a89_default.starsBadge,
|
|
5489
5520
|
role: "img",
|
|
5490
5521
|
"aria-label": t("stars", { count: stars }),
|
|
5491
5522
|
children: ["★ ", formatStars(stars)]
|
|
@@ -5495,38 +5526,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5495
5526
|
})]
|
|
5496
5527
|
}),
|
|
5497
5528
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5498
|
-
className:
|
|
5529
|
+
className: _dsh_plugin_shop_css_e3675a89_default.body,
|
|
5499
5530
|
children: [
|
|
5500
5531
|
summary !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5501
|
-
className: open ? `${
|
|
5532
|
+
className: open ? `${_dsh_plugin_shop_css_e3675a89_default.summary} ${_dsh_plugin_shop_css_e3675a89_default.summaryExpanded}` : _dsh_plugin_shop_css_e3675a89_default.summary,
|
|
5502
5533
|
children: summary.en
|
|
5503
5534
|
}),
|
|
5504
5535
|
summary?.zh !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5505
|
-
className: open ? `${
|
|
5536
|
+
className: open ? `${_dsh_plugin_shop_css_e3675a89_default.summaryZh} ${_dsh_plugin_shop_css_e3675a89_default.summaryZhExpanded}` : _dsh_plugin_shop_css_e3675a89_default.summaryZh,
|
|
5506
5537
|
children: summary.zh
|
|
5507
5538
|
}),
|
|
5508
5539
|
missing.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5509
|
-
className:
|
|
5540
|
+
className: _dsh_plugin_shop_css_e3675a89_default.incompatibleDetail,
|
|
5510
5541
|
children: t("incompatibleDetail", { modules: missing.join(", ") })
|
|
5511
5542
|
}),
|
|
5512
5543
|
open && entry.catalog !== void 0 && entry.catalog.capabilities.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5513
|
-
className:
|
|
5544
|
+
className: _dsh_plugin_shop_css_e3675a89_default.capabilitiesBlock,
|
|
5514
5545
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5515
|
-
className:
|
|
5546
|
+
className: _dsh_plugin_shop_css_e3675a89_default.capabilitiesNote,
|
|
5516
5547
|
children: t("capabilitiesNote")
|
|
5517
5548
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
5518
|
-
className:
|
|
5549
|
+
className: _dsh_plugin_shop_css_e3675a89_default.capabilities,
|
|
5519
5550
|
children: entry.catalog.capabilities.map((capability) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: capability }, capability))
|
|
5520
5551
|
})]
|
|
5521
5552
|
}),
|
|
5522
5553
|
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
5523
5554
|
id: detailId,
|
|
5524
|
-
className:
|
|
5555
|
+
className: _dsh_plugin_shop_css_e3675a89_default.detail,
|
|
5525
5556
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
5526
|
-
className:
|
|
5557
|
+
className: _dsh_plugin_shop_css_e3675a89_default.detailRows,
|
|
5527
5558
|
children: [
|
|
5528
5559
|
npmUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5529
|
-
className:
|
|
5560
|
+
className: _dsh_plugin_shop_css_e3675a89_default.detailRow,
|
|
5530
5561
|
"data-shop-npm": true,
|
|
5531
5562
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("npmPage") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
5532
5563
|
href: npmUrl,
|
|
@@ -5536,7 +5567,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5536
5567
|
}) })]
|
|
5537
5568
|
}),
|
|
5538
5569
|
entry.repository !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5539
|
-
className:
|
|
5570
|
+
className: _dsh_plugin_shop_css_e3675a89_default.detailRow,
|
|
5540
5571
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("repository") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /^https?:\/\//.test(entry.repository) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
5541
5572
|
href: entry.repository,
|
|
5542
5573
|
target: "_blank",
|
|
@@ -5545,12 +5576,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5545
5576
|
}) : entry.repository })]
|
|
5546
5577
|
}),
|
|
5547
5578
|
entry.license !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5548
|
-
className:
|
|
5579
|
+
className: _dsh_plugin_shop_css_e3675a89_default.detailRow,
|
|
5549
5580
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("license") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: isCustomLicense(entry.license) ? t("customLicense") : entry.license })]
|
|
5550
5581
|
})
|
|
5551
5582
|
]
|
|
5552
5583
|
}), entry.tier === "verified-stale" && entry.review !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5553
|
-
className:
|
|
5584
|
+
className: _dsh_plugin_shop_css_e3675a89_default.reviewedLine,
|
|
5554
5585
|
children: entry.review.reviewedVersion !== void 0 ? t("reviewedVersionLine", {
|
|
5555
5586
|
reviewed: entry.review.reviewedVersion,
|
|
5556
5587
|
current: entry.version
|
|
@@ -5563,7 +5594,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5563
5594
|
]
|
|
5564
5595
|
}),
|
|
5565
5596
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5566
|
-
className:
|
|
5597
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cardActions,
|
|
5567
5598
|
"data-shop-actions": true,
|
|
5568
5599
|
children: [installed === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallPanel, {
|
|
5569
5600
|
name: entry.name,
|
|
@@ -5588,7 +5619,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5588
5619
|
restart,
|
|
5589
5620
|
restartSupported
|
|
5590
5621
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5591
|
-
className:
|
|
5622
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installedLabel,
|
|
5592
5623
|
"data-shop-installed": true,
|
|
5593
5624
|
children: t("installed")
|
|
5594
5625
|
}),
|
|
@@ -5606,7 +5637,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5606
5637
|
restartSupported
|
|
5607
5638
|
})
|
|
5608
5639
|
] }), author !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5609
|
-
className:
|
|
5640
|
+
className: _dsh_plugin_shop_css_e3675a89_default.author,
|
|
5610
5641
|
"data-shop-author": true,
|
|
5611
5642
|
children: t("authorLine", { author })
|
|
5612
5643
|
})]
|
|
@@ -5623,23 +5654,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5623
5654
|
const [gateOpen, setGateOpen] = (0, react.useState)(false);
|
|
5624
5655
|
const { view, start } = useInstall(install, installStatus);
|
|
5625
5656
|
if (view.kind === "running") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5626
|
-
className:
|
|
5657
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installPanel,
|
|
5627
5658
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5628
|
-
className:
|
|
5659
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installing,
|
|
5629
5660
|
children: t("installing")
|
|
5630
5661
|
}), view.log.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5631
|
-
className:
|
|
5662
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
5632
5663
|
children: view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5633
|
-
className:
|
|
5664
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
5634
5665
|
children: line
|
|
5635
5666
|
}, index))
|
|
5636
5667
|
})]
|
|
5637
5668
|
});
|
|
5638
5669
|
if (view.kind === "done") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5639
|
-
className:
|
|
5670
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installedActions,
|
|
5640
5671
|
children: [
|
|
5641
5672
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5642
|
-
className:
|
|
5673
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5643
5674
|
"data-shop-restart-notice": true,
|
|
5644
5675
|
children: view.needsRestart ? t(restartReasonKey(view.restartReason)) : t("installedNoRestartNotice")
|
|
5645
5676
|
}),
|
|
@@ -5648,63 +5679,63 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5648
5679
|
restart
|
|
5649
5680
|
}),
|
|
5650
5681
|
view.needsRestart && !restartSupported && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5651
|
-
className:
|
|
5682
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5652
5683
|
"data-shop-restart-disabled": true,
|
|
5653
5684
|
children: t("restartDisabledNotice")
|
|
5654
5685
|
})
|
|
5655
5686
|
]
|
|
5656
5687
|
});
|
|
5657
5688
|
if (view.kind === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5658
|
-
className:
|
|
5689
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installPanel,
|
|
5659
5690
|
children: [
|
|
5660
5691
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5661
|
-
className:
|
|
5692
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedHeading,
|
|
5662
5693
|
children: t("installFailed")
|
|
5663
5694
|
}),
|
|
5664
5695
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5665
|
-
className:
|
|
5696
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
5666
5697
|
children: view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5667
|
-
className:
|
|
5698
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
5668
5699
|
children: line
|
|
5669
5700
|
}, index))
|
|
5670
5701
|
}),
|
|
5671
5702
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5672
|
-
className:
|
|
5703
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedDetail,
|
|
5673
5704
|
children: view.detail === "" ? t("installTransportFailed") : view.detail
|
|
5674
5705
|
})
|
|
5675
5706
|
]
|
|
5676
5707
|
});
|
|
5677
5708
|
if (view.kind === "rejected") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5678
|
-
className:
|
|
5709
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installPanel,
|
|
5679
5710
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5680
|
-
className:
|
|
5711
|
+
className: _dsh_plugin_shop_css_e3675a89_default.rejectedCode,
|
|
5681
5712
|
children: t(rejectionCodeKey(view.code))
|
|
5682
5713
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5683
|
-
className:
|
|
5714
|
+
className: _dsh_plugin_shop_css_e3675a89_default.rejectedDetail,
|
|
5684
5715
|
children: view.detail
|
|
5685
5716
|
})]
|
|
5686
5717
|
});
|
|
5687
5718
|
if (gateOpen) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5688
|
-
className:
|
|
5719
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gate,
|
|
5689
5720
|
children: [
|
|
5690
5721
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5691
|
-
className:
|
|
5722
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateTitle,
|
|
5692
5723
|
children: t("acknowledgementTitle")
|
|
5693
5724
|
}),
|
|
5694
5725
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5695
|
-
className:
|
|
5726
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateBody,
|
|
5696
5727
|
children: t("acknowledgementBody")
|
|
5697
5728
|
}),
|
|
5698
5729
|
missing.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5699
|
-
className:
|
|
5730
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateWarning,
|
|
5700
5731
|
"data-shop-incompatible-warning": true,
|
|
5701
5732
|
children: t("incompatibleInstallWarning", { modules: missing.join(", ") })
|
|
5702
5733
|
}),
|
|
5703
5734
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5704
|
-
className:
|
|
5735
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateActions,
|
|
5705
5736
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5706
5737
|
type: "button",
|
|
5707
|
-
className:
|
|
5738
|
+
className: _dsh_plugin_shop_css_e3675a89_default.confirmButton,
|
|
5708
5739
|
"data-shop-confirm": true,
|
|
5709
5740
|
onClick: () => {
|
|
5710
5741
|
setGateOpen(false);
|
|
@@ -5717,7 +5748,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5717
5748
|
children: t("confirm")
|
|
5718
5749
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5719
5750
|
type: "button",
|
|
5720
|
-
className:
|
|
5751
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cancelButton,
|
|
5721
5752
|
onClick: () => setGateOpen(false),
|
|
5722
5753
|
children: t("cancel")
|
|
5723
5754
|
})]
|
|
@@ -5727,7 +5758,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5727
5758
|
const update = variant === "update";
|
|
5728
5759
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5729
5760
|
type: "button",
|
|
5730
|
-
className:
|
|
5761
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installButton,
|
|
5731
5762
|
...update ? { "data-shop-update": true } : { "data-shop-install": true },
|
|
5732
5763
|
onClick: () => {
|
|
5733
5764
|
if (tier === "verified") start({
|
|
@@ -5749,23 +5780,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5749
5780
|
function UninstallPanel({ name, t, uninstall, installStatus, restart, restartSupported }) {
|
|
5750
5781
|
const { view, start } = useUninstall(uninstall, installStatus);
|
|
5751
5782
|
if (view.kind === "running") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5752
|
-
className:
|
|
5783
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installPanel,
|
|
5753
5784
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5754
|
-
className:
|
|
5785
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installing,
|
|
5755
5786
|
children: t("uninstalling")
|
|
5756
5787
|
}), view.log.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5757
|
-
className:
|
|
5788
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
5758
5789
|
children: view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5759
|
-
className:
|
|
5790
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
5760
5791
|
children: line
|
|
5761
5792
|
}, index))
|
|
5762
5793
|
})]
|
|
5763
5794
|
});
|
|
5764
5795
|
if (view.kind === "done") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5765
|
-
className:
|
|
5796
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installedActions,
|
|
5766
5797
|
children: [
|
|
5767
5798
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5768
|
-
className:
|
|
5799
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5769
5800
|
"data-shop-uninstall-done": true,
|
|
5770
5801
|
children: view.needsRestart ? t("uninstalledRestartNotice") : t("uninstalledLiveNotice")
|
|
5771
5802
|
}),
|
|
@@ -5774,28 +5805,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5774
5805
|
restart
|
|
5775
5806
|
}),
|
|
5776
5807
|
view.needsRestart && !restartSupported && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5777
|
-
className:
|
|
5808
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5778
5809
|
"data-shop-restart-disabled": true,
|
|
5779
5810
|
children: t("restartDisabledNotice")
|
|
5780
5811
|
})
|
|
5781
5812
|
]
|
|
5782
5813
|
});
|
|
5783
5814
|
if (view.kind === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5784
|
-
className:
|
|
5815
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installPanel,
|
|
5785
5816
|
children: [
|
|
5786
5817
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5787
|
-
className:
|
|
5818
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedHeading,
|
|
5788
5819
|
children: t("uninstallFailed")
|
|
5789
5820
|
}),
|
|
5790
5821
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5791
|
-
className:
|
|
5822
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
5792
5823
|
children: view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5793
|
-
className:
|
|
5824
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
5794
5825
|
children: line
|
|
5795
5826
|
}, index))
|
|
5796
5827
|
}),
|
|
5797
5828
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5798
|
-
className:
|
|
5829
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedDetail,
|
|
5799
5830
|
children: view.detail === "" ? t("uninstallTransportFailed") : view.detail
|
|
5800
5831
|
})
|
|
5801
5832
|
]
|
|
@@ -5803,7 +5834,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5803
5834
|
if (view.kind !== "idle") return null;
|
|
5804
5835
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5805
5836
|
type: "button",
|
|
5806
|
-
className:
|
|
5837
|
+
className: _dsh_plugin_shop_css_e3675a89_default.uninstallButton,
|
|
5807
5838
|
"data-shop-uninstall": true,
|
|
5808
5839
|
onClick: () => void start({ name }),
|
|
5809
5840
|
children: t("uninstall")
|
|
@@ -5860,37 +5891,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5860
5891
|
return () => clearInterval(timer);
|
|
5861
5892
|
}, [state, t]);
|
|
5862
5893
|
if (state.kind === "restarting") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5863
|
-
className:
|
|
5894
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5864
5895
|
"data-shop-restarting": true,
|
|
5865
5896
|
children: t("restarting")
|
|
5866
5897
|
});
|
|
5867
5898
|
if (state.kind === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5868
|
-
className:
|
|
5899
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedDetail,
|
|
5869
5900
|
"data-shop-restart-error": true,
|
|
5870
5901
|
children: state.detail
|
|
5871
5902
|
});
|
|
5872
5903
|
if (gateOpen) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5873
|
-
className:
|
|
5904
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gate,
|
|
5874
5905
|
children: [
|
|
5875
5906
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5876
|
-
className:
|
|
5907
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateTitle,
|
|
5877
5908
|
children: t("restartTitle")
|
|
5878
5909
|
}),
|
|
5879
5910
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5880
|
-
className:
|
|
5911
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateBody,
|
|
5881
5912
|
children: t("restartBody")
|
|
5882
5913
|
}),
|
|
5883
5914
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5884
|
-
className:
|
|
5915
|
+
className: _dsh_plugin_shop_css_e3675a89_default.gateActions,
|
|
5885
5916
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5886
5917
|
type: "button",
|
|
5887
|
-
className:
|
|
5918
|
+
className: _dsh_plugin_shop_css_e3675a89_default.confirmButton,
|
|
5888
5919
|
"data-shop-restart-confirm": true,
|
|
5889
5920
|
onClick: () => void onConfirm(),
|
|
5890
5921
|
children: t("restartConfirm")
|
|
5891
5922
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5892
5923
|
type: "button",
|
|
5893
|
-
className:
|
|
5924
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cancelButton,
|
|
5894
5925
|
onClick: () => setGateOpen(false),
|
|
5895
5926
|
children: t("cancel")
|
|
5896
5927
|
})]
|
|
@@ -5899,7 +5930,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5899
5930
|
});
|
|
5900
5931
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5901
5932
|
type: "button",
|
|
5902
|
-
className:
|
|
5933
|
+
className: _dsh_plugin_shop_css_e3675a89_default.restartButton,
|
|
5903
5934
|
"data-shop-restart": true,
|
|
5904
5935
|
onClick: () => setGateOpen(true),
|
|
5905
5936
|
children: t("restart")
|
|
@@ -5939,7 +5970,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5939
5970
|
}
|
|
5940
5971
|
};
|
|
5941
5972
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5942
|
-
className:
|
|
5973
|
+
className: _dsh_plugin_shop_css_e3675a89_default.switchWrap,
|
|
5943
5974
|
"data-shop-enabled-switch": row.name,
|
|
5944
5975
|
children: [
|
|
5945
5976
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -5948,18 +5979,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5948
5979
|
"aria-checked": enabled,
|
|
5949
5980
|
"aria-label": t("enabledSwitch"),
|
|
5950
5981
|
"data-shop-toggle": true,
|
|
5951
|
-
className: `${
|
|
5982
|
+
className: `${_dsh_plugin_shop_css_e3675a89_default.switch} ${enabled ? _dsh_plugin_shop_css_e3675a89_default.switchOn : ""}`,
|
|
5952
5983
|
onClick: () => void onToggle(),
|
|
5953
5984
|
disabled: toggle.kind === "saving",
|
|
5954
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className:
|
|
5985
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.switchKnob })
|
|
5955
5986
|
}),
|
|
5956
5987
|
toggle.kind === "saved" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5957
|
-
className:
|
|
5988
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
5958
5989
|
"data-shop-hot-apply": true,
|
|
5959
5990
|
children: t("hotApplyNote")
|
|
5960
5991
|
}),
|
|
5961
5992
|
toggle.kind === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5962
|
-
className:
|
|
5993
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedDetail,
|
|
5963
5994
|
"data-shop-toggle-error": true,
|
|
5964
5995
|
children: toggle.detail
|
|
5965
5996
|
})
|
|
@@ -5971,27 +6002,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5971
6002
|
* install flow for `name@latest`, reusing `InstallPanel`). */
|
|
5972
6003
|
function OutdatedRow({ row, tier, source, missing, t, setEnabled, install, installStatus, restart, restartSupported }) {
|
|
5973
6004
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5974
|
-
className:
|
|
6005
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedRow,
|
|
5975
6006
|
"data-shop-outdated-entry": row.name,
|
|
5976
6007
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5977
|
-
className:
|
|
6008
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedInfo,
|
|
5978
6009
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5979
|
-
className:
|
|
6010
|
+
className: _dsh_plugin_shop_css_e3675a89_default.badges,
|
|
5980
6011
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5981
|
-
className:
|
|
6012
|
+
className: _dsh_plugin_shop_css_e3675a89_default.name,
|
|
5982
6013
|
children: row.name
|
|
5983
6014
|
}), missing.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5984
|
-
className:
|
|
6015
|
+
className: _dsh_plugin_shop_css_e3675a89_default.incompatibleBadge,
|
|
5985
6016
|
"data-shop-incompatible": true,
|
|
5986
6017
|
title: t("incompatibleUpdateDetail", { modules: missing.join(", ") }),
|
|
5987
6018
|
children: t("incompatibleBadge")
|
|
5988
6019
|
})]
|
|
5989
6020
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5990
|
-
className:
|
|
6021
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersions,
|
|
5991
6022
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("installedVersion", { version: source === "github" ? row.installed.slice(0, 7) : row.installed }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("latestVersion", { version: row.latest }) })]
|
|
5992
6023
|
})]
|
|
5993
6024
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5994
|
-
className:
|
|
6025
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedActions,
|
|
5995
6026
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnabledSwitch, {
|
|
5996
6027
|
row,
|
|
5997
6028
|
t,
|
|
@@ -6021,20 +6052,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6021
6052
|
function OutdatedSection({ state, tiers, sources, missingByName, t, setEnabled, install, installStatus, restart, restartSupported }) {
|
|
6022
6053
|
if (state.kind === "loading") return null;
|
|
6023
6054
|
if (state.kind === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6024
|
-
className:
|
|
6055
|
+
className: _dsh_plugin_shop_css_e3675a89_default.stateLine,
|
|
6025
6056
|
"data-shop-outdated-error": true,
|
|
6026
6057
|
children: t("error")
|
|
6027
6058
|
});
|
|
6028
6059
|
const outdated = state.entries.filter((entry) => entry.outdated);
|
|
6029
6060
|
if (outdated.length === 0) return null;
|
|
6030
6061
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6031
|
-
className:
|
|
6062
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedSection,
|
|
6032
6063
|
"data-shop-outdated": true,
|
|
6033
6064
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
6034
|
-
className:
|
|
6065
|
+
className: _dsh_plugin_shop_css_e3675a89_default.catalogHeading,
|
|
6035
6066
|
children: t("installedSection")
|
|
6036
6067
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
6037
|
-
className:
|
|
6068
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedList,
|
|
6038
6069
|
children: outdated.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OutdatedRow, {
|
|
6039
6070
|
row,
|
|
6040
6071
|
tier: tiers.get(row.name) ?? "community",
|
|
@@ -6060,6 +6091,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6060
6091
|
const restartSupported = selfVersion?.restartSupported ?? true;
|
|
6061
6092
|
const selfUpdate = useUpdateSelf(updateStart, installStatus);
|
|
6062
6093
|
const [request, setRequest] = (0, react.useState)({ kind: "initial" });
|
|
6094
|
+
const [reloading, setReloading] = (0, react.useState)(false);
|
|
6095
|
+
const [reloadFailed, setReloadFailed] = (0, react.useState)(false);
|
|
6063
6096
|
const [query, setQuery] = (0, react.useState)("");
|
|
6064
6097
|
const [category, setCategory] = (0, react.useState)(null);
|
|
6065
6098
|
const incremental = typeof IntersectionObserver !== "undefined";
|
|
@@ -6077,7 +6110,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6077
6110
|
result
|
|
6078
6111
|
});
|
|
6079
6112
|
} catch {
|
|
6080
|
-
if (
|
|
6113
|
+
if (cancelled) return;
|
|
6114
|
+
setCatalogState((current) => current.kind === "ready" ? current : { kind: "error" });
|
|
6115
|
+
setReloadFailed(true);
|
|
6116
|
+
} finally {
|
|
6117
|
+
if (!cancelled) setReloading(false);
|
|
6081
6118
|
}
|
|
6082
6119
|
};
|
|
6083
6120
|
load();
|
|
@@ -6140,11 +6177,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6140
6177
|
if (installedState.kind === "ready") for (const entry of installedState.entries) map.set(entry.name, entry);
|
|
6141
6178
|
return map;
|
|
6142
6179
|
}, [installedState]);
|
|
6143
|
-
const
|
|
6180
|
+
const browsable = (0, react.useMemo)(() => {
|
|
6144
6181
|
if (catalogState.kind !== "ready") return [];
|
|
6182
|
+
const cleared = new Set(catalogState.result.notAShop ?? []);
|
|
6183
|
+
return catalogState.result.plugins.filter((entry) => cleared.has(entry.name) || !isShopLike(entry.name) && (entry.repo === void 0 || !isShopLike(entry.repo)));
|
|
6184
|
+
}, [catalogState]);
|
|
6185
|
+
const filtered = (0, react.useMemo)(() => {
|
|
6145
6186
|
const q = query.trim().toLowerCase();
|
|
6146
|
-
return
|
|
6147
|
-
if (isShopLike(entry.name) || entry.repo !== void 0 && isShopLike(entry.repo)) return false;
|
|
6187
|
+
return browsable.filter((entry) => {
|
|
6148
6188
|
if (category === "installed") {
|
|
6149
6189
|
if (!installedByName.has(entry.name)) return false;
|
|
6150
6190
|
} else if (category !== null && categoryKey(entry) !== categoryLocaleKey(category)) return false;
|
|
@@ -6154,7 +6194,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6154
6194
|
return entry.name.toLowerCase().includes(q) || summaryEn.toLowerCase().includes(q) || summaryZh.toLowerCase().includes(q);
|
|
6155
6195
|
});
|
|
6156
6196
|
}, [
|
|
6157
|
-
|
|
6197
|
+
browsable,
|
|
6158
6198
|
query,
|
|
6159
6199
|
category,
|
|
6160
6200
|
installedByName
|
|
@@ -6179,14 +6219,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6179
6219
|
const visible = incremental ? sorted.slice(0, visibleCount) : sorted;
|
|
6180
6220
|
const categoryCounts = (0, react.useMemo)(() => {
|
|
6181
6221
|
const counts = /* @__PURE__ */ new Map();
|
|
6182
|
-
|
|
6183
|
-
if (isShopLike(entry.name) || entry.repo !== void 0 && isShopLike(entry.repo)) continue;
|
|
6222
|
+
for (const entry of browsable) {
|
|
6184
6223
|
const key = categoryKey(entry);
|
|
6185
6224
|
const bare = CATEGORY_ORDER.find((c) => categoryLocaleKey(c) === key);
|
|
6186
6225
|
if (bare !== void 0) counts.set(bare, (counts.get(bare) ?? 0) + 1);
|
|
6187
6226
|
}
|
|
6188
6227
|
return counts;
|
|
6189
|
-
}, [
|
|
6228
|
+
}, [browsable]);
|
|
6190
6229
|
const installedCount = (0, react.useMemo)(() => {
|
|
6191
6230
|
if (installedState.kind !== "ready") return 0;
|
|
6192
6231
|
return installedState.entries.filter((entry) => !isShopLike(entry.name)).length;
|
|
@@ -6207,50 +6246,50 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6207
6246
|
return map;
|
|
6208
6247
|
}, [catalogState]);
|
|
6209
6248
|
if (catalogState.kind === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6210
|
-
className:
|
|
6249
|
+
className: _dsh_plugin_shop_css_e3675a89_default.panel,
|
|
6211
6250
|
"data-shop-tab": true,
|
|
6212
6251
|
"aria-busy": "true",
|
|
6213
6252
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6214
|
-
className:
|
|
6253
|
+
className: _dsh_plugin_shop_css_e3675a89_default.srOnly,
|
|
6215
6254
|
children: t("loading")
|
|
6216
6255
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6217
|
-
className:
|
|
6256
|
+
className: _dsh_plugin_shop_css_e3675a89_default.skeletonGrid,
|
|
6218
6257
|
"data-shop-skeleton": true,
|
|
6219
6258
|
"aria-hidden": "true",
|
|
6220
6259
|
children: Array.from({ length: 8 }, (_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6221
|
-
className:
|
|
6260
|
+
className: _dsh_plugin_shop_css_e3675a89_default.skeletonCard,
|
|
6222
6261
|
children: [
|
|
6223
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className:
|
|
6224
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className:
|
|
6225
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className:
|
|
6226
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className:
|
|
6262
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.skeletonName }),
|
|
6263
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.skeletonSummary }),
|
|
6264
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.skeletonSummaryShort }),
|
|
6265
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.skeletonActions })
|
|
6227
6266
|
]
|
|
6228
6267
|
}, i))
|
|
6229
6268
|
})]
|
|
6230
6269
|
});
|
|
6231
6270
|
if (catalogState.kind === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6232
|
-
className:
|
|
6271
|
+
className: _dsh_plugin_shop_css_e3675a89_default.panel,
|
|
6233
6272
|
"data-shop-tab": true,
|
|
6234
6273
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6235
|
-
className:
|
|
6274
|
+
className: _dsh_plugin_shop_css_e3675a89_default.stateLine,
|
|
6236
6275
|
children: t("error")
|
|
6237
6276
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6238
6277
|
type: "button",
|
|
6239
|
-
className:
|
|
6278
|
+
className: _dsh_plugin_shop_css_e3675a89_default.actionButton,
|
|
6240
6279
|
onClick: () => setRequest({ kind: "retry" }),
|
|
6241
6280
|
children: t("retry")
|
|
6242
6281
|
})]
|
|
6243
6282
|
});
|
|
6244
6283
|
const { result } = catalogState;
|
|
6245
6284
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6246
|
-
className:
|
|
6285
|
+
className: _dsh_plugin_shop_css_e3675a89_default.panel,
|
|
6247
6286
|
"data-shop-tab": true,
|
|
6248
6287
|
children: [
|
|
6249
6288
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6250
|
-
className:
|
|
6289
|
+
className: _dsh_plugin_shop_css_e3675a89_default.toolbar,
|
|
6251
6290
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
6252
6291
|
type: "search",
|
|
6253
|
-
className:
|
|
6292
|
+
className: _dsh_plugin_shop_css_e3675a89_default.searchInput,
|
|
6254
6293
|
"aria-label": t("search"),
|
|
6255
6294
|
placeholder: t("search"),
|
|
6256
6295
|
value: query,
|
|
@@ -6259,39 +6298,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6259
6298
|
setVisibleCount(48);
|
|
6260
6299
|
}
|
|
6261
6300
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6262
|
-
className:
|
|
6301
|
+
className: _dsh_plugin_shop_css_e3675a89_default.toolbarRight,
|
|
6263
6302
|
children: [
|
|
6264
|
-
result.stale && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6265
|
-
className:
|
|
6266
|
-
children:
|
|
6267
|
-
className: _dsh_plugin_shop_css_26093961_default.staleBadge,
|
|
6268
|
-
children: t("staleLabel", { date: result.builtAt.slice(0, 10) })
|
|
6269
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6270
|
-
type: "button",
|
|
6271
|
-
className: _dsh_plugin_shop_css_26093961_default.actionButton,
|
|
6272
|
-
onClick: () => setRequest({ kind: "refresh" }),
|
|
6273
|
-
children: t("refresh")
|
|
6274
|
-
})]
|
|
6303
|
+
result.stale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6304
|
+
className: _dsh_plugin_shop_css_e3675a89_default.staleBadge,
|
|
6305
|
+
children: t("staleLabel", { date: result.builtAt.slice(0, 10) })
|
|
6275
6306
|
}),
|
|
6276
6307
|
selfVersion !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6277
|
-
className:
|
|
6308
|
+
className: _dsh_plugin_shop_css_e3675a89_default.versionBlock,
|
|
6278
6309
|
children: [
|
|
6279
6310
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6280
|
-
className:
|
|
6311
|
+
className: _dsh_plugin_shop_css_e3675a89_default.versionText,
|
|
6281
6312
|
"data-shop-version": true,
|
|
6282
6313
|
children: ["v", selfVersion.installed]
|
|
6283
6314
|
}),
|
|
6284
6315
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6285
6316
|
type: "button",
|
|
6286
|
-
className:
|
|
6317
|
+
className: _dsh_plugin_shop_css_e3675a89_default.checkUpdateButton,
|
|
6287
6318
|
"data-shop-check-update": true,
|
|
6319
|
+
title: t("checkUpdateTitle"),
|
|
6288
6320
|
disabled: checkState !== "idle",
|
|
6289
6321
|
onClick: () => void checkVersion(),
|
|
6290
6322
|
children: checkState === "up-to-date" ? t("upToDate") : t("checkUpdate")
|
|
6291
6323
|
}),
|
|
6292
6324
|
selfVersion.outdated && selfVersion.latest !== null && selfUpdate.view.kind === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6293
6325
|
type: "button",
|
|
6294
|
-
className:
|
|
6326
|
+
className: _dsh_plugin_shop_css_e3675a89_default.updateSelfButton,
|
|
6295
6327
|
"data-shop-update-self": true,
|
|
6296
6328
|
onClick: () => {
|
|
6297
6329
|
if (selfVersion.latest !== null) selfUpdate.start({ version: selfVersion.latest });
|
|
@@ -6301,7 +6333,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6301
6333
|
]
|
|
6302
6334
|
}),
|
|
6303
6335
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
6304
|
-
className:
|
|
6336
|
+
className: _dsh_plugin_shop_css_e3675a89_default.githubLink,
|
|
6305
6337
|
href: SHOP_REPO_URL,
|
|
6306
6338
|
target: "_blank",
|
|
6307
6339
|
rel: "noopener noreferrer",
|
|
@@ -6320,27 +6352,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6320
6352
|
})]
|
|
6321
6353
|
}),
|
|
6322
6354
|
selfUpdate.view.kind === "running" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6323
|
-
className:
|
|
6355
|
+
className: _dsh_plugin_shop_css_e3675a89_default.selfUpdatePanel,
|
|
6324
6356
|
"data-shop-self-updating": true,
|
|
6325
6357
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6326
|
-
className:
|
|
6358
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installing,
|
|
6327
6359
|
children: t("installing")
|
|
6328
6360
|
}), selfUpdate.view.log.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6329
|
-
className:
|
|
6361
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
6330
6362
|
children: selfUpdate.view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6331
|
-
className:
|
|
6363
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
6332
6364
|
children: line
|
|
6333
6365
|
}, index))
|
|
6334
6366
|
})]
|
|
6335
6367
|
}),
|
|
6336
6368
|
selfUpdate.view.kind === "done" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6337
|
-
className:
|
|
6369
|
+
className: _dsh_plugin_shop_css_e3675a89_default.selfUpdatePanel,
|
|
6338
6370
|
"data-shop-self-update-done": true,
|
|
6339
6371
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6340
|
-
className:
|
|
6372
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installedActions,
|
|
6341
6373
|
children: [
|
|
6342
6374
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6343
|
-
className:
|
|
6375
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
6344
6376
|
children: t("installedRestartNotice")
|
|
6345
6377
|
}),
|
|
6346
6378
|
restartSupported && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RestartPanel, {
|
|
@@ -6348,7 +6380,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6348
6380
|
restart
|
|
6349
6381
|
}),
|
|
6350
6382
|
!restartSupported && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6351
|
-
className:
|
|
6383
|
+
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
6352
6384
|
"data-shop-restart-disabled": true,
|
|
6353
6385
|
children: t("restartDisabledNotice")
|
|
6354
6386
|
})
|
|
@@ -6356,48 +6388,49 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6356
6388
|
})
|
|
6357
6389
|
}),
|
|
6358
6390
|
selfUpdate.view.kind === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6359
|
-
className:
|
|
6391
|
+
className: _dsh_plugin_shop_css_e3675a89_default.selfUpdatePanel,
|
|
6360
6392
|
"data-shop-self-update-failed": true,
|
|
6361
6393
|
children: [
|
|
6362
6394
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6363
|
-
className:
|
|
6395
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedHeading,
|
|
6364
6396
|
children: t("updateFailed")
|
|
6365
6397
|
}),
|
|
6366
6398
|
selfUpdate.view.log.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6367
|
-
className:
|
|
6399
|
+
className: _dsh_plugin_shop_css_e3675a89_default.log,
|
|
6368
6400
|
children: selfUpdate.view.log.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6369
|
-
className:
|
|
6401
|
+
className: _dsh_plugin_shop_css_e3675a89_default.logLine,
|
|
6370
6402
|
children: line
|
|
6371
6403
|
}, index))
|
|
6372
6404
|
}),
|
|
6373
6405
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6374
|
-
className:
|
|
6406
|
+
className: _dsh_plugin_shop_css_e3675a89_default.failedDetail,
|
|
6375
6407
|
children: selfUpdate.view.detail === "" ? t("updateTransportFailed") : selfUpdate.view.detail
|
|
6376
6408
|
})
|
|
6377
6409
|
]
|
|
6378
6410
|
}),
|
|
6379
6411
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6380
|
-
className:
|
|
6412
|
+
className: _dsh_plugin_shop_css_e3675a89_default.categoryBar,
|
|
6381
6413
|
role: "group",
|
|
6382
6414
|
"aria-label": t("catalog"),
|
|
6383
6415
|
children: [
|
|
6384
6416
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6385
6417
|
type: "button",
|
|
6386
|
-
className: category === null ? `${
|
|
6418
|
+
className: category === null ? `${_dsh_plugin_shop_css_e3675a89_default.categoryButton} ${_dsh_plugin_shop_css_e3675a89_default.categoryButtonOn}` : _dsh_plugin_shop_css_e3675a89_default.categoryButton,
|
|
6387
6419
|
"aria-pressed": category === null,
|
|
6388
6420
|
onClick: () => {
|
|
6389
6421
|
setCategory(null);
|
|
6390
6422
|
setVisibleCount(48);
|
|
6391
6423
|
},
|
|
6424
|
+
"data-shop-category-all": true,
|
|
6392
6425
|
children: [
|
|
6393
6426
|
t("all"),
|
|
6394
6427
|
" ",
|
|
6395
|
-
|
|
6428
|
+
browsable.length
|
|
6396
6429
|
]
|
|
6397
6430
|
}),
|
|
6398
6431
|
CATEGORY_ORDER.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6399
6432
|
type: "button",
|
|
6400
|
-
className: category === key ? `${
|
|
6433
|
+
className: category === key ? `${_dsh_plugin_shop_css_e3675a89_default.categoryButton} ${_dsh_plugin_shop_css_e3675a89_default.categoryButtonOn}` : _dsh_plugin_shop_css_e3675a89_default.categoryButton,
|
|
6401
6434
|
"aria-pressed": category === key,
|
|
6402
6435
|
onClick: () => {
|
|
6403
6436
|
setCategory(key);
|
|
@@ -6411,7 +6444,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6411
6444
|
}, key)),
|
|
6412
6445
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6413
6446
|
type: "button",
|
|
6414
|
-
className: category === "installed" ? `${
|
|
6447
|
+
className: category === "installed" ? `${_dsh_plugin_shop_css_e3675a89_default.categoryButton} ${_dsh_plugin_shop_css_e3675a89_default.categoryButtonOn}` : _dsh_plugin_shop_css_e3675a89_default.categoryButton,
|
|
6415
6448
|
"aria-pressed": category === "installed",
|
|
6416
6449
|
onClick: () => {
|
|
6417
6450
|
setCategory("installed");
|
|
@@ -6425,21 +6458,44 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6425
6458
|
})
|
|
6426
6459
|
]
|
|
6427
6460
|
}),
|
|
6428
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6429
|
-
className:
|
|
6430
|
-
children:
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6461
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6462
|
+
className: _dsh_plugin_shop_css_e3675a89_default.catalogStatsRow,
|
|
6463
|
+
children: [
|
|
6464
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6465
|
+
className: _dsh_plugin_shop_css_e3675a89_default.catalogStats,
|
|
6466
|
+
"data-shop-catalog-stats": true,
|
|
6467
|
+
children: t("catalogStats", {
|
|
6468
|
+
count: String(browsable.length),
|
|
6469
|
+
date: result.builtAt.slice(0, 10)
|
|
6470
|
+
})
|
|
6471
|
+
}),
|
|
6472
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6473
|
+
type: "button",
|
|
6474
|
+
className: _dsh_plugin_shop_css_e3675a89_default.reloadButton,
|
|
6475
|
+
"data-shop-reload": true,
|
|
6476
|
+
disabled: reloading,
|
|
6477
|
+
onClick: () => {
|
|
6478
|
+
setReloading(true);
|
|
6479
|
+
setReloadFailed(false);
|
|
6480
|
+
setRequest({ kind: "refresh" });
|
|
6481
|
+
},
|
|
6482
|
+
children: reloading ? t("refreshing") : t("refresh")
|
|
6483
|
+
}),
|
|
6484
|
+
reloadFailed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6485
|
+
className: _dsh_plugin_shop_css_e3675a89_default.reloadFailed,
|
|
6486
|
+
"data-shop-reload-failed": true,
|
|
6487
|
+
children: t("refreshFailed")
|
|
6488
|
+
})
|
|
6489
|
+
]
|
|
6434
6490
|
}),
|
|
6435
6491
|
result.plugins.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6436
|
-
className:
|
|
6492
|
+
className: _dsh_plugin_shop_css_e3675a89_default.emptyLine,
|
|
6437
6493
|
children: t("empty")
|
|
6438
6494
|
}) : filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6439
|
-
className:
|
|
6495
|
+
className: _dsh_plugin_shop_css_e3675a89_default.emptyLine,
|
|
6440
6496
|
children: t("emptySearch")
|
|
6441
6497
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
|
|
6442
|
-
className:
|
|
6498
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cards,
|
|
6443
6499
|
children: [visible.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EntryCard, {
|
|
6444
6500
|
entry,
|
|
6445
6501
|
stars: starsOf(entry, stars),
|
|
@@ -6454,12 +6510,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6454
6510
|
setEnabled
|
|
6455
6511
|
}) }, entryKey(entry))), incremental && visibleCount < filtered.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
6456
6512
|
ref: sentinelRef,
|
|
6457
|
-
className:
|
|
6513
|
+
className: _dsh_plugin_shop_css_e3675a89_default.cardsSentry,
|
|
6458
6514
|
"data-shop-sentry": true,
|
|
6459
6515
|
"aria-hidden": "true"
|
|
6460
6516
|
})]
|
|
6461
6517
|
}), incremental && visibleCount < filtered.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6462
|
-
className:
|
|
6518
|
+
className: _dsh_plugin_shop_css_e3675a89_default.showingLine,
|
|
6463
6519
|
"aria-live": "polite",
|
|
6464
6520
|
children: t("showing", {
|
|
6465
6521
|
shown: String(visibleCount),
|