@wordrhyme/plugin 0.1.0-alpha.11 → 0.1.0-alpha.14

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.
@@ -68,6 +68,8 @@ interface PluginContext {
68
68
  marketplaceRegistrySigner?: MarketplaceRegistrySigningCapability | undefined;
69
69
  /** Host-configured public Marketplace origin; null means production configuration is missing. */
70
70
  marketplaceRegistryBaseUrl?: string | null | undefined;
71
+ /** Host-owned Marketplace availability policy exposed only to the first-party Marketplace plugin. */
72
+ marketplacePolicy?: MarketplacePolicyCapability | undefined;
71
73
  /** Host-mediated Core organization creation for explicitly trusted plugins. */
72
74
  organizationProvisioning?: PluginOrganizationProvisioningCapability | undefined;
73
75
  /** Host-mediated exact membership lookup within the current organization. */
@@ -95,6 +97,8 @@ interface PluginContext {
95
97
  media?: PluginMediaCapability | undefined;
96
98
  /** Storage capability (for registering custom storage providers) */
97
99
  storage?: PluginStorageCapability | undefined;
100
+ /** SMS capability (for registering transactional SMS providers) */
101
+ sms?: PluginSmsCapability | undefined;
98
102
  /** Opaque plugin artifact storage for explicitly approved first-party workflows. */
99
103
  artifacts?: PluginArtifactCapability | undefined;
100
104
  /** Metrics capability (for recording usage metrics) */
@@ -122,6 +126,10 @@ interface PluginContext {
122
126
  /** Host registration boundary; injected only for the declared official AI Runtime provider. */
123
127
  aiRuntime?: PluginAiRuntimeCapability | undefined;
124
128
  }
129
+ type MarketplacePolicyAction = "catalog" | "publish";
130
+ interface MarketplacePolicyCapability {
131
+ allows(action: MarketplacePolicyAction): Promise<boolean>;
132
+ }
125
133
  /**
126
134
  * Public SDK shape for the Host-provided Drizzle-compatible database.
127
135
  *
@@ -643,7 +651,7 @@ interface AiModelOption {
643
651
  provider: string;
644
652
  model: string;
645
653
  reasoning: boolean;
646
- input: Array<'text' | 'image'>;
654
+ input: Array<"text" | "image">;
647
655
  contextWindow: number;
648
656
  maxOutputTokens: number;
649
657
  }
@@ -656,10 +664,10 @@ interface AiModelListRequest {
656
664
  alias?: string | undefined;
657
665
  }
658
666
  type AiStreamEvent = {
659
- type: 'text-delta';
667
+ type: "text-delta";
660
668
  delta: string;
661
669
  } | {
662
- type: 'usage';
670
+ type: "usage";
663
671
  usage: AiUsage;
664
672
  provider: string;
665
673
  model: string;
@@ -668,7 +676,7 @@ type AiStreamEvent = {
668
676
  revision: string;
669
677
  alias?: string | undefined;
670
678
  } | {
671
- type: 'done';
679
+ type: "done";
672
680
  };
673
681
  interface PluginAiCapability {
674
682
  /** Optional, backward-compatible availability probe for AI-enabled UI. */
@@ -698,7 +706,7 @@ interface AiUsageAuthorization {
698
706
  estimatedCostUsd: number;
699
707
  }
700
708
  interface AiUsageObservation {
701
- status: 'succeeded' | 'failed' | 'aborted';
709
+ status: "succeeded" | "failed" | "aborted";
702
710
  deploymentId: string;
703
711
  revision: string;
704
712
  alias?: string | undefined;
@@ -1322,6 +1330,53 @@ interface PluginSettingEntry {
1322
1330
  encrypted: boolean;
1323
1331
  description?: string | undefined;
1324
1332
  }
1333
+ /**
1334
+ * Host registration boundary for transactional SMS providers.
1335
+ *
1336
+ * Provider plugins own their credentials and templates. Core only supplies a
1337
+ * destination, a stable template key, variables, and a plain-text fallback.
1338
+ */
1339
+ interface PluginSmsCapability {
1340
+ registerProvider(config: PluginSmsProviderConfig): Promise<void>;
1341
+ unregisterProvider(type: string): Promise<void>;
1342
+ }
1343
+ interface PluginSmsProviderConfig {
1344
+ /** Provider type within this plugin, for example `sns` or `dysms`. */
1345
+ type: string;
1346
+ /** Display name used in diagnostics and administration. */
1347
+ name: string;
1348
+ /** Optional provider description. */
1349
+ description?: string;
1350
+ /** Provider implementation. */
1351
+ provider: PluginSmsProvider;
1352
+ }
1353
+ interface PluginSmsProviderContext {
1354
+ /** Host-resolved configuration owner after applying infrastructure policy. */
1355
+ organizationId: string;
1356
+ /** Request identity retained for auditing and provider diagnostics. */
1357
+ requestId?: string;
1358
+ userId?: string;
1359
+ }
1360
+ interface PluginSmsProvider {
1361
+ /** Whether this provider is enabled and has the minimum required configuration. */
1362
+ isConfigured(context: PluginSmsProviderContext): Promise<boolean>;
1363
+ /** Send one transactional SMS. */
1364
+ send(input: PluginSmsSendInput, context: PluginSmsProviderContext): Promise<PluginSmsSendResult>;
1365
+ }
1366
+ interface PluginSmsSendInput {
1367
+ /** Destination in canonical E.164 format. */
1368
+ to: string;
1369
+ /** Stable template key owned by Core, for example `auth.phone.verify`. */
1370
+ template: string;
1371
+ /** Structured values for providers that use approved server-side templates. */
1372
+ variables: Record<string, string>;
1373
+ /** Plain-text fallback for providers that accept arbitrary message bodies. */
1374
+ text: string;
1375
+ }
1376
+ interface PluginSmsSendResult {
1377
+ /** Provider-assigned message identifier when available. */
1378
+ messageId?: string;
1379
+ }
1325
1380
  /**
1326
1381
  * Plugin Media Capability - Unified file and asset management
1327
1382
  *
@@ -1994,4 +2049,4 @@ type ApiPayload<T> = {
1994
2049
  [K in keyof T]: T[K] extends Date ? string : T[K] extends Date | null ? string | null : T[K] extends Date | undefined ? string | undefined : T[K];
1995
2050
  };
1996
2051
 
1997
- export { type PluginActionInvokerCapability as $, type ActionContractMeta as A, type ApiPayload as B, type EAuthProvider as C, type EAuthRefreshInput as D, type EAuthModel as E, type EAuthRefreshResult as F, type EAuthStatus as G, type HookContext as H, type EAuthTokenResult as I, type EAuthUpsertInput as J, type EAuthUse as K, HookAbortError as L, type HookEmitOptions as M, HookPriority as N, MARKETPLACE_PUBLISH_AUTH_METHODS as O, type PluginMediaInfo as P, type MarketplaceAttestationTargetV1 as Q, type MarketplaceExecutionErrorCode as R, type MarketplaceExecutionFailureCode as S, type MarketplaceOrganizationExecutionV1 as T, type MarketplacePlatformReadAction as U, type MarketplacePublishActor as V, type WebSlotRemoteExtension as W, type MarketplacePublishAuthMethod as X, type MarketplacePublisherAction as Y, type MarketplaceRegistrySigningCapability as Z, type OpaquePublisherCandidateV1 as _, type PluginContext as a, type WebPluginHead as a$, type PluginAgentCapability as a0, type PluginAiCapability as a1, type PluginAiRuntimeCapability as a2, type PluginApisCapability as a3, type PluginArtifactCapability as a4, type PluginAssetCapability as a5, type PluginAssetCreateOptions as a6, type PluginAssetInfo as a7, type PluginAssetQuery as a8, type PluginAssetUpdateData as a9, type PluginNotificationSendResult as aA, type PluginNotificationTarget as aB, type PluginNotificationTemplate as aC, type PluginOrganizationMembersCapability as aD, type PluginOrganizationProvisioningCapability as aE, type PluginPaginatedResult as aF, type PluginPermissionCapability as aG, type PluginPermissionCheckContext as aH, type PluginPermissionDef as aI, type PluginQueueCapability as aJ, type PluginScopedDb as aK, type PluginSettingEntry as aL, type PluginSettingOptions as aM, type PluginSettingsCapability as aN, type PluginStorageCapability as aO, type PluginStorageProvider as aP, type PluginStorageProviderConfig as aQ, type PluginStorageProviderInfo as aR, type PluginStorageUploadInput as aS, type PluginStorageUploadResult as aT, type PluginTraceCapability as aU, type PluginUsageCapability as aV, type PluginWebCapability as aW, type ReadonlyPluginScopedDb as aX, type WebJsonPrimitive as aY, type WebJsonValue as aZ, type WebPluginDocumentMode as a_, type PluginAssetVariant as aa, type PluginCurrencyCapability as ab, type PluginEAuthCapability as ac, type PluginEntityExtensionCapability as ad, type PluginEntityExtensionFilter as ae, type PluginFileCapability as af, type PluginFileInfo as ag, type PluginFileQuery as ah, type PluginFileUploadInput as ai, type PluginHookCapability as aj, type PluginJobOptions as ak, type PluginJobStatus as al, type PluginMediaCapability as am, type PluginMediaQuery as an, type PluginMediaUpdateData as ao, type PluginMediaUploadInput as ap, type PluginMediaVariant as aq, type PluginMetricsAllowedLabels as ar, type PluginMetricsCapability as as, type PluginNotificationActor as at, type PluginNotificationCapability as au, type PluginNotificationChannel as av, type PluginNotificationEvent as aw, type PluginNotificationInput as ax, type PluginNotificationResult as ay, type PluginNotificationSendParams as az, type HookHandlerOptions as b, type WebPluginHeadLink as b0, type WebPluginPresentationSurfaceResult as b1, type WebPluginRouteHandler as b2, type WebPluginRouteRequest as b3, type WebPluginRouteResult as b4, type WebPluginTenantInfo as b5, type WebPresentationAdapterClientDescriptor as b6, type WebResolvedPresentationAdapter as b7, type WebResolvedSitePresentation as b8, type WebResolvedSiteShell as b9, type WebResolvedThemeAsset as ba, type WebSerializableGlobalizationState as bb, type WebSlotExtensionQuery as bc, type WebSlotQueryResult as bd, type WebSlotRenderMode as be, type WebSlotRenderOptions as bf, type WebSlotRenderRequest as bg, type WebSlotRenderResult as bh, type WebSlotRenderer as bi, type WebThemeShellClientDescriptor as bj, type WebThemeShellDocumentModel as bk, type WebThemeShellRenderResult as bl, type WebThemeShellRenderer as bm, type WebThemeShellRouteModel as bn, type HookTransaction as c, type PluginLogger as d, type WebPluginSiteInfo as e, type ActionDescriptor as f, type ActionInvokeRequest as g, type AgentToolDescriptor as h, type AiAliasDescriptor as i, type AiBudget as j, type AiModelCatalog as k, type AiModelHint as l, type AiModelListRequest as m, type AiModelOption as n, type AiObjectRequest as o, type AiObjectResult as p, type AiObjectSchema as q, type AiRuntimeHandler as r, type AiRuntimeHost as s, type AiRuntimeInvocation as t, type AiStreamEvent as u, type AiTextRequest as v, type AiTextResult as w, type AiUsage as x, type AiUsageAuthorization as y, type AiUsageObservation as z };
2052
+ export { type MarketplaceRegistrySigningCapability as $, type ActionContractMeta as A, type ApiPayload as B, type EAuthProvider as C, type EAuthRefreshInput as D, type EAuthModel as E, type EAuthRefreshResult as F, type EAuthStatus as G, type HookContext as H, type EAuthTokenResult as I, type EAuthUpsertInput as J, type EAuthUse as K, HookAbortError as L, type HookEmitOptions as M, HookPriority as N, MARKETPLACE_PUBLISH_AUTH_METHODS as O, type PluginMediaInfo as P, type MarketplaceAttestationTargetV1 as Q, type MarketplaceExecutionErrorCode as R, type MarketplaceExecutionFailureCode as S, type MarketplaceOrganizationExecutionV1 as T, type MarketplacePlatformReadAction as U, type MarketplacePolicyAction as V, type WebSlotRemoteExtension as W, type MarketplacePolicyCapability as X, type MarketplacePublishActor as Y, type MarketplacePublishAuthMethod as Z, type MarketplacePublisherAction as _, type PluginContext as a, type PluginStorageUploadResult as a$, type OpaquePublisherCandidateV1 as a0, type PluginActionInvokerCapability as a1, type PluginAgentCapability as a2, type PluginAiCapability as a3, type PluginAiRuntimeCapability as a4, type PluginApisCapability as a5, type PluginArtifactCapability as a6, type PluginAssetCapability as a7, type PluginAssetCreateOptions as a8, type PluginAssetInfo as a9, type PluginNotificationResult as aA, type PluginNotificationSendParams as aB, type PluginNotificationSendResult as aC, type PluginNotificationTarget as aD, type PluginNotificationTemplate as aE, type PluginOrganizationMembersCapability as aF, type PluginOrganizationProvisioningCapability as aG, type PluginPaginatedResult as aH, type PluginPermissionCapability as aI, type PluginPermissionCheckContext as aJ, type PluginPermissionDef as aK, type PluginQueueCapability as aL, type PluginScopedDb as aM, type PluginSettingEntry as aN, type PluginSettingOptions as aO, type PluginSettingsCapability as aP, type PluginSmsCapability as aQ, type PluginSmsProvider as aR, type PluginSmsProviderConfig as aS, type PluginSmsProviderContext as aT, type PluginSmsSendInput as aU, type PluginSmsSendResult as aV, type PluginStorageCapability as aW, type PluginStorageProvider as aX, type PluginStorageProviderConfig as aY, type PluginStorageProviderInfo as aZ, type PluginStorageUploadInput as a_, type PluginAssetQuery as aa, type PluginAssetUpdateData as ab, type PluginAssetVariant as ac, type PluginCurrencyCapability as ad, type PluginEAuthCapability as ae, type PluginEntityExtensionCapability as af, type PluginEntityExtensionFilter as ag, type PluginFileCapability as ah, type PluginFileInfo as ai, type PluginFileQuery as aj, type PluginFileUploadInput as ak, type PluginHookCapability as al, type PluginJobOptions as am, type PluginJobStatus as an, type PluginMediaCapability as ao, type PluginMediaQuery as ap, type PluginMediaUpdateData as aq, type PluginMediaUploadInput as ar, type PluginMediaVariant as as, type PluginMetricsAllowedLabels as at, type PluginMetricsCapability as au, type PluginNotificationActor as av, type PluginNotificationCapability as aw, type PluginNotificationChannel as ax, type PluginNotificationEvent as ay, type PluginNotificationInput as az, type HookHandlerOptions as b, type PluginTraceCapability as b0, type PluginUsageCapability as b1, type PluginWebCapability as b2, type ReadonlyPluginScopedDb as b3, type WebJsonPrimitive as b4, type WebJsonValue as b5, type WebPluginDocumentMode as b6, type WebPluginHead as b7, type WebPluginHeadLink as b8, type WebPluginPresentationSurfaceResult as b9, type WebPluginRouteHandler as ba, type WebPluginRouteRequest as bb, type WebPluginRouteResult as bc, type WebPluginTenantInfo as bd, type WebPresentationAdapterClientDescriptor as be, type WebResolvedPresentationAdapter as bf, type WebResolvedSitePresentation as bg, type WebResolvedSiteShell as bh, type WebResolvedThemeAsset as bi, type WebSerializableGlobalizationState as bj, type WebSlotExtensionQuery as bk, type WebSlotQueryResult as bl, type WebSlotRenderMode as bm, type WebSlotRenderOptions as bn, type WebSlotRenderRequest as bo, type WebSlotRenderResult as bp, type WebSlotRenderer as bq, type WebThemeShellClientDescriptor as br, type WebThemeShellDocumentModel as bs, type WebThemeShellRenderResult as bt, type WebThemeShellRenderer as bu, type WebThemeShellRouteModel as bv, type HookTransaction as c, type PluginLogger as d, type WebPluginSiteInfo as e, type ActionDescriptor as f, type ActionInvokeRequest as g, type AgentToolDescriptor as h, type AiAliasDescriptor as i, type AiBudget as j, type AiModelCatalog as k, type AiModelHint as l, type AiModelListRequest as m, type AiModelOption as n, type AiObjectRequest as o, type AiObjectResult as p, type AiObjectSchema as q, type AiRuntimeHandler as r, type AiRuntimeHost as s, type AiRuntimeInvocation as t, type AiStreamEvent as u, type AiTextRequest as v, type AiTextResult as w, type AiUsage as x, type AiUsageAuthorization as y, type AiUsageObservation as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordrhyme/plugin",
3
- "version": "0.1.0-alpha.11",
3
+ "version": "0.1.0-alpha.14",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -33,6 +33,12 @@
33
33
  "require": "./dist/dev-utils.js",
34
34
  "default": "./dist/dev-utils.js"
35
35
  },
36
+ "./build": {
37
+ "types": "./dist/build.d.ts",
38
+ "import": "./dist/build.js",
39
+ "require": "./dist/build.js",
40
+ "default": "./dist/build.js"
41
+ },
36
42
  "./react": {
37
43
  "types": "./dist/react.d.ts",
38
44
  "import": "./dist/react.js"
@@ -76,8 +82,9 @@
76
82
  "react": "^18.0.0 || ^19.0.0"
77
83
  },
78
84
  "devDependencies": {
79
- "react": "^19.2.1",
80
85
  "@types/react": "^19.2.14",
86
+ "@types/node": "^22.19.13",
87
+ "react": "^19.2.1",
81
88
  "tsup": "^8.3.5",
82
89
  "typescript": "^5.7.2",
83
90
  "vitest": "^4.0.18"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/dev-utils.ts"],"sourcesContent":["/**\n * Plugin Development Utilities\n * \n * Shared utilities for plugin development, including automatic port assignment.\n */\n\nexport type PluginRemoteSurface = 'admin' | 'web';\n\nexport interface PluginDevRuntimeConfig {\n enabled: boolean;\n remotePlugins: string[];\n}\n\nexport interface PluginReactOptions {\n swcReactOptions: {\n development: boolean;\n };\n}\n\nexport interface PluginReactSharedOptions {\n singleton: true;\n eager: true;\n import: false;\n requiredVersion: string;\n}\n\nexport type PluginPublicWebSharedName =\n | 'react'\n | 'react-dom'\n | 'react/jsx-runtime'\n | '@wordrhyme/plugin/react'\n | '@trpc/client'\n | '@trpc/react-query'\n | '@tanstack/react-query';\n\nexport interface ResolvedPluginRemoteEntry {\n remoteEntry: string;\n source: 'dev' | 'manifest';\n}\n\nexport interface ResolvePluginRemoteEntryOptions {\n pluginId: string;\n manifestRemoteEntry: string;\n devRemoteEntry?: string | undefined;\n surface?: PluginRemoteSurface | undefined;\n isDev?: boolean | undefined;\n devRemoteEnabled?: boolean | undefined;\n probeTimeoutMs?: number | undefined;\n probeAttempts?: number | undefined;\n probeRetryDelayMs?: number | undefined;\n entryChunkPaths?: readonly string[] | undefined;\n}\n\ninterface DevProbeCacheEntry {\n result: ResolvedPluginRemoteEntry;\n expiresAt: number;\n}\n\ninterface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\ninterface RuntimeLike {\n __WORDRHYME_PLUGIN_DEV__?: unknown;\n location?: { search?: string | undefined } | undefined;\n sessionStorage?: StorageLike | undefined;\n localStorage?: StorageLike | undefined;\n fetch?: ((url: string, init: { method: 'HEAD' | 'GET'; signal?: unknown }) => Promise<{ ok: boolean; status: number }>) | undefined;\n AbortSignal?: { timeout?: (ms: number) => unknown } | undefined;\n AbortController?: (new () => { signal: unknown; abort: () => void }) | undefined;\n setTimeout?: ((handler: () => void, timeoutMs: number) => unknown) | undefined;\n clearTimeout?: ((handle: unknown) => void) | undefined;\n}\n\nconst DEV_ADMIN_ENTRY_CHUNK_PATHS = [\n '/static/js/admin.js',\n '/static/js/src_admin_index_tsx.js',\n] as const;\n\nconst DEV_WEB_ENTRY_CHUNK_PATHS = [\n '/static/js/web.js',\n '/static/js/client.js',\n '/static/js/src_web_index_tsx.js',\n '/static/js/src_web_client_tsx.js',\n] as const;\n\nconst DEV_REMOTE_FAILURE_TTL_MS = 30_000;\nconst ACTIVE_DEV_REMOTE_PROBE_ATTEMPTS = 20;\nconst ACTIVE_DEV_REMOTE_RETRY_DELAY_MS = 250;\nconst DEV_PROBE_CACHE_STORAGE_KEY = 'wr.plugin-dev-probe-cache';\nconst DEV_REMOTE_OPT_IN_QUERY_KEY = 'pluginDevRemote';\nconst DEV_REMOTE_OPT_IN_STORAGE_KEY = 'wr.plugin-dev-remote';\nconst devProbeCache = new Map<string, DevProbeCacheEntry>();\n\n/**\n * Keep plugin remotes on the production-compatible JSX runtime even while the\n * remote dev server and React Fast Refresh are active. A prebuilt Dev Host uses\n * production React, which cannot execute react-jsx-dev-runtime safely.\n */\nexport function pluginReactOptions(): PluginReactOptions {\n return {\n swcReactOptions: {\n development: false,\n },\n };\n}\n\nexport function pluginReactShared(\n requiredVersion = '>=18.0.0 <20.0.0',\n): Record<'react' | 'react-dom' | 'react/jsx-runtime', PluginReactSharedOptions> {\n const shared = {\n singleton: true,\n eager: true,\n import: false,\n requiredVersion,\n } as const;\n\n return {\n react: { ...shared },\n 'react-dom': { ...shared },\n 'react/jsx-runtime': { ...shared },\n };\n}\n\n/**\n * Module Federation shared contract for public Web React remotes.\n *\n * The public Host injects its tRPC client into @wordrhyme/plugin/react, so Web\n * remotes must consume the Host copy of the SDK and its query dependencies.\n */\nexport function pluginPublicWebShared(\n reactRequiredVersion = '>=18.0.0 <20.0.0',\n): Record<PluginPublicWebSharedName, PluginReactSharedOptions> {\n const hostShared = {\n singleton: true,\n eager: true,\n import: false,\n requiredVersion: '*',\n } as const;\n\n return {\n ...pluginReactShared(reactRequiredVersion),\n '@wordrhyme/plugin/react': { ...hostShared },\n '@trpc/client': { ...hostShared },\n '@trpc/react-query': { ...hostShared },\n '@tanstack/react-query': { ...hostShared },\n };\n}\n\n/**\n * Calculate a deterministic dev port for a plugin based on its ID.\n * \n * This allows multiple plugins to run simultaneously without port conflicts,\n * while keeping the port assignment automatic and predictable.\n * \n * Port range: 3010-3109 (100 possible ports)\n * \n * @param pluginId - Full plugin ID (e.g., \"com.wordrhyme.hello-world\")\n * @returns Port number for the plugin's dev server\n * \n * @example\n * getPluginDevPort('com.wordrhyme.hello-world') // e.g., 3042\n * getPluginDevPort('com.wordrhyme.analytics') // e.g., 3015\n */\nexport function getPluginDevPort(pluginId: string): number {\n const BASE_PORT = 3010;\n const PORT_RANGE = 100;\n\n // Simple hash based on character codes\n const hash = pluginId.split('').reduce((acc, char) => {\n return acc + char.charCodeAt(0);\n }, 0);\n\n return BASE_PORT + (hash % PORT_RANGE);\n}\n\n/**\n * Get the dev remote entry URL for a plugin.\n * \n * @param pluginId - Full plugin ID\n * @returns Full URL to the plugin's remoteEntry.js in dev mode\n */\nexport function getPluginDevRemoteEntry(pluginId: string): string {\n const port = getPluginDevPort(pluginId);\n return `http://localhost:${port}/remoteEntry.js`;\n}\n\n/**\n * Calculate a deterministic public web dev port for a plugin.\n *\n * Public web remotes run beside admin remotes, so they use the same stable\n * plugin hash with a +100 offset.\n */\nexport function getPluginWebDevPort(pluginId: string): number {\n return getPluginDevPort(pluginId) + 100;\n}\n\n/**\n * Get the public web dev remote entry URL for a plugin.\n */\nexport function getPluginWebDevRemoteEntry(pluginId: string): string {\n return `http://localhost:${getPluginWebDevPort(pluginId)}/remoteEntry.js`;\n}\n\n/**\n * Normalize plugin ID to a valid Module Federation name.\n * \n * MF names must be valid JavaScript identifiers.\n * \"com.wordrhyme.hello-world\" → \"plugin_hello_world\"\n * \n * @param pluginId - Full plugin ID\n * @returns Valid MF module name\n */\nexport function getPluginMfName(pluginId: string): string {\n // Keep the established short name for official plugins, while accepting\n // every valid reverse-domain plugin id from the public Plugin Contract.\n const shortId = pluginId.replace(/^com\\.wordrhyme\\./, '');\n const normalized = shortId.replace(/[^a-zA-Z0-9_$]/g, '_');\n return `plugin_${normalized}`;\n}\n\nfunction runtime(): RuntimeLike {\n return globalThis as unknown as RuntimeLike;\n}\n\nfunction readQueryValue(search: string | undefined, key: string): string | null {\n const query = search?.replace(/^\\?/, '');\n if (!query) return null;\n\n for (const part of query.split('&')) {\n const [rawKey, rawValue = ''] = part.split('=');\n if (!rawKey) continue;\n try {\n if (decodeURIComponent(rawKey.replace(/\\+/g, ' ')) === key) {\n return decodeURIComponent(rawValue.replace(/\\+/g, ' '));\n }\n } catch {\n if (rawKey === key) return rawValue;\n }\n }\n\n return null;\n}\n\nfunction matchesPluginOptIn(rawValue: string | null, pluginId: string): boolean {\n const value = rawValue?.trim();\n if (!value) return false;\n\n return value === '1'\n || value.toLowerCase() === 'true'\n || value.toLowerCase() === 'all'\n || value === pluginId;\n}\n\nexport function isPluginListed(pluginId: string, rawValue: unknown): boolean {\n return parsePluginList(rawValue).includes(pluginId);\n}\n\nexport function parsePluginList(rawValue: unknown): string[] {\n if (typeof rawValue !== 'string') return [];\n\n return Array.from(new Set(\n rawValue\n .split(',')\n .map((value) => value.trim())\n .filter(Boolean),\n ));\n}\n\nexport function getPluginDevRuntimeConfig(): PluginDevRuntimeConfig {\n const value = runtime().__WORDRHYME_PLUGIN_DEV__;\n if (!value || typeof value !== 'object') {\n return { enabled: false, remotePlugins: [] };\n }\n\n const config = value as { enabled?: unknown; remotePlugins?: unknown };\n const remotePlugins = Array.isArray(config.remotePlugins)\n ? Array.from(new Set(config.remotePlugins.filter((pluginId): pluginId is string => (\n typeof pluginId === 'string' && pluginId.trim().length > 0\n )).map((pluginId) => pluginId.trim())))\n : parsePluginList(config.remotePlugins);\n\n return {\n enabled: config.enabled === true,\n remotePlugins,\n };\n}\n\nexport function isPluginDevRemoteSelected(pluginId: string): boolean {\n const config = getPluginDevRuntimeConfig();\n return config.enabled && config.remotePlugins.includes(pluginId);\n}\n\nexport function isPluginDevRemoteEnabled(pluginId: string): boolean {\n const host = runtime();\n if (matchesPluginOptIn(readQueryValue(host.location?.search, DEV_REMOTE_OPT_IN_QUERY_KEY), pluginId)) {\n return true;\n }\n\n try {\n if (matchesPluginOptIn(host.sessionStorage?.getItem(DEV_REMOTE_OPT_IN_STORAGE_KEY) ?? null, pluginId)) {\n return true;\n }\n } catch {\n // Ignore storage access failures.\n }\n\n try {\n if (matchesPluginOptIn(host.localStorage?.getItem(DEV_REMOTE_OPT_IN_STORAGE_KEY) ?? null, pluginId)) {\n return true;\n }\n } catch {\n // Ignore storage access failures.\n }\n\n return false;\n}\n\nfunction readStoredProbeCache(): Record<string, DevProbeCacheEntry> {\n try {\n const raw = runtime().sessionStorage?.getItem(DEV_PROBE_CACHE_STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as Record<string, DevProbeCacheEntry> | null;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeStoredProbeCache(cache: Record<string, DevProbeCacheEntry>) {\n try {\n runtime().sessionStorage?.setItem(DEV_PROBE_CACHE_STORAGE_KEY, JSON.stringify(cache));\n } catch {\n // Ignore storage failures and rely on in-memory cache.\n }\n}\n\nfunction probeCacheKey(surface: PluginRemoteSurface, pluginId: string, devRemoteEntry: string): string {\n return `${surface}:${pluginId}:${devRemoteEntry}`;\n}\n\nfunction getCachedProbeResult(key: string, now: number): ResolvedPluginRemoteEntry | null {\n const cached = devProbeCache.get(key);\n if (cached) {\n if (cached.expiresAt <= now) {\n devProbeCache.delete(key);\n } else {\n return cached.result;\n }\n }\n\n const storedCache = readStoredProbeCache();\n const stored = storedCache[key];\n if (!stored) return null;\n if (stored.expiresAt <= now) {\n delete storedCache[key];\n writeStoredProbeCache(storedCache);\n devProbeCache.delete(key);\n return null;\n }\n devProbeCache.set(key, stored);\n return stored.result;\n}\n\nfunction cacheProbeResult(key: string, result: ResolvedPluginRemoteEntry, ttlMs: number) {\n const entry = {\n result,\n expiresAt: Date.now() + ttlMs,\n };\n devProbeCache.set(key, entry);\n\n const storedCache = readStoredProbeCache();\n storedCache[key] = entry;\n writeStoredProbeCache(storedCache);\n}\n\nfunction createTimeoutSignal(timeoutMs: number): { signal?: unknown; cleanup: () => void } {\n const host = runtime();\n const timeout = host.AbortSignal?.timeout;\n if (timeout) {\n return { signal: timeout(timeoutMs), cleanup: () => {} };\n }\n\n const Controller = host.AbortController;\n if (!Controller || !host.setTimeout || !host.clearTimeout) {\n return { cleanup: () => {} };\n }\n\n const probeController = new Controller();\n const timeoutId = host.setTimeout(() => probeController.abort(), timeoutMs);\n return {\n signal: probeController.signal,\n cleanup: () => host.clearTimeout?.(timeoutId),\n };\n}\n\nfunction waitForRetry(delayMs: number): Promise<void> {\n const schedule = runtime().setTimeout;\n if (!schedule || delayMs <= 0) return Promise.resolve();\n\n return new Promise((resolve) => {\n schedule(() => resolve(), delayMs);\n });\n}\n\nfunction resolveChunkUrl(path: string, devRemoteEntry: string): string {\n const originMatch = devRemoteEntry.match(/^(https?:\\/\\/[^/?#]+)(?:[/?#]|$)/);\n if (originMatch?.[1] && path.startsWith('/')) {\n return `${originMatch[1]}${path}`;\n }\n\n const base = devRemoteEntry.replace(/[?#].*$/, '').replace(/\\/[^/]*$/, '/');\n return `${base}${path.replace(/^\\//, '')}`;\n}\n\nasync function requestOk(url: string, signal: unknown): Promise<boolean> {\n const fetcher = runtime().fetch;\n if (!fetcher) return false;\n\n const response = await fetcher(url, {\n method: 'HEAD',\n ...(signal ? { signal } : {}),\n });\n\n if (response.ok) return true;\n if (response.status !== 405) return false;\n\n const fallbackResponse = await fetcher(url, {\n method: 'GET',\n ...(signal ? { signal } : {}),\n });\n return fallbackResponse.ok;\n}\n\nasync function canLoadDevRemote(\n devRemoteEntry: string,\n surface: PluginRemoteSurface,\n signal: unknown,\n entryChunkPaths?: readonly string[] | undefined,\n): Promise<boolean> {\n if (!await requestOk(devRemoteEntry, signal)) {\n return false;\n }\n\n const chunkPaths = entryChunkPaths\n ?? (surface === 'web' ? DEV_WEB_ENTRY_CHUNK_PATHS : DEV_ADMIN_ENTRY_CHUNK_PATHS);\n for (const path of chunkPaths) {\n if (await requestOk(resolveChunkUrl(path, devRemoteEntry), signal)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction defaultDevRemoteEntry(pluginId: string, surface: PluginRemoteSurface): string {\n return surface === 'web'\n ? getPluginWebDevRemoteEntry(pluginId)\n : getPluginDevRemoteEntry(pluginId);\n}\n\nexport async function resolvePluginRemoteEntry({\n pluginId,\n manifestRemoteEntry,\n devRemoteEntry,\n surface = 'admin',\n isDev = false,\n devRemoteEnabled = false,\n probeTimeoutMs = 1500,\n probeAttempts,\n probeRetryDelayMs = ACTIVE_DEV_REMOTE_RETRY_DELAY_MS,\n entryChunkPaths,\n}: ResolvePluginRemoteEntryOptions): Promise<ResolvedPluginRemoteEntry> {\n const manifestResult = {\n remoteEntry: manifestRemoteEntry,\n source: 'manifest',\n } as const;\n\n if (!isDev || (!devRemoteEnabled && !isPluginDevRemoteEnabled(pluginId))) {\n return manifestResult;\n }\n\n const devUrl = devRemoteEntry?.trim() || defaultDevRemoteEntry(pluginId, surface);\n const cacheKey = probeCacheKey(surface, pluginId, devUrl);\n const cachedResult = getCachedProbeResult(cacheKey, Date.now());\n if (cachedResult && !(devRemoteEnabled && cachedResult.source === 'manifest')) {\n return cachedResult;\n }\n\n const attempts = Math.max(\n 1,\n Math.trunc(probeAttempts ?? (devRemoteEnabled ? ACTIVE_DEV_REMOTE_PROBE_ATTEMPTS : 1)),\n );\n\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n const { signal, cleanup } = createTimeoutSignal(probeTimeoutMs);\n\n try {\n if (await canLoadDevRemote(devUrl, surface, signal, entryChunkPaths)) {\n return {\n remoteEntry: devUrl,\n source: 'dev',\n };\n }\n } catch {\n // The selected dev process may still be starting. Retry below when explicitly active.\n } finally {\n cleanup();\n }\n\n if (attempt + 1 < attempts) {\n await waitForRetry(probeRetryDelayMs);\n }\n }\n\n console.info(`[Plugin] ${pluginId}: ${surface} dev server 不在线,使用预构建静态文件`);\n if (!devRemoteEnabled) {\n cacheProbeResult(cacheKey, manifestResult, DEV_REMOTE_FAILURE_TTL_MS);\n }\n return manifestResult;\n}\n\nexport function appendRemoteEntryCacheBust(remoteEntry: string, value: string | number): string {\n const separator = remoteEntry.includes('?') ? '&' : '?';\n return `${remoteEntry}${separator}t=${encodeURIComponent(String(value))}`;\n}\n"],"mappings":";AA2EA,IAAM,8BAA8B;AAAA,EAChC;AAAA,EACA;AACJ;AAEA,IAAM,4BAA4B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEA,IAAM,4BAA4B;AAClC,IAAM,mCAAmC;AACzC,IAAM,mCAAmC;AACzC,IAAM,8BAA8B;AACpC,IAAM,8BAA8B;AACpC,IAAM,gCAAgC;AACtC,IAAM,gBAAgB,oBAAI,IAAgC;AAOnD,SAAS,qBAAyC;AACrD,SAAO;AAAA,IACH,iBAAiB;AAAA,MACb,aAAa;AAAA,IACjB;AAAA,EACJ;AACJ;AAEO,SAAS,kBACZ,kBAAkB,oBAC2D;AAC7E,QAAM,SAAS;AAAA,IACX,WAAW;AAAA,IACX,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,EACJ;AAEA,SAAO;AAAA,IACH,OAAO,EAAE,GAAG,OAAO;AAAA,IACnB,aAAa,EAAE,GAAG,OAAO;AAAA,IACzB,qBAAqB,EAAE,GAAG,OAAO;AAAA,EACrC;AACJ;AAQO,SAAS,sBACZ,uBAAuB,oBACoC;AAC3D,QAAM,aAAa;AAAA,IACf,WAAW;AAAA,IACX,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,EACrB;AAEA,SAAO;AAAA,IACH,GAAG,kBAAkB,oBAAoB;AAAA,IACzC,2BAA2B,EAAE,GAAG,WAAW;AAAA,IAC3C,gBAAgB,EAAE,GAAG,WAAW;AAAA,IAChC,qBAAqB,EAAE,GAAG,WAAW;AAAA,IACrC,yBAAyB,EAAE,GAAG,WAAW;AAAA,EAC7C;AACJ;AAiBO,SAAS,iBAAiB,UAA0B;AACvD,QAAM,YAAY;AAClB,QAAM,aAAa;AAGnB,QAAM,OAAO,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,SAAS;AAClD,WAAO,MAAM,KAAK,WAAW,CAAC;AAAA,EAClC,GAAG,CAAC;AAEJ,SAAO,YAAa,OAAO;AAC/B;AAQO,SAAS,wBAAwB,UAA0B;AAC9D,QAAM,OAAO,iBAAiB,QAAQ;AACtC,SAAO,oBAAoB,IAAI;AACnC;AAQO,SAAS,oBAAoB,UAA0B;AAC1D,SAAO,iBAAiB,QAAQ,IAAI;AACxC;AAKO,SAAS,2BAA2B,UAA0B;AACjE,SAAO,oBAAoB,oBAAoB,QAAQ,CAAC;AAC5D;AAWO,SAAS,gBAAgB,UAA0B;AAGtD,QAAM,UAAU,SAAS,QAAQ,qBAAqB,EAAE;AACxD,QAAM,aAAa,QAAQ,QAAQ,mBAAmB,GAAG;AACzD,SAAO,UAAU,UAAU;AAC/B;AAEA,SAAS,UAAuB;AAC5B,SAAO;AACX;AAEA,SAAS,eAAe,QAA4B,KAA4B;AAC5E,QAAM,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AACvC,MAAI,CAAC,MAAO,QAAO;AAEnB,aAAW,QAAQ,MAAM,MAAM,GAAG,GAAG;AACjC,UAAM,CAAC,QAAQ,WAAW,EAAE,IAAI,KAAK,MAAM,GAAG;AAC9C,QAAI,CAAC,OAAQ;AACb,QAAI;AACA,UAAI,mBAAmB,OAAO,QAAQ,OAAO,GAAG,CAAC,MAAM,KAAK;AACxD,eAAO,mBAAmB,SAAS,QAAQ,OAAO,GAAG,CAAC;AAAA,MAC1D;AAAA,IACJ,QAAQ;AACJ,UAAI,WAAW,IAAK,QAAO;AAAA,IAC/B;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,SAAS,mBAAmB,UAAyB,UAA2B;AAC5E,QAAM,QAAQ,UAAU,KAAK;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,SAAO,UAAU,OACV,MAAM,YAAY,MAAM,UACxB,MAAM,YAAY,MAAM,SACxB,UAAU;AACrB;AAEO,SAAS,eAAe,UAAkB,UAA4B;AACzE,SAAO,gBAAgB,QAAQ,EAAE,SAAS,QAAQ;AACtD;AAEO,SAAS,gBAAgB,UAA6B;AACzD,MAAI,OAAO,aAAa,SAAU,QAAO,CAAC;AAE1C,SAAO,MAAM,KAAK,IAAI;AAAA,IAClB,SACK,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,OAAO;AAAA,EACvB,CAAC;AACL;AAEO,SAAS,4BAAoD;AAChE,QAAM,QAAQ,QAAQ,EAAE;AACxB,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACrC,WAAO,EAAE,SAAS,OAAO,eAAe,CAAC,EAAE;AAAA,EAC/C;AAEA,QAAM,SAAS;AACf,QAAM,gBAAgB,MAAM,QAAQ,OAAO,aAAa,IAClD,MAAM,KAAK,IAAI,IAAI,OAAO,cAAc,OAAO,CAAC,aAC9C,OAAO,aAAa,YAAY,SAAS,KAAK,EAAE,SAAS,CAC5D,EAAE,IAAI,CAAC,aAAa,SAAS,KAAK,CAAC,CAAC,CAAC,IACpC,gBAAgB,OAAO,aAAa;AAE1C,SAAO;AAAA,IACH,SAAS,OAAO,YAAY;AAAA,IAC5B;AAAA,EACJ;AACJ;AAEO,SAAS,0BAA0B,UAA2B;AACjE,QAAM,SAAS,0BAA0B;AACzC,SAAO,OAAO,WAAW,OAAO,cAAc,SAAS,QAAQ;AACnE;AAEO,SAAS,yBAAyB,UAA2B;AAChE,QAAM,OAAO,QAAQ;AACrB,MAAI,mBAAmB,eAAe,KAAK,UAAU,QAAQ,2BAA2B,GAAG,QAAQ,GAAG;AAClG,WAAO;AAAA,EACX;AAEA,MAAI;AACA,QAAI,mBAAmB,KAAK,gBAAgB,QAAQ,6BAA6B,KAAK,MAAM,QAAQ,GAAG;AACnG,aAAO;AAAA,IACX;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,MAAI;AACA,QAAI,mBAAmB,KAAK,cAAc,QAAQ,6BAA6B,KAAK,MAAM,QAAQ,GAAG;AACjG,aAAO;AAAA,IACX;AAAA,EACJ,QAAQ;AAAA,EAER;AAEA,SAAO;AACX;AAEA,SAAS,uBAA2D;AAChE,MAAI;AACA,UAAM,MAAM,QAAQ,EAAE,gBAAgB,QAAQ,2BAA2B;AACzE,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,UAAU,OAAO,WAAW,WAAW,SAAS,CAAC;AAAA,EAC5D,QAAQ;AACJ,WAAO,CAAC;AAAA,EACZ;AACJ;AAEA,SAAS,sBAAsB,OAA2C;AACtE,MAAI;AACA,YAAQ,EAAE,gBAAgB,QAAQ,6BAA6B,KAAK,UAAU,KAAK,CAAC;AAAA,EACxF,QAAQ;AAAA,EAER;AACJ;AAEA,SAAS,cAAc,SAA8B,UAAkB,gBAAgC;AACnG,SAAO,GAAG,OAAO,IAAI,QAAQ,IAAI,cAAc;AACnD;AAEA,SAAS,qBAAqB,KAAa,KAA+C;AACtF,QAAM,SAAS,cAAc,IAAI,GAAG;AACpC,MAAI,QAAQ;AACR,QAAI,OAAO,aAAa,KAAK;AACzB,oBAAc,OAAO,GAAG;AAAA,IAC5B,OAAO;AACH,aAAO,OAAO;AAAA,IAClB;AAAA,EACJ;AAEA,QAAM,cAAc,qBAAqB;AACzC,QAAM,SAAS,YAAY,GAAG;AAC9B,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,aAAa,KAAK;AACzB,WAAO,YAAY,GAAG;AACtB,0BAAsB,WAAW;AACjC,kBAAc,OAAO,GAAG;AACxB,WAAO;AAAA,EACX;AACA,gBAAc,IAAI,KAAK,MAAM;AAC7B,SAAO,OAAO;AAClB;AAEA,SAAS,iBAAiB,KAAa,QAAmC,OAAe;AACrF,QAAM,QAAQ;AAAA,IACV;AAAA,IACA,WAAW,KAAK,IAAI,IAAI;AAAA,EAC5B;AACA,gBAAc,IAAI,KAAK,KAAK;AAE5B,QAAM,cAAc,qBAAqB;AACzC,cAAY,GAAG,IAAI;AACnB,wBAAsB,WAAW;AACrC;AAEA,SAAS,oBAAoB,WAA8D;AACvF,QAAM,OAAO,QAAQ;AACrB,QAAM,UAAU,KAAK,aAAa;AAClC,MAAI,SAAS;AACT,WAAO,EAAE,QAAQ,QAAQ,SAAS,GAAG,SAAS,MAAM;AAAA,IAAC,EAAE;AAAA,EAC3D;AAEA,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,cAAc,CAAC,KAAK,cAAc,CAAC,KAAK,cAAc;AACvD,WAAO,EAAE,SAAS,MAAM;AAAA,IAAC,EAAE;AAAA,EAC/B;AAEA,QAAM,kBAAkB,IAAI,WAAW;AACvC,QAAM,YAAY,KAAK,WAAW,MAAM,gBAAgB,MAAM,GAAG,SAAS;AAC1E,SAAO;AAAA,IACH,QAAQ,gBAAgB;AAAA,IACxB,SAAS,MAAM,KAAK,eAAe,SAAS;AAAA,EAChD;AACJ;AAEA,SAAS,aAAa,SAAgC;AAClD,QAAM,WAAW,QAAQ,EAAE;AAC3B,MAAI,CAAC,YAAY,WAAW,EAAG,QAAO,QAAQ,QAAQ;AAEtD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC5B,aAAS,MAAM,QAAQ,GAAG,OAAO;AAAA,EACrC,CAAC;AACL;AAEA,SAAS,gBAAgB,MAAc,gBAAgC;AACnE,QAAM,cAAc,eAAe,MAAM,kCAAkC;AAC3E,MAAI,cAAc,CAAC,KAAK,KAAK,WAAW,GAAG,GAAG;AAC1C,WAAO,GAAG,YAAY,CAAC,CAAC,GAAG,IAAI;AAAA,EACnC;AAEA,QAAM,OAAO,eAAe,QAAQ,WAAW,EAAE,EAAE,QAAQ,YAAY,GAAG;AAC1E,SAAO,GAAG,IAAI,GAAG,KAAK,QAAQ,OAAO,EAAE,CAAC;AAC5C;AAEA,eAAe,UAAU,KAAa,QAAmC;AACrE,QAAM,UAAU,QAAQ,EAAE;AAC1B,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC/B,CAAC;AAED,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,SAAS,WAAW,IAAK,QAAO;AAEpC,QAAM,mBAAmB,MAAM,QAAQ,KAAK;AAAA,IACxC,QAAQ;AAAA,IACR,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC/B,CAAC;AACD,SAAO,iBAAiB;AAC5B;AAEA,eAAe,iBACX,gBACA,SACA,QACA,iBACgB;AAChB,MAAI,CAAC,MAAM,UAAU,gBAAgB,MAAM,GAAG;AAC1C,WAAO;AAAA,EACX;AAEA,QAAM,aAAa,oBACX,YAAY,QAAQ,4BAA4B;AACxD,aAAW,QAAQ,YAAY;AAC3B,QAAI,MAAM,UAAU,gBAAgB,MAAM,cAAc,GAAG,MAAM,GAAG;AAChE,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,SAAS,sBAAsB,UAAkB,SAAsC;AACnF,SAAO,YAAY,QACb,2BAA2B,QAAQ,IACnC,wBAAwB,QAAQ;AAC1C;AAEA,eAAsB,yBAAyB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB;AAAA,EACA,oBAAoB;AAAA,EACpB;AACJ,GAAwE;AACpE,QAAM,iBAAiB;AAAA,IACnB,aAAa;AAAA,IACb,QAAQ;AAAA,EACZ;AAEA,MAAI,CAAC,SAAU,CAAC,oBAAoB,CAAC,yBAAyB,QAAQ,GAAI;AACtE,WAAO;AAAA,EACX;AAEA,QAAM,SAAS,gBAAgB,KAAK,KAAK,sBAAsB,UAAU,OAAO;AAChF,QAAM,WAAW,cAAc,SAAS,UAAU,MAAM;AACxD,QAAM,eAAe,qBAAqB,UAAU,KAAK,IAAI,CAAC;AAC9D,MAAI,gBAAgB,EAAE,oBAAoB,aAAa,WAAW,aAAa;AAC3E,WAAO;AAAA,EACX;AAEA,QAAM,WAAW,KAAK;AAAA,IAClB;AAAA,IACA,KAAK,MAAM,kBAAkB,mBAAmB,mCAAmC,EAAE;AAAA,EACzF;AAEA,WAAS,UAAU,GAAG,UAAU,UAAU,WAAW,GAAG;AACpD,UAAM,EAAE,QAAQ,QAAQ,IAAI,oBAAoB,cAAc;AAE9D,QAAI;AACA,UAAI,MAAM,iBAAiB,QAAQ,SAAS,QAAQ,eAAe,GAAG;AAClE,eAAO;AAAA,UACH,aAAa;AAAA,UACb,QAAQ;AAAA,QACZ;AAAA,MACJ;AAAA,IACJ,QAAQ;AAAA,IAER,UAAE;AACE,cAAQ;AAAA,IACZ;AAEA,QAAI,UAAU,IAAI,UAAU;AACxB,YAAM,aAAa,iBAAiB;AAAA,IACxC;AAAA,EACJ;AAEA,UAAQ,KAAK,YAAY,QAAQ,KAAK,OAAO,4FAA2B;AACxE,MAAI,CAAC,kBAAkB;AACnB,qBAAiB,UAAU,gBAAgB,yBAAyB;AAAA,EACxE;AACA,SAAO;AACX;AAEO,SAAS,2BAA2B,aAAqB,OAAgC;AAC5F,QAAM,YAAY,YAAY,SAAS,GAAG,IAAI,MAAM;AACpD,SAAO,GAAG,WAAW,GAAG,SAAS,KAAK,mBAAmB,OAAO,KAAK,CAAC,CAAC;AAC3E;","names":[]}