@sharpee/stdlib 0.9.111 → 1.0.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/actions/capability-dispatch.d.ts.map +1 -1
- package/actions/capability-dispatch.js +5 -3
- package/actions/capability-dispatch.js.map +1 -1
- package/actions/enhanced-context.d.ts.map +1 -1
- package/actions/enhanced-context.js +16 -0
- package/actions/enhanced-context.js.map +1 -1
- package/actions/enhanced-types.d.ts +35 -0
- package/actions/enhanced-types.d.ts.map +1 -1
- package/actions/enhanced-types.js.map +1 -1
- package/actions/index.d.ts +0 -1
- package/actions/index.d.ts.map +1 -1
- package/actions/index.js +0 -1
- package/actions/index.js.map +1 -1
- package/actions/standard/about/about-events.d.ts +2 -0
- package/actions/standard/about/about-events.d.ts.map +1 -1
- package/actions/standard/about/about.d.ts.map +1 -1
- package/actions/standard/about/about.js +4 -1
- package/actions/standard/about/about.js.map +1 -1
- package/actions/standard/attacking/attacking.d.ts.map +1 -1
- package/actions/standard/attacking/attacking.js +22 -14
- package/actions/standard/attacking/attacking.js.map +1 -1
- package/actions/standard/climbing/climbing.d.ts.map +1 -1
- package/actions/standard/climbing/climbing.js +8 -4
- package/actions/standard/climbing/climbing.js.map +1 -1
- package/actions/standard/closing/closing.d.ts.map +1 -1
- package/actions/standard/closing/closing.js +12 -11
- package/actions/standard/closing/closing.js.map +1 -1
- package/actions/standard/drinking/drinking.d.ts.map +1 -1
- package/actions/standard/drinking/drinking.js +8 -5
- package/actions/standard/drinking/drinking.js.map +1 -1
- package/actions/standard/dropping/dropping-data.d.ts.map +1 -1
- package/actions/standard/dropping/dropping-data.js +7 -5
- package/actions/standard/dropping/dropping-data.js.map +1 -1
- package/actions/standard/dropping/dropping.d.ts.map +1 -1
- package/actions/standard/dropping/dropping.js +20 -18
- package/actions/standard/dropping/dropping.js.map +1 -1
- package/actions/standard/eating/eating.d.ts.map +1 -1
- package/actions/standard/eating/eating.js +10 -7
- package/actions/standard/eating/eating.js.map +1 -1
- package/actions/standard/entering/entering.d.ts.map +1 -1
- package/actions/standard/entering/entering.js +15 -17
- package/actions/standard/entering/entering.js.map +1 -1
- package/actions/standard/examining/examining-data.d.ts.map +1 -1
- package/actions/standard/examining/examining-data.js +38 -3
- package/actions/standard/examining/examining-data.js.map +1 -1
- package/actions/standard/examining/examining-messages.d.ts +1 -0
- package/actions/standard/examining/examining-messages.d.ts.map +1 -1
- package/actions/standard/examining/examining-messages.js +1 -0
- package/actions/standard/examining/examining-messages.js.map +1 -1
- package/actions/standard/examining/examining.d.ts.map +1 -1
- package/actions/standard/examining/examining.js +5 -1
- package/actions/standard/examining/examining.js.map +1 -1
- package/actions/standard/exiting/exiting.d.ts.map +1 -1
- package/actions/standard/exiting/exiting.js +7 -3
- package/actions/standard/exiting/exiting.js.map +1 -1
- package/actions/standard/giving/giving.d.ts.map +1 -1
- package/actions/standard/giving/giving.js +12 -9
- package/actions/standard/giving/giving.js.map +1 -1
- package/actions/standard/going/going.d.ts.map +1 -1
- package/actions/standard/going/going.js +12 -13
- package/actions/standard/going/going.js.map +1 -1
- package/actions/standard/inserting/inserting.d.ts.map +1 -1
- package/actions/standard/inserting/inserting.js +11 -6
- package/actions/standard/inserting/inserting.js.map +1 -1
- package/actions/standard/listening/listening.d.ts.map +1 -1
- package/actions/standard/listening/listening.js +4 -2
- package/actions/standard/listening/listening.js.map +1 -1
- package/actions/standard/lock-shared.d.ts.map +1 -1
- package/actions/standard/lock-shared.js +10 -9
- package/actions/standard/lock-shared.js.map +1 -1
- package/actions/standard/locking/locking.d.ts.map +1 -1
- package/actions/standard/locking/locking.js +11 -7
- package/actions/standard/locking/locking.js.map +1 -1
- package/actions/standard/looking/looking-data.d.ts.map +1 -1
- package/actions/standard/looking/looking-data.js +8 -4
- package/actions/standard/looking/looking-data.js.map +1 -1
- package/actions/standard/looking/looking.d.ts.map +1 -1
- package/actions/standard/looking/looking.js +7 -1
- package/actions/standard/looking/looking.js.map +1 -1
- package/actions/standard/opening/opening.d.ts.map +1 -1
- package/actions/standard/opening/opening.js +9 -7
- package/actions/standard/opening/opening.js.map +1 -1
- package/actions/standard/pulling/pulling.d.ts.map +1 -1
- package/actions/standard/pulling/pulling.js +10 -5
- package/actions/standard/pulling/pulling.js.map +1 -1
- package/actions/standard/pushing/pushing.d.ts.map +1 -1
- package/actions/standard/pushing/pushing.js +15 -15
- package/actions/standard/pushing/pushing.js.map +1 -1
- package/actions/standard/putting/putting.d.ts.map +1 -1
- package/actions/standard/putting/putting.js +26 -28
- package/actions/standard/putting/putting.js.map +1 -1
- package/actions/standard/reading/reading.d.ts.map +1 -1
- package/actions/standard/reading/reading.js +7 -4
- package/actions/standard/reading/reading.js.map +1 -1
- package/actions/standard/removing/removing.d.ts.map +1 -1
- package/actions/standard/removing/removing.js +27 -26
- package/actions/standard/removing/removing.js.map +1 -1
- package/actions/standard/searching/searching.d.ts.map +1 -1
- package/actions/standard/searching/searching.js +4 -2
- package/actions/standard/searching/searching.js.map +1 -1
- package/actions/standard/searching-helpers.d.ts.map +1 -1
- package/actions/standard/searching-helpers.js +3 -1
- package/actions/standard/searching-helpers.js.map +1 -1
- package/actions/standard/showing/showing.d.ts.map +1 -1
- package/actions/standard/showing/showing.js +9 -6
- package/actions/standard/showing/showing.js.map +1 -1
- package/actions/standard/smelling/smelling.d.ts.map +1 -1
- package/actions/standard/smelling/smelling.js +5 -3
- package/actions/standard/smelling/smelling.js.map +1 -1
- package/actions/standard/switching_off/switching_off.d.ts.map +1 -1
- package/actions/standard/switching_off/switching_off.js +8 -5
- package/actions/standard/switching_off/switching_off.js.map +1 -1
- package/actions/standard/switching_on/switching_on.d.ts.map +1 -1
- package/actions/standard/switching_on/switching_on.js +16 -10
- package/actions/standard/switching_on/switching_on.js.map +1 -1
- package/actions/standard/taking/taking.d.ts.map +1 -1
- package/actions/standard/taking/taking.js +25 -18
- package/actions/standard/taking/taking.js.map +1 -1
- package/actions/standard/taking_off/taking-off.d.ts.map +1 -1
- package/actions/standard/taking_off/taking-off.js +12 -10
- package/actions/standard/taking_off/taking-off.js.map +1 -1
- package/actions/standard/talking/talking.d.ts.map +1 -1
- package/actions/standard/talking/talking.js +8 -4
- package/actions/standard/talking/talking.js.map +1 -1
- package/actions/standard/throwing/throwing.d.ts.map +1 -1
- package/actions/standard/throwing/throwing.js +13 -14
- package/actions/standard/throwing/throwing.js.map +1 -1
- package/actions/standard/touching/touching.d.ts.map +1 -1
- package/actions/standard/touching/touching.js +6 -2
- package/actions/standard/touching/touching.js.map +1 -1
- package/actions/standard/unlocking/unlocking.d.ts.map +1 -1
- package/actions/standard/unlocking/unlocking.js +10 -6
- package/actions/standard/unlocking/unlocking.js.map +1 -1
- package/actions/standard/wearable-shared.d.ts.map +1 -1
- package/actions/standard/wearable-shared.js +3 -1
- package/actions/standard/wearable-shared.js.map +1 -1
- package/actions/standard/wearing/wearing.d.ts.map +1 -1
- package/actions/standard/wearing/wearing.js +7 -5
- package/actions/standard/wearing/wearing.js.map +1 -1
- package/channels/index.d.ts +40 -0
- package/channels/index.d.ts.map +1 -0
- package/channels/index.js +86 -0
- package/channels/index.js.map +1 -0
- package/channels/keys.d.ts +23 -0
- package/channels/keys.d.ts.map +1 -0
- package/channels/keys.js +36 -0
- package/channels/keys.js.map +1 -0
- package/channels/media.d.ts +135 -0
- package/channels/media.d.ts.map +1 -0
- package/channels/media.js +397 -0
- package/channels/media.js.map +1 -0
- package/channels/registry.d.ts +58 -0
- package/channels/registry.d.ts.map +1 -0
- package/channels/registry.js +84 -0
- package/channels/registry.js.map +1 -0
- package/channels/sound-events.d.ts +72 -0
- package/channels/sound-events.d.ts.map +1 -0
- package/channels/sound-events.js +88 -0
- package/channels/sound-events.js.map +1 -0
- package/channels/standard.d.ts +209 -0
- package/channels/standard.d.ts.map +1 -0
- package/channels/standard.js +403 -0
- package/channels/standard.js.map +1 -0
- package/channels/world-helpers.d.ts +43 -0
- package/channels/world-helpers.d.ts.map +1 -0
- package/channels/world-helpers.js +72 -0
- package/channels/world-helpers.js.map +1 -0
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +7 -6
- package/utils/entity-info.d.ts +45 -0
- package/utils/entity-info.d.ts.map +1 -0
- package/utils/entity-info.js +68 -0
- package/utils/entity-info.js.map +1 -0
- package/utils/index.d.ts +9 -0
- package/utils/index.d.ts.map +1 -0
- package/utils/index.js +13 -0
- package/utils/index.js.map +1 -0
- package/validation/command-validator.d.ts +11 -1
- package/validation/command-validator.d.ts.map +1 -1
- package/validation/command-validator.js +31 -1
- package/validation/command-validator.js.map +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/stdlib/channels — channel registry instance.
|
|
4
|
+
*
|
|
5
|
+
* Owner context: stdlib language layer. Hosts the canonical
|
|
6
|
+
* `IChannelRegistry` instance for Sharpee's channel-I/O system.
|
|
7
|
+
* Engine bootstrap imports this instance, lets stories register their
|
|
8
|
+
* channels onto it (`Story.registerChannels?.(registry)`), then hands
|
|
9
|
+
* it to a fresh `ChannelService` (per ADR-163 §13, §14).
|
|
10
|
+
*
|
|
11
|
+
* The instance is populated at module init with the ten standard
|
|
12
|
+
* channels and the eleven static media channels. The `Story.registerChannels`
|
|
13
|
+
* hook may add story-specific channels or override standards by
|
|
14
|
+
* re-registering with the same id (last-write-wins per ADR-163 §6).
|
|
15
|
+
*
|
|
16
|
+
* Lifecycle: a fresh `ChannelService` is created per session
|
|
17
|
+
* (engine restart, RESTART command). The registry itself is reused —
|
|
18
|
+
* stdlib's standard channels stay registered across sessions, and the
|
|
19
|
+
* `ChannelService`'s per-session `prevValues` map provides the
|
|
20
|
+
* isolation. The Story.registerChannels hook is invoked once per
|
|
21
|
+
* engine bootstrap; if a story overrides a standard channel, that
|
|
22
|
+
* override persists for the lifetime of the engine instance.
|
|
23
|
+
*
|
|
24
|
+
* Tests can construct their own `IChannelRegistry` instance for
|
|
25
|
+
* isolation (unit tests should not depend on this singleton's
|
|
26
|
+
* pre-populated state for behavior-specific assertions).
|
|
27
|
+
*
|
|
28
|
+
* @see ADR-163 — Channel-Service Platform — §6, §7, §13, §14
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.channelRegistry = exports.StdlibChannelRegistry = void 0;
|
|
32
|
+
const standard_1 = require("./standard");
|
|
33
|
+
const media_1 = require("./media");
|
|
34
|
+
const sound_events_1 = require("./sound-events");
|
|
35
|
+
/**
|
|
36
|
+
* In-memory `IChannelRegistry` implementation. Last-write-wins on
|
|
37
|
+
* `add(channel)` by `channel.id` — which is how stories override
|
|
38
|
+
* platform standards (ADR-163 §6).
|
|
39
|
+
*/
|
|
40
|
+
class StdlibChannelRegistry {
|
|
41
|
+
channels = new Map();
|
|
42
|
+
add(channel) {
|
|
43
|
+
this.channels.set(channel.id, channel);
|
|
44
|
+
}
|
|
45
|
+
get(id) {
|
|
46
|
+
return this.channels.get(id);
|
|
47
|
+
}
|
|
48
|
+
all() {
|
|
49
|
+
return [...this.channels.values()];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Test-only helper: snapshot the current channel ids. Stable
|
|
53
|
+
* iteration order matches insertion order (Map semantics).
|
|
54
|
+
*/
|
|
55
|
+
ids() {
|
|
56
|
+
return [...this.channels.keys()];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.StdlibChannelRegistry = StdlibChannelRegistry;
|
|
60
|
+
/**
|
|
61
|
+
* The canonical channel registry instance for Sharpee. Pre-populated
|
|
62
|
+
* with ten standard channels (`main`, `prompt`, `score`, `turn`,
|
|
63
|
+
* `location`, `info`, `ifid`, `death`, `endgame`, `score_notify`)
|
|
64
|
+
* plus eleven static media channels (`image:preload`,
|
|
65
|
+
* `image:background`, `image:main`, `image:overlay`, `sound`,
|
|
66
|
+
* `music`, `animation`, `animate`, `transition`, `layout`, `clear`).
|
|
67
|
+
*
|
|
68
|
+
* Engine bootstrap consumes this directly; stories extend through
|
|
69
|
+
* the `Story.registerChannels?(registry)` hook.
|
|
70
|
+
*/
|
|
71
|
+
exports.channelRegistry = (() => {
|
|
72
|
+
const registry = new StdlibChannelRegistry();
|
|
73
|
+
for (const channel of standard_1.STANDARD_CHANNELS) {
|
|
74
|
+
registry.add(channel);
|
|
75
|
+
}
|
|
76
|
+
for (const channel of media_1.MEDIA_CHANNELS) {
|
|
77
|
+
registry.add(channel);
|
|
78
|
+
}
|
|
79
|
+
for (const channel of sound_events_1.SOUND_CHANNELS) {
|
|
80
|
+
registry.add(channel);
|
|
81
|
+
}
|
|
82
|
+
return registry;
|
|
83
|
+
})();
|
|
84
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/stdlib/src/channels/registry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;AAGH,yCAA+C;AAC/C,mCAAyC;AACzC,iDAAgD;AAEhD;;;;GAIG;AACH,MAAa,qBAAqB;IACf,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEzD,GAAG,CAAC,OAAkB;QACpB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACH,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;CACF;AAtBD,sDAsBC;AAED;;;;;;;;;;GAUG;AACU,QAAA,eAAe,GAAqB,CAAC,GAAG,EAAE;IACrD,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,4BAAiB,EAAE,CAAC;QACxC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,sBAAc,EAAE,CAAC;QACrC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,6BAAc,EAAE,CAAC;QACrC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/stdlib/channels — spatial sound channel (ADR-172 Phase 5).
|
|
3
|
+
*
|
|
4
|
+
* Owner context: stdlib language layer. Defines:
|
|
5
|
+
*
|
|
6
|
+
* - `SOUND_EVENT_TYPES` — semantic-event type constants the engine's
|
|
7
|
+
* sound dispatcher (Phase 6) emits when the propagation function
|
|
8
|
+
* delivers an `AudibilityEvent` to a listener.
|
|
9
|
+
* - `audibilityChannel` — the `IOChannel` that filters those events
|
|
10
|
+
* out of the per-turn event stream and projects their payloads.
|
|
11
|
+
*
|
|
12
|
+
* **Channel id is `'audibility'`, not `'sound'`.** The `'sound'` id is
|
|
13
|
+
* reserved by ADR-163 for the media-cue channel (`media.sound.play`
|
|
14
|
+
* payloads). ADR-172's per-listener audibility events are a distinct
|
|
15
|
+
* concept (perception of a propagated sound, with prose+audio render
|
|
16
|
+
* branches) so they ride a distinct channel id.
|
|
17
|
+
*
|
|
18
|
+
* The channel is **not** capability-gated. Per ADR-172 §Channel routing,
|
|
19
|
+
* both text-only and audio-capable clients consume audibility events:
|
|
20
|
+
* text-only renders descriptive prose ("muffled voices to the north"),
|
|
21
|
+
* audio-capable additionally plays a cue at a tier-mapped playback
|
|
22
|
+
* volume. The wire shape is the `AudibilityEvent`; clients render what
|
|
23
|
+
* they can.
|
|
24
|
+
*
|
|
25
|
+
* @see ADR-172 — Spatial Sound Propagation §Channel routing
|
|
26
|
+
* @see ADR-163 — Channel-Service Platform §6, §7 (closure-per-channel)
|
|
27
|
+
*/
|
|
28
|
+
import type { IOChannel } from "../../if-domain/index";
|
|
29
|
+
import type { IAudibilityEvent } from "../../if-domain/index";
|
|
30
|
+
/**
|
|
31
|
+
* Semantic-event types emitted by the sound subsystem. Phase 6's
|
|
32
|
+
* dispatcher fires `AUDIBILITY_HEARD` once per listener per propagated
|
|
33
|
+
* sound; the event's `data` field carries the listener-specific
|
|
34
|
+
* `IAudibilityEvent` payload.
|
|
35
|
+
*/
|
|
36
|
+
export declare const SOUND_EVENT_TYPES: {
|
|
37
|
+
/**
|
|
38
|
+
* A listener perceived a propagated sound. Event `data` is an
|
|
39
|
+
* `IAudibilityEvent` (per-listener tier, source-room, optional
|
|
40
|
+
* crossing wall, content if content-bearing).
|
|
41
|
+
*/
|
|
42
|
+
readonly AUDIBILITY_HEARD: "sound.audibility.heard";
|
|
43
|
+
};
|
|
44
|
+
export type SoundEventType = typeof SOUND_EVENT_TYPES[keyof typeof SOUND_EVENT_TYPES];
|
|
45
|
+
/**
|
|
46
|
+
* `audibility` — append-mode channel carrying every `AudibilityEvent`
|
|
47
|
+
* delivered to listeners during the turn just executed.
|
|
48
|
+
*
|
|
49
|
+
* Mode is `append` because a single turn may produce multiple
|
|
50
|
+
* `AUDIBILITY_HEARD` events (multiple emissions × multiple listeners
|
|
51
|
+
* after dispatcher fan-out in Phase 6). Each turn's projected value is
|
|
52
|
+
* the array of newly-heard events; quiet turns emit nothing under the
|
|
53
|
+
* `sparse` policy.
|
|
54
|
+
*
|
|
55
|
+
* Renderers consume per their capability:
|
|
56
|
+
* - text-only — language layer maps `(kind, audibilityTier)` to
|
|
57
|
+
* descriptive prose (see `sound-messages` in lang-{locale}).
|
|
58
|
+
* - audio-capable — optionally plays an audio cue per the existing
|
|
59
|
+
* Web Audio infrastructure (ADR-169), playback volume mapped from
|
|
60
|
+
* `audibilityTier`.
|
|
61
|
+
*/
|
|
62
|
+
export declare const audibilityChannel: IOChannel<IAudibilityEvent>;
|
|
63
|
+
/**
|
|
64
|
+
* Sound-subsystem channels. Currently a single entry; the constant
|
|
65
|
+
* exists to match the `STANDARD_CHANNELS` / `MEDIA_CHANNELS`
|
|
66
|
+
* registration pattern and to give future sound-related channels a
|
|
67
|
+
* stable bucket.
|
|
68
|
+
*/
|
|
69
|
+
export declare const SOUND_CHANNELS: ReadonlyArray<IOChannel>;
|
|
70
|
+
export declare const SOUND_CHANNEL_IDS: readonly ["audibility"];
|
|
71
|
+
export type SoundChannelId = typeof SOUND_CHANNEL_IDS[number];
|
|
72
|
+
//# sourceMappingURL=sound-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sound-events.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/stdlib/src/channels/sound-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAEtF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,CAAC,gBAAgB,CAezD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,SAAS,CAAuB,CAAC;AAE5E,eAAO,MAAM,iBAAiB,yBAA0B,CAAC;AACzD,MAAM,MAAM,cAAc,GAAG,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/stdlib/channels — spatial sound channel (ADR-172 Phase 5).
|
|
4
|
+
*
|
|
5
|
+
* Owner context: stdlib language layer. Defines:
|
|
6
|
+
*
|
|
7
|
+
* - `SOUND_EVENT_TYPES` — semantic-event type constants the engine's
|
|
8
|
+
* sound dispatcher (Phase 6) emits when the propagation function
|
|
9
|
+
* delivers an `AudibilityEvent` to a listener.
|
|
10
|
+
* - `audibilityChannel` — the `IOChannel` that filters those events
|
|
11
|
+
* out of the per-turn event stream and projects their payloads.
|
|
12
|
+
*
|
|
13
|
+
* **Channel id is `'audibility'`, not `'sound'`.** The `'sound'` id is
|
|
14
|
+
* reserved by ADR-163 for the media-cue channel (`media.sound.play`
|
|
15
|
+
* payloads). ADR-172's per-listener audibility events are a distinct
|
|
16
|
+
* concept (perception of a propagated sound, with prose+audio render
|
|
17
|
+
* branches) so they ride a distinct channel id.
|
|
18
|
+
*
|
|
19
|
+
* The channel is **not** capability-gated. Per ADR-172 §Channel routing,
|
|
20
|
+
* both text-only and audio-capable clients consume audibility events:
|
|
21
|
+
* text-only renders descriptive prose ("muffled voices to the north"),
|
|
22
|
+
* audio-capable additionally plays a cue at a tier-mapped playback
|
|
23
|
+
* volume. The wire shape is the `AudibilityEvent`; clients render what
|
|
24
|
+
* they can.
|
|
25
|
+
*
|
|
26
|
+
* @see ADR-172 — Spatial Sound Propagation §Channel routing
|
|
27
|
+
* @see ADR-163 — Channel-Service Platform §6, §7 (closure-per-channel)
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.SOUND_CHANNEL_IDS = exports.SOUND_CHANNELS = exports.audibilityChannel = exports.SOUND_EVENT_TYPES = void 0;
|
|
31
|
+
/**
|
|
32
|
+
* Semantic-event types emitted by the sound subsystem. Phase 6's
|
|
33
|
+
* dispatcher fires `AUDIBILITY_HEARD` once per listener per propagated
|
|
34
|
+
* sound; the event's `data` field carries the listener-specific
|
|
35
|
+
* `IAudibilityEvent` payload.
|
|
36
|
+
*/
|
|
37
|
+
exports.SOUND_EVENT_TYPES = {
|
|
38
|
+
/**
|
|
39
|
+
* A listener perceived a propagated sound. Event `data` is an
|
|
40
|
+
* `IAudibilityEvent` (per-listener tier, source-room, optional
|
|
41
|
+
* crossing wall, content if content-bearing).
|
|
42
|
+
*/
|
|
43
|
+
AUDIBILITY_HEARD: 'sound.audibility.heard',
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* `audibility` — append-mode channel carrying every `AudibilityEvent`
|
|
47
|
+
* delivered to listeners during the turn just executed.
|
|
48
|
+
*
|
|
49
|
+
* Mode is `append` because a single turn may produce multiple
|
|
50
|
+
* `AUDIBILITY_HEARD` events (multiple emissions × multiple listeners
|
|
51
|
+
* after dispatcher fan-out in Phase 6). Each turn's projected value is
|
|
52
|
+
* the array of newly-heard events; quiet turns emit nothing under the
|
|
53
|
+
* `sparse` policy.
|
|
54
|
+
*
|
|
55
|
+
* Renderers consume per their capability:
|
|
56
|
+
* - text-only — language layer maps `(kind, audibilityTier)` to
|
|
57
|
+
* descriptive prose (see `sound-messages` in lang-{locale}).
|
|
58
|
+
* - audio-capable — optionally plays an audio cue per the existing
|
|
59
|
+
* Web Audio infrastructure (ADR-169), playback volume mapped from
|
|
60
|
+
* `audibilityTier`.
|
|
61
|
+
*/
|
|
62
|
+
exports.audibilityChannel = {
|
|
63
|
+
id: 'audibility',
|
|
64
|
+
contentType: 'json',
|
|
65
|
+
mode: 'append',
|
|
66
|
+
emit: 'sparse',
|
|
67
|
+
produce: (ctx) => {
|
|
68
|
+
const heard = [];
|
|
69
|
+
for (const event of ctx.events) {
|
|
70
|
+
if (event.type !== exports.SOUND_EVENT_TYPES.AUDIBILITY_HEARD)
|
|
71
|
+
continue;
|
|
72
|
+
const data = event.data;
|
|
73
|
+
if (!data)
|
|
74
|
+
continue;
|
|
75
|
+
heard.push(data);
|
|
76
|
+
}
|
|
77
|
+
return heard.length > 0 ? heard : undefined;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Sound-subsystem channels. Currently a single entry; the constant
|
|
82
|
+
* exists to match the `STANDARD_CHANNELS` / `MEDIA_CHANNELS`
|
|
83
|
+
* registration pattern and to give future sound-related channels a
|
|
84
|
+
* stable bucket.
|
|
85
|
+
*/
|
|
86
|
+
exports.SOUND_CHANNELS = [exports.audibilityChannel];
|
|
87
|
+
exports.SOUND_CHANNEL_IDS = ['audibility'];
|
|
88
|
+
//# sourceMappingURL=sound-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sound-events.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/stdlib/src/channels/sound-events.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAKH;;;;;GAKG;AACU,QAAA,iBAAiB,GAAG;IAC/B;;;;OAIG;IACH,gBAAgB,EAAE,wBAAwB;CAClC,CAAC;AAIX;;;;;;;;;;;;;;;;GAgBG;AACU,QAAA,iBAAiB,GAAgC;IAC5D,EAAE,EAAE,YAAY;IAChB,WAAW,EAAE,MAAM;IACnB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,KAAK,GAAuB,EAAE,CAAC;QACrC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAiB,CAAC,gBAAgB;gBAAE,SAAS;YAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAoC,CAAC;YACxD,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACU,QAAA,cAAc,GAA6B,CAAC,yBAAiB,CAAC,CAAC;AAE/D,QAAA,iBAAiB,GAAG,CAAC,YAAY,CAAU,CAAC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/stdlib/channels — standard `IOChannel` definitions.
|
|
3
|
+
*
|
|
4
|
+
* Owner context: stdlib language layer. The ten platform-vocabulary
|
|
5
|
+
* channels from ADR-163 §4 — co-located with stdlib because their
|
|
6
|
+
* closures read stdlib data sources (capabilities, blocks the
|
|
7
|
+
* text-service produces, world projections).
|
|
8
|
+
*
|
|
9
|
+
* Per ADR-163 §6, channels are self-contained: each `IOChannel`
|
|
10
|
+
* carries its identity, configuration, and a closure that computes
|
|
11
|
+
* the channel's value for the current turn from the
|
|
12
|
+
* `ChannelProduceContext`. There is no separate rule schema or
|
|
13
|
+
* routing layer; closures are the routing.
|
|
14
|
+
*
|
|
15
|
+
* **Standard channels are NOT capability-gated** (per §6 — they exist
|
|
16
|
+
* on every surface). Media channels gate; standards do not.
|
|
17
|
+
*
|
|
18
|
+
* @see ADR-163 — Channel-Service Platform — §4, §5, §6
|
|
19
|
+
*/
|
|
20
|
+
import type { IOChannel, MainEntry } from "../../if-domain/index";
|
|
21
|
+
/**
|
|
22
|
+
* Event types the standard channels listen for. Stories or extensions
|
|
23
|
+
* that want to populate `death`, `endgame`, or `score_notify` emit
|
|
24
|
+
* events of these types; stdlib does not emit them itself.
|
|
25
|
+
*
|
|
26
|
+
* The values align with what the engine and stdlib extensions actually
|
|
27
|
+
* emit today:
|
|
28
|
+
*
|
|
29
|
+
* - `game.won` / `game.lost` — engine emits these from `engine.stop()`
|
|
30
|
+
* via `createGameWonEvent` / `createGameLostEvent` (core/events).
|
|
31
|
+
* - `combat.player_died` — emitted by the `@sharpee/ext-basic-combat`
|
|
32
|
+
* extension. Stories not using basic-combat that want a death
|
|
33
|
+
* channel emission must either fire `combat.player_died` themselves
|
|
34
|
+
* or override `deathChannel` with their own closure.
|
|
35
|
+
* - `game.score_changed` — no production emitter today. The channel
|
|
36
|
+
* listens for it, but it stays silent until a story or extension
|
|
37
|
+
* adopts the convention. Listed for forward-compatibility.
|
|
38
|
+
*
|
|
39
|
+
* Each event carries its message in `event.data.message` (string).
|
|
40
|
+
*/
|
|
41
|
+
export declare const STANDARD_CHANNEL_EVENTS: {
|
|
42
|
+
readonly PLAYER_DIED: "combat.player_died";
|
|
43
|
+
readonly GAME_WON: "game.won";
|
|
44
|
+
readonly GAME_LOST: "game.lost";
|
|
45
|
+
readonly SCORE_CHANGED: "game.score_changed";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* `main` — append-mode prose transcript. Carries `MainEntry` objects
|
|
49
|
+
* (`{ content, tight? }`) so renderers can preserve decorations *and*
|
|
50
|
+
* the per-entry visual-continuation hint introduced by the pre-line
|
|
51
|
+
* removal (session 2026-05-12). Closure projects every block whose key
|
|
52
|
+
* is in `MAIN_KEYS` into the channel's append stream.
|
|
53
|
+
*/
|
|
54
|
+
export declare const mainChannel: IOChannel<MainEntry>;
|
|
55
|
+
/**
|
|
56
|
+
* `prompt` — replace-mode input prompt. Defaults to `'> '` when no
|
|
57
|
+
* prompt block is emitted, so the renderer always has a sensible
|
|
58
|
+
* placeholder. Closure flattens the prompt block's content to plain
|
|
59
|
+
* string (decorations stripped).
|
|
60
|
+
*/
|
|
61
|
+
export declare const promptChannel: IOChannel<string>;
|
|
62
|
+
/**
|
|
63
|
+
* `location` — replace-mode status-line location name. Closure reads
|
|
64
|
+
* the player's containing room from the world and returns its display
|
|
65
|
+
* name. Returns `undefined` (the channel re-emits its prevValue) if
|
|
66
|
+
* the world has no player or the room cannot be resolved.
|
|
67
|
+
*/
|
|
68
|
+
export declare const locationChannel: IOChannel<string>;
|
|
69
|
+
/**
|
|
70
|
+
* `score` — replace-mode `{current, max}` payload.
|
|
71
|
+
*
|
|
72
|
+
* Reads the canonical ADR-129 score ledger first (`world.getScore()`
|
|
73
|
+
* and `world.getMaxScore()`); falls back to the legacy `scoring`
|
|
74
|
+
* capability's `scoreValue`/`maxScore` for older worlds that haven't
|
|
75
|
+
* adopted the ledger. The fallback path also serves stories that
|
|
76
|
+
* track score outside the ledger (rare; ADR-129 is the recommended
|
|
77
|
+
* pattern).
|
|
78
|
+
*
|
|
79
|
+
* `max: null` (not `0`) signals an unbounded score per ADR-163 §4
|
|
80
|
+
* commentary; `maxScore: 0` is treated as null since a 0-cap scoring
|
|
81
|
+
* system has no usable progress fraction.
|
|
82
|
+
*
|
|
83
|
+
* Returns `undefined` only when the world is missing entirely (test
|
|
84
|
+
* harness with a stub) — `always`-mode then re-emits prev.
|
|
85
|
+
*/
|
|
86
|
+
export declare const scoreChannel: IOChannel<{
|
|
87
|
+
current: number;
|
|
88
|
+
max: number | null;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* `turn` — replace-mode turn count. Closure returns `ctx.turn`
|
|
92
|
+
* directly. Always emits because the turn counter changes every turn.
|
|
93
|
+
*/
|
|
94
|
+
export declare const turnChannel: IOChannel<number>;
|
|
95
|
+
/**
|
|
96
|
+
* Wire shape for the `info` channel — full story metadata.
|
|
97
|
+
*
|
|
98
|
+
* Optional fields are omitted from the emitted payload when empty so
|
|
99
|
+
* renderers can branch cleanly on presence. The engine populates the
|
|
100
|
+
* underlying `storyInfo` capability from `StoryConfig` + `StoryInfoTrait`
|
|
101
|
+
* during `setStory()`.
|
|
102
|
+
*/
|
|
103
|
+
export interface StoryInfoPayload {
|
|
104
|
+
title?: string;
|
|
105
|
+
author?: string;
|
|
106
|
+
version?: string;
|
|
107
|
+
description?: string;
|
|
108
|
+
buildDate?: string;
|
|
109
|
+
engineVersion?: string;
|
|
110
|
+
clientVersion?: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* `info` — replace-mode story metadata. Closure projects every
|
|
114
|
+
* non-empty field from the `storyInfo` capability into a single
|
|
115
|
+
* payload object. The same payload is consumed by the browser
|
|
116
|
+
* `info` renderer (sets `document.title` + `data-*` attributes) and
|
|
117
|
+
* by any author-supplied dashboards.
|
|
118
|
+
*/
|
|
119
|
+
export declare const infoChannel: IOChannel<StoryInfoPayload>;
|
|
120
|
+
/**
|
|
121
|
+
* `ifid` — replace-mode IFID string. Closure reads `storyInfo.ifid`
|
|
122
|
+
* and skips emission when the value is empty (sparse-suppress style),
|
|
123
|
+
* so stories without an IFID don't emit empty strings into the
|
|
124
|
+
* channel state.
|
|
125
|
+
*/
|
|
126
|
+
export declare const ifidChannel: IOChannel<string>;
|
|
127
|
+
/**
|
|
128
|
+
* `death` — event-mode death notification. Closure looks for an
|
|
129
|
+
* `if.event.player_died` event in this turn's events and projects its
|
|
130
|
+
* `data.message` field. Stories that want different death handling
|
|
131
|
+
* register a replacement `IOChannel` with id `'death'` (last-write-wins
|
|
132
|
+
* per ADR-163 §6).
|
|
133
|
+
*/
|
|
134
|
+
export declare const deathChannel: IOChannel<string>;
|
|
135
|
+
/**
|
|
136
|
+
* `endgame` — event-mode endgame notification (game won OR game lost
|
|
137
|
+
* — the closure folds both into one channel since renderers typically
|
|
138
|
+
* present them similarly). Closure scans for either event type and
|
|
139
|
+
* returns the message of the first match.
|
|
140
|
+
*/
|
|
141
|
+
export declare const endgameChannel: IOChannel<string>;
|
|
142
|
+
/**
|
|
143
|
+
* `score_notify` — event-mode transient score-change announcement.
|
|
144
|
+
* Closure scans for `if.event.score_changed` and emits its message.
|
|
145
|
+
*/
|
|
146
|
+
export declare const scoreNotifyChannel: IOChannel<string>;
|
|
147
|
+
/**
|
|
148
|
+
* Discriminator values for `LifecyclePayload`.
|
|
149
|
+
*
|
|
150
|
+
* - `save_failed` — save handler reported failure or threw.
|
|
151
|
+
* - `restore_failed` — restore handler returned no data, threw, or
|
|
152
|
+
* was not registered.
|
|
153
|
+
* - `restore_completed` — restore succeeded; renderers should refresh
|
|
154
|
+
* any cached UI derived from world state.
|
|
155
|
+
*/
|
|
156
|
+
export type LifecycleEventKind = 'save_failed' | 'restore_failed' | 'restore_completed';
|
|
157
|
+
/**
|
|
158
|
+
* Wire shape for the `lifecycle` channel. `message` is populated for
|
|
159
|
+
* the failure kinds and copied verbatim from the platform event's
|
|
160
|
+
* `payload.error` field. Successful kinds (`restore_completed`) carry
|
|
161
|
+
* no message — they are pure signals.
|
|
162
|
+
*/
|
|
163
|
+
export interface LifecyclePayload {
|
|
164
|
+
kind: LifecycleEventKind;
|
|
165
|
+
message?: string;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* `lifecycle` — event-mode save/restore signals. Projects the trio of
|
|
169
|
+
* platform completion events (`platform.save_failed`,
|
|
170
|
+
* `platform.restore_failed`, `platform.restore_completed`) into a
|
|
171
|
+
* single sparse channel.
|
|
172
|
+
*
|
|
173
|
+
* Renderers branch on `payload.kind`: failures display `payload.message`
|
|
174
|
+
* (or a fallback string), `restore_completed` triggers UI refresh
|
|
175
|
+
* without text. Sparse-emit semantics mean turns without a lifecycle
|
|
176
|
+
* event suppress emission entirely — the channel value retains its
|
|
177
|
+
* prior state on quiet turns.
|
|
178
|
+
*
|
|
179
|
+
* If multiple lifecycle events appear in one turn, the **last** one
|
|
180
|
+
* wins. In practice this is unobservable since each save/restore
|
|
181
|
+
* operation produces exactly one completion event, but the rule is
|
|
182
|
+
* documented so test authors don't expect first-wins semantics.
|
|
183
|
+
*/
|
|
184
|
+
export declare const lifecycleChannel: IOChannel<LifecyclePayload>;
|
|
185
|
+
/**
|
|
186
|
+
* The ten platform-standard channels in iteration order. Order is
|
|
187
|
+
* preserved for stable diffing in tests and manifests; the
|
|
188
|
+
* `ChannelService` itself does not depend on ordering.
|
|
189
|
+
*/
|
|
190
|
+
export declare const STANDARD_CHANNELS: ReadonlyArray<IOChannel>;
|
|
191
|
+
/**
|
|
192
|
+
* Channel id literals for the platform-standard set. Used by tests
|
|
193
|
+
* and consumers that need string-literal types.
|
|
194
|
+
*/
|
|
195
|
+
export declare const STANDARD_CHANNEL_IDS: {
|
|
196
|
+
readonly MAIN: "main";
|
|
197
|
+
readonly PROMPT: "prompt";
|
|
198
|
+
readonly LOCATION: "location";
|
|
199
|
+
readonly SCORE: "score";
|
|
200
|
+
readonly TURN: "turn";
|
|
201
|
+
readonly INFO: "info";
|
|
202
|
+
readonly IFID: "ifid";
|
|
203
|
+
readonly DEATH: "death";
|
|
204
|
+
readonly ENDGAME: "endgame";
|
|
205
|
+
readonly SCORE_NOTIFY: "score_notify";
|
|
206
|
+
readonly LIFECYCLE: "lifecycle";
|
|
207
|
+
};
|
|
208
|
+
export type StandardChannelId = (typeof STANDARD_CHANNEL_IDS)[keyof typeof STANDARD_CHANNEL_IDS];
|
|
209
|
+
//# sourceMappingURL=standard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/stdlib/src/channels/standard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAuB/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB;;;;;CAK1B,CAAC;AAwCX;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,SAAS,CAkB5C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,MAAM,CAa3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,MAAM,CAM7C,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CA0B3E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,MAAM,CAMzC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,gBAAgB,CAkBnD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,MAAM,CAYzC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,MAAM,CAa1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,MAAM,CAgB5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,MAAM,CAahD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,aAAa,GACb,gBAAgB,GAChB,mBAAmB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA8BD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,CAexD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,SAAS,CAYtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;CAYvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAC3B,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC"}
|