@vanillaskyai/video 0.4.1 → 0.5.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/CHANGELOG.md +83 -0
- package/PUBLIC-API.md +12 -5
- package/README.md +14 -17
- package/dist/{builtin-server-BRTZN4Q7.js → builtin-server-YHEZ2JRF.js} +2 -2
- package/dist/check-runtime.js +1 -1
- package/dist/{chunk-BKF3A357.js → chunk-34O5BY6X.js} +1 -1
- package/dist/{chunk-LHFADNWJ.js → chunk-3ROGEU5A.js} +179 -342
- package/dist/{chunk-XAMUOSX7.js → chunk-3RV4YKB3.js} +0 -1
- package/dist/{chunk-GHJEAP4O.js → chunk-66MNRUCR.js} +1 -1
- package/dist/{chunk-EE6PK6XC.js → chunk-AOWSXU2K.js} +1 -1
- package/dist/{chunk-GR4I3MN2.js → chunk-EFL34TXF.js} +3 -3
- package/dist/{chunk-I5YWVQ5R.js → chunk-FVTMYS6U.js} +1 -1
- package/dist/{chunk-STIFILQG.js → chunk-FZHMQFG3.js} +46 -38
- package/dist/{chunk-JW47XCRL.js → chunk-G66Z5CWR.js} +30 -72
- package/dist/{chunk-RBQN3VSY.js → chunk-HVCPEAQF.js} +83 -1265
- package/dist/{chunk-N3KUA7VP.js → chunk-K6YVQODK.js} +4 -1
- package/dist/{chunk-WHPZED7X.js → chunk-PNS52FL4.js} +2 -5
- package/dist/{chunk-S5ZU5WUU.js → chunk-ZQQQAAKP.js} +2 -2
- package/dist/cli.js +20 -14
- package/dist/compose-video-QJHKTOQ7.js +13 -0
- package/dist/{events-D_1F6gw5.d.ts → events-BBP30j3c.d.ts} +3 -14
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{kit-DLeCr3d0.d.ts → kit-DEG3fcaL.d.ts} +1 -1
- package/dist/react.d.ts +6 -5
- package/dist/react.js +999 -348
- package/dist/server.d.ts +3 -3
- package/dist/server.js +18 -79
- package/dist/{system-prompt-NMYHLAMJ.js → system-prompt-4I6Z5HK3.js} +1 -1
- package/dist/template-catalog.js +1 -1
- package/dist/templates.d.ts +3 -3
- package/dist/templates.js +87 -4
- package/dist/test.d.ts +3 -27
- package/dist/test.js +3 -3
- package/dist/{text-stream-UPGUD2TD.js → text-stream-J6EDDJP4.js} +3 -3
- package/dist/{types-Cg0Onj7l.d.ts → types-BV9IqExh.d.ts} +1 -16
- package/docs/agent-integration.md +4 -3
- package/docs/concepts.md +4 -4
- package/docs/custom-templates.md +2 -2
- package/docs/getting-started.md +13 -18
- package/docs/integrate-nextjs.md +12 -8
- package/docs/persistence.md +1 -1
- package/docs/prompt-and-input.md +2 -2
- package/docs/reference/protocol.md +9 -12
- package/docs/reference/provider-adapters.md +5 -5
- package/docs/testing.md +1 -1
- package/examples/nextjs-quickstart/.env.example +2 -2
- package/examples/nextjs-quickstart/README.md +4 -1
- package/examples/nextjs-quickstart/package.json +4 -4
- package/examples/nextjs-quickstart/src/app/api/video/route.ts +4 -2
- package/package.json +8 -8
- package/dist/chunk-CR7FE7BW.js +0 -109
- package/dist/compose-video-6UQ33DOO.js +0 -13
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createVideoSystemPrompt
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PNS52FL4.js";
|
|
4
4
|
import {
|
|
5
5
|
PACING_PLANNER_RULES
|
|
6
6
|
} from "./chunk-3O7OMMMF.js";
|
|
@@ -108,7 +108,7 @@ function createTemplateSystemPrompt(options) {
|
|
|
108
108
|
const ids = new Set(templates.map(({ id }) => id));
|
|
109
109
|
const fields = new Set(templates.flatMap(({ schema }) => Object.keys(schema.properties)));
|
|
110
110
|
const basePrompt = createVideoSystemPrompt(options.knowledgeMode).split("\n").filter(
|
|
111
|
-
(line) => !line.includes("Never use media, ctaMedia, or reaction as the first generated body template") && !(resolverMediaAvailable && line.includes("Never expose a loading placeholder or unresolved media keyword"))
|
|
111
|
+
(line) => !line.includes("Never use media, ctaMedia, or reaction as the first generated body template") && !(resolverMediaAvailable && line.includes("Never expose a loading placeholder or unresolved media keyword"))
|
|
112
112
|
).join("\n");
|
|
113
113
|
const factRules = [
|
|
114
114
|
...ids.has("cardList") ? ["cardList needs two or three unused parallel facts"] : [],
|
|
@@ -142,7 +142,7 @@ ${options.basePrompt.trim()}` : void 0,
|
|
|
142
142
|
mediaTemplates.length > 0 ? `For streaming startup, ${mediaTemplateNames} ${mediaTemplates.length === 1 ? "is" : "are"} forbidden as the first generated body template, even when mediaType is gradient. Start with a content-fit non-media template.` : void 0,
|
|
143
143
|
listFields.length > 0 ? `For list variables (${listFields.join(", ")}), emit actual JSON arrays. Keep list labels to 1\u20133 words. Keep step labels to 1\u20132 words and at most 18 characters. Do not use pipes or newlines as list delimiters.` : void 0,
|
|
144
144
|
fields.has("bars") ? 'For bars, emit an actual JSON array of 2\u20136 grounded objects with "label" and "value" fields. Use comparable units and avoid a largest-to-smallest positive ratio above 20. Do not encode bars as a string.' : void 0,
|
|
145
|
-
resolverMediaAvailable ? "Prefer a relevant resolved image or video background on later media-capable scenes whenever the permitted factual basis names a concrete person, place, product context, activity, or outcome that can be depicted honestly. Emit mediaKeyword on scene.add as a specific 2\u20138 word semantic query of at most 80 characters
|
|
145
|
+
resolverMediaAvailable ? "Prefer a relevant resolved image or video background on later media-capable scenes whenever the permitted factual basis names a concrete person, place, product context, activity, or outcome that can be depicted honestly. Emit mediaKeyword on scene.add as a specific 2\u20138 word semantic query of at most 80 characters. The host removes mediaKeyword before the complete scene reaches the browser and replaces it with an approved asset. Use mediaType=gradient for abstract, sensitive, unsafe, or visually ambiguous material. Never emit or invent mediaUrl or mediaPoster." : mediaTemplates.length > 0 ? `Use exact grounded values for required fields. mediaUrl must come verbatim from supplied input. Stock queries are not available. Do not select ${mediaTemplateNames} without a supplied mediaUrl; if another template has no mediaUrl, explicitly use mediaType=gradient. mediaType auto detects a URL, while gradient deliberately uses no external asset.` : "Use exact grounded values for required fields.",
|
|
146
146
|
"Catalog guidance describes composition; it is not a factual source and must never replace the permitted factual basis.",
|
|
147
147
|
JSON.stringify(plannerCatalog(templates, resolverMediaAvailable))
|
|
148
148
|
].filter((line) => line != null).join("\n");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseVideoEvent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-G66Z5CWR.js";
|
|
4
4
|
import {
|
|
5
5
|
VIDEO_SCHEMA_VERSION
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AOWSXU2K.js";
|
|
7
7
|
|
|
8
8
|
// src/protocol/stable-json.ts
|
|
9
9
|
function stableJson(value) {
|
|
@@ -29,14 +29,13 @@ function createVideoState() {
|
|
|
29
29
|
return {
|
|
30
30
|
status: "idle",
|
|
31
31
|
lastSequence: -1,
|
|
32
|
-
sceneRevisions: {},
|
|
33
32
|
appliedEvents: {},
|
|
34
33
|
extensions: [],
|
|
35
34
|
errors: [],
|
|
36
35
|
warnings: []
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
|
-
function applyVideoEvent(state, untrustedEvent
|
|
38
|
+
function applyVideoEvent(state, untrustedEvent) {
|
|
40
39
|
const event = parseVideoEvent(untrustedEvent);
|
|
41
40
|
const signature = stableJson(event);
|
|
42
41
|
const priorSignature = state.appliedEvents[event.eventId];
|
|
@@ -91,43 +90,12 @@ function applyVideoEvent(state, untrustedEvent, options = {}) {
|
|
|
91
90
|
if (event.data.position !== state.config.scenes.length) {
|
|
92
91
|
throw new Error(`scene.add position must be ${state.config.scenes.length}`);
|
|
93
92
|
}
|
|
94
|
-
if (
|
|
95
|
-
if (state.sceneRevisions[event.data.scene.id] != null) {
|
|
93
|
+
if (state.config.scenes.some(({ id }) => id === event.data.scene.id)) {
|
|
96
94
|
throw new Error(`Scene ${event.data.scene.id} already exists`);
|
|
97
95
|
}
|
|
98
96
|
return {
|
|
99
97
|
...base,
|
|
100
|
-
config: { ...state.config, scenes: [...state.config.scenes, event.data.scene] }
|
|
101
|
-
sceneRevisions: { ...state.sceneRevisions, [event.data.scene.id]: 0 }
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
if (event.type === "scene.patch" || event.type === "asset.patch") {
|
|
105
|
-
const sceneId = event.data.sceneId;
|
|
106
|
-
const currentRevision = state.sceneRevisions[sceneId];
|
|
107
|
-
if (currentRevision == null) throw new Error(`Scene ${sceneId} does not exist`);
|
|
108
|
-
if (options.mutableSceneIds && !options.mutableSceneIds.has(sceneId)) {
|
|
109
|
-
throw new Error(`Cannot patch scene ${sceneId} after it has already played`);
|
|
110
|
-
}
|
|
111
|
-
if (event.data.revision !== currentRevision + 1) {
|
|
112
|
-
throw new Error(`Scene ${sceneId} expected revision ${currentRevision + 1}`);
|
|
113
|
-
}
|
|
114
|
-
const sceneIndex = state.config.scenes.findIndex((item) => item.id === sceneId);
|
|
115
|
-
const currentScene = state.config.scenes[sceneIndex];
|
|
116
|
-
const nextScene = event.type === "scene.patch" ? {
|
|
117
|
-
...currentScene,
|
|
118
|
-
...event.data.patch,
|
|
119
|
-
variables: event.data.patch.variables ? { ...currentScene.variables, ...event.data.patch.variables } : currentScene.variables,
|
|
120
|
-
timing: event.data.patch.timing ? { ...currentScene.timing, ...event.data.patch.timing } : currentScene.timing
|
|
121
|
-
} : {
|
|
122
|
-
...currentScene,
|
|
123
|
-
variables: { ...currentScene.variables, ...event.data.variables }
|
|
124
|
-
};
|
|
125
|
-
const scenes = [...state.config.scenes];
|
|
126
|
-
scenes[sceneIndex] = nextScene;
|
|
127
|
-
return {
|
|
128
|
-
...base,
|
|
129
|
-
config: { ...state.config, scenes },
|
|
130
|
-
sceneRevisions: { ...state.sceneRevisions, [sceneId]: event.data.revision }
|
|
98
|
+
config: { ...state.config, scenes: [...state.config.scenes, event.data.scene] }
|
|
131
99
|
};
|
|
132
100
|
}
|
|
133
101
|
if (event.type === "response.complete") {
|
|
@@ -180,8 +148,48 @@ function applyVideoEvent(state, untrustedEvent, options = {}) {
|
|
|
180
148
|
throw new Error(`Reducer does not yet support ${event.type}`);
|
|
181
149
|
}
|
|
182
150
|
|
|
151
|
+
// src/replayable-stream.ts
|
|
152
|
+
function createReplayableStream(source, onError) {
|
|
153
|
+
const buffered = [];
|
|
154
|
+
const waiters = /* @__PURE__ */ new Set();
|
|
155
|
+
let done = false;
|
|
156
|
+
let streamError;
|
|
157
|
+
const notify = () => {
|
|
158
|
+
for (const waiter of waiters) waiter();
|
|
159
|
+
waiters.clear();
|
|
160
|
+
};
|
|
161
|
+
void (async () => {
|
|
162
|
+
try {
|
|
163
|
+
for await (const item of source) {
|
|
164
|
+
buffered.push(item);
|
|
165
|
+
notify();
|
|
166
|
+
}
|
|
167
|
+
} catch (cause) {
|
|
168
|
+
streamError = cause;
|
|
169
|
+
onError(cause);
|
|
170
|
+
} finally {
|
|
171
|
+
done = true;
|
|
172
|
+
notify();
|
|
173
|
+
}
|
|
174
|
+
})();
|
|
175
|
+
return {
|
|
176
|
+
async *[Symbol.asyncIterator]() {
|
|
177
|
+
let index = 0;
|
|
178
|
+
while (true) {
|
|
179
|
+
while (index < buffered.length) yield buffered[index++];
|
|
180
|
+
if (done) {
|
|
181
|
+
if (streamError) throw streamError;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
await new Promise((resolve) => waiters.add(resolve));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
183
190
|
export {
|
|
184
191
|
checksumVideo,
|
|
185
192
|
createVideoState,
|
|
186
|
-
applyVideoEvent
|
|
193
|
+
applyVideoEvent,
|
|
194
|
+
createReplayableStream
|
|
187
195
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VIDEO_PROTOCOL_VERSION,
|
|
3
3
|
VIDEO_SCHEMA_VERSION
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AOWSXU2K.js";
|
|
5
5
|
import {
|
|
6
6
|
validateVideoBrand
|
|
7
7
|
} from "./chunk-XGRA2MUV.js";
|
|
@@ -11,7 +11,6 @@ var VIDEO_WARNING_CATEGORIES = {
|
|
|
11
11
|
scene_duration_adjusted: "readability",
|
|
12
12
|
scene_omitted_unreadable: "readability",
|
|
13
13
|
scene_omitted_for_closer: "readability",
|
|
14
|
-
scene_patch_rejected_readability: "readability",
|
|
15
14
|
chart_scale_imbalance: "readability",
|
|
16
15
|
plan_incomplete: "provider",
|
|
17
16
|
plan_missing_closer: "provider",
|
|
@@ -34,18 +33,7 @@ function safePublicDiagnostic(value, fallback) {
|
|
|
34
33
|
return `${redacted.slice(0, MAX_PUBLIC_DIAGNOSTIC_LENGTH - 1).trimEnd()}\u2026`;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
// src/protocol/validation.ts
|
|
38
|
-
var CORE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
39
|
-
"response.start",
|
|
40
|
-
"audio.set",
|
|
41
|
-
"scene.add",
|
|
42
|
-
"scene.patch",
|
|
43
|
-
"asset.patch",
|
|
44
|
-
"response.warning",
|
|
45
|
-
"response.complete",
|
|
46
|
-
"response.error",
|
|
47
|
-
"response.abort"
|
|
48
|
-
]);
|
|
36
|
+
// src/protocol/json-validation.ts
|
|
49
37
|
var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
50
38
|
function record(value, path) {
|
|
51
39
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -63,17 +51,6 @@ function string(value, path) {
|
|
|
63
51
|
if (typeof value !== "string" || !value.trim()) throw new Error(`${path} must be a non-empty string`);
|
|
64
52
|
return value;
|
|
65
53
|
}
|
|
66
|
-
function publicDiagnostic(value, path) {
|
|
67
|
-
const result = string(value, path);
|
|
68
|
-
if (result.length > MAX_PUBLIC_DIAGNOSTIC_LENGTH) {
|
|
69
|
-
throw new Error(`${path} must be at most ${MAX_PUBLIC_DIAGNOSTIC_LENGTH} characters`);
|
|
70
|
-
}
|
|
71
|
-
if (Array.from(result).some((character) => {
|
|
72
|
-
const code = character.codePointAt(0) ?? 0;
|
|
73
|
-
return code < 32 || code === 127;
|
|
74
|
-
})) throw new Error(`${path} contains control characters`);
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
54
|
function finite(value, path) {
|
|
78
55
|
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${path} must be finite`);
|
|
79
56
|
return value;
|
|
@@ -102,6 +79,28 @@ function jsonValue(value, path, seen = /* @__PURE__ */ new Set()) {
|
|
|
102
79
|
}
|
|
103
80
|
seen.delete(value);
|
|
104
81
|
}
|
|
82
|
+
|
|
83
|
+
// src/protocol/validation.ts
|
|
84
|
+
var CORE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
85
|
+
"response.start",
|
|
86
|
+
"audio.set",
|
|
87
|
+
"scene.add",
|
|
88
|
+
"response.warning",
|
|
89
|
+
"response.complete",
|
|
90
|
+
"response.error",
|
|
91
|
+
"response.abort"
|
|
92
|
+
]);
|
|
93
|
+
function publicDiagnostic(value, path) {
|
|
94
|
+
const result = string(value, path);
|
|
95
|
+
if (result.length > MAX_PUBLIC_DIAGNOSTIC_LENGTH) {
|
|
96
|
+
throw new Error(`${path} must be at most ${MAX_PUBLIC_DIAGNOSTIC_LENGTH} characters`);
|
|
97
|
+
}
|
|
98
|
+
if (Array.from(result).some((character) => {
|
|
99
|
+
const code = character.codePointAt(0) ?? 0;
|
|
100
|
+
return code < 32 || code === 127;
|
|
101
|
+
})) throw new Error(`${path} contains control characters`);
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
105
104
|
function timing(value, path) {
|
|
106
105
|
const result = record(value, path);
|
|
107
106
|
allowedKeys(result, [
|
|
@@ -137,22 +136,6 @@ function scene(value, path) {
|
|
|
137
136
|
if (result.backgroundEffect != null) string(result.backgroundEffect, `${path}.backgroundEffect`);
|
|
138
137
|
return result;
|
|
139
138
|
}
|
|
140
|
-
function scenePatch(value, path) {
|
|
141
|
-
const patch = record(value, path);
|
|
142
|
-
allowedKeys(patch, [
|
|
143
|
-
"variables",
|
|
144
|
-
"textArchetype",
|
|
145
|
-
"backgroundEffect",
|
|
146
|
-
"timing"
|
|
147
|
-
], path);
|
|
148
|
-
if (patch.variables != null) {
|
|
149
|
-
record(patch.variables, `${path}.variables`);
|
|
150
|
-
jsonValue(patch.variables, `${path}.variables`);
|
|
151
|
-
}
|
|
152
|
-
if (patch.timing != null) timing(patch.timing, `${path}.timing`);
|
|
153
|
-
if (patch.textArchetype != null) string(patch.textArchetype, `${path}.textArchetype`);
|
|
154
|
-
if (patch.backgroundEffect != null) string(patch.backgroundEffect, `${path}.backgroundEffect`);
|
|
155
|
-
}
|
|
156
139
|
function capabilities(value, path) {
|
|
157
140
|
const result = record(value, path);
|
|
158
141
|
allowedKeys(result, ["templates", "extensions"], path);
|
|
@@ -267,21 +250,9 @@ function validateCoreData(type, value) {
|
|
|
267
250
|
allowedKeys(data, ["audio"], "event.data");
|
|
268
251
|
audio(data.audio, "event.data.audio");
|
|
269
252
|
} else if (type === "scene.add") {
|
|
270
|
-
allowedKeys(data, ["scene", "position"
|
|
253
|
+
allowedKeys(data, ["scene", "position"], "event.data");
|
|
271
254
|
scene(data.scene, "event.data.scene");
|
|
272
255
|
nonNegativeInteger(data.position, "event.data.position");
|
|
273
|
-
nonNegativeInteger(data.revision, "event.data.revision");
|
|
274
|
-
} else if (type === "scene.patch") {
|
|
275
|
-
allowedKeys(data, ["sceneId", "revision", "patch"], "event.data");
|
|
276
|
-
string(data.sceneId, "event.data.sceneId");
|
|
277
|
-
nonNegativeInteger(data.revision, "event.data.revision");
|
|
278
|
-
scenePatch(data.patch, "event.data.patch");
|
|
279
|
-
} else if (type === "asset.patch") {
|
|
280
|
-
allowedKeys(data, ["sceneId", "revision", "variables"], "event.data");
|
|
281
|
-
string(data.sceneId, "event.data.sceneId");
|
|
282
|
-
nonNegativeInteger(data.revision, "event.data.revision");
|
|
283
|
-
record(data.variables, "event.data.variables");
|
|
284
|
-
jsonValue(data.variables, "event.data.variables");
|
|
285
256
|
} else if (type === "response.complete") {
|
|
286
257
|
allowedKeys(data, ["finishReason", "snapshot", "checksum"], "event.data");
|
|
287
258
|
if (!["stop", "length", "content-filter", "error", "other"].includes(String(data.finishReason))) {
|
|
@@ -354,29 +325,11 @@ function parseVideoPlanPart(value) {
|
|
|
354
325
|
throw new Error("plan part.placement is unsupported");
|
|
355
326
|
}
|
|
356
327
|
scene(part.scene, "plan part.scene");
|
|
357
|
-
} else if (type === "scene.patch") {
|
|
358
|
-
allowedKeys(part, ["type", "sceneId", "patch"], "plan part");
|
|
359
|
-
string(part.sceneId, "plan part.sceneId");
|
|
360
|
-
scenePatch(part.patch, "plan part.patch");
|
|
361
|
-
} else if (type === "asset.patch") {
|
|
362
|
-
allowedKeys(part, ["type", "sceneId", "variables"], "plan part");
|
|
363
|
-
string(part.sceneId, "plan part.sceneId");
|
|
364
|
-
record(part.variables, "plan part.variables");
|
|
365
|
-
jsonValue(part.variables, "plan part.variables");
|
|
366
328
|
} else if (type === "plan.complete") {
|
|
367
329
|
allowedKeys(part, ["type", "finishReason"], "plan part");
|
|
368
330
|
if (part.finishReason != null && !["stop", "length", "content-filter", "other"].includes(String(part.finishReason))) {
|
|
369
331
|
throw new Error("plan part.finishReason is unsupported");
|
|
370
332
|
}
|
|
371
|
-
} else if (type === "plan.error") {
|
|
372
|
-
allowedKeys(part, ["type", "error"], "plan part");
|
|
373
|
-
const error = record(part.error, "plan part.error");
|
|
374
|
-
allowedKeys(error, ["message", "code", "recoverable"], "plan part.error");
|
|
375
|
-
string(error.message, "plan part.error.message");
|
|
376
|
-
if (error.code != null) string(error.code, "plan part.error.code");
|
|
377
|
-
if (error.recoverable != null && typeof error.recoverable !== "boolean") {
|
|
378
|
-
throw new Error("plan part.error.recoverable must be boolean");
|
|
379
|
-
}
|
|
380
333
|
} else {
|
|
381
334
|
throw new Error(`plan part.type ${type} is unsupported`);
|
|
382
335
|
}
|
|
@@ -385,6 +338,11 @@ function parseVideoPlanPart(value) {
|
|
|
385
338
|
|
|
386
339
|
export {
|
|
387
340
|
safePublicDiagnostic,
|
|
341
|
+
record,
|
|
342
|
+
allowedKeys,
|
|
343
|
+
string,
|
|
344
|
+
nonNegativeInteger,
|
|
345
|
+
jsonValue,
|
|
388
346
|
parseVideoEvent,
|
|
389
347
|
parseVideoPlanPart
|
|
390
348
|
};
|