dsh-ptc-plus 0.4.1 → 0.4.2
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.en.md +6 -10
- package/README.md +6 -10
- package/client.js +262 -31
- package/compiler-core.cjs +132 -130
- package/compiler-core.cjs.map +3 -3
- package/docs/README.md +1 -0
- package/docs/adr/0023-global-user-bindings.md +6 -6
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +3 -3
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +5 -5
- package/docs/architecture.md +9 -5
- package/docs/client-ui.md +1 -1
- package/docs/durability-design.md +6 -3
- package/docs/installation.md +4 -4
- package/docs/runtime-reference.md +5 -1
- package/docs/stateful-binding-updates-proposal.md +8 -4
- package/docs/user-bindings.en.md +5 -3
- package/docs/user-bindings.md +4 -2
- package/docs/verification-optimization-work.md +41 -0
- package/docs/verification.md +15 -1
- package/internal/async-local-storage-intrinsics.js +38 -0
- package/internal/binding-declaration-contract.js +8 -0
- package/internal/binding-source-analysis.js +381 -64
- package/internal/binding-update-policy.js +7 -1
- package/internal/cell-analysis.js +21 -8
- package/internal/compiler-intrinsics.js +9 -43
- package/internal/compiler-module-links.js +7 -4
- package/internal/dynamic-environment-integration.js +8 -4
- package/internal/dynamic-environment-runtime.js +24 -3
- package/internal/dynamic-native-calls.js +4 -1
- package/internal/dynamic-native-runtime.js +15 -1
- package/internal/failure-reporting.js +38 -30
- package/internal/isolated-worker.js +17 -10
- package/internal/kernel-worker.js +493 -331
- package/internal/module-compilation.js +5 -4
- package/internal/module-transform-contract.js +32 -2
- package/internal/record-utils.js +24 -15
- package/internal/repl-value-observer.js +6 -3
- package/internal/runtime-intrinsics.js +101 -0
- package/internal/session-cell-executor.js +2 -1
- package/internal/session-journal-schema.js +30 -13
- package/internal/session-journal.js +19 -4
- package/internal/session-runtime.js +1 -0
- package/internal/source-position-map.js +19 -0
- package/internal/stateful-root-compiler.js +3 -1
- package/internal/typescript-transform.js +4 -2
- package/internal/user-binding-console-worker.js +101 -41
- package/internal/user-bindings.js +10 -2
- package/internal/value-wire.js +101 -71
- package/internal/worker-cwd-virtualization.js +80 -53
- package/internal/worker-environment.js +20 -0
- package/internal/worker-repl-realm.js +134 -0
- package/package.json +2 -1
- package/src/client-activity.js +8 -1
package/README.en.md
CHANGED
|
@@ -115,16 +115,16 @@ The Agent can test and revise the helper incrementally with in-memory REPL examp
|
|
|
115
115
|
|
|
116
116
|
The panel can be collapsed or closed; the sparkle button's badge reopens it. A successful save or discard closes the panel automatically. The original request retains its source and outcome in history.
|
|
117
117
|
|
|
118
|
-
Before the first message, hover over or click the sparkle button to view and toggle global bindings. These choices apply to all sessions
|
|
118
|
+
Before the first message, hover over or click the sparkle button to view and toggle global bindings. These choices apply to all sessions. The shortcut appears only while the current session uses the `ptc` or compatible `code` preset. The menu also provides new-binding authoring, existing-binding revision, full management, and a PTC Plus settings shortcut. The settings shortcut opens an in-app dialog containing every plugin setting, while its hover hint still names the host's native settings path. The reusable REPL binding list shows per-binding and total reuse counts, and a redeclaration never resets them.
|
|
119
119
|
|
|
120
|
-
Enabled binding interfaces are supplied to the model in new sessions and updated at the next permitted request in an existing session. Each binding can include a separate usage prompt or omit its interface. Changing only the prompt preserves the helper's runtime state. Assigning or redeclaring one name in a session overrides only that name; the entry's other names keep working, and the session-local override never writes back to the saved entry. See the [global binding guide](docs/user-bindings.en.md) for details.
|
|
120
|
+
Enabled binding interfaces are supplied to the model in new sessions and updated at the next permitted request in an existing session. A source-derived interface retains standard global types, referenced local types, representable class heritage, and class instance fields used by its public signatures; abstract classes remain non-constructable, and an imported type that cannot form a self-contained interface produces an explicit error before save. Each binding can include a separate usage prompt or omit its interface. Changing only the prompt preserves the helper's runtime state. Assigning or redeclaring one name in a session overrides only that name; the entry's other names keep working, and the session-local override never writes back to the saved entry. See the [global binding guide](docs/user-bindings.en.md) for details.
|
|
121
121
|
|
|
122
122
|
## Settings
|
|
123
123
|
|
|
124
|
-
Choose **PTC Plus settings** in the sparkle menu beside the composer to open the complete settings dialog directly. The host's native entry remains available
|
|
124
|
+
Choose **PTC Plus settings** in the sparkle menu beside the composer to open the complete settings dialog directly. The host's native entry remains available. Depending on the DSH interface, find the plugin on the side-bar **Plugins** page and choose **Configure**, or open **Settings → Plugin configuration → PTC Plus**. The main switch controls the plugin; other settings are grouped by purpose:
|
|
125
125
|
|
|
126
126
|
- **Tool call tolerance**: accept `run_code` without a summary and repair uniquely identifiable top-level native-tool miscalls.
|
|
127
|
-
- **REPL syntax**: `bindingUpdates` defaults to `stateful`, allowing cross-cell updates of variables, functions, classes, and import aliases, and letting a repeated declaration in one logical scope of one cell update the same identity; choose `protected` to keep name protection.
|
|
127
|
+
- **REPL syntax**: `bindingUpdates` defaults to `stateful`, allowing cross-cell updates of variables, functions, classes, and import aliases, and letting a repeated declaration in one logical scope of one cell update the same identity; choose `protected` to keep name protection. `tools` and the injected error classes can be neither redeclared nor written: a declaration collision reports `PTC-N001`, and a failed assignment names the affected binding. Existing configurations that still contain five separate switches appear as pending migration, and the settings page lets you choose either unified policy directly. Module syntax is enabled by default.
|
|
128
128
|
- **Module interoperability**: PTC-managed namespaces support live reads and local overrides, including when passed to external functions. External code independently importing a compiled module through native APIs does not receive the same namespace or writable-export guarantee. See the [runtime reference](docs/runtime-reference.md#cell-semantics).
|
|
129
129
|
- **State and recovery**: control restart recovery and contextual error tips.
|
|
130
130
|
- **Tool extensions**: enable global bindings or official Cordis tools for advanced use.
|
|
@@ -133,11 +133,7 @@ Choose **PTC Plus settings** in the sparkle menu beside the composer to open the
|
|
|
133
133
|
|
|
134
134
|
Global bindings and Cordis tools default to off. Settings generally apply immediately; a worker's memory limit cannot change while it is active. See the [configuration reference](docs/runtime-reference.md#configuration) for fields, defaults, and limits.
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Indirect `eval` and all four `Function` constructors use their owning realm's root, including when passed as native callbacks: after `const value=41`, `["typeof value"].map(eval)` returns `["number"]`. Function source observations retain original JavaScript source and its actual dependencies, so self-contained functions can be recompiled with `Function`. Function values, user overrides, and separately created realms retain their respective semantics.
|
|
139
|
-
|
|
140
|
-
Switching computation modes preserves existing closures' execution environments and saved function identities, including direct `eval` in asynchronous continuations and `Function.prototype.toString`. Each source generation selects stable callback interfaces while global and prototype properties retain their original values. Legacy code reuses established logical bindings through its native REPL environment, with existing native declarations retaining precedence, and reads modules through PTC-managed namespaces.
|
|
136
|
+
`run_code`, `edit_run_code`, binding workbench runs, and user binding execution follow the same stateful semantics. Within each computation environment, cells, PTC-managed modules, `require`, and binding modules share the worker's Node realm, so `Error` subclass checks and `globalThis` writes retain Node behavior. Explicit use of `eval`, `Function`, `node:vm`, or an independent runtime retains its native boundary. Changing the binding update policy does not rewrite the execution environment of existing closures and functions. See the [runtime reference](docs/runtime-reference.md#cell-semantics) for scope, source observation, module interoperability, and recorded-session compatibility rules.
|
|
141
137
|
|
|
142
138
|

|
|
143
139
|
|
|
@@ -151,7 +147,7 @@ On wide screens, the green **PTC Plus** header indicator offers a quick binding
|
|
|
151
147
|
|
|
152
148
|
## Scope
|
|
153
149
|
|
|
154
|
-
DSH continues to own tool permissions, approvals, cancellation, and sandbox policy.
|
|
150
|
+
DSH continues to own tool permissions, approvals, cancellation, and sandbox policy. PTC Plus evaluates session code in a reclaimable helper process, so stuck or unresponsive computation can be terminated without ending DSH; this process boundary is not a security sandbox. Electron Desktop compatibility does not change the environment visible to evaluated code or its child processes. PTC Plus cannot recover every state across restarts: external inputs, unverifiable history, and context compaction can reduce the recovered state. Recovery neither repeats nor reverses historical external operations.
|
|
155
151
|
|
|
156
152
|
Value previews have size and type limits; objects that cannot be read reliably appear as unavailable. An enabled binding can also fail initialization, with failures reported in execution results. See the [runtime reference](docs/runtime-reference.md) for details.
|
|
157
153
|
|
package/README.md
CHANGED
|
@@ -115,16 +115,16 @@ Agent 可以在会话 REPL 中用内存样例逐步测试和修正,再交出
|
|
|
115
115
|
|
|
116
116
|
草稿面板可折叠或关闭,输入框星光按钮上的角标可重新打开。保存或丢弃成功后自动关闭,历史请求保留当时的源码和结果。
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
会话开始前也可以悬停或点击星光按钮,查看并启停全局绑定;这些选择对所有会话生效。快捷入口只在当前会话使用 `ptc` 或兼容 `code` preset 时显示。菜单同时提供编写新绑定、修改已有绑定、完整管理入口和 PTC Plus 设置快捷入口;设置快捷入口直接打开包含全部插件配置的应用内窗口,悬浮提示仍标明宿主原生设置页的路径。REPL 可复用绑定列表显示每项复用次数和总复用次数,重定义或重声明不会清零。
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
已启用绑定的接口会提供给新会话中的模型,也会在现有会话的下一次允许请求中更新。接口从源码保留公开签名引用的标准全局类型、本地类型、可表示的类继承链和类实例字段;抽象类仍不可直接构造,无法生成自足接口的导入类型会在保存前明确报错。每个绑定可以另写使用提示词,或关闭接口展示;仅改提示词不会重置 helper 的运行状态。在会话中给某个名字赋值或重声明只覆盖该名字,同一条目的其他名字继续可用,会话内的覆盖也不会写回保存的条目。详细操作见[全局绑定使用指南](docs/user-bindings.md)。
|
|
121
121
|
|
|
122
122
|
## 设置
|
|
123
123
|
|
|
124
|
-
可以从输入框旁的星光菜单选择 **PTC Plus
|
|
124
|
+
可以从输入框旁的星光菜单选择 **PTC Plus 设置**,直接打开完整设置窗口。宿主原生入口也保留;根据 DSH 界面,可在侧栏 **Plugins** 页面找到本插件并点 **Configure**,或打开 **设置 → 插件配置 → PTC Plus**。总开关控制插件,其余设置按用途分组:
|
|
125
125
|
|
|
126
126
|
- **调用容错**:允许缺少摘要的 `run_code`,修复可以准确识别的顶层工具误调用。
|
|
127
|
-
- **REPL 语法**:`bindingUpdates` 默认是 `stateful`,允许跨 cell 更新变量、函数、类和 import alias,也允许同一 cell 内同一逻辑 scope 的重复声明更新同一身份;`protected` 可选择名称保护。`tools`
|
|
127
|
+
- **REPL 语法**:`bindingUpdates` 默认是 `stateful`,允许跨 cell 更新变量、函数、类和 import alias,也允许同一 cell 内同一逻辑 scope 的重复声明更新同一身份;`protected` 可选择名称保护。`tools` 与注入的错误类不能重声明或写入:声明冲突报 `PTC-N001`,赋值失败时会指出对应名称。已有配置若仍含五个细分开关,设置页会显示待迁移状态,可直接选择任一种统一策略。模块语法默认可用。
|
|
128
128
|
- **模块互操作**:PTC 管理的 namespace 支持实时读取和局部覆盖,传给外部函数后仍保留这些语义。外部代码自行原生导入编译模块不承诺同一 namespace 或可写导出语义,详见[运行时说明](docs/runtime-reference.md#cell-semantics)。
|
|
129
129
|
- **状态与恢复**:控制重启恢复和按需错误提示。
|
|
130
130
|
- **工具扩展**:开启全局绑定,或供高级用户使用的官方 Cordis 工具。
|
|
@@ -133,11 +133,7 @@ Agent 可以在会话 REPL 中用内存样例逐步测试和修正,再交出
|
|
|
133
133
|
|
|
134
134
|
全局绑定与 Cordis 工具默认关闭。设置通常即时生效;活动 worker 存在时不能更改其内存上限。字段、默认值和限制见[配置参考](docs/runtime-reference.md#configuration)。
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
间接 `eval` 和四种 `Function` 构造器使用所属 realm 的 root,作为原生回调传递时也一样,例如 `const value=41` 后的 `["typeof value"].map(eval)` 返回 `["number"]`。函数源码观察保留原始 JavaScript 源码及其真实依赖,自包含函数可用 `Function` 重新编译;函数值本身、用户改写和另外创建的 realm 保持各自语义。
|
|
139
|
-
|
|
140
|
-
切换计算模式时,旧闭包仍保留原有执行环境和已保存的函数身份,包括异步继续执行中的直接 `eval` 与 `Function.prototype.toString`。各代源码取得稳定的回调接口,全局和原型属性保持原值;兼容模式通过原生 REPL 环境复用已有逻辑绑定,原有原生声明仍优先,其模块导入也通过 PTC 管理的 namespace 读取。
|
|
136
|
+
`run_code`、`edit_run_code`、绑定试运行和用户绑定执行遵循同一套有状态语义。每个计算环境中的 cell、PTC 管理模块、`require` 和绑定模块共享该 worker 的 Node realm,因此 `Error` 子类判断与 `globalThis` 写入保持 Node 语义。显式使用 `eval`、`Function`、`node:vm` 或独立运行时仍遵循对应的原生边界;切换绑定更新策略不会改写已有闭包和函数的执行环境。完整的作用域、源码观察、模块互操作和已记录会话兼容规则见[运行时参考](docs/runtime-reference.md#cell-semantics)。
|
|
141
137
|
|
|
142
138
|

|
|
143
139
|
|
|
@@ -151,7 +147,7 @@ PTC Plus 对 `run_code`、`edit_run_code`、插件自有子计算及用户绑定
|
|
|
151
147
|
|
|
152
148
|
## 范围
|
|
153
149
|
|
|
154
|
-
DSH
|
|
150
|
+
DSH 继续负责工具权限、审批、取消和沙箱策略。PTC Plus 在可回收的 helper 进程中执行会话代码,因此卡住或无响应的计算可以在不结束 DSH 的情况下终止;这一进程边界不是安全沙箱。Electron Desktop 兼容处理不会改变求值代码及其子进程看到的环境。PTC Plus 不保证所有状态都能跨重启恢复;外部输入、无法验证的历史或上下文压缩都可能缩小恢复范围。恢复不会重做或撤销历史外部操作。
|
|
155
151
|
|
|
156
152
|
值预览有大小和类型限制,无法可靠读取的对象会显示“不可读取”。绑定的启用配置也不等于初始化一定成功,具体失败会在执行结果中说明。更多行为见[运行时参考](docs/runtime-reference.md)。
|
|
157
153
|
|
package/client.js
CHANGED
|
@@ -679,25 +679,25 @@
|
|
|
679
679
|
if (!strict) merge(result, data);
|
|
680
680
|
return [result];
|
|
681
681
|
});
|
|
682
|
-
Schema.extend("union", (data, { list, toString:
|
|
682
|
+
Schema.extend("union", (data, { list, toString: toString3 }, options, strict) => {
|
|
683
683
|
const messages = [];
|
|
684
684
|
for (const inner of list) try {
|
|
685
685
|
return Schema.resolve(data, inner, options, strict);
|
|
686
686
|
} catch (error) {
|
|
687
687
|
messages.push(error);
|
|
688
688
|
}
|
|
689
|
-
throw new ValidationError(`expected ${
|
|
689
|
+
throw new ValidationError(`expected ${toString3()} but got ${JSON.stringify(data)}`, options);
|
|
690
690
|
});
|
|
691
|
-
Schema.extend("intersect", (data, { list, toString:
|
|
691
|
+
Schema.extend("intersect", (data, { list, toString: toString3 }, options, strict) => {
|
|
692
692
|
if (!list.length) return [data];
|
|
693
693
|
let result;
|
|
694
694
|
for (const inner of list) {
|
|
695
695
|
const value = Schema.resolve(data, inner, options, true)[0];
|
|
696
696
|
if (isNullable(value)) continue;
|
|
697
697
|
if (isNullable(result)) result = value;
|
|
698
|
-
else if (typeof result !== typeof value) throw new ValidationError(`expected ${
|
|
698
|
+
else if (typeof result !== typeof value) throw new ValidationError(`expected ${toString3()} but got ${JSON.stringify(data)}`, options);
|
|
699
699
|
else if (typeof value === "object") merge(result ??= {}, value);
|
|
700
|
-
else if (result !== value) throw new ValidationError(`expected ${
|
|
700
|
+
else if (result !== value) throw new ValidationError(`expected ${toString3()} but got ${JSON.stringify(data)}`, options);
|
|
701
701
|
}
|
|
702
702
|
if (!strict && isPlainObject(data)) merge(result, data);
|
|
703
703
|
return [result];
|
|
@@ -1228,7 +1228,8 @@
|
|
|
1228
1228
|
var IMPORT_BOUNDARY_JOURNAL_VERSION = 7;
|
|
1229
1229
|
var PER_NAME_USER_BINDINGS_JOURNAL_VERSION = 8;
|
|
1230
1230
|
var LANGUAGE_SEMANTICS_JOURNAL_VERSION = 9;
|
|
1231
|
-
var
|
|
1231
|
+
var MODULE_TRANSFORM_JOURNAL_VERSION = 10;
|
|
1232
|
+
var JOURNAL_VERSION = MODULE_TRANSFORM_JOURNAL_VERSION;
|
|
1232
1233
|
var LIVE_USER_BINDINGS_SHADOW_POLICY = "per-name";
|
|
1233
1234
|
var LEGACY_USER_BINDINGS_SHADOW_POLICY = "whole-entry";
|
|
1234
1235
|
var LIVE_USER_BINDINGS_REUSE_POLICY = "implementation-v1";
|
|
@@ -1243,7 +1244,8 @@
|
|
|
1243
1244
|
var BINDING_MODES = /* @__PURE__ */ new Set(["loose", "strict"]);
|
|
1244
1245
|
var WHOLE_ENTRY_JOURNAL_FIELDS = /* @__PURE__ */ new Set(["version", "bindingPolicy", "rewritePolicy", "moduleSemantics", "userBindingsFingerprint", "userBindingsReusePolicy", "status", "calls", "operations", "confirms", "diagnostics", "completion", "volatileReason"]);
|
|
1245
1246
|
var PER_NAME_JOURNAL_FIELDS = /* @__PURE__ */ new Set([...WHOLE_ENTRY_JOURNAL_FIELDS, "userBindingsShadowPolicy", "userBindingNames"]);
|
|
1246
|
-
var
|
|
1247
|
+
var LANGUAGE_SEMANTICS_JOURNAL_FIELDS = /* @__PURE__ */ new Set([...PER_NAME_JOURNAL_FIELDS, "languageSemantics"]);
|
|
1248
|
+
var JOURNAL_FIELDS = /* @__PURE__ */ new Set([...LANGUAGE_SEMANTICS_JOURNAL_FIELDS, "moduleTransform"]);
|
|
1247
1249
|
var FINGERPRINT_REUSE_JOURNAL_FIELDS = new Set([...WHOLE_ENTRY_JOURNAL_FIELDS].filter((field) => field !== "userBindingsReusePolicy"));
|
|
1248
1250
|
var RELATIONLESS_JOURNAL_FIELDS = new Set([...FINGERPRINT_REUSE_JOURNAL_FIELDS].filter((field) => field !== "userBindingsFingerprint"));
|
|
1249
1251
|
var PREDECESSOR_JOURNAL_FIELDS = /* @__PURE__ */ new Set(["version", "bindingMode", "rewritePolicy", "status", "calls", "operations", "confirms", "diagnostics", "completion", "volatileReason"]);
|
|
@@ -1268,26 +1270,46 @@
|
|
|
1268
1270
|
var ERROR_FIELDS = /* @__PURE__ */ new Set(["kind", "message"]);
|
|
1269
1271
|
var EDIT_TARGET_FIELDS = /* @__PURE__ */ new Set(["targetCallSeq"]);
|
|
1270
1272
|
var DERIVED_RUN_FIELDS = /* @__PURE__ */ new Set(["code", "description"]);
|
|
1271
|
-
var JOURNAL_VERSIONS = /* @__PURE__ */ new Set([LEGACY_JOURNAL_VERSION, INTERMEDIATE_JOURNAL_VERSION, PREVIOUS_JOURNAL_VERSION, USER_BINDING_RELATIONLESS_JOURNAL_VERSION, FINGERPRINT_REUSE_JOURNAL_VERSION, VERSIONED_BINDING_REUSE_JOURNAL_VERSION, IMPORT_BOUNDARY_JOURNAL_VERSION, PER_NAME_USER_BINDINGS_JOURNAL_VERSION, JOURNAL_VERSION]);
|
|
1273
|
+
var JOURNAL_VERSIONS = /* @__PURE__ */ new Set([LEGACY_JOURNAL_VERSION, INTERMEDIATE_JOURNAL_VERSION, PREVIOUS_JOURNAL_VERSION, USER_BINDING_RELATIONLESS_JOURNAL_VERSION, FINGERPRINT_REUSE_JOURNAL_VERSION, VERSIONED_BINDING_REUSE_JOURNAL_VERSION, IMPORT_BOUNDARY_JOURNAL_VERSION, PER_NAME_USER_BINDINGS_JOURNAL_VERSION, LANGUAGE_SEMANTICS_JOURNAL_VERSION, JOURNAL_VERSION]);
|
|
1272
1274
|
var USER_BINDINGS_REUSE_POLICIES = /* @__PURE__ */ new Set([LEGACY_USER_BINDINGS_REUSE_POLICY, LIVE_USER_BINDINGS_REUSE_POLICY]);
|
|
1273
1275
|
var USER_BINDINGS_SHADOW_POLICIES = /* @__PURE__ */ new Set([LEGACY_USER_BINDINGS_SHADOW_POLICY, LIVE_USER_BINDINGS_SHADOW_POLICY]);
|
|
1274
1276
|
var USER_BINDING_NAME_STATES = /* @__PURE__ */ new Set(["provider", "local", "absent", "unknown"]);
|
|
1277
|
+
var isArray = Array.isArray;
|
|
1278
|
+
var freeze = Object.freeze;
|
|
1279
|
+
var ownKeys = Reflect.ownKeys;
|
|
1280
|
+
var defineProperty = Object.defineProperty;
|
|
1281
|
+
var uncurry = Function.prototype.bind.bind(Function.prototype.call);
|
|
1282
|
+
var setHas = uncurry(Set.prototype.has);
|
|
1283
|
+
var setAdd = uncurry(Set.prototype.add);
|
|
1284
|
+
var sort = uncurry(Array.prototype.sort);
|
|
1285
|
+
var enumerable = uncurry(Object.prototype.propertyIsEnumerable);
|
|
1275
1286
|
function normalizeUserBindingNames(value) {
|
|
1276
|
-
if (!
|
|
1287
|
+
if (!isArray(value)) throw new TypeError("invalid user binding name evidence");
|
|
1277
1288
|
const names = /* @__PURE__ */ new Set();
|
|
1278
|
-
|
|
1279
|
-
|
|
1289
|
+
const normalized = [];
|
|
1290
|
+
for (let index = 0; index < value.length; index++) {
|
|
1291
|
+
const fact = value[index];
|
|
1292
|
+
if (fact === null || typeof fact !== "object" || !setHas(USER_BINDING_NAME_STATES, fact.state) || typeof fact.name !== "string" || fact.name.length > 128 || !/^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(fact.name) || setHas(names, fact.name)) throw new TypeError("invalid user binding name evidence");
|
|
1280
1293
|
const fields = fact.state === "provider" ? ["name", "state", "entryId"] : ["name", "state"];
|
|
1281
|
-
|
|
1294
|
+
let validFields = ownKeys(fact).length === fields.length;
|
|
1295
|
+
for (let field = 0; validFields && field < fields.length; field++) validFields = enumerable(fact, fields[field]);
|
|
1296
|
+
if (!validFields || fact.state === "provider" && (typeof fact.entryId !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(fact.entryId))) {
|
|
1282
1297
|
throw new TypeError("invalid user binding name evidence");
|
|
1283
1298
|
}
|
|
1284
|
-
names
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1299
|
+
setAdd(names, fact.name);
|
|
1300
|
+
defineProperty(normalized, normalized.length, {
|
|
1301
|
+
configurable: true,
|
|
1302
|
+
enumerable: true,
|
|
1303
|
+
writable: true,
|
|
1304
|
+
value: freeze({
|
|
1305
|
+
name: fact.name,
|
|
1306
|
+
state: fact.state,
|
|
1307
|
+
...fact.state === "provider" ? { entryId: fact.entryId } : {}
|
|
1308
|
+
})
|
|
1289
1309
|
});
|
|
1290
|
-
}
|
|
1310
|
+
}
|
|
1311
|
+
sort(normalized, (left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
1312
|
+
return freeze(normalized);
|
|
1291
1313
|
}
|
|
1292
1314
|
function normalizeJournalUserBindingNames(journal) {
|
|
1293
1315
|
if (!USER_BINDINGS_SHADOW_POLICIES.has(journal.userBindingsShadowPolicy)) {
|
|
@@ -1317,6 +1339,31 @@
|
|
|
1317
1339
|
return value;
|
|
1318
1340
|
}
|
|
1319
1341
|
|
|
1342
|
+
// internal/module-transform-contract.js
|
|
1343
|
+
var LEGACY_USER_BINDING_TRANSFORM = "amaro@1.1.11";
|
|
1344
|
+
var PREVIOUS_USER_BINDING_TRANSFORM = "stateful-module-v1+amaro@1.1.11";
|
|
1345
|
+
var USER_BINDING_TRANSFORM = "stateful-module-v2+amaro@1.1.11";
|
|
1346
|
+
var PROTECTED_MODULE_TRANSFORM = "protected-module-v1+amaro@1.1.11";
|
|
1347
|
+
var MODULE_TRANSFORMS = /* @__PURE__ */ new Set([
|
|
1348
|
+
LEGACY_USER_BINDING_TRANSFORM,
|
|
1349
|
+
PREVIOUS_USER_BINDING_TRANSFORM,
|
|
1350
|
+
USER_BINDING_TRANSFORM,
|
|
1351
|
+
PROTECTED_MODULE_TRANSFORM
|
|
1352
|
+
]);
|
|
1353
|
+
function isStatefulUserBindingTransform(transform) {
|
|
1354
|
+
return transform === USER_BINDING_TRANSFORM || transform === PREVIOUS_USER_BINDING_TRANSFORM;
|
|
1355
|
+
}
|
|
1356
|
+
function moduleTransformMatchesLanguage(transform, languageSemantics) {
|
|
1357
|
+
return languageSemantics === "stateful-v1" ? isStatefulUserBindingTransform(transform) : languageSemantics === "protected-v1" ? transform === PROTECTED_MODULE_TRANSFORM : languageSemantics === "legacy-v1" ? transform === LEGACY_USER_BINDING_TRANSFORM : false;
|
|
1358
|
+
}
|
|
1359
|
+
function normalizeModuleTransform(transform, languageSemantics) {
|
|
1360
|
+
if (!MODULE_TRANSFORMS.has(transform)) throw new TypeError("invalid dsh-ptc-plus journal module transform");
|
|
1361
|
+
if (!moduleTransformMatchesLanguage(transform, languageSemantics)) {
|
|
1362
|
+
throw new TypeError("dsh-ptc-plus journal module transform does not match its language semantics");
|
|
1363
|
+
}
|
|
1364
|
+
return transform;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1320
1367
|
// internal/value-wire-schema.js
|
|
1321
1368
|
var VALUE_CODEC = "ptc-value-graph/v1";
|
|
1322
1369
|
var DEFAULT_VALUE_LIMITS = Object.freeze({
|
|
@@ -1529,7 +1576,7 @@
|
|
|
1529
1576
|
return false;
|
|
1530
1577
|
}
|
|
1531
1578
|
const predecessor = value.version < 4;
|
|
1532
|
-
const fields = value.version === 1 ? LEGACY_JOURNAL_FIELDS : predecessor ? PREDECESSOR_JOURNAL_FIELDS : value.version === 4 ? RELATIONLESS_JOURNAL_FIELDS : value.version === 5 ? FINGERPRINT_REUSE_JOURNAL_FIELDS : value.version < PER_NAME_USER_BINDINGS_JOURNAL_VERSION ? WHOLE_ENTRY_JOURNAL_FIELDS : value.version < LANGUAGE_SEMANTICS_JOURNAL_VERSION ? PER_NAME_JOURNAL_FIELDS : JOURNAL_FIELDS;
|
|
1579
|
+
const fields = value.version === 1 ? LEGACY_JOURNAL_FIELDS : predecessor ? PREDECESSOR_JOURNAL_FIELDS : value.version === 4 ? RELATIONLESS_JOURNAL_FIELDS : value.version === 5 ? FINGERPRINT_REUSE_JOURNAL_FIELDS : value.version < PER_NAME_USER_BINDINGS_JOURNAL_VERSION ? WHOLE_ENTRY_JOURNAL_FIELDS : value.version < LANGUAGE_SEMANTICS_JOURNAL_VERSION ? PER_NAME_JOURNAL_FIELDS : value.version === LANGUAGE_SEMANTICS_JOURNAL_VERSION ? LANGUAGE_SEMANTICS_JOURNAL_FIELDS : JOURNAL_FIELDS;
|
|
1533
1580
|
const required = predecessor ? ["version", "bindingMode", "status", "calls", "operations", "diagnostics"] : ["version", "bindingPolicy", "rewritePolicy", "moduleSemantics", "status", "calls", "operations", "diagnostics"];
|
|
1534
1581
|
if (value.version !== 1 && value.version < 4) required.push("rewritePolicy");
|
|
1535
1582
|
if (value.version >= 5) required.push("userBindingsFingerprint");
|
|
@@ -1542,6 +1589,10 @@
|
|
|
1542
1589
|
required.push("languageSemantics");
|
|
1543
1590
|
normalizeLanguageSemantics(value.languageSemantics);
|
|
1544
1591
|
}
|
|
1592
|
+
if (value.version > LANGUAGE_SEMANTICS_JOURNAL_VERSION) {
|
|
1593
|
+
required.push("moduleTransform");
|
|
1594
|
+
normalizeModuleTransform(value.moduleTransform, value.languageSemantics);
|
|
1595
|
+
}
|
|
1545
1596
|
if (!hasClosedFields(value, fields, required) || predecessor && !BINDING_MODES.has(value.bindingMode) || value.version >= 4 && !isValidBindingPolicy(value.bindingPolicy) || value.version >= 4 && !isValidModuleSemantics(value.moduleSemantics, value.version) || value.version >= VERSIONED_BINDING_REUSE_JOURNAL_VERSION && !USER_BINDINGS_REUSE_POLICIES.has(value.userBindingsReusePolicy) || value.version >= 5 && value.userBindingsFingerprint !== null && (typeof value.userBindingsFingerprint !== "string" || !/^[a-f0-9]{64}$/.test(value.userBindingsFingerprint)) || value.version !== 1 && !isValidRewritePolicy(value.rewritePolicy) || !Array.isArray(value.calls) || !value.calls.every(isValidCall) || !Array.isArray(value.operations) || !value.operations.every(isValidOperation) || !isValidConfirms(value.confirms, value.version) || !Array.isArray(value.diagnostics) || !value.diagnostics.every(isValidDiagnostic)) return false;
|
|
1546
1597
|
const settlementOrder = value.calls.map((call) => call.settle).sort((left, right) => left - right);
|
|
1547
1598
|
if (settlementOrder.some((settle, index) => settle !== index)) return false;
|
|
@@ -2565,14 +2616,194 @@
|
|
|
2565
2616
|
return { ReplComposer, ReplConsole, ReplMemoryCard, replPopoverIsOpen, placeReplPopover };
|
|
2566
2617
|
}
|
|
2567
2618
|
|
|
2619
|
+
// internal/compiler-descriptors.js
|
|
2620
|
+
function createCompilerDescriptors(object, reflect) {
|
|
2621
|
+
const define = object.defineProperty, defineMany = object.defineProperties;
|
|
2622
|
+
const ownKeys2 = reflect.ownKeys, ownField = object.getOwnPropertyDescriptor;
|
|
2623
|
+
const reflectDefine = reflect.defineProperty;
|
|
2624
|
+
const descriptor = (fields) => ({ __proto__: null, ...fields });
|
|
2625
|
+
const ownedObject = function(value) {
|
|
2626
|
+
return object(value);
|
|
2627
|
+
};
|
|
2628
|
+
const names = object.getOwnPropertyNames(object);
|
|
2629
|
+
for (let index = 0; index < names.length; index++) {
|
|
2630
|
+
const name2 = names[index];
|
|
2631
|
+
if (name2 !== "name" && name2 !== "length" && name2 !== "prototype") {
|
|
2632
|
+
define(ownedObject, name2, descriptor(ownField(object, name2)));
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
const operations = {
|
|
2636
|
+
Object: ownedObject,
|
|
2637
|
+
descriptor,
|
|
2638
|
+
getOwnPropertyDescriptor(target, key) {
|
|
2639
|
+
const fields = ownField(target, key);
|
|
2640
|
+
return fields === void 0 ? void 0 : descriptor(fields);
|
|
2641
|
+
},
|
|
2642
|
+
defineProperty: (target, key, fields) => define(target, key, descriptor(fields)),
|
|
2643
|
+
reflectDefineProperty: (target, key, fields) => reflectDefine(target, key, descriptor(fields)),
|
|
2644
|
+
// Rehomed compiler data always writes an owned data field. The null
|
|
2645
|
+
// prototype still keeps native descriptor conversion from reaching an
|
|
2646
|
+
// inherited field, and this writer reaches it without the intermediate
|
|
2647
|
+
// own-field descriptor the generic path copies for every property.
|
|
2648
|
+
defineDataProperty(target, key, value, enumerable2) {
|
|
2649
|
+
const fields = { __proto__: null };
|
|
2650
|
+
fields.value = value;
|
|
2651
|
+
fields.enumerable = enumerable2;
|
|
2652
|
+
fields.writable = true;
|
|
2653
|
+
fields.configurable = true;
|
|
2654
|
+
return define(target, key, fields);
|
|
2655
|
+
},
|
|
2656
|
+
defineProperties(target, fields) {
|
|
2657
|
+
const table = { __proto__: null }, keys2 = ownKeys2(fields);
|
|
2658
|
+
for (let index = 0; index < keys2.length; index++) {
|
|
2659
|
+
const key = keys2[index];
|
|
2660
|
+
if (ownField(fields, key).enumerable) table[key] = descriptor(fields[key]);
|
|
2661
|
+
}
|
|
2662
|
+
return defineMany(target, table);
|
|
2663
|
+
}
|
|
2664
|
+
};
|
|
2665
|
+
ownedObject.defineProperty = operations.defineProperty;
|
|
2666
|
+
ownedObject.defineProperties = operations.defineProperties;
|
|
2667
|
+
ownedObject.getOwnPropertyDescriptor = operations.getOwnPropertyDescriptor;
|
|
2668
|
+
return operations;
|
|
2669
|
+
}
|
|
2670
|
+
var compilerDescriptorSource = Function.prototype.toString.call(createCompilerDescriptors);
|
|
2671
|
+
var compilerDescriptors = createCompilerDescriptors(Object, Reflect);
|
|
2672
|
+
|
|
2673
|
+
// internal/runtime-intrinsics.js
|
|
2674
|
+
var uncurry2 = Function.prototype.bind.bind(Function.prototype.call);
|
|
2675
|
+
var mapKeys = uncurry2(Map.prototype.keys);
|
|
2676
|
+
var mapIteratorNext = uncurry2(Object.getPrototypeOf((/* @__PURE__ */ new Map()).keys()).next);
|
|
2677
|
+
var weakMapGet = uncurry2(WeakMap.prototype.get);
|
|
2678
|
+
var weakMapSet = uncurry2(WeakMap.prototype.set);
|
|
2679
|
+
function appendArray(target, value) {
|
|
2680
|
+
compilerDescriptors.defineProperty(
|
|
2681
|
+
target,
|
|
2682
|
+
target.length,
|
|
2683
|
+
{ value, writable: true, enumerable: true, configurable: true }
|
|
2684
|
+
);
|
|
2685
|
+
return target;
|
|
2686
|
+
}
|
|
2687
|
+
function copyArray(source, start = 0, end = source.length, target = []) {
|
|
2688
|
+
for (let index = start; index < end; index++) appendArray(target, source[index]);
|
|
2689
|
+
return target;
|
|
2690
|
+
}
|
|
2691
|
+
var runtimeIntrinsics = {
|
|
2692
|
+
Object: compilerDescriptors.Object,
|
|
2693
|
+
Reflect: {
|
|
2694
|
+
apply: Reflect.apply,
|
|
2695
|
+
construct: Reflect.construct,
|
|
2696
|
+
deleteProperty: Reflect.deleteProperty,
|
|
2697
|
+
defineProperty: compilerDescriptors.reflectDefineProperty,
|
|
2698
|
+
has: Reflect.has,
|
|
2699
|
+
ownKeys: Reflect.ownKeys
|
|
2700
|
+
},
|
|
2701
|
+
Error,
|
|
2702
|
+
TypeError,
|
|
2703
|
+
Array,
|
|
2704
|
+
Map,
|
|
2705
|
+
Set,
|
|
2706
|
+
WeakMap,
|
|
2707
|
+
WeakSet,
|
|
2708
|
+
RegExp,
|
|
2709
|
+
Proxy,
|
|
2710
|
+
objectCreate: Object.create,
|
|
2711
|
+
objectDefineProperty: Object.defineProperty,
|
|
2712
|
+
objectEntries: Object.entries,
|
|
2713
|
+
objectFreeze: Object.freeze,
|
|
2714
|
+
objectGetOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,
|
|
2715
|
+
objectGetPrototypeOf: Object.getPrototypeOf,
|
|
2716
|
+
objectHasOwn: Object.hasOwn,
|
|
2717
|
+
objectIs: Object.is,
|
|
2718
|
+
objectKeys: Object.keys,
|
|
2719
|
+
objectPropertyIsEnumerable: uncurry2(Object.prototype.propertyIsEnumerable),
|
|
2720
|
+
reflectOwnKeys: Reflect.ownKeys,
|
|
2721
|
+
numberIsFinite: Number.isFinite,
|
|
2722
|
+
numberIsNaN: Number.isNaN,
|
|
2723
|
+
numberIsSafeInteger: Number.isSafeInteger,
|
|
2724
|
+
toBigInt: BigInt,
|
|
2725
|
+
toNumber: Number,
|
|
2726
|
+
toString: String,
|
|
2727
|
+
mapGet: uncurry2(Map.prototype.get),
|
|
2728
|
+
mapHas: uncurry2(Map.prototype.has),
|
|
2729
|
+
mapSet: uncurry2(Map.prototype.set),
|
|
2730
|
+
mapDelete: uncurry2(Map.prototype.delete),
|
|
2731
|
+
mapClear: uncurry2(Map.prototype.clear),
|
|
2732
|
+
mapSize: uncurry2(Object.getOwnPropertyDescriptor(Map.prototype, "size").get),
|
|
2733
|
+
mapFirstKey: (value) => mapIteratorNext(mapKeys(value)).value,
|
|
2734
|
+
mapForEach: uncurry2(Map.prototype.forEach),
|
|
2735
|
+
setHas: uncurry2(Set.prototype.has),
|
|
2736
|
+
setAdd: uncurry2(Set.prototype.add),
|
|
2737
|
+
setDelete: uncurry2(Set.prototype.delete),
|
|
2738
|
+
setClear: uncurry2(Set.prototype.clear),
|
|
2739
|
+
setSize: uncurry2(Object.getOwnPropertyDescriptor(Set.prototype, "size").get),
|
|
2740
|
+
setForEach: uncurry2(Set.prototype.forEach),
|
|
2741
|
+
weakMapHas: uncurry2(WeakMap.prototype.has),
|
|
2742
|
+
weakMapGet,
|
|
2743
|
+
weakMapSet,
|
|
2744
|
+
weakSetHas: uncurry2(WeakSet.prototype.has),
|
|
2745
|
+
weakSetAdd: uncurry2(WeakSet.prototype.add),
|
|
2746
|
+
isArray: Array.isArray,
|
|
2747
|
+
everyArray: uncurry2(Array.prototype.every),
|
|
2748
|
+
includes: uncurry2(Array.prototype.includes),
|
|
2749
|
+
join: uncurry2(Array.prototype.join),
|
|
2750
|
+
popArray: uncurry2(Array.prototype.pop),
|
|
2751
|
+
prependArray: uncurry2(Array.prototype.unshift),
|
|
2752
|
+
someArray: uncurry2(Array.prototype.some),
|
|
2753
|
+
sliceString: uncurry2(String.prototype.slice),
|
|
2754
|
+
splitString: uncurry2(String.prototype.split),
|
|
2755
|
+
searchString: uncurry2(String.prototype.search),
|
|
2756
|
+
replaceString: uncurry2(String.prototype.replace),
|
|
2757
|
+
trimString: uncurry2(String.prototype.trim),
|
|
2758
|
+
replaceAllString: uncurry2(String.prototype.replaceAll),
|
|
2759
|
+
includesString: uncurry2(String.prototype.includes),
|
|
2760
|
+
startsWith: uncurry2(String.prototype.startsWith),
|
|
2761
|
+
endsWith: uncurry2(String.prototype.endsWith),
|
|
2762
|
+
regexpExec: uncurry2(RegExp.prototype.exec),
|
|
2763
|
+
regexpTest: uncurry2(RegExp.prototype.test),
|
|
2764
|
+
floor: Math.floor,
|
|
2765
|
+
min: Math.min,
|
|
2766
|
+
max: Math.max,
|
|
2767
|
+
appendArray,
|
|
2768
|
+
copyArray,
|
|
2769
|
+
sort: uncurry2(Array.prototype.sort),
|
|
2770
|
+
compare: uncurry2(String.prototype.localeCompare)
|
|
2771
|
+
};
|
|
2772
|
+
if (typeof Buffer === "function") {
|
|
2773
|
+
runtimeIntrinsics.bufferByteLength = Buffer.byteLength;
|
|
2774
|
+
runtimeIntrinsics.bufferConcat = Buffer.concat;
|
|
2775
|
+
runtimeIntrinsics.bufferIsBuffer = Buffer.isBuffer;
|
|
2776
|
+
runtimeIntrinsics.bufferSubarray = uncurry2(Buffer.prototype.subarray);
|
|
2777
|
+
runtimeIntrinsics.bufferToString = uncurry2(Buffer.prototype.toString);
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2568
2780
|
// internal/record-utils.js
|
|
2781
|
+
var {
|
|
2782
|
+
TypeError: TypeError2,
|
|
2783
|
+
isArray: isArray2,
|
|
2784
|
+
reflectOwnKeys,
|
|
2785
|
+
objectGetOwnPropertyDescriptor,
|
|
2786
|
+
objectHasOwn,
|
|
2787
|
+
objectPropertyIsEnumerable,
|
|
2788
|
+
objectFreeze,
|
|
2789
|
+
trimString,
|
|
2790
|
+
toString: toString2,
|
|
2791
|
+
Set: Set2,
|
|
2792
|
+
setHas: setHas2,
|
|
2793
|
+
setAdd: setAdd2,
|
|
2794
|
+
setSize,
|
|
2795
|
+
appendArray: appendArray2,
|
|
2796
|
+
popArray
|
|
2797
|
+
} = runtimeIntrinsics;
|
|
2569
2798
|
function isRecord2(value) {
|
|
2570
|
-
return value !== null && typeof value === "object" && !
|
|
2799
|
+
return value !== null && typeof value === "object" && !isArray2(value);
|
|
2571
2800
|
}
|
|
2572
2801
|
function assertOwnFields(value, allowed, label) {
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2802
|
+
const keys2 = reflectOwnKeys(value);
|
|
2803
|
+
for (let index = 0; index < keys2.length; index += 1) {
|
|
2804
|
+
const key = keys2[index];
|
|
2805
|
+
if (typeof key !== "string" || !setHas2(allowed, key) || !objectPropertyIsEnumerable(value, key)) {
|
|
2806
|
+
throw new TypeError2(`invalid ${label} field ${toString2(key)}`);
|
|
2576
2807
|
}
|
|
2577
2808
|
}
|
|
2578
2809
|
}
|
|
@@ -6749,11 +6980,11 @@
|
|
|
6749
6980
|
`Y`.)
|
|
6750
6981
|
*/
|
|
6751
6982
|
update(updateSpec) {
|
|
6752
|
-
let { add: add2 = [], sort = false, filterFrom = 0, filterTo = this.length } = updateSpec;
|
|
6983
|
+
let { add: add2 = [], sort: sort2 = false, filterFrom = 0, filterTo = this.length } = updateSpec;
|
|
6753
6984
|
let filter = updateSpec.filter;
|
|
6754
6985
|
if (add2.length == 0 && !filter)
|
|
6755
6986
|
return this;
|
|
6756
|
-
if (
|
|
6987
|
+
if (sort2)
|
|
6757
6988
|
add2 = add2.slice().sort(cmpRange);
|
|
6758
6989
|
if (this.isEmpty)
|
|
6759
6990
|
return add2.length ? _RangeSet.of(add2) : this;
|
|
@@ -6919,9 +7150,9 @@
|
|
|
6919
7150
|
`value.startSide`). You can pass `true` as second argument to
|
|
6920
7151
|
cause the method to sort them.
|
|
6921
7152
|
*/
|
|
6922
|
-
static of(ranges,
|
|
7153
|
+
static of(ranges, sort2 = false) {
|
|
6923
7154
|
let build = new RangeSetBuilder();
|
|
6924
|
-
for (let range of ranges instanceof Range ? [ranges] :
|
|
7155
|
+
for (let range of ranges instanceof Range ? [ranges] : sort2 ? lazySort(ranges) : ranges)
|
|
6925
7156
|
build.add(range.from, range.to, range.value);
|
|
6926
7157
|
return build.finish();
|
|
6927
7158
|
}
|
|
@@ -7938,8 +8169,8 @@
|
|
|
7938
8169
|
decorated range or ranges. If the ranges aren't already sorted,
|
|
7939
8170
|
pass `true` for `sort` to make the library sort them for you.
|
|
7940
8171
|
*/
|
|
7941
|
-
static set(of,
|
|
7942
|
-
return RangeSet.of(of,
|
|
8172
|
+
static set(of, sort2 = false) {
|
|
8173
|
+
return RangeSet.of(of, sort2);
|
|
7943
8174
|
}
|
|
7944
8175
|
/**
|
|
7945
8176
|
@internal
|
|
@@ -8045,8 +8276,8 @@
|
|
|
8045
8276
|
/**
|
|
8046
8277
|
Create a range set from the given block wrapper ranges.
|
|
8047
8278
|
*/
|
|
8048
|
-
static set(of,
|
|
8049
|
-
return RangeSet.of(of,
|
|
8279
|
+
static set(of, sort2 = false) {
|
|
8280
|
+
return RangeSet.of(of, sort2);
|
|
8050
8281
|
}
|
|
8051
8282
|
};
|
|
8052
8283
|
BlockWrapper.prototype.startSide = BlockWrapper.prototype.endSide = -1;
|