@calmlens/sdk 0.16.2 → 0.17.1
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 +399 -162
- package/cjs/BrowserUpload-DZ0Vbmxi.js +10 -0
- package/cjs/BrowserUpload-uZjVFGfP.d.ts +11 -0
- package/cjs/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
- package/cjs/CalmLensAppClient-DBGmaDlG.js +89 -0
- package/cjs/CalmLensConnection-K1TAD1Z-.js +659 -0
- package/cjs/CalmLensServerClient-C-pxiz0C.js +645 -0
- package/cjs/CalmLensServerClient-JtP687a3.d.ts +235 -0
- package/cjs/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
- package/cjs/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
- package/cjs/CryptoUtils-B_x8lMIx-YBW1-bvL.js +42 -0
- package/cjs/FileIcons-Ob003MdS.js +175 -0
- package/cjs/Jurisdiction-FusEXb4U-zVs21tDv.js +91 -0
- package/cjs/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
- package/cjs/ModerationContextLimits-Dj1YAl3G.js +1311 -0
- package/cjs/ReactUpload-DxtFMr06.js +54 -0
- package/cjs/ReactUpload-nZahpmyg.d.ts +17 -0
- package/cjs/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
- package/cjs/TestTriggers-DcArt0Nu-CvoaONUB.js +1326 -0
- package/cjs/UploadController-BBkN4Ni6.js +618 -0
- package/{esm/index-C9Xw1aid.d.ts → cjs/WebhookPayload-2aL31v0J.d.ts} +131 -155
- package/cjs/app.d.ts +7 -44
- package/cjs/app.js +11 -89
- package/cjs/elements.d.ts +88 -0
- package/cjs/elements.js +555 -0
- package/cjs/file-icons.d.ts +67 -0
- package/cjs/file-icons.js +10 -0
- package/cjs/index-CI4BzN4W.d.ts +252 -0
- package/cjs/index.d.ts +6 -4
- package/cjs/index.js +9 -4
- package/cjs/react-native.d.ts +56 -0
- package/cjs/react-native.js +495 -0
- package/cjs/react.d.ts +30 -0
- package/cjs/react.js +370 -0
- package/cjs/server.d.ts +12 -191
- package/cjs/server.js +18 -378
- package/cjs/test-inputs.d.ts +2 -2
- package/cjs/test-inputs.js +9 -264
- package/cjs/testing.d.ts +285 -190
- package/cjs/testing.js +2393 -1203
- package/cjs/ui-CgZpgpNo.d.ts +526 -0
- package/cjs/ui-KceuoVCM.js +583 -0
- package/cjs/ui.d.ts +2 -0
- package/cjs/ui.js +27 -0
- package/cjs/vue.d.ts +490 -0
- package/cjs/vue.js +419 -0
- package/esm/BrowserUpload-D7-zNmc0.js +5 -0
- package/esm/BrowserUpload-uZjVFGfP.d.ts +11 -0
- package/esm/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
- package/esm/CalmLensAppClient-FVMwrHlH.js +84 -0
- package/esm/CalmLensConnection-iyNQHA8L.js +582 -0
- package/esm/CalmLensServerClient-JtP687a3.d.ts +235 -0
- package/esm/CalmLensServerClient-fQEYKLw4.js +586 -0
- package/esm/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
- package/esm/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
- package/esm/CryptoUtils-B_x8lMIx-DhuWGzqn.js +25 -0
- package/esm/FileIcons-M6dzjFxd.js +128 -0
- package/esm/Jurisdiction-FusEXb4U-1ov6m5yE.js +46 -0
- package/esm/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
- package/esm/ModerationContextLimits-D1x_WAtP.js +1114 -0
- package/esm/ReactUpload-D6yBCkcw.js +37 -0
- package/esm/ReactUpload-nZahpmyg.d.ts +17 -0
- package/esm/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
- package/esm/TestTriggers-DcArt0Nu-s0AQZuWE.js +1266 -0
- package/esm/UploadController-txp5NuzH.js +589 -0
- package/{cjs/index-C9Xw1aid.d.ts → esm/WebhookPayload-2aL31v0J.d.ts} +131 -155
- package/esm/app.d.ts +7 -44
- package/esm/app.js +3 -86
- package/esm/elements.d.ts +88 -0
- package/esm/elements.js +528 -0
- package/esm/file-icons.d.ts +67 -0
- package/esm/file-icons.js +1 -0
- package/esm/index-CI4BzN4W.d.ts +252 -0
- package/esm/index.d.ts +6 -4
- package/esm/index.js +1 -1
- package/esm/react-native.d.ts +56 -0
- package/esm/react-native.js +467 -0
- package/esm/react.d.ts +30 -0
- package/esm/react.js +343 -0
- package/esm/server.d.ts +12 -191
- package/esm/server.js +3 -369
- package/esm/styles.css +147 -0
- package/esm/svelte/CalmLensMedia.svelte +134 -0
- package/esm/svelte/CalmLensUploader.svelte +175 -0
- package/esm/svelte/Icon.svelte +7 -0
- package/esm/svelte/index.d.ts +37 -0
- package/esm/svelte/index.js +6 -0
- package/esm/test-inputs.d.ts +2 -2
- package/esm/test-inputs.js +1 -256
- package/esm/testing.d.ts +285 -190
- package/esm/testing.js +2329 -1122
- package/esm/ui-Ca_SpJXf.js +458 -0
- package/esm/ui-CgZpgpNo.d.ts +526 -0
- package/esm/ui.d.ts +2 -0
- package/esm/ui.js +3 -0
- package/esm/vue.d.ts +490 -0
- package/esm/vue.js +392 -0
- package/package.json +110 -11
- package/cjs/CalmLensConnection-5Hj3trGr.js +0 -234
- package/cjs/CalmLensUtils-BeIl1N6N.js +0 -699
- package/cjs/CalmLensVersion-BGpB9t4-.js +0 -480
- package/cjs/CalmLensWebhooks-CogUYk8-.js +0 -201
- package/cjs/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
- package/cjs/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
- package/cjs/WebhookPayload-CJoIkGBD.d.ts +0 -11753
- package/esm/CalmLensConnection-BAJdoZHy.js +0 -193
- package/esm/CalmLensUtils-DqniTKJ8.js +0 -574
- package/esm/CalmLensVersion-l_khh4nS.js +0 -415
- package/esm/CalmLensWebhooks-BtrKKLvg.js +0 -148
- package/esm/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
- package/esm/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
- package/esm/WebhookPayload-CJoIkGBD.d.ts +0 -11753
package/cjs/server.js
CHANGED
|
@@ -1,380 +1,20 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_ModerationContextLimits = require("./ModerationContextLimits-Dj1YAl3G.js");
|
|
3
3
|
require("./index.js");
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* throws `CalmLensError` on failure. Browsers and apps upload with `CalmLensAppClient` instead.
|
|
22
|
-
*/
|
|
23
|
-
var CalmLensServerClient = class CalmLensServerClient {
|
|
24
|
-
#apiKey;
|
|
25
|
-
#settings;
|
|
26
|
-
#lenses;
|
|
27
|
-
#connection;
|
|
28
|
-
/**
|
|
29
|
-
* Verifies that a webhook delivery came from CalmLens: checks the `v1=` HMAC-SHA256 in
|
|
30
|
-
* `x-calmlens-signature` over `"<x-calmlens-timestamp>.<raw body>"` and rejects timestamps
|
|
31
|
-
* more than `toleranceSeconds` (default 300) from now, which stops replayed deliveries.
|
|
32
|
-
* Also exported as `verifyWebhookSignature`; `parseWebhookEvent` verifies and parses.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* const payload = await request.text();
|
|
37
|
-
* const isValid = await CalmLensServerClient.verifyWebhookSignature({
|
|
38
|
-
* payload,
|
|
39
|
-
* headers: request.headers,
|
|
40
|
-
* secret: process.env.CALMLENS_WEBHOOK_SECRET!,
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
static async verifyWebhookSignature(options) {
|
|
45
|
-
return require_CalmLensWebhooks.verifyWebhookSignature(options);
|
|
46
|
-
}
|
|
47
|
-
constructor(options, lenses) {
|
|
48
|
-
require_CalmLensUtils.validateServerClientOptions(options);
|
|
49
|
-
if ((require_CalmLensVersion.isBrowserRuntime() || require_CalmLensVersion.isReactNativeRuntime()) && !options.dangerouslyAllowBrowser) throw require_CalmLensVersion.invalidConfig("CalmLensServerClient is running in a browser or app, where anyone could read the API key. Call CalmLens from your server, upload from the browser or app with CalmLensAppClient, or set dangerouslyAllowBrowser: true for trusted internal tools.");
|
|
50
|
-
const { apiKey, ...rest } = options;
|
|
51
|
-
this.#apiKey = apiKey;
|
|
52
|
-
this.#settings = {
|
|
53
|
-
...require_CalmLensConnection.resolveConnectionOptions(rest),
|
|
54
|
-
cdnBaseUrl: (rest.cdnBaseUrl ?? `https://cdn.calmlens.com/v1`).replace(/\/+$/, "")
|
|
55
|
-
};
|
|
56
|
-
this.#lenses = lenses ?? {
|
|
57
|
-
ensuredLenses: /* @__PURE__ */ new Map(),
|
|
58
|
-
pendingEnsureLenses: /* @__PURE__ */ new Map()
|
|
59
|
-
};
|
|
60
|
-
this.#connection = new require_CalmLensConnection.CalmLensConnection(this.#settings, apiKey);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* A client with different cancellation, deadlines or retries for the calls made through it,
|
|
64
|
-
* sharing this client's credentials and lens cache. This client is unchanged.
|
|
65
|
-
*/
|
|
66
|
-
withRequestOptions(options) {
|
|
67
|
-
require_CalmLensUtils.validateRequestOptions(options);
|
|
68
|
-
return new CalmLensServerClient({
|
|
69
|
-
...this.#settings,
|
|
70
|
-
...options,
|
|
71
|
-
apiKey: this.#apiKey
|
|
72
|
-
}, this.#lenses);
|
|
73
|
-
}
|
|
74
|
-
/** Keeps the API key out of `console.log`, `util.inspect` and `JSON.stringify`. */
|
|
75
|
-
[inspectSymbol]() {
|
|
76
|
-
const { projectId, baseUrl } = this.#settings;
|
|
77
|
-
return `CalmLensServerClient { projectId: ${JSON.stringify(projectId)}, baseUrl: ${JSON.stringify(baseUrl)} }`;
|
|
78
|
-
}
|
|
79
|
-
toJSON() {
|
|
80
|
-
const { projectId, baseUrl, cdnBaseUrl } = this.#settings;
|
|
81
|
-
return {
|
|
82
|
-
projectId,
|
|
83
|
-
baseUrl,
|
|
84
|
-
cdnBaseUrl
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
get projectPath() {
|
|
88
|
-
return `/projects/${encodeURIComponent(this.#settings.projectId)}`;
|
|
89
|
-
}
|
|
90
|
-
request(method, path, options = {}) {
|
|
91
|
-
return this.#connection.json(method, path, options);
|
|
92
|
-
}
|
|
93
|
-
async submitAsset(options, queue) {
|
|
94
|
-
const body = require_CalmLensConnection.prepareSubmitAssetOptions(options);
|
|
95
|
-
const uploadsPath = `${this.projectPath}/assets`;
|
|
96
|
-
if ("content" in body || "part" in body) return require_CalmLensConnection.expectAsset(await this.#connection.submitRawUpload(uploadsPath, body, queue));
|
|
97
|
-
const { idempotencyKey, ...fields } = body;
|
|
98
|
-
const data = await this.#connection.json("POST", uploadsPath, {
|
|
99
|
-
query: { queue },
|
|
100
|
-
body: fields,
|
|
101
|
-
idempotencyKey: idempotencyKey ?? require_CalmLensConnection.newIdempotencyKey()
|
|
102
|
-
});
|
|
103
|
-
return require_CalmLensConnection.expectAsset(data);
|
|
104
|
-
}
|
|
105
|
-
get cdn() {
|
|
106
|
-
return {
|
|
107
|
-
/**
|
|
108
|
-
* Builds a CDN URL for asset content or a preview, without a request. Private assets
|
|
109
|
-
* need a signed URL (`assets.createSignedUrl`) or an authenticated request.
|
|
110
|
-
*/
|
|
111
|
-
getAssetUrl: ({ assetIdentifier, ...options }) => {
|
|
112
|
-
const resource = options.resource ?? "content";
|
|
113
|
-
const { projectId } = this.#settings;
|
|
114
|
-
const url = `${this.#settings.cdnBaseUrl}/assets/${encodeURIComponent(projectId)}/${requireId(assetIdentifier, "Asset identifier")}/${resource}`;
|
|
115
|
-
return require_CalmLensUtils.appendCdnSelector(url, options);
|
|
116
|
-
},
|
|
117
|
-
/**
|
|
118
|
-
* Fetches asset content or a preview from the CDN with the client's API key, and returns
|
|
119
|
-
* the `Response` as soon as headers arrive, so the body streams. Non-2xx responses are
|
|
120
|
-
* returned, not thrown; `timeoutMs` covers only the wait for headers.
|
|
121
|
-
*/
|
|
122
|
-
serve: async ({ assetIdentifier, init, ...urlOptions }) => {
|
|
123
|
-
const url = this.cdn.getAssetUrl({
|
|
124
|
-
assetIdentifier,
|
|
125
|
-
...urlOptions
|
|
126
|
-
});
|
|
127
|
-
const method = init?.method?.toUpperCase() ?? "GET";
|
|
128
|
-
const { response } = await this.#connection.transport.send({
|
|
129
|
-
method,
|
|
130
|
-
url,
|
|
131
|
-
init,
|
|
132
|
-
timeoutMs: this.#connection.timeoutMs,
|
|
133
|
-
deadline: "headers",
|
|
134
|
-
fetch: this.#settings.cdnFetch
|
|
135
|
-
}, { allowHttpErrors: true });
|
|
136
|
-
return response;
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
get text() {
|
|
141
|
-
return {
|
|
142
|
-
/**
|
|
143
|
-
* Moderates text and waits for the decision. Sends `text` as `text/plain` content named
|
|
144
|
-
* `text` unless you pass `name`.
|
|
145
|
-
*/
|
|
146
|
-
moderate: async (options) => this.buildAssets().moderate(require_CalmLensUtils.toTextAssetOptions(options)) };
|
|
147
|
-
}
|
|
148
|
-
/** Assets: uploads, moderation and management. */
|
|
149
|
-
get assets() {
|
|
150
|
-
return this.buildAssets();
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Signs upload tokens on your server, so a browser or app can upload through an upload preset
|
|
154
|
-
* that requires one. Signing happens locally with your API key: it makes no request.
|
|
155
|
-
*/
|
|
156
|
-
get uploadTokens() {
|
|
157
|
-
return {
|
|
158
|
-
/**
|
|
159
|
-
* Signs a single-use token for one upload through `uploadPresetId`. Give `token` to the
|
|
160
|
-
* browser or app, which passes it to `CalmLensAppClient` as `token`.
|
|
161
|
-
*/
|
|
162
|
-
sign: async (options) => {
|
|
163
|
-
return require_CalmLensWebhooks.signUploadTokenWithApiKey(this.#apiKey, options);
|
|
164
|
-
} };
|
|
165
|
-
}
|
|
166
|
-
buildAssets() {
|
|
167
|
-
return {
|
|
168
|
-
/** Searches accessible assets by keyword or a natural-language description. */
|
|
169
|
-
search: async (options) => this.request("GET", `${this.projectPath}/assets/search`, { query: options }),
|
|
170
|
-
/** Lists one page of the project's assets, with optional filter and ordering. */
|
|
171
|
-
list: async (options = {}) => this.request("GET", `${this.projectPath}/assets/page`, { query: options }),
|
|
172
|
-
/**
|
|
173
|
-
* Yields every asset matching `options`, fetching pages as needed. The cursor keeps the position
|
|
174
|
-
* stable when other assets are inserted or deleted.
|
|
175
|
-
*/
|
|
176
|
-
iterate: (options = {}) => this.iteratePages((cursor) => this.buildAssets().list({
|
|
177
|
-
...options,
|
|
178
|
-
cursor
|
|
179
|
-
})),
|
|
180
|
-
/** Retrieves an asset with its status and moderation report. */
|
|
181
|
-
retrieve: async ({ assetId }) => this.request("GET", `/assets/${requireId(assetId, "Asset ID")}`),
|
|
182
|
-
/** Updates an asset's editable fields. */
|
|
183
|
-
update: async ({ assetId, ...body }) => this.request("PATCH", `/assets/${requireId(assetId, "Asset ID")}`, { body }),
|
|
184
|
-
/** Lists one page of the assets extracted from a website or multimedia document. */
|
|
185
|
-
listChildren: async ({ assetId, ...options } = {}) => this.request("GET", `/assets/${requireId(assetId, "Asset ID")}/children`, { query: options }),
|
|
186
|
-
/** Yields every child of an asset, fetching pages as needed. */
|
|
187
|
-
iterateChildren: (options) => {
|
|
188
|
-
requireId(options?.assetId, "Asset ID");
|
|
189
|
-
return this.iteratePages((cursor) => this.buildAssets().listChildren({
|
|
190
|
-
...options,
|
|
191
|
-
cursor
|
|
192
|
-
}));
|
|
193
|
-
},
|
|
194
|
-
/**
|
|
195
|
-
* Uploads an asset and queues it for moderation, returning immediately with processing
|
|
196
|
-
* status `processing` (or `uploading` for the first multipart part). Retried safely with an
|
|
197
|
-
* `Idempotency-Key`.
|
|
198
|
-
*/
|
|
199
|
-
create: async (options) => this.submitAsset(options, true),
|
|
200
|
-
/**
|
|
201
|
-
* Uploads an asset and waits for its moderation decision. Audio and video still finish
|
|
202
|
-
* in the background. Retried safely with an `Idempotency-Key`.
|
|
203
|
-
*/
|
|
204
|
-
moderate: async (options) => {
|
|
205
|
-
if (options && "content" in options && "plainText" in options.content && (typeof options.content.plainText !== "string" || !options.content.plainText.trim())) throw require_CalmLensConnection.invalidPayload("Text to moderate must be a non-empty string");
|
|
206
|
-
return this.submitAsset(options, false);
|
|
207
|
-
},
|
|
208
|
-
/**
|
|
209
|
-
* Uploads the next part of a multipart upload. The upload's queue mode, chosen when it
|
|
210
|
-
* started, applies when the final part arrives; pass `queue` to override it.
|
|
211
|
-
*/
|
|
212
|
-
uploadPart: async ({ assetId, ...options }) => {
|
|
213
|
-
const encodedAssetId = requireId(assetId, "Asset ID");
|
|
214
|
-
return require_CalmLensConnection.expectAsset(await this.#connection.uploadPart(`/assets/${encodedAssetId}/part`, options));
|
|
215
|
-
},
|
|
216
|
-
/**
|
|
217
|
-
* Creates a short-lived signed CDN URL, so browsers can load private content without
|
|
218
|
-
* an API key.
|
|
219
|
-
*/
|
|
220
|
-
createSignedUrl: async ({ assetId, ...options }) => {
|
|
221
|
-
const encodedAssetId = requireId(assetId, "Asset ID");
|
|
222
|
-
return this.request("POST", `/assets/${encodedAssetId}/signed-url`, { body: {
|
|
223
|
-
resource: options.resource ?? "content",
|
|
224
|
-
expiresInSeconds: options.expiresInSeconds ?? 900,
|
|
225
|
-
lens: options.lens,
|
|
226
|
-
transform: require_CalmLensUtils.transformSelector(options.transform)
|
|
227
|
-
} });
|
|
228
|
-
},
|
|
229
|
-
/** Moves an asset into a folder, or to the project root with `folderId: null`. */
|
|
230
|
-
move: async ({ assetId, folderId }) => this.request("POST", `/assets/${requireId(assetId, "Asset ID")}/move`, { body: { folderId } }),
|
|
231
|
-
/**
|
|
232
|
-
* Processes an asset that failed (processing status `failed`) again. It returns to
|
|
233
|
-
* `processing` and is
|
|
234
|
-
* moderated like a new upload; its content must still be stored.
|
|
235
|
-
*/
|
|
236
|
-
retry: async ({ assetId }) => this.request("POST", `/assets/${requireId(assetId, "Asset ID")}/retry`),
|
|
237
|
-
/**
|
|
238
|
-
* Waits until an asset's `moderation.status` is `approved` or `rejected`, or its
|
|
239
|
-
* `processing.status` is `failed`, and returns that asset, checking every few seconds. Rejects with `sdk/timeout` if there is no
|
|
240
|
-
* decision within `timeoutMs` (default 60000). Webhooks report decisions without polling.
|
|
241
|
-
*/
|
|
242
|
-
waitForDecision: async ({ assetId, ...options }) => {
|
|
243
|
-
requireId(assetId, "Asset ID");
|
|
244
|
-
const client = options.signal ? this.withRequestOptions({ signal: options.signal }) : this;
|
|
245
|
-
return require_CalmLensUtils.pollForDecision(() => client.assets.retrieve({ assetId }), options, require_CalmLensUtils.sleep);
|
|
246
|
-
},
|
|
247
|
-
/**
|
|
248
|
-
* Removes an asset's stored content (source, preview and retained extracted text) while
|
|
249
|
-
* keeping the asset record, metadata and moderation report. The returned asset has
|
|
250
|
-
* `storageDeletedAt` set; the CDN no longer serves it.
|
|
251
|
-
*/
|
|
252
|
-
deleteContent: async ({ assetId }) => this.request("DELETE", `/assets/${requireId(assetId, "Asset ID")}/content`),
|
|
253
|
-
/** Deletes an asset record together with its stored content. */
|
|
254
|
-
delete: async ({ assetId }) => {
|
|
255
|
-
await this.request("DELETE", `/assets/${requireId(assetId, "Asset ID")}`);
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
get events() {
|
|
260
|
-
return {
|
|
261
|
-
/**
|
|
262
|
-
* Lists project events after a cursor, oldest first. Call without `after` to get a cursor
|
|
263
|
-
* for "now", then poll with the returned `cursor`. Webhook deliveries carry the same events
|
|
264
|
-
* reshaped as `{ id, type, createdAt, projectId, data }`.
|
|
265
|
-
*/
|
|
266
|
-
list: async (options = {}) => this.request("GET", `${this.projectPath}/events`, { query: { ...options } }),
|
|
267
|
-
/**
|
|
268
|
-
* Yields pages of events after `after` until no more are waiting. Save each page's
|
|
269
|
-
* `cursor` to resume later. Without `after`, yields one empty page whose cursor is "now".
|
|
270
|
-
*/
|
|
271
|
-
pages: (options = {}) => this.iterateEventPages(options)
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
async *iterateEventPages(options) {
|
|
275
|
-
let after = options.after;
|
|
276
|
-
for (;;) {
|
|
277
|
-
const page = await this.events.list({
|
|
278
|
-
...options,
|
|
279
|
-
after
|
|
280
|
-
});
|
|
281
|
-
yield page;
|
|
282
|
-
if (!page.hasMore || page.cursor === after) return;
|
|
283
|
-
after = page.cursor;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
async *iteratePages(listPage) {
|
|
287
|
-
let cursor;
|
|
288
|
-
for (;;) {
|
|
289
|
-
const page = await listPage(cursor);
|
|
290
|
-
yield* page.items;
|
|
291
|
-
if (!page.nextCursor || !page.hasMore || page.items.length === 0) return;
|
|
292
|
-
cursor = page.nextCursor;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
get folders() {
|
|
296
|
-
return {
|
|
297
|
-
/** Lists every folder in the project. */
|
|
298
|
-
list: async () => (await this.request("GET", `${this.projectPath}/folders`)).folders,
|
|
299
|
-
retrieve: async ({ folderId }) => this.request("GET", `/folders/${requireId(folderId, "Folder ID")}`),
|
|
300
|
-
/** Creates a folder at the project root or inside `parentId`. */
|
|
301
|
-
create: async (options) => this.request("POST", `${this.projectPath}/folders`, { body: options }),
|
|
302
|
-
update: async ({ folderId, ...body }) => this.request("PATCH", `/folders/${requireId(folderId, "Folder ID")}`, { body }),
|
|
303
|
-
/** Deletes an empty folder; throws `folder/not-empty` otherwise. */
|
|
304
|
-
delete: async ({ folderId }) => {
|
|
305
|
-
await this.request("DELETE", `/folders/${requireId(folderId, "Folder ID")}`);
|
|
306
|
-
},
|
|
307
|
-
/** Moves a folder under `parentId`, or to the project root with `parentId: null`. */
|
|
308
|
-
move: async ({ folderId, parentId }) => this.request("POST", `/folders/${requireId(folderId, "Folder ID")}/move`, { body: { parentId } })
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Create a named lens at any positive version, or update it with a greater version.
|
|
313
|
-
* Supplying the same definition and version is idempotent.
|
|
314
|
-
*/
|
|
315
|
-
async ensureLens(options) {
|
|
316
|
-
if (!options?.identifier) throw require_CalmLensVersion.invalidArgument("Lens identifier is required");
|
|
317
|
-
const [lens] = await this.ensureLenses({ lenses: [options] });
|
|
318
|
-
return lens;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Create or update several named lenses. New definitions are sent in one API request, or in
|
|
322
|
-
* consecutive requests of at most {@link ENSURE_LENSES_MAX_PER_REQUEST} definitions, in order.
|
|
323
|
-
* Each lens follows the same versioning and idempotency rules as ensureLens().
|
|
324
|
-
*/
|
|
325
|
-
async ensureLenses({ lenses }) {
|
|
326
|
-
if (!Array.isArray(lenses) || lenses.length === 0) throw require_CalmLensVersion.invalidArgument("At least one lens is required");
|
|
327
|
-
if (lenses.some((option) => !option?.identifier)) throw require_CalmLensVersion.invalidArgument("Lens identifier is required");
|
|
328
|
-
const { ensuredLenses, pendingEnsureLenses } = this.#lenses;
|
|
329
|
-
const missingOptions = [];
|
|
330
|
-
const missingKeys = /* @__PURE__ */ new Set();
|
|
331
|
-
for (const option of lenses) {
|
|
332
|
-
const cacheKey = getEnsureLensCacheKey(option);
|
|
333
|
-
if (!ensuredLenses.has(cacheKey) && !missingKeys.has(cacheKey)) {
|
|
334
|
-
missingKeys.add(cacheKey);
|
|
335
|
-
missingOptions.push(option);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
if (missingOptions.length > 0) {
|
|
339
|
-
const batchCacheKey = JSON.stringify([...missingKeys].sort());
|
|
340
|
-
let pending = pendingEnsureLenses.get(batchCacheKey);
|
|
341
|
-
if (!pending) {
|
|
342
|
-
pending = this.submitEnsureLenses(missingOptions);
|
|
343
|
-
pendingEnsureLenses.set(batchCacheKey, pending);
|
|
344
|
-
pending.then(() => pendingEnsureLenses.delete(batchCacheKey), () => pendingEnsureLenses.delete(batchCacheKey));
|
|
345
|
-
}
|
|
346
|
-
await pending;
|
|
347
|
-
}
|
|
348
|
-
return lenses.map((option) => {
|
|
349
|
-
const lens = ensuredLenses.get(getEnsureLensCacheKey(option));
|
|
350
|
-
if (!lens) throw new require_CalmLensVersion.CalmLensError(require_CalmLensVersion.SDK_ERROR_CODES.INVALID_RESPONSE, { message: `CalmLens did not return lens "${option.identifier}"` });
|
|
351
|
-
return lens;
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
async submitEnsureLenses(options) {
|
|
355
|
-
for (let start = 0; start < options.length; start += 100) await this.submitEnsureLensesChunk(options.slice(start, start + 100));
|
|
356
|
-
}
|
|
357
|
-
async submitEnsureLensesChunk(options) {
|
|
358
|
-
const result = await this.request("PUT", `${this.projectPath}/lenses`, { body: { lenses: options } });
|
|
359
|
-
const returned = Array.isArray(result?.lenses) ? result.lenses : [];
|
|
360
|
-
if (returned.length !== options.length) throw new require_CalmLensVersion.CalmLensError(require_CalmLensVersion.SDK_ERROR_CODES.INVALID_RESPONSE, { message: `Expected ${options.length} lenses but CalmLens returned ${returned.length}` });
|
|
361
|
-
const { ensuredLenses } = this.#lenses;
|
|
362
|
-
for (const [index, lens] of returned.entries()) {
|
|
363
|
-
const optionsForLens = options[index];
|
|
364
|
-
if (lens?.identifier !== optionsForLens.identifier) throw new require_CalmLensVersion.CalmLensError(require_CalmLensVersion.SDK_ERROR_CODES.INVALID_RESPONSE, { message: `Expected lens "${optionsForLens.identifier}" at position ${index}` });
|
|
365
|
-
for (const [cacheKey, cachedLens] of ensuredLenses) if (cachedLens.identifier === optionsForLens.identifier) ensuredLenses.delete(cacheKey);
|
|
366
|
-
ensuredLenses.set(getEnsureLensCacheKey(optionsForLens), lens);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
//#endregion
|
|
371
|
-
exports.CALMLENS_ERROR_CODES = require_CalmLensVersion.CALMLENS_ERROR_CODES;
|
|
372
|
-
exports.CalmLensError = require_CalmLensVersion.CalmLensError;
|
|
373
|
-
exports.CalmLensServerClient = CalmLensServerClient;
|
|
374
|
-
exports.SDK_VERSION = require_CalmLensVersion.SDK_VERSION;
|
|
375
|
-
exports.WEBHOOK_DELIVERY_HEADER = require_CalmLensWebhooks.WEBHOOK_DELIVERY_HEADER;
|
|
376
|
-
exports.WEBHOOK_SIGNATURE_HEADER = require_CalmLensWebhooks.WEBHOOK_SIGNATURE_HEADER;
|
|
377
|
-
exports.WEBHOOK_SIGNATURE_TOLERANCE_SECONDS = require_CalmLensWebhooks.WEBHOOK_SIGNATURE_TOLERANCE_SECONDS;
|
|
378
|
-
exports.WEBHOOK_TIMESTAMP_HEADER = require_CalmLensWebhooks.WEBHOOK_TIMESTAMP_HEADER;
|
|
379
|
-
exports.parseWebhookEvent = require_CalmLensWebhooks.parseWebhookEvent;
|
|
380
|
-
exports.verifyWebhookSignature = require_CalmLensWebhooks.verifyWebhookSignature;
|
|
4
|
+
const require_CalmLensServerClient = require("./CalmLensServerClient-C-pxiz0C.js");
|
|
5
|
+
exports.CALMLENS_ERROR_CODES = require_ModerationContextLimits.CALMLENS_ERROR_CODES;
|
|
6
|
+
exports.CalmLensError = require_ModerationContextLimits.CalmLensError;
|
|
7
|
+
exports.CalmLensServerClient = require_CalmLensServerClient.CalmLensServerClient;
|
|
8
|
+
exports.DEFAULT_CDN_BASE_URL = require_ModerationContextLimits.DEFAULT_CDN_BASE_URL;
|
|
9
|
+
exports.MODERATION_CONTEXT_USED_CHARACTERS = require_ModerationContextLimits.MODERATION_CONTEXT_USED_CHARACTERS;
|
|
10
|
+
exports.MODERATION_CONTEXT_USED_ITEMS = require_ModerationContextLimits.MODERATION_CONTEXT_USED_ITEMS;
|
|
11
|
+
exports.SDK_VERSION = require_ModerationContextLimits.SDK_VERSION;
|
|
12
|
+
exports.WEBHOOK_DELIVERY_HEADER = require_CalmLensServerClient.WEBHOOK_DELIVERY_HEADER;
|
|
13
|
+
exports.WEBHOOK_SIGNATURE_HEADER = require_CalmLensServerClient.WEBHOOK_SIGNATURE_HEADER;
|
|
14
|
+
exports.WEBHOOK_SIGNATURE_TOLERANCE_SECONDS = require_CalmLensServerClient.WEBHOOK_SIGNATURE_TOLERANCE_SECONDS;
|
|
15
|
+
exports.WEBHOOK_TIMESTAMP_HEADER = require_CalmLensServerClient.WEBHOOK_TIMESTAMP_HEADER;
|
|
16
|
+
exports.getAssetUrl = require_ModerationContextLimits.getAssetUrl;
|
|
17
|
+
exports.isTestWebhookEvent = require_CalmLensServerClient.isTestWebhookEvent;
|
|
18
|
+
exports.parseWebhookEvent = require_CalmLensServerClient.parseWebhookEvent;
|
|
19
|
+
exports.selectModerationContextItems = require_ModerationContextLimits.selectModerationContextItems;
|
|
20
|
+
exports.verifyWebhookSignature = require_CalmLensServerClient.verifyWebhookSignature;
|
package/cjs/test-inputs.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as detectTestImage, c as getImageTestCategories,
|
|
2
|
-
export { type ClassificationTestSignal,
|
|
1
|
+
import { a as detectTestImage, c as getImageTestCategories, i as TestInput, l as paintTestImage, n as TEST_INPUT_KEY_PATTERN, o as detectTestTrigger, r as TEST_INPUT_PRESETS, s as generateTestTextCode, t as ClassificationTestSignal, u as testInputForSignal } from "./TestTriggers-By07LR31-CmK0yTyR.js";
|
|
2
|
+
export { type ClassificationTestSignal, TEST_INPUT_KEY_PATTERN, TEST_INPUT_PRESETS, type TestInput, detectTestImage, detectTestTrigger, generateTestTextCode, getImageTestCategories, paintTestImage, testInputForSignal };
|
package/cjs/test-inputs.js
CHANGED
|
@@ -1,265 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
[
|
|
12
|
-
255,
|
|
13
|
-
105,
|
|
14
|
-
180,
|
|
15
|
-
255
|
|
16
|
-
],
|
|
17
|
-
[
|
|
18
|
-
199,
|
|
19
|
-
21,
|
|
20
|
-
133,
|
|
21
|
-
255
|
|
22
|
-
],
|
|
23
|
-
[
|
|
24
|
-
255,
|
|
25
|
-
69,
|
|
26
|
-
0,
|
|
27
|
-
255
|
|
28
|
-
]
|
|
29
|
-
],
|
|
30
|
-
violence: [
|
|
31
|
-
[
|
|
32
|
-
139,
|
|
33
|
-
0,
|
|
34
|
-
0,
|
|
35
|
-
255
|
|
36
|
-
],
|
|
37
|
-
[
|
|
38
|
-
220,
|
|
39
|
-
20,
|
|
40
|
-
60,
|
|
41
|
-
255
|
|
42
|
-
],
|
|
43
|
-
[
|
|
44
|
-
178,
|
|
45
|
-
34,
|
|
46
|
-
34,
|
|
47
|
-
255
|
|
48
|
-
],
|
|
49
|
-
[
|
|
50
|
-
255,
|
|
51
|
-
0,
|
|
52
|
-
0,
|
|
53
|
-
255
|
|
54
|
-
]
|
|
55
|
-
],
|
|
56
|
-
harassment: [
|
|
57
|
-
[
|
|
58
|
-
180,
|
|
59
|
-
83,
|
|
60
|
-
9,
|
|
61
|
-
255
|
|
62
|
-
],
|
|
63
|
-
[
|
|
64
|
-
217,
|
|
65
|
-
119,
|
|
66
|
-
6,
|
|
67
|
-
255
|
|
68
|
-
],
|
|
69
|
-
[
|
|
70
|
-
245,
|
|
71
|
-
158,
|
|
72
|
-
11,
|
|
73
|
-
255
|
|
74
|
-
],
|
|
75
|
-
[
|
|
76
|
-
251,
|
|
77
|
-
191,
|
|
78
|
-
36,
|
|
79
|
-
255
|
|
80
|
-
]
|
|
81
|
-
],
|
|
82
|
-
hate: [
|
|
83
|
-
[
|
|
84
|
-
30,
|
|
85
|
-
64,
|
|
86
|
-
175,
|
|
87
|
-
255
|
|
88
|
-
],
|
|
89
|
-
[
|
|
90
|
-
37,
|
|
91
|
-
99,
|
|
92
|
-
235,
|
|
93
|
-
255
|
|
94
|
-
],
|
|
95
|
-
[
|
|
96
|
-
59,
|
|
97
|
-
130,
|
|
98
|
-
246,
|
|
99
|
-
255
|
|
100
|
-
],
|
|
101
|
-
[
|
|
102
|
-
96,
|
|
103
|
-
165,
|
|
104
|
-
250,
|
|
105
|
-
255
|
|
106
|
-
]
|
|
107
|
-
],
|
|
108
|
-
"criminal-activity": [
|
|
109
|
-
[
|
|
110
|
-
6,
|
|
111
|
-
95,
|
|
112
|
-
70,
|
|
113
|
-
255
|
|
114
|
-
],
|
|
115
|
-
[
|
|
116
|
-
5,
|
|
117
|
-
150,
|
|
118
|
-
105,
|
|
119
|
-
255
|
|
120
|
-
],
|
|
121
|
-
[
|
|
122
|
-
16,
|
|
123
|
-
185,
|
|
124
|
-
129,
|
|
125
|
-
255
|
|
126
|
-
],
|
|
127
|
-
[
|
|
128
|
-
52,
|
|
129
|
-
211,
|
|
130
|
-
153,
|
|
131
|
-
255
|
|
132
|
-
]
|
|
133
|
-
],
|
|
134
|
-
"self-harm": [
|
|
135
|
-
[
|
|
136
|
-
75,
|
|
137
|
-
0,
|
|
138
|
-
130,
|
|
139
|
-
255
|
|
140
|
-
],
|
|
141
|
-
[
|
|
142
|
-
138,
|
|
143
|
-
43,
|
|
144
|
-
226,
|
|
145
|
-
255
|
|
146
|
-
],
|
|
147
|
-
[
|
|
148
|
-
72,
|
|
149
|
-
61,
|
|
150
|
-
139,
|
|
151
|
-
255
|
|
152
|
-
],
|
|
153
|
-
[
|
|
154
|
-
147,
|
|
155
|
-
112,
|
|
156
|
-
219,
|
|
157
|
-
255
|
|
158
|
-
]
|
|
159
|
-
]
|
|
160
|
-
};
|
|
161
|
-
/** A project's test input key: eight hexadecimal characters only its members can see. */
|
|
162
|
-
const TEST_INPUT_KEY_PATTERN = /^[a-f0-9]{8}$/;
|
|
163
|
-
const TEXT_CODE_SIGNALS = [
|
|
164
|
-
"harassment",
|
|
165
|
-
"hate",
|
|
166
|
-
"criminal-activity",
|
|
167
|
-
"sexual.involving-minors"
|
|
168
|
-
];
|
|
169
|
-
/**
|
|
170
|
-
* The text code that CalmLens classifies as `category` for the project with this test input key.
|
|
171
|
-
* @returns The code, or an empty string for a category without a text code
|
|
172
|
-
*/
|
|
173
|
-
const generateTestTextCode = (category, testInputKey) => TEXT_CODE_SIGNALS.includes(category) ? `<!calmlens-test ${testInputKey} ${category}>` : "";
|
|
174
|
-
const TEST_TRIGGER_PATTERN = /<!calmlens-test\s+([a-f0-9]{8})\s+(harassment|hate|criminal-activity|sexual\.involving-minors)\s*>/gi;
|
|
175
|
-
/**
|
|
176
|
-
* The test signals in `text` whose codes carry the project's test input key. Codes with another
|
|
177
|
-
* key are ignored, so a code can only be used by the project it belongs to.
|
|
178
|
-
*/
|
|
179
|
-
const detectTestTrigger = (text, testInputKey) => {
|
|
180
|
-
const signals = [];
|
|
181
|
-
for (const [, key, signal] of text.matchAll(TEST_TRIGGER_PATTERN)) {
|
|
182
|
-
if (key.toLowerCase() !== testInputKey.toLowerCase()) continue;
|
|
183
|
-
const testSignal = signal.toLowerCase();
|
|
184
|
-
if (!signals.includes(testSignal)) signals.push(testSignal);
|
|
185
|
-
}
|
|
186
|
-
return {
|
|
187
|
-
isTestTrigger: signals.length > 0,
|
|
188
|
-
signals
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
|
-
/** Sixteen cells encode two bits each using the category's four existing colours. */
|
|
192
|
-
const getTestImageKeyCells = (width, height) => {
|
|
193
|
-
return Array.from({ length: 16 }, (_, index) => {
|
|
194
|
-
const column = index % 4;
|
|
195
|
-
const row = Math.floor(index / 4);
|
|
196
|
-
const x = Math.floor(column * width / 4);
|
|
197
|
-
const y = Math.floor(row * height / 4);
|
|
198
|
-
return {
|
|
199
|
-
x,
|
|
200
|
-
y,
|
|
201
|
-
width: Math.floor((column + 1) * width / 4) - x,
|
|
202
|
-
height: Math.floor((row + 1) * height / 4) - y
|
|
203
|
-
};
|
|
204
|
-
});
|
|
205
|
-
};
|
|
206
|
-
const getTestImageKeyColors = (signal, testInputKey) => {
|
|
207
|
-
const colors = TEST_IMAGE_PALETTES[signal];
|
|
208
|
-
if (!colors || !TEST_INPUT_KEY_PATTERN.test(testInputKey)) throw new Error("Invalid image test signal or key");
|
|
209
|
-
return [...testInputKey].flatMap((character) => {
|
|
210
|
-
const value = Number.parseInt(character, 16);
|
|
211
|
-
return [colors[value >> 2], colors[value & 3]];
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
/**
|
|
215
|
-
* Gets all test trigger categories that support images
|
|
216
|
-
*/
|
|
217
|
-
const getImageTestCategories = () => {
|
|
218
|
-
return Object.keys(TEST_IMAGE_PALETTES);
|
|
219
|
-
};
|
|
220
|
-
/** Paint a full-image 4×4 grid as RGBA pixels; callers choose their image encoder. */
|
|
221
|
-
const paintTestImage = (signal, testInputKey, width = 512, height = width) => {
|
|
222
|
-
if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width < 24 || height < 24) throw new RangeError("Test image dimensions must be integers of at least 24 pixels");
|
|
223
|
-
const colors = getTestImageKeyColors(signal, testInputKey);
|
|
224
|
-
const rgba = new Uint8Array(width * height * 4);
|
|
225
|
-
getTestImageKeyCells(width, height).forEach((cell, index) => {
|
|
226
|
-
for (let y = cell.y; y < cell.y + cell.height; y++) for (let x = cell.x; x < cell.x + cell.width; x++) rgba.set(colors[index], (y * width + x) * 4);
|
|
227
|
-
});
|
|
228
|
-
return rgba;
|
|
229
|
-
};
|
|
230
|
-
/** Decode the project key from pixels, tolerating resizing and lossy compression. */
|
|
231
|
-
const detectTestImage = (image, testInputKey) => {
|
|
232
|
-
const { width, height, rgba } = image;
|
|
233
|
-
if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width < 24 || height < 24 || rgba.length !== width * height * 4 || !TEST_INPUT_KEY_PATTERN.test(testInputKey)) return void 0;
|
|
234
|
-
const cells = getTestImageKeyCells(width, height);
|
|
235
|
-
for (const category of getImageTestCategories()) {
|
|
236
|
-
const colors = getTestImageKeyColors(category, testInputKey);
|
|
237
|
-
if (cells.every((cell, index) => {
|
|
238
|
-
const sample = [
|
|
239
|
-
0,
|
|
240
|
-
0,
|
|
241
|
-
0
|
|
242
|
-
];
|
|
243
|
-
let count = 0;
|
|
244
|
-
for (let y = cell.y + Math.ceil(cell.height / 4); y < cell.y + cell.height * 3 / 4; y++) for (let x = cell.x + Math.ceil(cell.width / 4); x < cell.x + cell.width * 3 / 4; x++) {
|
|
245
|
-
const offset = (y * width + x) * 4;
|
|
246
|
-
if (rgba[offset + 3] < 250) return false;
|
|
247
|
-
for (let c = 0; c < 3; c++) sample[c] += rgba[offset + c];
|
|
248
|
-
count++;
|
|
249
|
-
}
|
|
250
|
-
const distances = TEST_IMAGE_PALETTES[category].map((color) => sample.reduce((sum, value, c) => sum + (value / count - color[c]) ** 2, 0));
|
|
251
|
-
const nearest = distances.indexOf(Math.min(...distances));
|
|
252
|
-
return distances[nearest] <= 900 && TEST_IMAGE_PALETTES[category][nearest] === colors[index];
|
|
253
|
-
})) return category;
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
//#endregion
|
|
257
|
-
exports.TEST_IMAGE_PALETTES = TEST_IMAGE_PALETTES;
|
|
258
|
-
exports.TEST_INPUT_KEY_PATTERN = TEST_INPUT_KEY_PATTERN;
|
|
259
|
-
exports.detectTestImage = detectTestImage;
|
|
260
|
-
exports.detectTestTrigger = detectTestTrigger;
|
|
261
|
-
exports.generateTestTextCode = generateTestTextCode;
|
|
262
|
-
exports.getImageTestCategories = getImageTestCategories;
|
|
263
|
-
exports.getTestImageKeyCells = getTestImageKeyCells;
|
|
264
|
-
exports.getTestImageKeyColors = getTestImageKeyColors;
|
|
265
|
-
exports.paintTestImage = paintTestImage;
|
|
2
|
+
const require_TestTriggers_DcArt0Nu = require("./TestTriggers-DcArt0Nu-CvoaONUB.js");
|
|
3
|
+
exports.TEST_INPUT_KEY_PATTERN = require_TestTriggers_DcArt0Nu.TEST_INPUT_KEY_PATTERN;
|
|
4
|
+
exports.TEST_INPUT_PRESETS = require_TestTriggers_DcArt0Nu.TEST_INPUT_PRESETS;
|
|
5
|
+
exports.detectTestImage = require_TestTriggers_DcArt0Nu.detectTestImage;
|
|
6
|
+
exports.detectTestTrigger = require_TestTriggers_DcArt0Nu.detectTestTrigger;
|
|
7
|
+
exports.generateTestTextCode = require_TestTriggers_DcArt0Nu.generateTestTextCode;
|
|
8
|
+
exports.getImageTestCategories = require_TestTriggers_DcArt0Nu.getImageTestCategories;
|
|
9
|
+
exports.paintTestImage = require_TestTriggers_DcArt0Nu.paintTestImage;
|
|
10
|
+
exports.testInputForSignal = require_TestTriggers_DcArt0Nu.testInputForSignal;
|