@world-engines/agent-kit 0.1.0-alpha.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/LICENSE +46 -0
- package/assets/README.md +58 -0
- package/assets/docs/development/README.md +25 -0
- package/assets/docs/development/authoring-bridge.md +52 -0
- package/assets/docs/development/authoring-workflows.md +48 -0
- package/assets/docs/development/chatplay-view.md +111 -0
- package/assets/docs/development/cli.md +145 -0
- package/assets/docs/development/desktop-transfer-security.md +46 -0
- package/assets/docs/development/generated/authoring-bridge-contract.json +598 -0
- package/assets/docs/development/generated/authoring-bridge-contract.md +660 -0
- package/assets/docs/development/generated/chatplay-sdk/SOURCE.json +10 -0
- package/assets/docs/development/generated/chatplay-sdk/chatplay-sdk.d.ts +309 -0
- package/assets/docs/development/generated/chatplay-sdk/descriptor.json +699 -0
- package/assets/docs/development/generated/chatplay-sdk/descriptor.md +363 -0
- package/assets/docs/development/installation-and-structure.md +70 -0
- package/assets/docs/development/local-gui.md +94 -0
- package/assets/docs/development/scene-authoring.md +74 -0
- package/assets/guides/long-form-ladybug-trigger.md +98 -0
- package/assets/launchers/worldengine-codex.ps1 +105 -0
- package/assets/launchers/worldengine-mcp.cmd +5 -0
- package/assets/launchers/worldengine-npm.cjs +18 -0
- package/assets/launchers/worldengine.cmd +39 -0
- package/assets/prompts/local-author-system.md +40 -0
- package/assets/skills/caveman/LICENSE.md +13 -0
- package/assets/skills/caveman/SKILL.md +50 -0
- package/assets/skills/caveman/SOURCE.md +9 -0
- package/assets/skills/diagnose/SKILL.md +118 -0
- package/assets/skills/diagnose/SOURCE.md +3 -0
- package/assets/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
- package/assets/skills/i-have-adhd/LICENSE.md +9 -0
- package/assets/skills/i-have-adhd/SKILL.md +139 -0
- package/assets/skills/i-have-adhd/SOURCE.md +9 -0
- package/assets/skills/i-have-adhd/agents/gemini.toml +24 -0
- package/assets/skills/i-have-adhd/agents/openai.yaml +7 -0
- package/assets/skills/improve-codebase-architecture/DEEPENING.md +37 -0
- package/assets/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
- package/assets/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
- package/assets/skills/improve-codebase-architecture/SKILL.md +72 -0
- package/assets/skills/improve-codebase-architecture/SOURCE.md +3 -0
- package/assets/skills/lossless-document-authoring/SKILL.md +45 -0
- package/assets/skills/lossless-document-authoring/references/d4f-workflow.md +155 -0
- package/assets/skills/platform-conversion/SKILL.md +23 -0
- package/assets/skills/platform-conversion/references/scenario-conversion.md +17 -0
- package/assets/skills/platform-conversion/references/view-conversion.md +19 -0
- package/assets/skills/setup-matt-pocock-skills/LICENSE.md +9 -0
- package/assets/skills/setup-matt-pocock-skills/SKILL.md +122 -0
- package/assets/skills/setup-matt-pocock-skills/SOURCE.md +11 -0
- package/assets/skills/setup-matt-pocock-skills/domain.md +51 -0
- package/assets/skills/setup-matt-pocock-skills/issue-tracker-github.md +22 -0
- package/assets/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +23 -0
- package/assets/skills/setup-matt-pocock-skills/issue-tracker-local.md +19 -0
- package/assets/skills/setup-matt-pocock-skills/triage-labels.md +15 -0
- package/assets/skills/tdd/SKILL.md +110 -0
- package/assets/skills/tdd/SOURCE.md +3 -0
- package/assets/skills/tdd/deep-modules.md +33 -0
- package/assets/skills/tdd/interface-design.md +31 -0
- package/assets/skills/tdd/mocking.md +59 -0
- package/assets/skills/tdd/refactoring.md +10 -0
- package/assets/skills/tdd/tests.md +61 -0
- package/assets/skills/to-issues/SKILL.md +90 -0
- package/assets/skills/to-issues/SOURCE.md +3 -0
- package/assets/skills/to-prd/SKILL.md +77 -0
- package/assets/skills/to-prd/SOURCE.md +3 -0
- package/assets/skills/triage/AGENT-BRIEF.md +168 -0
- package/assets/skills/triage/OUT-OF-SCOPE.md +101 -0
- package/assets/skills/triage/SKILL.md +104 -0
- package/assets/skills/triage/SOURCE.md +3 -0
- package/assets/skills/zoom-out/SKILL.md +8 -0
- package/assets/skills/zoom-out/SOURCE.md +3 -0
- package/assets/skills-disabled/chat-authority-recovery/SKILL.md +8 -0
- package/assets/skills-disabled/codepicker/SKILL.md +8 -0
- package/assets/skills-disabled/pacemaker/SKILL.md +8 -0
- package/assets/skills-disabled/project-spec-ticket-orchestration/SKILL.md +8 -0
- package/assets/skills-disabled/release-deployment-auditor/SKILL.md +8 -0
- package/dist/index.d.ts +132 -0
- package/dist/index.js +382 -0
- package/package.json +51 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// AUTO-GENERATED by tools/gen-chatplay-sdk-descriptor.mjs
|
|
2
|
+
// Runtime 3.1; 请勿手改 使用 --release 3.1 生成
|
|
3
|
+
// 关联 ADR docs/adr/0105-editor-sdk-awareness.md
|
|
4
|
+
// 真源 src/player-client/ui-shell/src/chat-play-sdk/runtime.ts 注入对象图
|
|
5
|
+
// 消费侧 WebContainer 子工程 tsconfig.json include + IDE TypeScript LSP
|
|
6
|
+
|
|
7
|
+
export interface SdkCapabilities {
|
|
8
|
+
readonly schemaVersion: number;
|
|
9
|
+
readonly capabilitiesShapeVersion: number;
|
|
10
|
+
readonly runtimeMajor: number;
|
|
11
|
+
readonly runtimePatch: number;
|
|
12
|
+
readonly protocolVersion: number;
|
|
13
|
+
readonly customStateMaxBytes: number;
|
|
14
|
+
readonly assetMaxBytes: number;
|
|
15
|
+
readonly supportsAssets: boolean;
|
|
16
|
+
readonly supportsEdit: boolean;
|
|
17
|
+
readonly supportsDelete: boolean;
|
|
18
|
+
readonly supportsWorldlines?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ChatPlayContext {
|
|
22
|
+
readonly scriptId: string;
|
|
23
|
+
readonly saveId: string;
|
|
24
|
+
readonly locale: string;
|
|
25
|
+
readonly theme: ThemeSnapshot;
|
|
26
|
+
readonly capabilities: SdkCapabilities;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type CustomStateScope = 'public' | 'protected';
|
|
30
|
+
export interface CustomStateEntry<T = unknown> {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly value: T;
|
|
33
|
+
readonly scope: CustomStateScope;
|
|
34
|
+
readonly authorizedUserIds: ReadonlyArray<string>;
|
|
35
|
+
readonly revision: number;
|
|
36
|
+
}
|
|
37
|
+
export interface CustomStateCommitResult {
|
|
38
|
+
readonly generation: number;
|
|
39
|
+
readonly changedKeys: ReadonlyArray<string>;
|
|
40
|
+
readonly entries: ReadonlyArray<CustomStateEntry>;
|
|
41
|
+
readonly replayed: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface CustomStateApi {
|
|
44
|
+
get<T = unknown>(key: string): Promise<CustomStateEntry<T> | undefined>;
|
|
45
|
+
set(key: string, value: unknown, options?: { readonly scope?: CustomStateScope; readonly authorizedUserIds?: ReadonlyArray<string> }): Promise<{ readonly ok: true; readonly generation: number }>;
|
|
46
|
+
delete(key: string): Promise<{ readonly ok: true; readonly generation: number }>;
|
|
47
|
+
keys(): Promise<string[]>;
|
|
48
|
+
commitBatch(batch: { readonly idempotencyKey: string; readonly expectedGeneration?: number; readonly mutations: ReadonlyArray<unknown> }): Promise<CustomStateCommitResult>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ReadonlyCustomStateApi {
|
|
52
|
+
get<T = unknown>(key: string): Promise<CustomStateEntry<T> | undefined>;
|
|
53
|
+
keys(): Promise<string[]>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface CustomStateChangedEvent {
|
|
57
|
+
readonly generation: number;
|
|
58
|
+
readonly changedKeys: ReadonlyArray<string>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type TmwViewJsonValue =
|
|
62
|
+
| null
|
|
63
|
+
| boolean
|
|
64
|
+
| number
|
|
65
|
+
| string
|
|
66
|
+
| readonly TmwViewJsonValue[]
|
|
67
|
+
| { readonly [key: string]: TmwViewJsonValue };
|
|
68
|
+
|
|
69
|
+
export interface TmwViewEventEmitReceipt {
|
|
70
|
+
readonly interactionId: string;
|
|
71
|
+
readonly nonce: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface TmwInteractionResult {
|
|
75
|
+
readonly interactionId: string;
|
|
76
|
+
readonly nonce: string;
|
|
77
|
+
readonly status: 'committed' | 'failed' | 'uncertain';
|
|
78
|
+
readonly code?: 'activation_failed' | 'activation_unconfirmed' | 'commit_sink_unavailable';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface TmwViewEventsApi {
|
|
82
|
+
emit(eventType: string, payload: Readonly<Record<string, TmwViewJsonValue>>, interactionId: string): TmwViewEventEmitReceipt;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** manifest 声明的 committed-event 下行投影;opaqueId 仅可用于去重。 */
|
|
86
|
+
export interface TmwDelivery {
|
|
87
|
+
readonly deliveryId: string;
|
|
88
|
+
readonly eventType: string;
|
|
89
|
+
readonly payload: Readonly<Record<string, null | boolean | number | string>>;
|
|
90
|
+
readonly opaqueId: string;
|
|
91
|
+
}
|
|
92
|
+
export type ThemeChoice = 'light' | 'dark' | 'system';
|
|
93
|
+
export type ResolvedTheme = 'light' | 'dark';
|
|
94
|
+
export interface ThemeSnapshot {
|
|
95
|
+
readonly choice: ThemeChoice;
|
|
96
|
+
readonly resolved: ResolvedTheme;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface PersistedListItem {
|
|
100
|
+
readonly id: string;
|
|
101
|
+
readonly saveId: string;
|
|
102
|
+
readonly role: 'user' | 'assistant' | 'system' | 'tool';
|
|
103
|
+
readonly text: string;
|
|
104
|
+
readonly ts: number;
|
|
105
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface SendHandle {
|
|
109
|
+
readonly messageId: Promise<string>;
|
|
110
|
+
readonly stream: ReadableStream<{ delta: string }>;
|
|
111
|
+
readonly done: Promise<{ fullContent: string }>;
|
|
112
|
+
abort(reason?: string): void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface RegenerateHandle extends SendHandle {
|
|
116
|
+
readonly rollback: Promise<{
|
|
117
|
+
readonly removedMessageIds: ReadonlyArray<string>;
|
|
118
|
+
readonly deletedEntities: number;
|
|
119
|
+
readonly deletedRelations: number;
|
|
120
|
+
}>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface EditAssistantMessageResult {
|
|
124
|
+
readonly kind: "assistant";
|
|
125
|
+
readonly removedMessageIds: ReadonlyArray<string>;
|
|
126
|
+
readonly deletedEntities: number;
|
|
127
|
+
readonly deletedRelations: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface EditUserMessageResult {
|
|
131
|
+
readonly kind: "user";
|
|
132
|
+
readonly id: string;
|
|
133
|
+
readonly content: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface AssetRecord {
|
|
137
|
+
readonly id: string;
|
|
138
|
+
readonly url: string;
|
|
139
|
+
readonly size: number;
|
|
140
|
+
readonly mime: string;
|
|
141
|
+
readonly filename: string;
|
|
142
|
+
readonly scriptId: string;
|
|
143
|
+
readonly createdTs: number;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface RewindResult {
|
|
147
|
+
readonly removedMessageIds: ReadonlyArray<string>;
|
|
148
|
+
readonly deletedEntities: number;
|
|
149
|
+
readonly deletedRelations: number;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface OwnedResource {
|
|
153
|
+
readonly type: string;
|
|
154
|
+
readonly uri: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface OwnedResourceGroup {
|
|
158
|
+
readonly node_id: string;
|
|
159
|
+
readonly attr_key: string;
|
|
160
|
+
readonly resources: ReadonlyArray<OwnedResource>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export type ViewExposureTarget = 'llm' | 'trigger' | 'both';
|
|
164
|
+
export type ViewToolBindingStatus = 'declared' | 'bound';
|
|
165
|
+
|
|
166
|
+
export interface ViewToolBinding {
|
|
167
|
+
readonly exposureId: string;
|
|
168
|
+
readonly name: string;
|
|
169
|
+
readonly signatureHash: string;
|
|
170
|
+
readonly handlerEndpoint: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ViewToolBindResult {
|
|
174
|
+
readonly exposureId: string;
|
|
175
|
+
readonly name: string;
|
|
176
|
+
readonly status: 'bound';
|
|
177
|
+
readonly boundAt: number;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface ViewExposureInfo {
|
|
181
|
+
readonly exposureId: string;
|
|
182
|
+
readonly name: string;
|
|
183
|
+
readonly description: string;
|
|
184
|
+
readonly target: ViewExposureTarget;
|
|
185
|
+
readonly signatureHash: string;
|
|
186
|
+
readonly status: ViewToolBindingStatus;
|
|
187
|
+
readonly handlerEndpoint?: string;
|
|
188
|
+
readonly boundAt?: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface ViewExposureListResult {
|
|
192
|
+
readonly manifestHash: string;
|
|
193
|
+
readonly revision: number;
|
|
194
|
+
readonly exposures: ReadonlyArray<ViewExposureInfo>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface DirectorViewToolDescriptor {
|
|
198
|
+
readonly exposureId: string;
|
|
199
|
+
readonly name: string;
|
|
200
|
+
readonly description: string;
|
|
201
|
+
readonly parameters: unknown;
|
|
202
|
+
readonly returns: unknown;
|
|
203
|
+
readonly manifestHash: string;
|
|
204
|
+
readonly manifestRevision: number;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
export interface WorldlineMutationEffects {
|
|
209
|
+
readonly removedMessageIds: ReadonlyArray<string>;
|
|
210
|
+
readonly deletedEntities: number;
|
|
211
|
+
readonly deletedRelations: number;
|
|
212
|
+
}
|
|
213
|
+
export interface WorldlineSummary {
|
|
214
|
+
readonly worldlineId: string;
|
|
215
|
+
readonly title: string;
|
|
216
|
+
readonly parentWorldlineId: string | null;
|
|
217
|
+
readonly createdAtMs: number;
|
|
218
|
+
readonly updatedAtMs: number;
|
|
219
|
+
readonly revision: number;
|
|
220
|
+
}
|
|
221
|
+
export interface WorldlineListResult {
|
|
222
|
+
readonly activeWorldlineId: string;
|
|
223
|
+
readonly worldlineCount: number;
|
|
224
|
+
readonly worldlines: ReadonlyArray<WorldlineSummary>;
|
|
225
|
+
}
|
|
226
|
+
export interface ForkWorldlineResult extends WorldlineMutationEffects {
|
|
227
|
+
readonly worldlineId: string;
|
|
228
|
+
readonly activeWorldlineId: string;
|
|
229
|
+
readonly anchorMessageId: string;
|
|
230
|
+
readonly worldlineCount: number;
|
|
231
|
+
}
|
|
232
|
+
export interface ActivateWorldlineResult {
|
|
233
|
+
readonly worldlineId: string;
|
|
234
|
+
readonly activeWorldlineId: string;
|
|
235
|
+
readonly worldlineCount: number;
|
|
236
|
+
readonly messageCount: number;
|
|
237
|
+
}
|
|
238
|
+
export interface TrimWorldlineResult {
|
|
239
|
+
readonly worldlineId: string;
|
|
240
|
+
readonly activeWorldlineId: string;
|
|
241
|
+
readonly worldlineCount: number;
|
|
242
|
+
readonly removedOpCount: number;
|
|
243
|
+
readonly removedBlobCount: number;
|
|
244
|
+
}
|
|
245
|
+
export interface ReadonlyPlayerWorldlines {
|
|
246
|
+
list(): Promise<WorldlineListResult>;
|
|
247
|
+
fork(messageId: string, title?: string): Promise<ForkWorldlineResult>;
|
|
248
|
+
activate(worldlineId: string): Promise<ActivateWorldlineResult>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export type ChatPlayEvent = 'messageAdded' | 'messageUpdated' | 'messageDeleted' | 'stateChanged' | 'streamStart' | 'streamDelta' | 'streamDone' | 'streamError' | 'localeChanged' | 'themeChanged' | 'saveForked' | 'resourceUnlocked' | 'saveCloned' | 'worldlineForked' | 'worldlineActivated' | 'worldlineTrimmed' | 'subagentStatus' | 'tmwDelivery' | 'interactionResult';
|
|
252
|
+
|
|
253
|
+
export interface ChatPlayApi {
|
|
254
|
+
/** 同步握手 Promise 入口必先 await window.ChatPlay.ready 完成后才能调任何 wrapper */
|
|
255
|
+
readonly ready: Promise<ChatPlayContext>;
|
|
256
|
+
/** 同步取当前握手 context ready 之前返回 null */
|
|
257
|
+
context(): ChatPlayContext | null;
|
|
258
|
+
/** 拉当前 save 持久化消息列表 支持 after/before 切片与 limit 截断 */
|
|
259
|
+
listMessages(opts?: { readonly after?: string; readonly before?: string; readonly limit?: number }): Promise<PersistedListItem[]>;
|
|
260
|
+
/** 通过宿主受控 chat.sendUserMessage 发送非空 user 消息;不暴露底层 RPC */
|
|
261
|
+
sendUserMessage(text: string): Promise<{ readonly messageId: string; readonly turnId: string }>;
|
|
262
|
+
/** 列出当前 script 名下所有资产 */
|
|
263
|
+
listAssets(): Promise<AssetRecord[]>;
|
|
264
|
+
/** 把 asset id 解析成运行时可访问 URL (blob:) */
|
|
265
|
+
getAssetUrl(id: string): Promise<string>;
|
|
266
|
+
/** 读 view 端自定义状态 缺省 key 返回 undefined */
|
|
267
|
+
loadCustomState(key: string): Promise<unknown>;
|
|
268
|
+
/** 列出当前 save 下所有 custom state key */
|
|
269
|
+
listCustomStateKeys(): Promise<string[]>;
|
|
270
|
+
/** 按当前 view 作用域只读查询自定义状态;写入、删除和批量提交不暴露给 TMW3 view */
|
|
271
|
+
readonly customState: ReadonlyCustomStateApi;
|
|
272
|
+
/** TMW3 view interaction capability;仅可提交 manifest 预声明 eventType,返回 interactionId 与 nonce 回执;最终激活结果通过 interactionResult 事件异步回传,不生成或扩大宿主权限 */
|
|
273
|
+
readonly events: TmwViewEventsApi;
|
|
274
|
+
/** TMW3 same-Save worldline API. Scope is host-derived; no Save identifier is accepted or returned. */
|
|
275
|
+
readonly worldline: ReadonlyPlayerWorldlines;
|
|
276
|
+
/** 取当前剧本元信息 */
|
|
277
|
+
getScenarioMeta(): Promise<{ scriptId: string; title: string; schemaVersion: number }>;
|
|
278
|
+
/** 取进度比 0..1 */
|
|
279
|
+
getProgress(): Promise<number>;
|
|
280
|
+
/** 读取当前 save 的触发器变量;scope 由宿主固定为 save,View 不可改写 */
|
|
281
|
+
getVariable(name: string): Promise<unknown>;
|
|
282
|
+
/** 读取当前 save 中指定节点或边的触发器解锁状态 */
|
|
283
|
+
getUnlock(target: "node" | "edge", id: string): Promise<{ readonly unlocked: boolean }>;
|
|
284
|
+
/** 返回当前已解锁资源 按节点和属性锚点分组 */
|
|
285
|
+
getOwnedResources(): Promise<OwnedResourceGroup[]>;
|
|
286
|
+
/** 请求宿主打开模型设置面板;只返回是否接受意图,不读取或返回任何配置 */
|
|
287
|
+
openModelSettings(): Promise<{ ok: true }>;
|
|
288
|
+
/** 取当前 UI locale (zh / en / ja) */
|
|
289
|
+
getLocale(): Promise<string>;
|
|
290
|
+
/** 只读获取宿主主题选择和当前解析后的明暗配色 */
|
|
291
|
+
getTheme(): Promise<ThemeSnapshot>;
|
|
292
|
+
/** 同步返回 SDK runtime 版本号 */
|
|
293
|
+
runtimeVersion(): { readonly major: number; readonly patch: number };
|
|
294
|
+
/** 订阅 SDK 事件 返回取消订阅函数;interactionResult 只关联本 iframe 的 interactionId/nonce,不暴露 committed event envelope、capability 或原始错误;tmwDelivery 不参与互动结果关联 */
|
|
295
|
+
on(event: "tmwDelivery", listener: (delivery: TmwDelivery) => void): () => void;
|
|
296
|
+
on(event: "interactionResult", listener: (result: TmwInteractionResult) => void): () => void;
|
|
297
|
+
on(event: "stateChanged", listener: (event: CustomStateChangedEvent) => void): () => void;
|
|
298
|
+
on(event: "worldlineForked", listener: (result: ForkWorldlineResult) => void): () => void;
|
|
299
|
+
on(event: "worldlineActivated", listener: (result: ActivateWorldlineResult) => void): () => void;
|
|
300
|
+
on(event: ChatPlayEvent, listener: (payload: unknown) => void): () => void;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
declare global {
|
|
304
|
+
interface Window {
|
|
305
|
+
ChatPlay: ChatPlayApi;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export {};
|