@moku-labs/game 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +495 -40
- package/dist/assets.d.mts +213 -0
- package/dist/assets.mjs +6125 -0
- package/dist/commands-BOxqlv7w.d.mts +99 -0
- package/dist/component-DGg5DqKK.mjs +44 -0
- package/dist/control.d.mts +73 -0
- package/dist/control.mjs +4 -0
- package/dist/define-BMo0pHe_.d.mts +51 -0
- package/dist/dev-CcwFrwok.mjs +413 -0
- package/dist/index.d.mts +1396 -54
- package/dist/index.mjs +26433 -2013
- package/dist/inspect.d.mts +111 -0
- package/dist/inspect.mjs +3 -0
- package/dist/jsx-dev-runtime.d.mts +2 -0
- package/dist/jsx-dev-runtime.mjs +2 -0
- package/dist/jsx-runtime.d.mts +2 -0
- package/dist/jsx-runtime.mjs +2 -0
- package/dist/memory-CvgdnsQO.mjs +259 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
- package/dist/run-tlcn1w7y.mjs +944 -0
- package/dist/runtime-BstIkrhH.d.mts +77 -0
- package/dist/runtime-DRlwxkIv.mjs +182 -0
- package/dist/session-DmAxY6Ll.mjs +145 -0
- package/dist/sources-BooL2MsX.mjs +545 -0
- package/dist/testing.d.mts +302 -88
- package/dist/testing.mjs +2005 -228
- package/dist/types-BTycq8_Z.d.mts +1196 -0
- package/dist/types-C0SLQsx0.d.mts +2058 -0
- package/dist/types-Cjf3ywai.d.mts +5982 -0
- package/dist/types-D0uYTTC3.d.mts +392 -0
- package/dist/types-DgwbzDLP.d.mts +690 -0
- package/dist/types-KlE_GL1z.d.mts +1444 -0
- package/dist/visual-NPrDkvUk.mjs +740 -0
- package/package.json +42 -5
- package/dist/registry-DWV5C0Mf.mjs +0 -666
- package/dist/types-BfsmUzLC.d.mts +0 -1908
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { a as JsxChild, m as UiIntrinsicElements, t as DescriptionNode } from "./types-C0SLQsx0.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/ui/jsx/runtime.d.ts
|
|
4
|
+
/** What the compiler passes as props: the children plus whatever the tag declared. */
|
|
5
|
+
type JsxProperties = Record<string, unknown> & {
|
|
6
|
+
children?: JsxChild;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Builds one description node. A string tag becomes an intrinsic, a component definition becomes
|
|
10
|
+
* one node the reconcile expands, and a plain function runs now.
|
|
11
|
+
*
|
|
12
|
+
* @param type - The tag: a string, `Fragment`, a component definition or a plain function.
|
|
13
|
+
* @param props - What the compiler collected, `children` included.
|
|
14
|
+
* @param key - The `key` attribute, passed as the third argument, never inside `props`.
|
|
15
|
+
* @returns The node.
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* jsx("row", { style: { gap: 8 } }, "tabs"); // { type: "row", key: "tabs", props: { style: { gap: 8 } }, children: [] }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function jsx(type: unknown, props: JsxProperties, key?: string): DescriptionNode;
|
|
22
|
+
/**
|
|
23
|
+
* The factory for a tag with several static children. The same function as `jsx`.
|
|
24
|
+
*/
|
|
25
|
+
declare const jsxs: typeof jsx;
|
|
26
|
+
/**
|
|
27
|
+
* The development factory. The last three arguments are debug information the runtime drops.
|
|
28
|
+
*
|
|
29
|
+
* @param type - The tag.
|
|
30
|
+
* @param props - What the compiler collected.
|
|
31
|
+
* @param key - The `key` attribute.
|
|
32
|
+
* @param _isStatic - Whether the children list is static. Ignored.
|
|
33
|
+
* @param _source - The file and line of the tag. Ignored.
|
|
34
|
+
* @param _self - The `this` of the enclosing scope. Ignored.
|
|
35
|
+
* @returns The node `jsx` builds.
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* jsxDEV("row", {}, "tabs", false, { fileName: "hud.tsx" }, undefined).key; // "tabs"
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare function jsxDEV(type: unknown, props: JsxProperties, key?: string, _isStatic?: boolean, _source?: unknown, _self?: unknown): DescriptionNode;
|
|
42
|
+
/**
|
|
43
|
+
* Groups children without a tag of its own. Its children are lifted into the parent.
|
|
44
|
+
*
|
|
45
|
+
* @param props - The children between the two ends of the fragment.
|
|
46
|
+
* @returns The fragment node, which `flatten` lifts.
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* Fragment({ children: ["a"] }).children.length; // 1
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare function Fragment(props: JsxProperties): DescriptionNode;
|
|
53
|
+
/**
|
|
54
|
+
* The namespace TypeScript reads a `.tsx` file against. A game sets `"jsx": "react-jsx"` and
|
|
55
|
+
* `"jsxImportSource": "@moku-labs/game"`, and both entry files export this namespace.
|
|
56
|
+
*/
|
|
57
|
+
declare namespace JSX {
|
|
58
|
+
/** What a tag evaluates to. */
|
|
59
|
+
interface Element extends DescriptionNode {}
|
|
60
|
+
/** The thirteen tags a screen is written with. */
|
|
61
|
+
interface IntrinsicElements extends UiIntrinsicElements {}
|
|
62
|
+
/** The prop children are collected into. */
|
|
63
|
+
interface ElementChildrenAttribute {
|
|
64
|
+
children: unknown;
|
|
65
|
+
}
|
|
66
|
+
/** The attribute every tag takes next to its own props. */
|
|
67
|
+
interface IntrinsicAttributes {
|
|
68
|
+
key?: string;
|
|
69
|
+
}
|
|
70
|
+
/** The same attribute on a component tag. */
|
|
71
|
+
interface IntrinsicClassAttributes<Component> {
|
|
72
|
+
key?: string;
|
|
73
|
+
ref?: Component;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { jsxs as a, jsxDEV as i, JSX as n, jsx as r, Fragment as t };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { n as isComponentDefinition } from "./component-DGg5DqKK.mjs";
|
|
2
|
+
//#region src/plugins/ui/jsx/flatten.ts
|
|
3
|
+
/** The type of the node `Fragment` builds. It never reaches a reconcile: `flatten` lifts it. */
|
|
4
|
+
const FRAGMENT = "#fragment";
|
|
5
|
+
/**
|
|
6
|
+
* Builds the node a bare string or number child becomes.
|
|
7
|
+
*
|
|
8
|
+
* @param content - What stood between the tags.
|
|
9
|
+
* @returns A text node carrying it.
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* textNode(5); // { type: "text", props: { content: "5" }, children: [] }
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function textNode(content) {
|
|
16
|
+
return {
|
|
17
|
+
type: "text",
|
|
18
|
+
props: { content: String(content) },
|
|
19
|
+
children: []
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Tells a description node from the other things a child may be.
|
|
24
|
+
*
|
|
25
|
+
* @param child - One child of a tag.
|
|
26
|
+
* @returns True when it is a node.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* isNode({ type: "row", props: {}, children: [] }); // true
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function isNode(child) {
|
|
33
|
+
return typeof child === "object" && child !== null && !Array.isArray(child) && "type" in child;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Turns whatever stood between two tags into the children of that tag.
|
|
37
|
+
*
|
|
38
|
+
* @param child - One child, an array of children, or nothing.
|
|
39
|
+
* @returns The children as nodes, fragments lifted and empty values dropped.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* flatten(["a", undefined, 2]).map(node => node.props.content); // ["a", "2"]
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function flatten(child) {
|
|
46
|
+
if (child === null || child === void 0 || typeof child === "boolean") return [];
|
|
47
|
+
if (typeof child === "string" || typeof child === "number") return [textNode(child)];
|
|
48
|
+
if (Array.isArray(child)) {
|
|
49
|
+
const nodes = [];
|
|
50
|
+
for (const item of child) nodes.push(...flatten(item));
|
|
51
|
+
return nodes;
|
|
52
|
+
}
|
|
53
|
+
if (!isNode(child)) return [];
|
|
54
|
+
if (child.type === "#fragment") return [...child.children];
|
|
55
|
+
return [child];
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/plugins/ui/jsx/runtime.ts
|
|
59
|
+
/**
|
|
60
|
+
* @file ui/jsx — the JSX runtime itself: the three factories a TypeScript build calls, the
|
|
61
|
+
* fragment, and the `JSX` namespace `"jsxImportSource": "@moku-labs/game"` resolves to. Pure and
|
|
62
|
+
* reachable only through `src/jsx-runtime.ts` and `src/jsx-dev-runtime.ts` (lint L9).
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* Splits the children out of the props the compiler built, so a node never carries them twice.
|
|
66
|
+
*
|
|
67
|
+
* @param props - What the compiler passed.
|
|
68
|
+
* @returns The props without `children`.
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* withoutChildren({ style: {}, children: "a" }); // { style: {} }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
function withoutChildren(props) {
|
|
75
|
+
const rest = { ...props };
|
|
76
|
+
delete rest.children;
|
|
77
|
+
return rest;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Wraps what a plain function component returned so it can stand where one node is expected.
|
|
81
|
+
*
|
|
82
|
+
* @param produced - What the function returned.
|
|
83
|
+
* @param key - The key the tag carried, if any.
|
|
84
|
+
* @returns One node; several results are lifted by the parent's `flatten`.
|
|
85
|
+
*/
|
|
86
|
+
function asSingleNode(produced, key) {
|
|
87
|
+
const nodes = flatten(produced);
|
|
88
|
+
const single = nodes.length === 1 ? nodes[0] : void 0;
|
|
89
|
+
if (single === void 0) return {
|
|
90
|
+
type: FRAGMENT,
|
|
91
|
+
props: {},
|
|
92
|
+
children: nodes
|
|
93
|
+
};
|
|
94
|
+
if (key === void 0) return single;
|
|
95
|
+
return {
|
|
96
|
+
...single,
|
|
97
|
+
key
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Builds one description node. A string tag becomes an intrinsic, a component definition becomes
|
|
102
|
+
* one node the reconcile expands, and a plain function runs now.
|
|
103
|
+
*
|
|
104
|
+
* @param type - The tag: a string, `Fragment`, a component definition or a plain function.
|
|
105
|
+
* @param props - What the compiler collected, `children` included.
|
|
106
|
+
* @param key - The `key` attribute, passed as the third argument, never inside `props`.
|
|
107
|
+
* @returns The node.
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* jsx("row", { style: { gap: 8 } }, "tabs"); // { type: "row", key: "tabs", props: { style: { gap: 8 } }, children: [] }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
function jsx(type, props, key) {
|
|
114
|
+
const rest = withoutChildren(props);
|
|
115
|
+
if (type === Fragment) return {
|
|
116
|
+
type: FRAGMENT,
|
|
117
|
+
props: rest,
|
|
118
|
+
children: flatten(props.children)
|
|
119
|
+
};
|
|
120
|
+
if (isComponentDefinition(type)) {
|
|
121
|
+
const node = {
|
|
122
|
+
type: type.name,
|
|
123
|
+
props,
|
|
124
|
+
children: []
|
|
125
|
+
};
|
|
126
|
+
return key === void 0 ? node : {
|
|
127
|
+
...node,
|
|
128
|
+
key
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (typeof type === "function") return asSingleNode(type(props), key);
|
|
132
|
+
const node = {
|
|
133
|
+
type: String(type),
|
|
134
|
+
props: rest,
|
|
135
|
+
children: flatten(props.children)
|
|
136
|
+
};
|
|
137
|
+
return key === void 0 ? node : {
|
|
138
|
+
...node,
|
|
139
|
+
key
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The factory for a tag with several static children. The same function as `jsx`.
|
|
144
|
+
*/
|
|
145
|
+
const jsxs = jsx;
|
|
146
|
+
/**
|
|
147
|
+
* The development factory. The last three arguments are debug information the runtime drops.
|
|
148
|
+
*
|
|
149
|
+
* @param type - The tag.
|
|
150
|
+
* @param props - What the compiler collected.
|
|
151
|
+
* @param key - The `key` attribute.
|
|
152
|
+
* @param _isStatic - Whether the children list is static. Ignored.
|
|
153
|
+
* @param _source - The file and line of the tag. Ignored.
|
|
154
|
+
* @param _self - The `this` of the enclosing scope. Ignored.
|
|
155
|
+
* @returns The node `jsx` builds.
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* jsxDEV("row", {}, "tabs", false, { fileName: "hud.tsx" }, undefined).key; // "tabs"
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
function jsxDEV(type, props, key, _isStatic, _source, _self) {
|
|
162
|
+
return jsx(type, props, key);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Groups children without a tag of its own. Its children are lifted into the parent.
|
|
166
|
+
*
|
|
167
|
+
* @param props - The children between the two ends of the fragment.
|
|
168
|
+
* @returns The fragment node, which `flatten` lifts.
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* Fragment({ children: ["a"] }).children.length; // 1
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
function Fragment(props) {
|
|
175
|
+
return {
|
|
176
|
+
type: FRAGMENT,
|
|
177
|
+
props: {},
|
|
178
|
+
children: flatten(props.children)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
export { jsxs as i, jsx as n, jsxDEV as r, Fragment as t };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
//#region src/plugins/flow/doors/define.ts
|
|
2
|
+
/** Lowercase-first camelCase words joined by dots, at least two: `game.position`. */
|
|
3
|
+
const idPattern = /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)+$/;
|
|
4
|
+
/**
|
|
5
|
+
* Refuses an id that is not a dotted name.
|
|
6
|
+
*
|
|
7
|
+
* @param kind - `"source"` or `"command"`, for the message.
|
|
8
|
+
* @param id - The id to check.
|
|
9
|
+
* @throws {Error} When the id is not camelCase words joined by dots.
|
|
10
|
+
*/
|
|
11
|
+
function checkId(kind, id) {
|
|
12
|
+
if (idPattern.test(id)) return;
|
|
13
|
+
throw new Error(`[game] The ${kind} id "${id}" is not a dotted name.\n Name it like "game.position": camelCase words joined by dots.`);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Declares a source: a read-only view the editor lists, reads and watches. The types flow from
|
|
17
|
+
* the object: the input from `input`, the app from the `read` parameter, the output from its
|
|
18
|
+
* result.
|
|
19
|
+
*
|
|
20
|
+
* @param source - The descriptor.
|
|
21
|
+
* @returns The same descriptor, frozen.
|
|
22
|
+
* @throws {Error} When the id is not a dotted name such as `"game.position"`.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* // A game's .dev module: the orders on the board, re-read after every edge.
|
|
26
|
+
* export const orders = defineSource({
|
|
27
|
+
* id: "timber.orders",
|
|
28
|
+
* title: "Orders",
|
|
29
|
+
* input: {},
|
|
30
|
+
* changes: "edge",
|
|
31
|
+
* read: app => app.flow.state().path
|
|
32
|
+
* });
|
|
33
|
+
* read(app, orders); // "board/awaitIntent"
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function defineSource(source) {
|
|
37
|
+
checkId("source", source.id);
|
|
38
|
+
Object.freeze(source.input);
|
|
39
|
+
return Object.freeze(source);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Declares a command: a dev-only action the editor lists and runs. Its body starts with the
|
|
43
|
+
* inline dev guard, so a production build drops it.
|
|
44
|
+
*
|
|
45
|
+
* @param command - The descriptor.
|
|
46
|
+
* @returns The same descriptor, frozen.
|
|
47
|
+
* @throws {Error} When the id is not a dotted name such as `"game.answer"`.
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* // A game's .dev module: open the shop from anywhere, through the graph.
|
|
51
|
+
* export const openShop = defineCommand({
|
|
52
|
+
* id: "timber.openShop",
|
|
53
|
+
* title: "Open the shop",
|
|
54
|
+
* input: {},
|
|
55
|
+
* effect: "route",
|
|
56
|
+
* run: app => {
|
|
57
|
+
* if (typeof __MOKU_GAME_DEV__ === "undefined" || !__MOKU_GAME_DEV__) throw controlRefused();
|
|
58
|
+
* return app.flow.walk([{ at: "home", intent: "shop" }]);
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
* (await run(app, openShop)).state.path; // "shop"
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function defineCommand(command) {
|
|
65
|
+
checkId("command", command.id);
|
|
66
|
+
Object.freeze(command.input);
|
|
67
|
+
return Object.freeze(command);
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/plugins/flow/doors/input.ts
|
|
71
|
+
/** The input of a call that passed none. */
|
|
72
|
+
const noInput = Object.freeze({});
|
|
73
|
+
/**
|
|
74
|
+
* Hands the given input on, or an empty one. `InputArguments` and `WatchInput` let a call leave
|
|
75
|
+
* the input out only when every field of the schema is optional, so `{}` is an input of that
|
|
76
|
+
* schema.
|
|
77
|
+
*
|
|
78
|
+
* @param input - The input of the call, if any.
|
|
79
|
+
* @returns The input to pass to the descriptor.
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* inputOrEmpty<{ last: "number?" }>(undefined); // {}
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
function inputOrEmpty(input) {
|
|
86
|
+
return input ?? noInput;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/plugins/flow/doors/session.ts
|
|
90
|
+
/** The journal of an app that ran no cheat. */
|
|
91
|
+
const noCheats = Object.freeze([]);
|
|
92
|
+
const sessions = /*#__PURE__*/ new WeakMap();
|
|
93
|
+
/**
|
|
94
|
+
* Tells whether a cheat or a raw command ran on this app.
|
|
95
|
+
*
|
|
96
|
+
* @param app - The app.
|
|
97
|
+
* @returns True once a `cheat` or `raw` command ran.
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* // After run(app, commands.restore, { repro }): a restore is raw.
|
|
101
|
+
* isTainted(app); // true
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
function isTainted(app) {
|
|
105
|
+
return sessions.get(app)?.tainted ?? false;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Reads the journal of cheat and raw commands of this app, oldest first.
|
|
109
|
+
*
|
|
110
|
+
* @param app - The app.
|
|
111
|
+
* @returns The frozen journal, the same list until the next cheat.
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* // After run(app, commands.restore, { bookmark }) on frame 96.
|
|
115
|
+
* cheatsOf(app); // [{ id: "game.restore", input: { bookmark: { path: "home", ... } }, frame: 96 }]
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
function cheatsOf(app) {
|
|
119
|
+
return sessions.get(app)?.cheats ?? noCheats;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Taints the session of this app and journals the command. The input is copied, so the caller
|
|
123
|
+
* cannot rewrite the journal afterwards.
|
|
124
|
+
*
|
|
125
|
+
* @param app - The app.
|
|
126
|
+
* @param id - The command id.
|
|
127
|
+
* @param input - The input the command got.
|
|
128
|
+
* @param frame - The frame it runs on.
|
|
129
|
+
*/
|
|
130
|
+
function recordCheat(app, id, input, frame) {
|
|
131
|
+
const session = sessions.get(app) ?? {
|
|
132
|
+
tainted: true,
|
|
133
|
+
cheats: noCheats
|
|
134
|
+
};
|
|
135
|
+
const entry = Object.freeze({
|
|
136
|
+
id,
|
|
137
|
+
input: structuredClone(input),
|
|
138
|
+
frame
|
|
139
|
+
});
|
|
140
|
+
session.tainted = true;
|
|
141
|
+
session.cheats = Object.freeze([...session.cheats.slice(-499), entry]);
|
|
142
|
+
sessions.set(app, session);
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { defineCommand as a, inputOrEmpty as i, isTainted as n, defineSource as o, recordCheat as r, cheatsOf as t };
|