@bison-lab/payload-core 3.24.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -7
- package/dist/admin.d.mts +8 -1
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +87 -2
- package/dist/admin.mjs.map +1 -1
- package/dist/index.d.mts +41 -13
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +219 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@ are extracted.
|
|
|
8
8
|
Full guide: <https://payload.bisonlab.ai/site/seo/>
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
pnpm add @bison-lab/payload-core @payloadcms/plugin-seo @bison-lab/tokens @bison-lab/fonts
|
|
11
|
+
pnpm add @bison-lab/payload-core @payloadcms/plugin-seo @payloadcms/plugin-redirects @bison-lab/tokens @bison-lab/fonts
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
Peers: `payload
|
|
14
|
+
Peers: `payload`, `@payloadcms/plugin-seo`, and `@payloadcms/plugin-redirects` are required. `@bison-lab/tokens`
|
|
15
15
|
and `@bison-lab/fonts` are needed to adopt the Theme Global; `@payloadcms/ui`
|
|
16
16
|
and `react` are needed for its admin fields; `@bison-lab/ui` and
|
|
17
17
|
`@payloadcms/live-preview-react` are needed for the live theme preview.
|
|
@@ -22,7 +22,7 @@ lockstep.
|
|
|
22
22
|
|
|
23
23
|
| Import | Contents | Runs where |
|
|
24
24
|
| ---------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
|
25
|
-
| `@bison-lab/payload-core` | `seoPlugin`, `createTheme`, `createBrandAssets`, `createRoles`, `createFeatures`, `createPages`, `createUsers`, `createMedia`, `createAdminNav`, `adminNav`, `createNavigation`, `adminOnlyApiTab`, `documentTitleActions`, `seedTheme`, `seedRoles`, `seedFeatures`, predicates, `lookField`, `colorTokenField`, import-map strings, title and text helpers, types | Node. What `payload.config.ts` imports; it loads the plugin. |
|
|
25
|
+
| `@bison-lab/payload-core` | `seoPlugin`, `createTheme`, `createBrandAssets`, `createRoles`, `createFeatures`, `createPages`, `createUsers`, `createMedia`, `createRedirects`, `createAdminNav`, `adminNav`, `createNavigation`, `adminOnlyApiTab`, `documentTitleActions`, `seedTheme`, `seedRoles`, `seedFeatures`, predicates, `lookField`, `colorTokenField`, import-map strings, title and text helpers, types | Node. What `payload.config.ts` imports; it loads the plugin. |
|
|
26
26
|
| `@bison-lab/payload-core/metadata` | `pageMetadata`, the title helpers, the same types | Server. What a page route imports; it does not load the plugin. |
|
|
27
27
|
| `@bison-lab/payload-core/theme` | `getPublishedTheme`, `getPublishedIdentity`, `themeConfigFromDoc`, `themeHead`, `themeHeadFromDoc` | Server. What a root layout imports; it does not load the plugin or React. |
|
|
28
28
|
| `@bison-lab/payload-core/navigation` | `getNavigation`, the Header and Footer slugs | Server. What a site header imports; it does not load the plugin or React. |
|
|
@@ -45,11 +45,12 @@ the site spells its name and its URL scheme once.
|
|
|
45
45
|
|
|
46
46
|
```ts
|
|
47
47
|
// payload.config.ts
|
|
48
|
-
import { firstImageIn, seoPlugin } from "@bison-lab/payload-core";
|
|
48
|
+
import { createRedirects, firstImageIn, seoPlugin } from "@bison-lab/payload-core";
|
|
49
49
|
import type { Page } from "@/payload-types";
|
|
50
50
|
|
|
51
51
|
export default buildConfig({
|
|
52
52
|
plugins: [
|
|
53
|
+
createRedirects(),
|
|
53
54
|
seoPlugin<Page>({
|
|
54
55
|
siteName: "Acme Clinics",
|
|
55
56
|
urlFor: (doc) => (doc.slug ? absoluteUrl(pagePath(doc.slug)) : undefined),
|
|
@@ -318,10 +319,16 @@ read from the live Features and Roles Globals) so Payload's
|
|
|
318
319
|
## Pages, users, and media
|
|
319
320
|
|
|
320
321
|
`createPages`, `createUsers`, `createMedia`, `slugField`,
|
|
321
|
-
`adminOnlyApiTab`, and `documentTitleActions` ship from the same
|
|
322
|
+
`createRedirects`, `adminOnlyApiTab`, and `documentTitleActions` ship from the same
|
|
322
323
|
React-free entry. Pages take the
|
|
323
324
|
site's hero and layout blocks, reserved-slug predicate, and preview
|
|
324
|
-
path.
|
|
325
|
+
path. The slug follows the title until first publish, then locks. Unlock
|
|
326
|
+
warns in plain words and the same save writes a 308. `createRedirects()`
|
|
327
|
+
wraps `@payloadcms/plugin-redirects` for `pages` only (permanent 308) and
|
|
328
|
+
collapses chains when a published slug changes. The plugin stores the
|
|
329
|
+
rows; the site still has to serve them. Pin the plugin to the same
|
|
330
|
+
version as `payload`, then `payload generate:importmap`,
|
|
331
|
+
`payload generate:types`, and `payload migrate:create`. Create follows the Content tick. Update without Publish is
|
|
325
332
|
constrained to `_status: draft` — an Author can save a draft and cannot
|
|
326
333
|
publish or edit a live page. Users sit under Settings next to Roles,
|
|
327
334
|
take `secureCookies`, and offer whatever rows the Global (or the seed
|
|
@@ -418,6 +425,7 @@ to a type that has one.
|
|
|
418
425
|
|
|
419
426
|
`noIndexField`, the plugin's own fields, the Theme Global fields, the
|
|
420
427
|
Roles Global fields, the Admin nav fields, the Header and Footer fields,
|
|
421
|
-
|
|
428
|
+
the Pages slug lock fields, the Redirects collection, and the
|
|
429
|
+
brand-assets collection fields are columns
|
|
422
430
|
in every consuming site. A change to them is a schema change: say "run
|
|
423
431
|
`payload migrate:create`" in the changeset.
|
package/dist/admin.d.mts
CHANGED
|
@@ -126,6 +126,13 @@ declare function RolesRowLabel(): react_jsx_runtime0.JSX.Element;
|
|
|
126
126
|
*/
|
|
127
127
|
declare const RoleSlugField: TextFieldClientComponent;
|
|
128
128
|
//#endregion
|
|
129
|
+
//#region src/admin/slug-field.d.ts
|
|
130
|
+
/**
|
|
131
|
+
* Slug follows the title until first publish. After that it is read-only
|
|
132
|
+
* until Unlock, which warns that the old address will redirect.
|
|
133
|
+
*/
|
|
134
|
+
declare const SlugField: TextFieldClientComponent;
|
|
135
|
+
//#endregion
|
|
129
136
|
//#region src/admin/role-name-field.d.ts
|
|
130
137
|
/**
|
|
131
138
|
* Role name. Letters and spaces only, so the hidden slug stays
|
|
@@ -214,5 +221,5 @@ declare function AdminNavItemRowLabel(): react_jsx_runtime0.JSX.Element;
|
|
|
214
221
|
*/
|
|
215
222
|
declare const AdminNavEntityField: TextFieldClientComponent;
|
|
216
223
|
//#endregion
|
|
217
|
-
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, ThemeDocumentControls, ThemeSaveButton, setThemePreviewMode };
|
|
224
|
+
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, SlugField, ThemeDocumentControls, ThemeSaveButton, setThemePreviewMode };
|
|
218
225
|
//# sourceMappingURL=admin.d.mts.map
|
package/dist/admin.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.d.mts","names":[],"sources":["../src/admin/color-field.tsx","../src/admin/color-scale-field.tsx","../src/admin/library-field.tsx","../src/admin/font-field.tsx","../src/admin/pairing-field.tsx","../src/admin/appearance-field.tsx","../src/admin/grey-scale-field.tsx","../src/admin/contrast-report.tsx","../src/admin/section-heading.tsx","../src/admin/publish-child.tsx","../src/admin/save-button.tsx","../src/admin/preview-mode.tsx","../src/admin/identity-fallback.tsx","../src/admin/look-field.tsx","../src/admin/roles-matrix-field.tsx","../src/admin/roles-row-label.tsx","../src/admin/role-slug-field.tsx","../src/admin/role-name-field.tsx","../src/admin/roles-field.tsx","../src/admin/roles-grants-field.tsx","../src/admin/features-matrix-field.tsx","../src/admin/document-title-actions.tsx","../src/admin/document-create-new.tsx","../src/admin-nav/types.ts","../src/admin/admin-nav.tsx","../src/admin/admin-nav-row-label.tsx","../src/admin/admin-nav-item-row-label.tsx","../src/admin/admin-nav-entity-field.tsx"],"mappings":";;;;;;;;;;;cAWa,UAAA,EAAY,wBAAA;;;;;;;cCsBZ,eAAA,EAAiB,yBAAA;;;;;;;;;cCOjB,YAAA,EAAc,yBAAA;;;;;;;;;cCtBd,SAAA,EAAW,0BAAA;;;;;;;cCNX,YAAA,EAAc,sBAAA;;;;;;;cCCd,eAAA,EAAiB,yBAAA;;;ALF9B;;;;AAAA,cM4Da,cAAA,EAAgB,0BAAA;;;;;;;cCnDhB,cAAA,EAAgB,sBAAA;;;;;;cCbhB,cAAA,EAAgB,sBAAA;;;cC0IhB,YAAA,EAAc,sBAAA;;;;;;;;iBCtIX,qBAAA,CAAA;;AVAhB;;;iBUQgB,eAAA,CAAA,GAAe,kBAAA,CAAA,GAAA,CAAA,OAAA;;iBA0Bf,gBAAA,CAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;KCrCpB,gBAAA;AAAA,iBAkCI,mBAAA,CAAoB,IAAA,EAAM,gBAAA;;;;;;;cClC7B,gBAAA,EAAkB,sBAAA;;;;;;;cCIlB,SAAA,EAAW,wBAAA;;;;;;;;cCqBX,gBAAA,EAAkB,yBAAA;;;;;;iBC1Bf,aAAA,CAAA,GAAa,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;cCChB,aAAA,EAAe,wBAAA;;;;;;;
|
|
1
|
+
{"version":3,"file":"admin.d.mts","names":[],"sources":["../src/admin/color-field.tsx","../src/admin/color-scale-field.tsx","../src/admin/library-field.tsx","../src/admin/font-field.tsx","../src/admin/pairing-field.tsx","../src/admin/appearance-field.tsx","../src/admin/grey-scale-field.tsx","../src/admin/contrast-report.tsx","../src/admin/section-heading.tsx","../src/admin/publish-child.tsx","../src/admin/save-button.tsx","../src/admin/preview-mode.tsx","../src/admin/identity-fallback.tsx","../src/admin/look-field.tsx","../src/admin/roles-matrix-field.tsx","../src/admin/roles-row-label.tsx","../src/admin/role-slug-field.tsx","../src/admin/slug-field.tsx","../src/admin/role-name-field.tsx","../src/admin/roles-field.tsx","../src/admin/roles-grants-field.tsx","../src/admin/features-matrix-field.tsx","../src/admin/document-title-actions.tsx","../src/admin/document-create-new.tsx","../src/admin-nav/types.ts","../src/admin/admin-nav.tsx","../src/admin/admin-nav-row-label.tsx","../src/admin/admin-nav-item-row-label.tsx","../src/admin/admin-nav-entity-field.tsx"],"mappings":";;;;;;;;;;;cAWa,UAAA,EAAY,wBAAA;;;;;;;cCsBZ,eAAA,EAAiB,yBAAA;;;;;;;;;cCOjB,YAAA,EAAc,yBAAA;;;;;;;;;cCtBd,SAAA,EAAW,0BAAA;;;;;;;cCNX,YAAA,EAAc,sBAAA;;;;;;;cCCd,eAAA,EAAiB,yBAAA;;;ALF9B;;;;AAAA,cM4Da,cAAA,EAAgB,0BAAA;;;;;;;cCnDhB,cAAA,EAAgB,sBAAA;;;;;;cCbhB,cAAA,EAAgB,sBAAA;;;cC0IhB,YAAA,EAAc,sBAAA;;;;;;;;iBCtIX,qBAAA,CAAA;;AVAhB;;;iBUQgB,eAAA,CAAA,GAAe,kBAAA,CAAA,GAAA,CAAA,OAAA;;iBA0Bf,gBAAA,CAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;KCrCpB,gBAAA;AAAA,iBAkCI,mBAAA,CAAoB,IAAA,EAAM,gBAAA;;;;;;;cClC7B,gBAAA,EAAkB,sBAAA;;;;;;;cCIlB,SAAA,EAAW,wBAAA;;;;;;;;cCqBX,gBAAA,EAAkB,yBAAA;;;;;;iBC1Bf,aAAA,CAAA,GAAa,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;cCChB,aAAA,EAAe,wBAAA;;;;;;;cCGf,SAAA,EAAW,wBAAA;;;;;;;cCFX,aAAA,EAAe,wBAAA;;;;;;;;cC8Cf,UAAA,EAAY,0BAAA;;;;;;;;cChCZ,gBAAA,EAAkB,wBAAA;;;;;;;;;ApBZ/B;;cqB0Ca,mBAAA,EAAqB,yBAAA;;;iBCflB,oBAAA,CAAA;EAAuB;AAAA;EAAc,QAAA,GAAW,SAAA;AAAA,IAAW,kBAAA,CAAA,GAAA,CAAA,OAAA;;;iBCxB3D,iBAAA,CAAA;EAAoB;AAAA;EAAU,IAAA;AAAA,IAAc,kBAAA,CAAA,GAAA,CAAA,OAAA;;;UCmB3C,uBAAA;EACf,WAAA;EACA,OAAA;AAAA;;;UC5Be,aAAA;EACf,eAAA,GAAkB,uBAAA;AAAA;;;AzBGpB;;;iByB6CgB,QAAA,CAAA;EAAW;AAAA,GAAmB,aAAA,GAAa,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;iBCnD3C,gBAAA,CAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;;iBCGhB,oBAAA,CAAA,GAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;;;cCEvB,mBAAA,EAAqB,wBAAA"}
|
package/dist/admin.mjs
CHANGED
|
@@ -4,10 +4,11 @@ import { ArrayField, Button, CheckboxInput, FieldDescription, FieldError, FieldL
|
|
|
4
4
|
import { GREY_SCALES, SHADE_STEPS, contrastForeground, contrastRatio, createColorScale, deriveDarkPalette, deriveLightPalette, hexToHSL, hslToString, includedShadeSteps, isThemeHex, presetHints, setColorScaleInclude } from "@bison-lab/tokens";
|
|
5
5
|
import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
import { Badge, Dialog, Field, Input, KitProvider, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@bison-lab/admin-ui";
|
|
7
|
+
import { Badge, Button as Button$1, Dialog, Field, Input, KitProvider, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@bison-lab/admin-ui";
|
|
8
8
|
import { HexColorPicker } from "react-colorful";
|
|
9
9
|
import { createPortal } from "react-dom";
|
|
10
10
|
import { findFont, fontFaceCss, isFontId } from "@bison-lab/fonts";
|
|
11
|
+
import "payload";
|
|
11
12
|
//#region src/admin/color-field.tsx
|
|
12
13
|
const HEX_ERROR = "Enter a six-digit hex colour like #1e3a5f";
|
|
13
14
|
/**
|
|
@@ -3004,6 +3005,90 @@ const RoleSlugField = ({ field, path, readOnly }) => {
|
|
|
3004
3005
|
});
|
|
3005
3006
|
};
|
|
3006
3007
|
//#endregion
|
|
3008
|
+
//#region src/fields/slug.ts
|
|
3009
|
+
const SLUG_UNLOCK_WARNING = "This page is live. Changing the address will send visitors from the old URL to the new one.";
|
|
3010
|
+
function slugifySegment(segment) {
|
|
3011
|
+
return segment.normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
3012
|
+
}
|
|
3013
|
+
/**
|
|
3014
|
+
* A stored slug from whatever was typed: NFKD, hyphenated, slash segments
|
|
3015
|
+
* kept, so `Café / About Us` becomes `cafe/about-us`.
|
|
3016
|
+
*/
|
|
3017
|
+
function normalizeSlug(value) {
|
|
3018
|
+
return value.split("/").map(slugifySegment).filter(Boolean).join("/");
|
|
3019
|
+
}
|
|
3020
|
+
//#endregion
|
|
3021
|
+
//#region src/admin/slug-field.tsx
|
|
3022
|
+
/**
|
|
3023
|
+
* Slug follows the title until first publish. After that it is read-only
|
|
3024
|
+
* until Unlock, which warns that the old address will redirect.
|
|
3025
|
+
*/
|
|
3026
|
+
const SlugField = ({ field, path, readOnly }) => {
|
|
3027
|
+
const { value, setValue, showError, errorMessage } = useField({ path });
|
|
3028
|
+
const { value: unlock, setValue: setUnlock } = useField({ path: "slugUnlock" });
|
|
3029
|
+
const title = useFormFields(([fields]) => fields.title?.value);
|
|
3030
|
+
const slugLocked = Boolean(useFormFields(([fields]) => fields.slugLocked?.value));
|
|
3031
|
+
const locked = Boolean(readOnly) || slugLocked && !unlock;
|
|
3032
|
+
const required = Boolean(field.required);
|
|
3033
|
+
const id = `field-${path.replace(/\./g, "__")}`;
|
|
3034
|
+
useEffect(() => {
|
|
3035
|
+
if (slugLocked || typeof title !== "string") return;
|
|
3036
|
+
const next = normalizeSlug(title);
|
|
3037
|
+
if (next !== (value ?? "")) setValue(next);
|
|
3038
|
+
}, [
|
|
3039
|
+
setValue,
|
|
3040
|
+
slugLocked,
|
|
3041
|
+
title,
|
|
3042
|
+
value
|
|
3043
|
+
]);
|
|
3044
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3045
|
+
className: [
|
|
3046
|
+
fieldBaseClass,
|
|
3047
|
+
"text",
|
|
3048
|
+
locked && "read-only"
|
|
3049
|
+
].filter(Boolean).join(" "),
|
|
3050
|
+
children: [
|
|
3051
|
+
/* @__PURE__ */ jsx(FieldLabel, {
|
|
3052
|
+
htmlFor: id,
|
|
3053
|
+
label: field.label,
|
|
3054
|
+
required
|
|
3055
|
+
}),
|
|
3056
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3057
|
+
className: `${fieldBaseClass}__wrap`,
|
|
3058
|
+
children: [
|
|
3059
|
+
/* @__PURE__ */ jsx(FieldError, {
|
|
3060
|
+
message: errorMessage,
|
|
3061
|
+
path,
|
|
3062
|
+
showError
|
|
3063
|
+
}),
|
|
3064
|
+
/* @__PURE__ */ jsx("input", {
|
|
3065
|
+
id,
|
|
3066
|
+
type: "text",
|
|
3067
|
+
autoComplete: "off",
|
|
3068
|
+
spellCheck: false,
|
|
3069
|
+
readOnly: locked,
|
|
3070
|
+
disabled: locked,
|
|
3071
|
+
value: value ?? "",
|
|
3072
|
+
onChange: (event) => {
|
|
3073
|
+
if (!locked) setValue(event.target.value);
|
|
3074
|
+
}
|
|
3075
|
+
}),
|
|
3076
|
+
slugLocked && !unlock ? /* @__PURE__ */ jsx(Button$1, {
|
|
3077
|
+
variant: "outline",
|
|
3078
|
+
onClick: () => setUnlock(true),
|
|
3079
|
+
children: "Unlock"
|
|
3080
|
+
}) : null
|
|
3081
|
+
]
|
|
3082
|
+
}),
|
|
3083
|
+
unlock ? /* @__PURE__ */ jsx("p", { children: SLUG_UNLOCK_WARNING }) : null,
|
|
3084
|
+
/* @__PURE__ */ jsx(FieldDescription, {
|
|
3085
|
+
description: field.admin?.description,
|
|
3086
|
+
path
|
|
3087
|
+
})
|
|
3088
|
+
]
|
|
3089
|
+
});
|
|
3090
|
+
};
|
|
3091
|
+
//#endregion
|
|
3007
3092
|
//#region src/admin/role-name-field.tsx
|
|
3008
3093
|
/**
|
|
3009
3094
|
* Role name. Letters and spaces only, so the hidden slug stays
|
|
@@ -3743,6 +3828,6 @@ const AdminNavEntityField = ({ field, path, permissions, readOnly, schemaPath })
|
|
|
3743
3828
|
});
|
|
3744
3829
|
};
|
|
3745
3830
|
//#endregion
|
|
3746
|
-
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, ThemeDocumentControls, ThemeSaveButton, setThemePreviewMode };
|
|
3831
|
+
export { AdminNav, AdminNavEntityField, AdminNavItemRowLabel, AdminNavRowLabel, AppearanceField, ColorField, ColorScaleField, ContrastReport, DocumentCreateNew, DocumentTitleActions, FeaturesMatrixField, FontField, GreyScaleField, HiddenSaveButton, IdentityFallback, LibraryField, LookField, PairingField, PublishChild, RoleNameField, RoleSlugField, RolesField, RolesGrantsField, RolesMatrixField, RolesRowLabel, SectionHeading, SlugField, ThemeDocumentControls, ThemeSaveButton, setThemePreviewMode };
|
|
3747
3832
|
|
|
3748
3833
|
//# sourceMappingURL=admin.mjs.map
|