insync-stage-handler 3.1.2 → 4.0.0-beta.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/dist/module.js CHANGED
@@ -1,9 +1,10 @@
1
- import { flip, prop, path, curry, map as map$1, compose, indexBy, pipe, converge, pathOr, defaultTo, of, prepend, append, flatten, join, applyTo, assoc, dissocPath, filter, propSatisfies, startsWith, pair, replace, reduce, assocPath, addIndex, lensPath, values, mergeLeft, when, test, head, either, ifElse, isNil, always, nth, unless, over, union, pluck, merge, without, propEq, apply, tap, propOr, complement, lensProp, pick, omit, mergeDeepRight, keys, has, hasPath, dissoc, isEmpty, mapObjIndexed, last, gte, is, both, anyPass, nAry } from 'ramda';
1
+ import * as R from 'ramda';
2
+ import { flip, prop, path, curry, map as map$1, compose, indexBy, pipe, converge, pathOr, defaultTo, of, prepend, append, flatten, join, applyTo, assoc, dissocPath, filter, propSatisfies, startsWith, pair, replace, reduce, assocPath, tap, propOr, always, last, gte, nth, apply, nAry, unless } from 'ramda';
2
3
  import Ajv from 'ajv';
3
4
  import { formatWithOptions, parseISO } from 'date-fns/fp';
4
5
 
5
6
  const lookup = flip(prop);
6
- const lookupPath = flip(path);
7
+ flip(path);
7
8
  const lookupAll = curry((from, ids) => map$1(lookup(from), ids));
8
9
  const lookupPathAll = curry((from, p, ids) => map$1(compose(path(p), lookup(from)), ids));
9
10
  const indexById = indexBy(prop("id"));
@@ -13,16 +14,13 @@ const listEntities = curry((entitiesContainerPath, from) => pipe(converge(lookup
13
14
  * Return the version of a stage object.
14
15
  * @param {Object} stage The stage for which to return the version.
15
16
  */
16
-
17
17
  var detectVersion = pipe(prop("version"), defaultTo(1));
18
18
 
19
19
  class ValidationError extends Error {
20
20
  setErrors(errors) {
21
21
  this.errors = errors;
22
22
  }
23
-
24
23
  }
25
-
26
24
  const formatErrorMessage = errors => {
27
25
  const header = "Validation errors occurred: \n";
28
26
  return pipe(map$1(({
@@ -30,26 +28,22 @@ const formatErrorMessage = errors => {
30
28
  message
31
29
  }) => `path: "${dataPath}", message: ${message}`), map$1(of), map$1(pipe(prepend(" - "), append("\n"))), flatten, prepend(header), join(""))(errors);
32
30
  };
33
-
34
- var createValidationError = (errors => {
31
+ var createValidationError = errors => {
35
32
  const err = new ValidationError(formatErrorMessage(errors));
36
33
  err.setErrors(errors);
37
34
  return err;
38
- });
35
+ };
39
36
 
40
37
  const ajv = new Ajv({
41
38
  $data: true,
42
39
  allErrors: true,
43
40
  logger: false
44
41
  });
45
-
46
42
  require("ajv-keywords")(ajv, "formatMinimum");
47
43
  /**
48
44
  * Creates a JSON schema validator.
49
45
  * @param {Object} obj Object containing json schema rules.
50
46
  */
51
-
52
-
53
47
  const createAJVValidator = schema => {
54
48
  const validator = ajv.compile(schema);
55
49
  return stage => {
@@ -65,11 +59,11 @@ const createAJVValidator = schema => {
65
59
  };
66
60
  };
67
61
 
68
- var $schema = "http://json-schema.org/draft-07/schema#";
69
- var id = "stage.1.schema.json";
70
- var description = "Version 1 of stage file";
71
- var type = "object";
72
- var definitions = {
62
+ var $schema$3 = "http://json-schema.org/draft-07/schema#";
63
+ var id$3 = "stage.1.schema.json";
64
+ var description$4 = "Version 1 of stage file";
65
+ var type$3 = "object";
66
+ var definitions$3 = {
73
67
  entitiesContainer: {
74
68
  type: "object",
75
69
  properties: {
@@ -617,7 +611,7 @@ var definitions = {
617
611
  ]
618
612
  }
619
613
  };
620
- var properties = {
614
+ var properties$3 = {
621
615
  menu: {
622
616
  type: "object",
623
617
  properties: {
@@ -759,25 +753,25 @@ var properties = {
759
753
  }
760
754
  }
761
755
  };
762
- var schema = {
763
- $schema: $schema,
764
- id: id,
765
- description: description,
766
- type: type,
767
- definitions: definitions,
768
- properties: properties
756
+ var schema$3 = {
757
+ $schema: $schema$3,
758
+ id: id$3,
759
+ description: description$4,
760
+ type: type$3,
761
+ definitions: definitions$3,
762
+ properties: properties$3
769
763
  };
770
764
 
771
- const jsonSchemaValidator = createAJVValidator(schema);
772
- var v1 = (stage => {
773
- return jsonSchemaValidator(stage);
774
- });
765
+ const jsonSchemaValidator$3 = createAJVValidator(schema$3);
766
+ var v1 = stage => {
767
+ return jsonSchemaValidator$3(stage);
768
+ };
775
769
 
776
- var $schema$1 = "http://json-schema.org/draft-07/schema#";
777
- var id$1 = "stage.2.schema.json";
778
- var description$1 = "Version 2 of stage file";
779
- var type$1 = "object";
780
- var definitions$1 = {
770
+ var $schema$2 = "http://json-schema.org/draft-07/schema#";
771
+ var id$2 = "stage.2.schema.json";
772
+ var description$3 = "Version 2 of stage file";
773
+ var type$2 = "object";
774
+ var definitions$2 = {
781
775
  entitiesContainer: {
782
776
  type: "object",
783
777
  properties: {
@@ -1338,7 +1332,7 @@ var definitions$1 = {
1338
1332
  ]
1339
1333
  }
1340
1334
  };
1341
- var properties$1 = {
1335
+ var properties$2 = {
1342
1336
  menu: {
1343
1337
  type: "object",
1344
1338
  properties: {
@@ -1480,25 +1474,25 @@ var properties$1 = {
1480
1474
  }
1481
1475
  }
1482
1476
  };
1483
- var schema$1 = {
1484
- $schema: $schema$1,
1485
- id: id$1,
1486
- description: description$1,
1487
- type: type$1,
1488
- definitions: definitions$1,
1489
- properties: properties$1
1477
+ var schema$2 = {
1478
+ $schema: $schema$2,
1479
+ id: id$2,
1480
+ description: description$3,
1481
+ type: type$2,
1482
+ definitions: definitions$2,
1483
+ properties: properties$2
1490
1484
  };
1491
1485
 
1492
- const jsonSchemaValidator$1 = createAJVValidator(schema$1);
1493
- var v2 = (stage => {
1494
- return jsonSchemaValidator$1(stage);
1495
- });
1486
+ const jsonSchemaValidator$2 = createAJVValidator(schema$2);
1487
+ var v2 = stage => {
1488
+ return jsonSchemaValidator$2(stage);
1489
+ };
1496
1490
 
1497
- var $schema$2 = "http://json-schema.org/draft-07/schema#";
1498
- var id$2 = "stage.3.schema.json";
1491
+ var $schema$1 = "http://json-schema.org/draft-07/schema#";
1492
+ var id$1 = "stage.3.schema.json";
1499
1493
  var description$2 = "Version 3 of stage file";
1500
- var type$2 = "object";
1501
- var definitions$2 = {
1494
+ var type$1 = "object";
1495
+ var definitions$1 = {
1502
1496
  entitiesContainer: {
1503
1497
  type: "object",
1504
1498
  properties: {
@@ -2055,7 +2049,7 @@ var definitions$2 = {
2055
2049
  ]
2056
2050
  }
2057
2051
  };
2058
- var properties$2 = {
2052
+ var properties$1 = {
2059
2053
  menu: {
2060
2054
  type: "object",
2061
2055
  properties: {
@@ -2194,299 +2188,1096 @@ var properties$2 = {
2194
2188
  }
2195
2189
  }
2196
2190
  };
2197
- var schema$2 = {
2198
- $schema: $schema$2,
2199
- id: id$2,
2191
+ var schema$1 = {
2192
+ $schema: $schema$1,
2193
+ id: id$1,
2200
2194
  description: description$2,
2201
- type: type$2,
2202
- definitions: definitions$2,
2203
- properties: properties$2
2204
- };
2205
-
2206
- const jsonSchemaValidator$2 = createAJVValidator(schema$2);
2207
- var v3 = (stage => {
2208
- return jsonSchemaValidator$2(stage);
2209
- });
2210
-
2211
- const map = Object.freeze({
2212
- "1": v1,
2213
- "2": v2,
2214
- "3": v3
2215
- });
2216
-
2217
- /**
2218
- * Parses validation specific options from global options.
2219
- * @param {obj} options
2220
- */
2221
-
2222
- const optionsParser = ({
2223
- validationVersion = undefined
2224
- }) => ({
2225
- version: validationVersion
2226
- });
2227
- /**
2228
- * Validates a stage
2229
- * @param {Object} stage
2230
- * @param {number} version
2231
- */
2232
-
2233
- var validate = ((stage, options = {}) => {
2234
- const {
2235
- version = undefined
2236
- } = options;
2237
- return pipe(defaultTo(detectVersion(stage)), lookup(map), applyTo(stage))(version);
2238
- });
2239
-
2240
- var versions = Object.freeze([1, 2, 3]);
2241
-
2242
- /**
2243
- * v1-to-v2.js
2244
- * Upgrader for version 1 stage files to version 2.
2245
- * Removes timelines axes with resources. And adds the zoomSteps for the dataviewer.
2246
- */
2247
- const outletsView = listEntities(["data", "entities", "outlets"]); // This adds the zoomsteps on dataviwer based on "visible" prop on the associated outlet.
2248
-
2249
- const addDataViewerZoomSteps = stage => pipe(outletsView, // The association to a dataviewer is defined in the outlet id (dataviewer/<DATAVIEWER ID>),
2250
- // This only takes outlets associated with a dataviewer.
2251
- filter(propSatisfies(startsWith("dataviewer/"), "id")), map$1( // This pairs the path to the associated dataviewer to its required zoomSteps.
2252
- converge(pair, [pipe(prop("id"), replace("dataviewer/", ""), id => ["data", "entities", "dataViewers", "byId", id, "zoomSteps"]), pipe(prop("visible"), visible => [visible])])), // Set the "zoomSteps" prop of the dataviewer to the visibility of the outlet.
2253
- reduce((acc, [path, zoomSteps]) => assocPath(path, zoomSteps, acc), stage))(stage);
2254
-
2255
- var v1ToV2 = pipe( // Sets the version prop to "2"
2256
- assoc("version", 2), // Remove the association to resources from the timline axes.
2257
- // In version 2 the tracks for files on the timeline are handled by the v2 consolidation strategy.
2258
- dissocPath(["timeline", "entities", "axes", "byId", "video", "resources"]), dissocPath(["timeline", "entities", "axes", "byId", "high-speed", "resources"]), // Adds the zoomsteps to the dataviewers.
2259
- addDataViewerZoomSteps);
2260
-
2261
- const NEW_TEST_REGEX = /^([0-9]{5})_(.+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$/;
2262
-
2263
- const fsPath = require("path");
2264
-
2265
- const match = curry((regex, st) => st.match(regex));
2266
- const mapWithIndex = addIndex(map$1);
2267
- const axesSettings = [{
2268
- id: "video",
2269
- color: "#41b51b"
2270
- }, {
2271
- id: "high-speed",
2272
- color: "#3318cc"
2273
- }, {
2274
- id: "comment",
2275
- color: "red"
2276
- }];
2277
- const tracksIdsPath = ["timeline", "entities", "tracks", "ids"];
2278
- const tracksByIdPath = ["timeline", "entities", "tracks", "byId"];
2279
- const axesIdsPath = ["timeline", "entities", "axes", "ids"];
2280
- const axesByIdPath = ["timeline", "entities", "axes", "byId"];
2281
- const resourcesIdsView = path(["resources", "entities", "resources", "ids"]);
2282
- const resourcesByIdView = path(["resources", "entities", "resources", "byId"]);
2283
- const filesIdsView = path(["files", "entities", "files", "ids"]);
2284
- const filesByIdView = path(["files", "entities", "files", "byId"]);
2285
- const commentsByIdView = path(["timeline", "entities", "comments", "byId"]);
2286
- const tracksIdsLens = lensPath(tracksIdsPath);
2287
- const tracksByIdLens = lensPath(tracksByIdPath);
2288
- const axesIdsLens = lensPath(axesIdsPath);
2289
- const axesByIdLens = lensPath(axesByIdPath);
2290
- const filesView = pipe(filesByIdView, values);
2291
- const commentsView = pipe(commentsByIdView, values);
2292
-
2293
- const highSpeedsFilesView = stage => {
2294
- const filesById = filesByIdView(stage);
2295
- const resourcesById = resourcesByIdView(stage);
2296
- return pipe( // Iterate R.over the resource ids
2297
- resourcesIdsView, // Filter out all the ids that don't start with high-speed.
2298
- filter(startsWith("high-speed:")), // Map the remaining resource ids to the files ids in the respective resource object.
2299
- lookupPathAll(resourcesById, ["files"]), // Flatten the ids so we get a single array containing all the files ids referred
2300
- // to across all high-speed resources.
2301
- flatten, // Map the file ids to file objects.
2302
- lookupAll(filesById))(stage);
2303
- };
2304
-
2305
- const videosFilesView = stage => {
2306
- const filesIds = filesIdsView(stage);
2307
- const filesById = filesByIdView(stage);
2308
- const highSpeedFiles = highSpeedsFilesView(stage);
2309
- return pipe(without(pluck("id", highSpeedFiles)), lookupAll(filesById), filter(propEq("type", "video")))(filesIds);
2310
- };
2311
-
2312
- const upsertAxes = axes => curry(pipe(unless(path(axesIdsPath), assocPath(axesIdsPath, [])), unless(path(axesByIdPath), assocPath(axesIdsPath, {})), over(axesIdsLens, union(pluck("id", axes))), over(axesByIdLens, merge(indexById(axes)))));
2313
- const createTrackFromEntity = curry((axis, entity) => {
2314
- const {
2315
- start,
2316
- end,
2317
- type,
2318
- id
2319
- } = entity;
2320
- return {
2321
- id: `track:${id}`,
2322
- start,
2323
- end,
2324
- type,
2325
- axisRef: axis,
2326
- ref: id
2327
- };
2328
- });
2329
- const mapEntitiesToTracks = curry((entitiesSelector, axis, stage) => map$1(createTrackFromEntity(axis), entitiesSelector(stage)));
2330
- const mapCommentsToTracks = pipe(mapEntitiesToTracks(commentsView, "comment"), map$1(mergeLeft({
2331
- type: "comment",
2332
- label: "comment"
2333
- })));
2334
-
2335
- const formatTestNo = input => {
2336
- const [// eslint-disable-next-line no-unused-vars
2337
- m, project, facility, program, category, test, experiment, measurement] = input.match(NEW_TEST_REGEX);
2338
- return `${project}_${program.padStart(2, "0")}${facility}_${category.padStart(2, "0")}_${test.padStart(3, "0")}_${experiment.padStart(3, "0")}_${measurement.padStart(2, "0")}`;
2339
- };
2340
-
2341
- const extractTestNumberFromMetadata = pipe(path(["metadata", "location", "$id"]), when(test(NEW_TEST_REGEX), formatTestNo));
2342
- const extractTestNumberFromFileName = compose(head, defaultTo([undefined]), either(match(/[0-9]{5}_[0-9]{2}[a-zA-Z]+_[0-9]{2}_[0-9]{3}_[0-9]{3}_[0-9]{2}/), match(/[A-Za-z]+[0-9]{5}_[0-9]+_[0-9]+_[0-9]+/)), prop("path"));
2343
-
2344
- const extractTestNumber = (stage, track) => pipe(filesByIdView, prop(track.ref), either(extractTestNumberFromMetadata, extractTestNumberFromFileName))(stage);
2345
-
2346
- const formatter = formatWithOptions({
2347
- awareOfUnicodeTokens: true
2348
- });
2349
-
2350
- const extractRecordingChannel = (stage, track) => pipe(filesByIdView, path([track.ref, "metadata", "recChannel"]))(stage);
2351
-
2352
- const createHighSpeedTracksLabels = stage => tracks => mapWithIndex((hs, index) => {
2353
- const recordingChannel = extractRecordingChannel(stage, hs);
2354
- const no = recordingChannel || index + 1;
2355
- return assoc("label", `HS ${no}`, hs);
2356
- }, tracks);
2357
-
2358
- const createVideoTracksLabels = stage => tracks => mapWithIndex((vid, index) => {
2359
- const recordingChannel = extractRecordingChannel(stage, vid);
2360
- const no = recordingChannel || index + 1;
2361
- return assoc("label", `VID ${no}`, vid);
2362
- }, tracks);
2363
-
2364
- const extractFormat = (stage, track) => pipe(filesByIdView, path([track.ref, "path"]), p => fsPath.extname(p))(stage);
2365
-
2366
- const extractSecondFractions = isoStr => pipe(match(/[0-9]{2}:[0-9]{2}:[0-9]{2}.([0-9]+)/), ifElse(isNil, always("000"), nth(1)))(isoStr);
2367
-
2368
- const extractDate = (stage, track) => {
2369
- return pipe(filesByIdView, path([track.ref, "start"]), parseISO, formatter("dd-MM-yyyy"))(stage);
2370
- };
2371
-
2372
- const createTime = converge(pipe(pair, join(".")), [pipe(parseISO, formatter("HH:mm:ss")), extractSecondFractions]);
2373
-
2374
- const extractStart = (stage, track) => pipe(filesByIdView, path([track.ref, "start"]), createTime)(stage);
2375
-
2376
- const extractEnd = (stage, track) => pipe(filesByIdView, path([track.ref, "end"]), createTime)(stage);
2377
-
2378
- const createVideoMetadata = curry((type, stage, track) => ({ ...track,
2379
- metadata: track.metadata || [[{
2380
- label: "Test",
2381
- value: extractTestNumber(stage, track)
2382
- }], [{
2383
- label: "Type",
2384
- value: type
2385
- }, {
2386
- label: "Recording channel",
2387
- value: extractRecordingChannel(stage, track)
2388
- }, {
2389
- label: "Format",
2390
- value: extractFormat(stage, track)
2391
- }], [{
2392
- label: "Date",
2393
- value: extractDate(stage, track)
2394
- }, {
2395
- label: "Start",
2396
- value: extractStart(stage, track)
2397
- }, {
2398
- label: "End",
2399
- value: extractEnd(stage, track)
2400
- }]]
2401
- }));
2402
- const createHighSpeedsMetadata = curry((stage, tracks) => map$1(createVideoMetadata("high-speed", stage), tracks));
2403
- const createVideosMetadata = curry((stage, tracks) => map$1(createVideoMetadata("video", stage), tracks));
2404
-
2405
- const createTracks = stage => converge((...args) => flatten(args), [pipe(mapEntitiesToTracks(highSpeedsFilesView, "high-speed"), createHighSpeedTracksLabels(stage), createHighSpeedsMetadata(stage)), pipe(mapEntitiesToTracks(videosFilesView, "video"), createVideoTracksLabels(stage), createVideosMetadata(stage)), mapCommentsToTracks])(stage);
2406
-
2407
- const upsertTracks = tracks => curry(pipe(unless(path(tracksIdsPath), assocPath(tracksIdsPath, [])), unless(path(tracksByIdPath), assocPath(tracksByIdPath, {})), over(tracksIdsLens, union(pluck("id", tracks))), over(tracksByIdLens, merge(indexById(tracks)))));
2408
-
2409
- const earliestTime = stage => pipe(filesView, map$1(prop("start")), map$1(Date.parse), apply(Math.min), t => new Date(t), d => d.toISOString())(stage);
2410
-
2411
- const latestTime = stage => pipe(filesView, map$1(prop("end")), map$1(Date.parse), apply(Math.max), t => new Date(t), d => d.toISOString())(stage);
2412
-
2413
- const setTimeLineStartEnd = stage => pipe(assocPath(["timeline", "start"], earliestTime(stage)), assocPath(["timeline", "end"], latestTime(stage)))(stage);
2414
-
2415
- const setCommentAxis = assocPath(["timeline", "commentAxis"], "comment");
2416
-
2417
- const consolidateTimeline = stage => {
2418
- return pipe(upsertAxes(axesSettings), upsertTracks(createTracks(stage)), setTimeLineStartEnd, setCommentAxis)(stage);
2419
- };
2420
-
2421
- const consolidate = stage => {
2422
- return consolidateTimeline(stage);
2195
+ type: type$1,
2196
+ definitions: definitions$1,
2197
+ properties: properties$1
2423
2198
  };
2424
2199
 
2425
- const NEW_TEST_REGEX$1 = /^([0-9]{5})_(.+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$/;
2426
-
2427
- const fsPath$1 = require("path");
2428
-
2429
- const match$1 = curry((regex, st) => st.match(regex));
2430
- const mapWithIndex$1 = addIndex(map$1);
2431
- const axesSettings$1 = [{
2432
- id: "video",
2433
- color: "#41b51b"
2434
- }, {
2435
- id: "high-speed",
2436
- color: "#3318cc"
2437
- }, {
2438
- id: "comment",
2439
- color: "red"
2440
- }];
2441
- const tracksIdsPath$1 = ["timeline", "entities", "tracks", "ids"];
2442
- const tracksByIdPath$1 = ["timeline", "entities", "tracks", "byId"];
2443
- const axesIdsPath$1 = ["timeline", "entities", "axes", "ids"];
2444
- const axesByIdPath$1 = ["timeline", "entities", "axes", "byId"];
2445
- const resourcesIdsView$1 = path(["resources", "entities", "resources", "ids"]);
2446
- const resourcesByIdView$1 = path(["resources", "entities", "resources", "byId"]);
2447
- const filesIdsView$1 = path(["files", "entities", "files", "ids"]);
2448
- const filesByIdView$1 = path(["files", "entities", "files", "byId"]);
2449
- const timingByIdView = path(["timing", "entities", "timing", "byId"]);
2450
- const commentsByIdView$1 = path(["timeline", "entities", "comments", "byId"]);
2451
- const tracksIdsLens$1 = lensPath(tracksIdsPath$1);
2452
- const tracksByIdLens$1 = lensPath(tracksByIdPath$1);
2453
- const axesIdsLens$1 = lensPath(axesIdsPath$1);
2454
- const axesByIdLens$1 = lensPath(axesByIdPath$1);
2455
- const timingsView = pipe(timingByIdView, values);
2456
- const commentsView$1 = pipe(commentsByIdView$1, values);
2457
-
2458
- const highSpeedsFilesView$1 = stage => {
2459
- const filesById = filesByIdView$1(stage);
2460
- const resourcesById = resourcesByIdView$1(stage);
2461
- return pipe( // Iterate R.over the resource ids
2462
- resourcesIdsView$1, // Filter out all the ids that don't start with high-speed.
2463
- filter(startsWith("high-speed:")), // Map the remaining resource ids to the files ids in the respective resource object.
2464
- lookupPathAll(resourcesById, ["props", "files"]), // Flatten the ids so we get a single array containing all the files ids referred
2465
- // to across all high-speed resources.
2466
- flatten, // Map the file ids to file objects.
2467
- lookupAll(filesById))(stage);
2200
+ const jsonSchemaValidator$1 = createAJVValidator(schema$1);
2201
+ var v3$1 = stage => {
2202
+ return jsonSchemaValidator$1(stage);
2468
2203
  };
2469
2204
 
2205
+ var $schema = "http://json-schema.org/draft-07/schema#";
2206
+ var id = "stage.4.schema.json";
2207
+ var description$1 = "Version 4 of stage file - DockView layout format";
2208
+ var type = "object";
2209
+ var definitions = {
2210
+ entitiesContainer: {
2211
+ type: "object",
2212
+ properties: {
2213
+ ids: {
2214
+ type: "array",
2215
+ items: {
2216
+ type: "string"
2217
+ }
2218
+ },
2219
+ byId: {
2220
+ type: "object",
2221
+ additionalProperties: {
2222
+ type: "object"
2223
+ }
2224
+ }
2225
+ }
2226
+ },
2227
+ entity: {
2228
+ type: "object",
2229
+ properties: {
2230
+ id: {
2231
+ type: "string"
2232
+ }
2233
+ },
2234
+ required: [
2235
+ "id"
2236
+ ]
2237
+ },
2238
+ ref: {
2239
+ type: "object",
2240
+ properties: {
2241
+ type: {
2242
+ type: "string"
2243
+ },
2244
+ id: {
2245
+ type: "string"
2246
+ }
2247
+ }
2248
+ },
2249
+ asset: {
2250
+ allOf: [
2251
+ {
2252
+ $ref: "#/definitions/entity"
2253
+ },
2254
+ {
2255
+ type: "object",
2256
+ properties: {
2257
+ resource: {
2258
+ type: "string"
2259
+ },
2260
+ annotationsViewerId: {
2261
+ type: "string"
2262
+ }
2263
+ }
2264
+ }
2265
+ ]
2266
+ },
2267
+ timing: {
2268
+ allOf: [
2269
+ {
2270
+ $ref: "#/definitions/entity"
2271
+ },
2272
+ {
2273
+ type: "object",
2274
+ properties: {
2275
+ start: {
2276
+ format: "date-time",
2277
+ message: "Is not a valid date time"
2278
+ },
2279
+ end: {
2280
+ format: "date-time",
2281
+ message: "Is not a valid date time",
2282
+ formatMinimum: {
2283
+ $data: "1/start"
2284
+ }
2285
+ },
2286
+ ref: {
2287
+ $ref: "#definitions/ref"
2288
+ }
2289
+ },
2290
+ required: [
2291
+ "start",
2292
+ "end",
2293
+ "ref"
2294
+ ]
2295
+ }
2296
+ ]
2297
+ },
2298
+ file: {
2299
+ allOf: [
2300
+ {
2301
+ $ref: "#/definitions/entity"
2302
+ },
2303
+ {
2304
+ type: "object",
2305
+ properties: {
2306
+ type: {
2307
+ type: "string"
2308
+ },
2309
+ path: {
2310
+ type: "string"
2311
+ },
2312
+ fps: {
2313
+ type: "number"
2314
+ },
2315
+ originalFps: {
2316
+ type: "number"
2317
+ }
2318
+ },
2319
+ required: [
2320
+ "type",
2321
+ "path"
2322
+ ],
2323
+ "if": {
2324
+ properties: {
2325
+ type: {
2326
+ "const": "video"
2327
+ }
2328
+ }
2329
+ },
2330
+ then: {
2331
+ required: [
2332
+ "fps"
2333
+ ]
2334
+ }
2335
+ }
2336
+ ]
2337
+ },
2338
+ resource: {
2339
+ allOf: [
2340
+ {
2341
+ $ref: "#/definitions/entity"
2342
+ },
2343
+ {
2344
+ type: "object",
2345
+ properties: {
2346
+ type: {
2347
+ type: "string"
2348
+ },
2349
+ files: {
2350
+ type: "array",
2351
+ items: {
2352
+ type: "string"
2353
+ }
2354
+ }
2355
+ }
2356
+ }
2357
+ ]
2358
+ },
2359
+ dataViewer: {
2360
+ allOf: [
2361
+ {
2362
+ $ref: "#/definitions/entity"
2363
+ },
2364
+ {
2365
+ type: "object",
2366
+ properties: {
2367
+ id: {
2368
+ type: "string"
2369
+ },
2370
+ configVisible: {
2371
+ type: "boolean"
2372
+ },
2373
+ configAvailable: {
2374
+ type: "boolean"
2375
+ },
2376
+ measurements: {
2377
+ type: "array",
2378
+ items: {
2379
+ time: "string"
2380
+ }
2381
+ },
2382
+ zoomSteps: {
2383
+ type: "array",
2384
+ items: {
2385
+ type: "number"
2386
+ }
2387
+ },
2388
+ activeZoomStep: {
2389
+ type: "number"
2390
+ }
2391
+ }
2392
+ }
2393
+ ]
2394
+ },
2395
+ measurement: {
2396
+ allOf: [
2397
+ {
2398
+ $ref: "#/definitions/entity"
2399
+ },
2400
+ {
2401
+ type: "object",
2402
+ properties: {
2403
+ color: {
2404
+ type: "string"
2405
+ }
2406
+ },
2407
+ required: [
2408
+ "color"
2409
+ ]
2410
+ }
2411
+ ]
2412
+ },
2413
+ annotation: {
2414
+ allOf: [
2415
+ {
2416
+ $ref: "#/definitions/entity"
2417
+ },
2418
+ {
2419
+ type: "object",
2420
+ properties: {
2421
+ type: {
2422
+ type: "string"
2423
+ },
2424
+ content: {
2425
+ type: "string"
2426
+ },
2427
+ contentRevision: {
2428
+ type: "number"
2429
+ },
2430
+ streamPoints: {
2431
+ type: "array",
2432
+ items: {
2433
+ type: "string"
2434
+ }
2435
+ },
2436
+ textEditable: {
2437
+ type: "boolean"
2438
+ },
2439
+ style: {
2440
+ type: "object"
2441
+ }
2442
+ }
2443
+ }
2444
+ ]
2445
+ },
2446
+ streamPoint: {
2447
+ allOf: [
2448
+ {
2449
+ $ref: "#/definitions/entity"
2450
+ },
2451
+ {
2452
+ type: "object",
2453
+ properties: {
2454
+ frequency: {
2455
+ type: "number"
2456
+ },
2457
+ x: {
2458
+ type: "object",
2459
+ properties: {
2460
+ active: {
2461
+ type: "boolean"
2462
+ },
2463
+ scaled: {
2464
+ type: "boolean"
2465
+ },
2466
+ format: {
2467
+ type: "string"
2468
+ }
2469
+ }
2470
+ },
2471
+ y: {
2472
+ type: "object",
2473
+ properties: {
2474
+ active: {
2475
+ type: "boolean"
2476
+ },
2477
+ format: {
2478
+ type: "string"
2479
+ }
2480
+ }
2481
+ },
2482
+ measurement: {
2483
+ type: "string"
2484
+ }
2485
+ }
2486
+ }
2487
+ ]
2488
+ },
2489
+ annotationViewer: {
2490
+ allOf: [
2491
+ {
2492
+ $ref: "#/definitions/entity"
2493
+ },
2494
+ {
2495
+ type: "object",
2496
+ properties: {
2497
+ id: {
2498
+ type: "string"
2499
+ },
2500
+ active: {
2501
+ type: "boolean"
2502
+ },
2503
+ editable: {
2504
+ type: "boolean"
2505
+ },
2506
+ annotations: {
2507
+ type: "array",
2508
+ items: {
2509
+ type: "string"
2510
+ }
2511
+ },
2512
+ inTextEditMode: {
2513
+ type: "boolean"
2514
+ }
2515
+ }
2516
+ }
2517
+ ]
2518
+ },
2519
+ dockviewLeafData: {
2520
+ type: "object",
2521
+ properties: {
2522
+ id: {
2523
+ type: "string"
2524
+ },
2525
+ views: {
2526
+ type: "array",
2527
+ items: {
2528
+ type: "string"
2529
+ }
2530
+ },
2531
+ activeView: {
2532
+ type: "string"
2533
+ }
2534
+ },
2535
+ required: [
2536
+ "id",
2537
+ "views"
2538
+ ]
2539
+ },
2540
+ dockviewNode: {
2541
+ oneOf: [
2542
+ {
2543
+ type: "object",
2544
+ properties: {
2545
+ type: {
2546
+ "const": "leaf"
2547
+ },
2548
+ size: {
2549
+ type: "number"
2550
+ },
2551
+ data: {
2552
+ $ref: "#/definitions/dockviewLeafData"
2553
+ }
2554
+ },
2555
+ required: [
2556
+ "type",
2557
+ "data"
2558
+ ]
2559
+ },
2560
+ {
2561
+ type: "object",
2562
+ properties: {
2563
+ type: {
2564
+ "const": "branch"
2565
+ },
2566
+ size: {
2567
+ type: "number"
2568
+ },
2569
+ data: {
2570
+ type: "array",
2571
+ items: {
2572
+ $ref: "#/definitions/dockviewNode"
2573
+ }
2574
+ }
2575
+ },
2576
+ required: [
2577
+ "type",
2578
+ "data"
2579
+ ]
2580
+ }
2581
+ ]
2582
+ },
2583
+ dockviewPanel: {
2584
+ type: "object",
2585
+ properties: {
2586
+ id: {
2587
+ type: "string"
2588
+ },
2589
+ contentComponent: {
2590
+ type: "string"
2591
+ },
2592
+ title: {
2593
+ type: "string"
2594
+ },
2595
+ params: {
2596
+ type: "object"
2597
+ }
2598
+ },
2599
+ required: [
2600
+ "id",
2601
+ "contentComponent",
2602
+ "title",
2603
+ "params"
2604
+ ]
2605
+ },
2606
+ dockviewLayout: {
2607
+ type: "object",
2608
+ properties: {
2609
+ grid: {
2610
+ type: "object",
2611
+ properties: {
2612
+ root: {
2613
+ $ref: "#/definitions/dockviewNode"
2614
+ },
2615
+ orientation: {
2616
+ type: "string",
2617
+ "enum": [
2618
+ "HORIZONTAL",
2619
+ "VERTICAL"
2620
+ ]
2621
+ },
2622
+ width: {
2623
+ type: "number"
2624
+ },
2625
+ height: {
2626
+ type: "number"
2627
+ }
2628
+ },
2629
+ required: [
2630
+ "root",
2631
+ "orientation",
2632
+ "width",
2633
+ "height"
2634
+ ]
2635
+ },
2636
+ panels: {
2637
+ type: "object",
2638
+ additionalProperties: {
2639
+ $ref: "#/definitions/dockviewPanel"
2640
+ }
2641
+ },
2642
+ activeGroup: {
2643
+ type: "string"
2644
+ }
2645
+ },
2646
+ required: [
2647
+ "grid",
2648
+ "panels"
2649
+ ]
2650
+ },
2651
+ axis: {
2652
+ allOf: [
2653
+ {
2654
+ $ref: "#/definitions/entity"
2655
+ },
2656
+ {
2657
+ type: "object",
2658
+ properties: {
2659
+ color: {
2660
+ type: "string"
2661
+ },
2662
+ resources: {
2663
+ type: "array",
2664
+ items: {
2665
+ type: "string"
2666
+ }
2667
+ }
2668
+ }
2669
+ }
2670
+ ]
2671
+ },
2672
+ assetsContainer: {
2673
+ allOf: [
2674
+ {
2675
+ $ref: "#/definitions/entitiesContainer"
2676
+ },
2677
+ {
2678
+ type: "object",
2679
+ properties: {
2680
+ byId: {
2681
+ type: "object",
2682
+ additionalProperties: {
2683
+ $ref: "#/definitions/asset"
2684
+ }
2685
+ }
2686
+ }
2687
+ }
2688
+ ]
2689
+ },
2690
+ annotationsContainer: {
2691
+ allOf: [
2692
+ {
2693
+ $ref: "#/definitions/entitiesContainer"
2694
+ },
2695
+ {
2696
+ type: "object",
2697
+ properties: {
2698
+ byId: {
2699
+ type: "object",
2700
+ additionalProperties: {
2701
+ $ref: "#/definitions/annotation"
2702
+ }
2703
+ }
2704
+ }
2705
+ }
2706
+ ]
2707
+ },
2708
+ streamPointsContainer: {
2709
+ allOf: [
2710
+ {
2711
+ $ref: "#/definitions/entitiesContainer"
2712
+ },
2713
+ {
2714
+ type: "object",
2715
+ properties: {
2716
+ byId: {
2717
+ type: "object",
2718
+ additionalProperties: {
2719
+ $ref: "#/definitions/streamPoint"
2720
+ }
2721
+ }
2722
+ }
2723
+ }
2724
+ ]
2725
+ },
2726
+ annotationsViewersContainer: {
2727
+ allOf: [
2728
+ {
2729
+ $ref: "#/definitions/entitiesContainer"
2730
+ },
2731
+ {
2732
+ type: "object",
2733
+ properties: {
2734
+ byId: {
2735
+ type: "object",
2736
+ additionalProperties: {
2737
+ $ref: "#/definitions/annotationViewer"
2738
+ }
2739
+ }
2740
+ }
2741
+ }
2742
+ ]
2743
+ },
2744
+ dataViewersContainer: {
2745
+ allOf: [
2746
+ {
2747
+ $ref: "#/definitions/entitiesContainer"
2748
+ },
2749
+ {
2750
+ type: "object",
2751
+ properties: {
2752
+ byId: {
2753
+ type: "object",
2754
+ additionalProperties: {
2755
+ $ref: "#/definitions/dataViewer"
2756
+ }
2757
+ }
2758
+ }
2759
+ }
2760
+ ]
2761
+ },
2762
+ measurementsContainer: {
2763
+ allOf: [
2764
+ {
2765
+ $ref: "#/definitions/entitiesContainer"
2766
+ },
2767
+ {
2768
+ type: "object",
2769
+ properties: {
2770
+ byId: {
2771
+ type: "object",
2772
+ additionalProperties: {
2773
+ $ref: "#/definitions/measurement"
2774
+ }
2775
+ }
2776
+ }
2777
+ }
2778
+ ]
2779
+ },
2780
+ filesContainer: {
2781
+ allOf: [
2782
+ {
2783
+ $ref: "#/definitions/entitiesContainer"
2784
+ },
2785
+ {
2786
+ type: "object",
2787
+ properties: {
2788
+ byId: {
2789
+ type: "object",
2790
+ additionalProperties: {
2791
+ $ref: "#/definitions/file"
2792
+ }
2793
+ }
2794
+ }
2795
+ }
2796
+ ]
2797
+ },
2798
+ resourcesContainer: {
2799
+ allOf: [
2800
+ {
2801
+ $ref: "#/definitions/entitiesContainer"
2802
+ },
2803
+ {
2804
+ type: "object",
2805
+ properties: {
2806
+ byId: {
2807
+ type: "object",
2808
+ additionalProperties: {
2809
+ $ref: "#/definitions/resource"
2810
+ }
2811
+ }
2812
+ }
2813
+ }
2814
+ ]
2815
+ },
2816
+ axesContainer: {
2817
+ allOf: [
2818
+ {
2819
+ $ref: "#/definitions/entitiesContainer"
2820
+ },
2821
+ {
2822
+ type: "object",
2823
+ properties: {
2824
+ byId: {
2825
+ type: "object",
2826
+ additionalProperties: {
2827
+ $ref: "#/definitions/axis"
2828
+ }
2829
+ }
2830
+ }
2831
+ }
2832
+ ]
2833
+ }
2834
+ };
2835
+ var properties = {
2836
+ version: {
2837
+ type: "number",
2838
+ "const": 4
2839
+ },
2840
+ menu: {
2841
+ type: "object",
2842
+ properties: {
2843
+ visible: {
2844
+ type: "boolean"
2845
+ }
2846
+ }
2847
+ },
2848
+ files: {
2849
+ type: "object",
2850
+ properties: {
2851
+ entities: {
2852
+ type: "object",
2853
+ properties: {
2854
+ files: {
2855
+ $ref: "#/definitions/filesContainer"
2856
+ }
2857
+ }
2858
+ }
2859
+ }
2860
+ },
2861
+ resources: {
2862
+ type: "object",
2863
+ properties: {
2864
+ entities: {
2865
+ type: "object",
2866
+ properties: {
2867
+ resources: {
2868
+ $ref: "#/definitions/resourcesContainer"
2869
+ }
2870
+ }
2871
+ }
2872
+ }
2873
+ },
2874
+ assets: {
2875
+ type: "object",
2876
+ properties: {
2877
+ entities: {
2878
+ type: "object",
2879
+ properties: {
2880
+ assets: {
2881
+ $ref: "#/definitions/assetsContainer"
2882
+ }
2883
+ }
2884
+ }
2885
+ }
2886
+ },
2887
+ layout: {
2888
+ type: "object",
2889
+ properties: {
2890
+ dockviewLayout: {
2891
+ oneOf: [
2892
+ {
2893
+ $ref: "#/definitions/dockviewLayout"
2894
+ },
2895
+ {
2896
+ type: "null"
2897
+ }
2898
+ ]
2899
+ },
2900
+ focus: {
2901
+ type: "string"
2902
+ },
2903
+ dragging: {
2904
+ type: "boolean"
2905
+ },
2906
+ resizingPanels: {
2907
+ type: "boolean"
2908
+ }
2909
+ }
2910
+ },
2911
+ data: {
2912
+ type: "object",
2913
+ properties: {
2914
+ measurementScale: {
2915
+ type: "number"
2916
+ },
2917
+ entities: {
2918
+ type: "object",
2919
+ properties: {
2920
+ dataViewers: {
2921
+ $ref: "#/definitions/dataViewersContainer"
2922
+ },
2923
+ measurements: {
2924
+ $ref: "#/definitions/measurementsContainer"
2925
+ }
2926
+ }
2927
+ }
2928
+ }
2929
+ },
2930
+ annotations: {
2931
+ type: "object",
2932
+ properties: {
2933
+ allowed: {
2934
+ type: "boolean"
2935
+ },
2936
+ editorOpen: {
2937
+ type: "boolean"
2938
+ },
2939
+ streamPointSelectorOpen: {
2940
+ type: "boolean"
2941
+ },
2942
+ entities: {
2943
+ type: "object",
2944
+ properties: {
2945
+ annotations: {
2946
+ $ref: "#/definitions/entitiesContainer"
2947
+ },
2948
+ streamPoints: {
2949
+ $ref: "#/definitions/streamPointsContainer"
2950
+ },
2951
+ annotationsViewers: {
2952
+ $ref: "#/definitions/annotationsViewersContainer"
2953
+ }
2954
+ }
2955
+ }
2956
+ }
2957
+ },
2958
+ timeline: {
2959
+ type: "object",
2960
+ properties: {
2961
+ entities: {
2962
+ type: "object",
2963
+ properties: {
2964
+ axes: {
2965
+ $ref: "#/definitions/axesContainer"
2966
+ }
2967
+ }
2968
+ }
2969
+ }
2970
+ },
2971
+ timer: {
2972
+ type: "object",
2973
+ properties: {
2974
+ running: {
2975
+ type: "boolean"
2976
+ },
2977
+ startTime: {
2978
+ oneOf: [
2979
+ {
2980
+ type: "number"
2981
+ },
2982
+ {
2983
+ type: "null"
2984
+ }
2985
+ ]
2986
+ },
2987
+ waiting: {
2988
+ type: "boolean"
2989
+ },
2990
+ waitingReasons: {
2991
+ type: "array"
2992
+ },
2993
+ range: {
2994
+ type: "array"
2995
+ },
2996
+ rate: {
2997
+ type: "number"
2998
+ }
2999
+ }
3000
+ }
3001
+ };
3002
+ var schema = {
3003
+ $schema: $schema,
3004
+ id: id,
3005
+ description: description$1,
3006
+ type: type,
3007
+ definitions: definitions,
3008
+ properties: properties
3009
+ };
3010
+
3011
+ const jsonSchemaValidator = createAJVValidator(schema);
3012
+ var v4 = stage => {
3013
+ return jsonSchemaValidator(stage);
3014
+ };
3015
+
3016
+ const map = Object.freeze({
3017
+ 1: v1,
3018
+ 2: v2,
3019
+ 3: v3$1,
3020
+ 4: v4
3021
+ });
3022
+
3023
+ /**
3024
+ * Parses validation specific options from global options.
3025
+ * @param {obj} options
3026
+ */
3027
+ const optionsParser$1 = ({
3028
+ validationVersion = undefined
3029
+ }) => ({
3030
+ version: validationVersion
3031
+ });
3032
+
3033
+ /**
3034
+ * Validates a stage
3035
+ * @param {Object} stage
3036
+ * @param {number} version
3037
+ */
3038
+
3039
+ var validate = (stage, options = {}) => {
3040
+ const {
3041
+ version = undefined
3042
+ } = options;
3043
+ return pipe(defaultTo(detectVersion(stage)), lookup(map), applyTo(stage))(version);
3044
+ };
3045
+
3046
+ var versions = Object.freeze([1, 2, 3, 4]);
3047
+
3048
+ /**
3049
+ * v1-to-v2.js
3050
+ * Upgrader for version 1 stage files to version 2.
3051
+ * Removes timelines axes with resources. And adds the zoomSteps for the dataviewer.
3052
+ */
3053
+ const outletsView = listEntities(["data", "entities", "outlets"]);
3054
+
3055
+ // This adds the zoomsteps on dataviwer based on "visible" prop on the associated outlet.
3056
+ const addDataViewerZoomSteps = stage => pipe(outletsView,
3057
+ // The association to a dataviewer is defined in the outlet id (dataviewer/<DATAVIEWER ID>),
3058
+ // This only takes outlets associated with a dataviewer.
3059
+ filter(propSatisfies(startsWith("dataviewer/"), "id")), map$1(
3060
+ // This pairs the path to the associated dataviewer to its required zoomSteps.
3061
+ converge(pair, [pipe(prop("id"), replace("dataviewer/", ""), id => ["data", "entities", "dataViewers", "byId", id, "zoomSteps"]), pipe(prop("visible"), visible => [visible])])),
3062
+ // Set the "zoomSteps" prop of the dataviewer to the visibility of the outlet.
3063
+ reduce((acc, [path, zoomSteps]) => assocPath(path, zoomSteps, acc), stage))(stage);
3064
+ var v1ToV2 = pipe(
3065
+ // Sets the version prop to "2"
3066
+ assoc("version", 2),
3067
+ // Remove the association to resources from the timline axes.
3068
+ // In version 2 the tracks for files on the timeline are handled by the v2 consolidation strategy.
3069
+ dissocPath(["timeline", "entities", "axes", "byId", "video", "resources"]), dissocPath(["timeline", "entities", "axes", "byId", "high-speed", "resources"]),
3070
+ // Adds the zoomsteps to the dataviewers.
3071
+ addDataViewerZoomSteps);
3072
+
3073
+ const NEW_TEST_REGEX$1 = /^([0-9]{5})_(.+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$/;
3074
+ const fsPath$1 = require("path");
3075
+ const match$1 = R.curry((regex, st) => st.match(regex));
3076
+ const mapWithIndex$1 = R.addIndex(R.map);
3077
+ const axesSettings$1 = [{
3078
+ id: "video",
3079
+ color: "#41b51b"
3080
+ }, {
3081
+ id: "high-speed",
3082
+ color: "#3318cc"
3083
+ }, {
3084
+ id: "comment",
3085
+ color: "red"
3086
+ }];
3087
+ const tracksIdsPath$1 = ["timeline", "entities", "tracks", "ids"];
3088
+ const tracksByIdPath$1 = ["timeline", "entities", "tracks", "byId"];
3089
+ const axesIdsPath$1 = ["timeline", "entities", "axes", "ids"];
3090
+ const axesByIdPath$1 = ["timeline", "entities", "axes", "byId"];
3091
+ const resourcesIdsView$1 = R.pathOr([], ["resources", "entities", "resources", "ids"]);
3092
+ const resourcesByIdView$1 = R.pathOr({}, ["resources", "entities", "resources", "byId"]);
3093
+ const filesIdsView$1 = R.pathOr([], ["files", "entities", "files", "ids"]);
3094
+ const filesByIdView$1 = R.pathOr({}, ["files", "entities", "files", "byId"]);
3095
+ const commentsByIdView$1 = R.pathOr({}, ["timeline", "entities", "comments", "byId"]);
3096
+ const tracksIdsLens$1 = R.lensPath(tracksIdsPath$1);
3097
+ const tracksByIdLens$1 = R.lensPath(tracksByIdPath$1);
3098
+ const axesIdsLens$1 = R.lensPath(axesIdsPath$1);
3099
+ const axesByIdLens$1 = R.lensPath(axesByIdPath$1);
3100
+ const filesView = R.pipe(filesByIdView$1, R.values);
3101
+ const commentsView$1 = R.pipe(commentsByIdView$1, R.values);
3102
+ const highSpeedsFilesView$1 = stage => {
3103
+ const filesById = filesByIdView$1(stage);
3104
+ const resourcesById = resourcesByIdView$1(stage);
3105
+ return R.pipe(
3106
+ // Iterate R.over the resource ids
3107
+ resourcesIdsView$1,
3108
+ // Filter out all the ids that don't start with high-speed.
3109
+ R.filter(R.startsWith("high-speed:")),
3110
+ // Map the remaining resource ids to the files ids in the respective resource object.
3111
+ lookupPathAll(resourcesById, ["files"]),
3112
+ // Flatten the ids so we get a single array containing all the files ids referred
3113
+ // to across all high-speed resources.
3114
+ R.flatten,
3115
+ // Map the file ids to file objects.
3116
+ lookupAll(filesById))(stage);
3117
+ };
3118
+ const videosFilesView$1 = stage => {
3119
+ const filesIds = filesIdsView$1(stage);
3120
+ const filesById = filesByIdView$1(stage);
3121
+ const highSpeedFiles = highSpeedsFilesView$1(stage);
3122
+ return R.pipe(R.without(R.pluck("id", highSpeedFiles)), lookupAll(filesById), R.filter(R.propEq("video", "type")))(filesIds);
3123
+ };
3124
+ const upsertAxes$1 = axes => R.curry(R.pipe(R.unless(R.path(axesIdsPath$1), R.assocPath(axesIdsPath$1, [])), R.unless(R.path(axesByIdPath$1), R.assocPath(axesIdsPath$1, {})), R.over(axesIdsLens$1, R.union(R.pluck("id", axes))), R.over(axesByIdLens$1, R.mergeRight(indexById(axes)))));
3125
+ const createTrackFromEntity$1 = R.curry((axis, entity) => {
3126
+ const {
3127
+ start,
3128
+ end,
3129
+ type,
3130
+ id
3131
+ } = entity;
3132
+ return {
3133
+ id: `track:${id}`,
3134
+ start,
3135
+ end,
3136
+ type,
3137
+ axisRef: axis,
3138
+ ref: id
3139
+ };
3140
+ });
3141
+ const mapEntitiesToTracks$1 = R.curry((entitiesSelector, axis, stage) => R.map(createTrackFromEntity$1(axis), entitiesSelector(stage)));
3142
+ const mapCommentsToTracks$1 = R.pipe(mapEntitiesToTracks$1(commentsView$1, "comment"), R.map(R.mergeLeft({
3143
+ type: "comment",
3144
+ label: "comment"
3145
+ })));
3146
+ const formatTestNo$1 = input => {
3147
+ const [
3148
+ // eslint-disable-next-line no-unused-vars
3149
+ m, project, facility, program, category, test, experiment, measurement] = input.match(NEW_TEST_REGEX$1);
3150
+ return `${project}_${program.padStart(2, "0")}${facility}_${category.padStart(2, "0")}_${test.padStart(3, "0")}_${experiment.padStart(3, "0")}_${measurement.padStart(2, "0")}`;
3151
+ };
3152
+ const extractTestNumberFromMetadata$1 = R.pipe(R.path(["metadata", "location", "$id"]), R.when(R.test(NEW_TEST_REGEX$1), formatTestNo$1));
3153
+ const extractTestNumberFromFileName$1 = R.compose(R.head, R.defaultTo([undefined]), R.either(match$1(/[0-9]{5}_[0-9]{2}[a-zA-Z]+_[0-9]{2}_[0-9]{3}_[0-9]{3}_[0-9]{2}/), match$1(/[A-Za-z]+[0-9]{5}_[0-9]+_[0-9]+_[0-9]+/)), R.prop("path"));
3154
+ const extractTestNumber$1 = (stage, track) => R.pipe(filesByIdView$1, R.prop(track.ref), R.either(extractTestNumberFromMetadata$1, extractTestNumberFromFileName$1))(stage);
3155
+ const formatter$1 = formatWithOptions({
3156
+ awareOfUnicodeTokens: true
3157
+ });
3158
+ const extractRecordingChannel$1 = (stage, track) => R.pipe(filesByIdView$1, R.path([track.ref, "metadata", "recChannel"]))(stage);
3159
+ const createHighSpeedTracksLabels$1 = stage => tracks => mapWithIndex$1((hs, index) => {
3160
+ const recordingChannel = extractRecordingChannel$1(stage, hs);
3161
+ const no = recordingChannel || index + 1;
3162
+ return R.assoc("label", `HS ${no}`, hs);
3163
+ }, tracks);
3164
+ const createVideoTracksLabels$1 = stage => tracks => mapWithIndex$1((vid, index) => {
3165
+ const recordingChannel = extractRecordingChannel$1(stage, vid);
3166
+ const no = recordingChannel || index + 1;
3167
+ return R.assoc("label", `VID ${no}`, vid);
3168
+ }, tracks);
3169
+ const extractFormat$1 = (stage, track) => R.pipe(filesByIdView$1, R.path([track.ref, "path"]), p => fsPath$1.extname(p))(stage);
3170
+ const extractSecondFractions$1 = isoStr => R.pipe(match$1(/[0-9]{2}:[0-9]{2}:[0-9]{2}.([0-9]+)/), R.ifElse(R.isNil, R.always("000"), R.nth(1)))(isoStr);
3171
+ const extractDate = (stage, track) => {
3172
+ return R.pipe(filesByIdView$1, R.path([track.ref, "start"]), parseISO, formatter$1("dd-MM-yyyy"))(stage);
3173
+ };
3174
+ const createTime$1 = R.converge(R.pipe(R.pair, R.join(".")), [R.pipe(parseISO, formatter$1("HH:mm:ss")), extractSecondFractions$1]);
3175
+ const extractStart = (stage, track) => R.pipe(filesByIdView$1, R.path([track.ref, "start"]), createTime$1)(stage);
3176
+ const extractEnd = (stage, track) => R.pipe(filesByIdView$1, R.path([track.ref, "end"]), createTime$1)(stage);
3177
+ const createVideoMetadata$1 = R.curry((type, stage, track) => ({
3178
+ ...track,
3179
+ metadata: track.metadata || [[{
3180
+ label: "Test",
3181
+ value: extractTestNumber$1(stage, track)
3182
+ }], [{
3183
+ label: "Type",
3184
+ value: type
3185
+ }, {
3186
+ label: "Recording channel",
3187
+ value: extractRecordingChannel$1(stage, track)
3188
+ }, {
3189
+ label: "Format",
3190
+ value: extractFormat$1(stage, track)
3191
+ }], [{
3192
+ label: "Date",
3193
+ value: extractDate(stage, track)
3194
+ }, {
3195
+ label: "Start",
3196
+ value: extractStart(stage, track)
3197
+ }, {
3198
+ label: "End",
3199
+ value: extractEnd(stage, track)
3200
+ }]]
3201
+ }));
3202
+ const createHighSpeedsMetadata$1 = R.curry((stage, tracks) => R.map(createVideoMetadata$1("high-speed", stage), tracks));
3203
+ const createVideosMetadata$1 = R.curry((stage, tracks) => R.map(createVideoMetadata$1("video", stage), tracks));
3204
+ const createTracks$1 = stage => R.converge((...args) => R.flatten(args), [R.pipe(mapEntitiesToTracks$1(highSpeedsFilesView$1, "high-speed"), createHighSpeedTracksLabels$1(stage), createHighSpeedsMetadata$1(stage)), R.pipe(mapEntitiesToTracks$1(videosFilesView$1, "video"), createVideoTracksLabels$1(stage), createVideosMetadata$1(stage)), mapCommentsToTracks$1])(stage);
3205
+ const upsertTracks$1 = tracks => R.curry(R.pipe(R.unless(R.path(tracksIdsPath$1), R.assocPath(tracksIdsPath$1, [])), R.unless(R.path(tracksByIdPath$1), R.assocPath(tracksByIdPath$1, {})), R.over(tracksIdsLens$1, R.union(R.pluck("id", tracks))), R.over(tracksByIdLens$1, R.mergeRight(indexById(tracks)))));
3206
+ const earliestTime$1 = stage => R.pipe(filesView, R.map(R.prop("start")), R.map(Date.parse), R.apply(Math.min), t => new Date(t), d => d.toISOString())(stage);
3207
+ const latestTime$1 = stage => R.pipe(filesView, R.map(R.prop("end")), R.map(Date.parse), R.apply(Math.max), t => new Date(t), d => d.toISOString())(stage);
3208
+ const setTimeLineStartEnd$1 = stage => R.pipe(R.assocPath(["timeline", "start"], earliestTime$1(stage)), R.assocPath(["timeline", "end"], latestTime$1(stage)))(stage);
3209
+ const setCommentAxis$1 = R.assocPath(["timeline", "commentAxis"], "comment");
3210
+ const consolidateTimeline$1 = stage => {
3211
+ return R.pipe(upsertAxes$1(axesSettings$1), upsertTracks$1(createTracks$1(stage)), setTimeLineStartEnd$1, setCommentAxis$1)(stage);
3212
+ };
3213
+ const consolidate$1 = stage => {
3214
+ return consolidateTimeline$1(stage);
3215
+ };
3216
+
3217
+ const NEW_TEST_REGEX = /^([0-9]{5})_(.+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)$/;
3218
+ const fsPath = require("path");
3219
+ const match = R.curry((regex, st) => st.match(regex));
3220
+ const mapWithIndex = R.addIndex(R.map);
3221
+ const axesSettings = [{
3222
+ id: "video",
3223
+ color: "#41b51b"
3224
+ }, {
3225
+ id: "high-speed",
3226
+ color: "#3318cc"
3227
+ }, {
3228
+ id: "comment",
3229
+ color: "red"
3230
+ }];
3231
+ const tracksIdsPath = ["timeline", "entities", "tracks", "ids"];
3232
+ const tracksByIdPath = ["timeline", "entities", "tracks", "byId"];
3233
+ const axesIdsPath = ["timeline", "entities", "axes", "ids"];
3234
+ const axesByIdPath = ["timeline", "entities", "axes", "byId"];
3235
+ const resourcesIdsView = R.pathOr([], ["resources", "entities", "resources", "ids"]);
3236
+ const resourcesByIdView = R.pathOr({}, ["resources", "entities", "resources", "byId"]);
3237
+ const filesIdsView = R.pathOr([], ["files", "entities", "files", "ids"]);
3238
+ const filesByIdView = R.pathOr({}, ["files", "entities", "files", "byId"]);
3239
+ const timingByIdView = R.pathOr({}, ["timing", "entities", "timing", "byId"]);
3240
+ const commentsByIdView = R.pathOr({}, ["timeline", "entities", "comments", "byId"]);
3241
+ const tracksIdsLens = R.lensPath(tracksIdsPath);
3242
+ const tracksByIdLens = R.lensPath(tracksByIdPath);
3243
+ const axesIdsLens = R.lensPath(axesIdsPath);
3244
+ const axesByIdLens = R.lensPath(axesByIdPath);
3245
+ const timingsView = R.pipe(timingByIdView, R.values);
3246
+ const commentsView = R.pipe(commentsByIdView, R.values);
3247
+ const highSpeedsFilesView = stage => {
3248
+ const filesById = filesByIdView(stage);
3249
+ const resourcesById = resourcesByIdView(stage);
3250
+ return R.pipe(
3251
+ // Iterate R.over the resource ids
3252
+ resourcesIdsView,
3253
+ // Filter out all the ids that don't start with high-speed.
3254
+ R.filter(R.startsWith("high-speed:")),
3255
+ // Map the remaining resource ids to the files ids in the respective resource object.
3256
+ lookupPathAll(resourcesById, ["props", "files"]),
3257
+ // Flatten the ids so we get a single array containing all the files ids referred
3258
+ // to across all high-speed resources.
3259
+ R.flatten,
3260
+ // Map the file ids to file objects.
3261
+ lookupAll(filesById))(stage);
3262
+ };
2470
3263
  const highSpeedsTimingsView = stage => {
2471
3264
  const timings = timingsView(stage);
2472
- return pipe(highSpeedsFilesView$1, // Map the file ids to file objects.
3265
+ return R.pipe(highSpeedsFilesView,
3266
+ // Map the file ids to file objects.
2473
3267
  files => files.map(file => timings.find(timing => timing.ref.id === file.id)))(stage);
2474
3268
  };
2475
-
2476
- const videosFilesView$1 = stage => {
2477
- const filesIds = filesIdsView$1(stage);
2478
- const filesById = filesByIdView$1(stage);
2479
- const highSpeedFiles = highSpeedsFilesView$1(stage);
2480
- return pipe(without(pluck("id", highSpeedFiles)), lookupAll(filesById), filter(propEq("type", "video")))(filesIds);
3269
+ const videosFilesView = stage => {
3270
+ const filesIds = filesIdsView(stage);
3271
+ const filesById = filesByIdView(stage);
3272
+ const highSpeedFiles = highSpeedsFilesView(stage);
3273
+ return R.pipe(R.without(R.pluck("id", highSpeedFiles)), lookupAll(filesById), R.filter(R.propEq("video", "type")))(filesIds);
2481
3274
  };
2482
-
2483
3275
  const videoTimingsView = stage => {
2484
3276
  const timings = timingsView(stage);
2485
- return pipe(videosFilesView$1, files => files.map(file => timings.find(timing => timing.ref.id === file.id)))(stage);
3277
+ return R.pipe(videosFilesView, files => files.map(file => timings.find(timing => timing.ref.id === file.id)))(stage);
2486
3278
  };
2487
-
2488
- const upsertAxes$1 = axes => curry(pipe(unless(path(axesIdsPath$1), assocPath(axesIdsPath$1, [])), unless(path(axesByIdPath$1), assocPath(axesIdsPath$1, {})), over(axesIdsLens$1, union(pluck("id", axes))), over(axesByIdLens$1, merge(indexById(axes)))));
2489
- const createTrackFromEntity$1 = curry((axis, entity) => {
3279
+ const upsertAxes = axes => R.curry(R.pipe(R.unless(R.path(axesIdsPath), R.assocPath(axesIdsPath, [])), R.unless(R.path(axesByIdPath), R.assocPath(axesIdsPath, {})), R.over(axesIdsLens, R.union(R.pluck("id", axes))), R.over(axesByIdLens, R.mergeRight(indexById(axes)))));
3280
+ const createTrackFromEntity = R.curry((axis, entity) => {
2490
3281
  const {
2491
3282
  start,
2492
3283
  end,
@@ -2506,8 +3297,8 @@ const createTrackFromEntity$1 = curry((axis, entity) => {
2506
3297
  timeline: "1"
2507
3298
  };
2508
3299
  });
2509
- const mapEntitiesToTracks$1 = curry((entitiesSelector, axis, stage) => map$1(createTrackFromEntity$1(axis), entitiesSelector(stage)));
2510
- const createTrackFromTiming = curry((axis, timing) => {
3300
+ const mapEntitiesToTracks = R.curry((entitiesSelector, axis, stage) => R.map(createTrackFromEntity(axis), entitiesSelector(stage)));
3301
+ const createTrackFromTiming = R.curry((axis, timing) => {
2511
3302
  const {
2512
3303
  start,
2513
3304
  end,
@@ -2530,62 +3321,54 @@ const createTrackFromTiming = curry((axis, timing) => {
2530
3321
  timeline: "1"
2531
3322
  };
2532
3323
  });
2533
- const mapTimingsToTracks = curry((entitiesSelector, axis, stage) => map$1(createTrackFromTiming(axis), entitiesSelector(stage)));
2534
- const mapCommentsToTracks$1 = pipe(mapEntitiesToTracks$1(commentsView$1, "comment"), map$1(mergeLeft({
3324
+ const mapTimingsToTracks = R.curry((entitiesSelector, axis, stage) => R.map(createTrackFromTiming(axis), entitiesSelector(stage)));
3325
+ const mapCommentsToTracks = R.pipe(mapEntitiesToTracks(commentsView, "comment"), R.map(R.mergeLeft({
2535
3326
  type: "comment",
2536
3327
  label: "comment"
2537
3328
  })));
2538
-
2539
- const formatTestNo$1 = input => {
2540
- const [// eslint-disable-next-line no-unused-vars
2541
- m, project, facility, program, category, test, experiment, measurement] = input.match(NEW_TEST_REGEX$1);
3329
+ const formatTestNo = input => {
3330
+ const [
3331
+ // eslint-disable-next-line no-unused-vars
3332
+ m, project, facility, program, category, test, experiment, measurement] = input.match(NEW_TEST_REGEX);
2542
3333
  return `${project}_${program.padStart(2, "0")}${facility}_${category.padStart(2, "0")}_${test.padStart(3, "0")}_${experiment.padStart(3, "0")}_${measurement.padStart(2, "0")}`;
2543
3334
  };
2544
-
2545
- const extractTestNumberFromMetadata$1 = pipe(path(["metadata", "location", "$id"]), when(test(NEW_TEST_REGEX$1), formatTestNo$1));
2546
- const extractTestNumberFromFileName$1 = compose(head, defaultTo([undefined]), either(match$1(/[0-9]{5}_[0-9]{2}[a-zA-Z]+_[0-9]{2}_[0-9]{3}_[0-9]{3}_[0-9]{2}/), match$1(/[A-Za-z]+[0-9]{5}_[0-9]+_[0-9]+_[0-9]+/)), prop("path"));
2547
-
2548
- const extractTestNumber$1 = (stage, track) => pipe(filesByIdView$1, prop(track.ref.id), either(extractTestNumberFromMetadata$1, extractTestNumberFromFileName$1))(stage);
2549
-
2550
- const formatter$1 = formatWithOptions({
3335
+ const extractTestNumberFromMetadata = R.pipe(R.path(["metadata", "location", "$id"]), R.when(R.test(NEW_TEST_REGEX), formatTestNo));
3336
+ const extractTestNumberFromFileName = R.compose(R.head, R.defaultTo([undefined]), R.either(match(/[0-9]{5}_[0-9]{2}[a-zA-Z]+_[0-9]{2}_[0-9]{3}_[0-9]{3}_[0-9]{2}/), match(/[A-Za-z]+[0-9]{5}_[0-9]+_[0-9]+_[0-9]+/)), R.prop("path"));
3337
+ const extractTestNumber = (stage, track) => R.pipe(filesByIdView, R.prop(track.ref.id), R.either(extractTestNumberFromMetadata, extractTestNumberFromFileName))(stage);
3338
+ const formatter = formatWithOptions({
2551
3339
  awareOfUnicodeTokens: true
2552
3340
  });
2553
-
2554
- const extractRecordingChannel$1 = (stage, track) => pipe(filesByIdView$1, path([track.ref.id, "metadata", "recChannel"]))(stage);
2555
-
2556
- const createHighSpeedTracksLabels$1 = stage => tracks => mapWithIndex$1((hs, index) => {
2557
- const recordingChannel = extractRecordingChannel$1(stage, hs);
3341
+ const extractRecordingChannel = (stage, track) => R.pipe(filesByIdView, R.path([track.ref.id, "metadata", "recChannel"]))(stage);
3342
+ const createHighSpeedTracksLabels = stage => tracks => mapWithIndex((hs, index) => {
3343
+ const recordingChannel = extractRecordingChannel(stage, hs);
2558
3344
  const no = recordingChannel || index + 1;
2559
- return assoc("label", `HS ${no}`, hs);
3345
+ return R.assoc("label", `HS ${no}`, hs);
2560
3346
  }, tracks);
2561
-
2562
- const createVideoTracksLabels$1 = stage => tracks => mapWithIndex$1((vid, index) => {
2563
- const recordingChannel = extractRecordingChannel$1(stage, vid);
3347
+ const createVideoTracksLabels = stage => tracks => mapWithIndex((vid, index) => {
3348
+ const recordingChannel = extractRecordingChannel(stage, vid);
2564
3349
  const no = recordingChannel || index + 1;
2565
- return assoc("label", `VID ${no}`, vid);
3350
+ return R.assoc("label", `VID ${no}`, vid);
2566
3351
  }, tracks);
2567
-
2568
- const extractFormat$1 = (stage, track) => pipe(filesByIdView$1, path([track.ref.id, "path"]), p => fsPath$1.extname(p))(stage);
2569
-
2570
- const extractSecondFractions$1 = isoStr => pipe(match$1(/[0-9]{2}:[0-9]{2}:[0-9]{2}.([0-9]+)/), ifElse(isNil, always("000"), nth(1)))(isoStr);
2571
-
2572
- const extractDateFromTrack = pipe(prop("start"), parseISO, formatter$1("dd-MM-yyyy"));
2573
- const createTime$1 = converge(pipe(pair, join(".")), [pipe(parseISO, formatter$1("HH:mm:ss")), extractSecondFractions$1]);
2574
- const extractStartFromTrack = pipe(prop("start"), createTime$1);
2575
- const extractEndFromTrack = pipe(prop("end"), createTime$1);
2576
- const createVideoMetadata$1 = curry((type, stage, track) => ({ ...track,
3352
+ const extractFormat = (stage, track) => R.pipe(filesByIdView, R.path([track.ref.id, "path"]), p => fsPath.extname(p))(stage);
3353
+ const extractSecondFractions = isoStr => R.pipe(match(/[0-9]{2}:[0-9]{2}:[0-9]{2}.([0-9]+)/), R.ifElse(R.isNil, R.always("000"), R.nth(1)))(isoStr);
3354
+ const extractDateFromTrack = R.pipe(R.prop("start"), parseISO, formatter("dd-MM-yyyy"));
3355
+ const createTime = R.converge(R.pipe(R.pair, R.join(".")), [R.pipe(parseISO, formatter("HH:mm:ss")), extractSecondFractions]);
3356
+ const extractStartFromTrack = R.pipe(R.prop("start"), createTime);
3357
+ const extractEndFromTrack = R.pipe(R.prop("end"), createTime);
3358
+ const createVideoMetadata = R.curry((type, stage, track) => ({
3359
+ ...track,
2577
3360
  metadata: [[{
2578
3361
  label: "Test",
2579
- value: extractTestNumber$1(stage, track)
3362
+ value: extractTestNumber(stage, track)
2580
3363
  }], [{
2581
3364
  label: "Type",
2582
3365
  value: type
2583
3366
  }, {
2584
3367
  label: "Recording channel",
2585
- value: extractRecordingChannel$1(stage, track)
3368
+ value: extractRecordingChannel(stage, track)
2586
3369
  }, {
2587
3370
  label: "Format",
2588
- value: extractFormat$1(stage, track)
3371
+ value: extractFormat(stage, track)
2589
3372
  }], [{
2590
3373
  label: "Date",
2591
3374
  value: extractDateFromTrack(track)
@@ -2597,41 +3380,33 @@ const createVideoMetadata$1 = curry((type, stage, track) => ({ ...track,
2597
3380
  value: extractEndFromTrack(track)
2598
3381
  }]]
2599
3382
  }));
2600
- const createHighSpeedsMetadata$1 = curry((stage, tracks) => map$1(createVideoMetadata$1("high-speed", stage), tracks));
2601
- const createVideosMetadata$1 = curry((stage, tracks) => map$1(createVideoMetadata$1("video", stage), tracks));
2602
-
2603
- const createTracks$1 = stage => converge((...args) => flatten(args), [pipe(mapTimingsToTracks(highSpeedsTimingsView, "high-speed"), createHighSpeedTracksLabels$1(stage), createHighSpeedsMetadata$1(stage)), pipe(mapTimingsToTracks(videoTimingsView, "video"), createVideoTracksLabels$1(stage), createVideosMetadata$1(stage)), mapCommentsToTracks$1])(stage);
2604
-
2605
- const upsertTracks$1 = tracks => stage => {
3383
+ const createHighSpeedsMetadata = R.curry((stage, tracks) => R.map(createVideoMetadata("high-speed", stage), tracks));
3384
+ const createVideosMetadata = R.curry((stage, tracks) => R.map(createVideoMetadata("video", stage), tracks));
3385
+ const createTracks = stage => R.converge((...args) => R.flatten(args), [R.pipe(mapTimingsToTracks(highSpeedsTimingsView, "high-speed"), createHighSpeedTracksLabels(stage), createHighSpeedsMetadata(stage)), R.pipe(mapTimingsToTracks(videoTimingsView, "video"), createVideoTracksLabels(stage), createVideosMetadata(stage)), mapCommentsToTracks])(stage);
3386
+ const upsertTracks = tracks => stage => {
2606
3387
  const indexedById = indexById(tracks);
2607
- return pipe(unless(path(tracksIdsPath$1), assocPath(tracksIdsPath$1, [])), unless(path(tracksByIdPath$1), assocPath(tracksByIdPath$1, {})), over(tracksIdsLens$1, union(pluck("id", tracks))), over(tracksByIdLens$1, mergeLeft(indexedById)))(stage);
3388
+ return R.pipe(R.unless(R.path(tracksIdsPath), R.assocPath(tracksIdsPath, [])), R.unless(R.path(tracksByIdPath), R.assocPath(tracksByIdPath, {})), R.over(tracksIdsLens, R.union(R.pluck("id", tracks))), R.over(tracksByIdLens, R.mergeLeft(indexedById)))(stage);
2608
3389
  };
2609
-
2610
- const earliestTime$1 = stage => pipe(timingsView, map$1(prop("start")), map$1(Date.parse), apply(Math.min), t => new Date(t), d => d.toISOString())(stage);
2611
-
2612
- const latestTime$1 = stage => pipe(timingsView, map$1(prop("end")), map$1(Date.parse), apply(Math.max), t => new Date(t), d => d.toISOString())(stage);
2613
-
2614
- const setTimeLineStartEnd$1 = stage => pipe(assocPath(["timeline", "start"], earliestTime$1(stage)), assocPath(["timeline", "end"], latestTime$1(stage)))(stage);
2615
-
2616
- const setCommentAxis$1 = assocPath(["timeline", "commentAxis"], "comment");
2617
-
2618
- const consolidateTimeline$1 = stage => {
2619
- return pipe(upsertAxes$1(axesSettings$1), upsertTracks$1(createTracks$1(stage)), setTimeLineStartEnd$1, setCommentAxis$1)(stage);
3390
+ const earliestTime = stage => R.pipe(timingsView, R.map(R.prop("start")), R.map(Date.parse), R.apply(Math.min), t => new Date(t), d => d.toISOString())(stage);
3391
+ const latestTime = stage => R.pipe(timingsView, R.map(R.prop("end")), R.map(Date.parse), R.apply(Math.max), t => new Date(t), d => d.toISOString())(stage);
3392
+ const setTimeLineStartEnd = stage => R.pipe(R.assocPath(["timeline", "start"], earliestTime(stage)), R.assocPath(["timeline", "end"], latestTime(stage)))(stage);
3393
+ const setCommentAxis = R.assocPath(["timeline", "commentAxis"], "comment");
3394
+ const consolidateTimeline = stage => {
3395
+ return R.pipe(upsertAxes(axesSettings), upsertTracks(createTracks(stage)), setTimeLineStartEnd, setCommentAxis)(stage);
2620
3396
  };
2621
-
2622
- var v3$1 = pipe(tap(s => {
3397
+ var v3 = pipe(tap(s => {
2623
3398
  console.log("consolidating v3 stage!", s);
2624
- }), consolidateTimeline$1);
3399
+ }), consolidateTimeline);
2625
3400
 
2626
3401
  var _consolidators = Object.freeze({
2627
- 2: consolidate,
2628
- 3: v3$1
3402
+ 2: consolidate$1,
3403
+ 3: v3,
3404
+ 4: v3
2629
3405
  });
2630
3406
 
2631
3407
  const _consolidate = consolidators => stage => {
2632
3408
  const version = detectVersion(stage);
2633
3409
  const consolidator = propOr(always(stage), version, consolidators);
2634
-
2635
3410
  try {
2636
3411
  return {
2637
3412
  stage: consolidator(stage)
@@ -2642,101 +3417,95 @@ const _consolidate = consolidators => stage => {
2642
3417
  };
2643
3418
  }
2644
3419
  };
2645
- var consolidate$1 = _consolidate(_consolidators);
3420
+ var consolidate = _consolidate(_consolidators);
2646
3421
 
2647
- const upgradeResources = over(lensPath(["resources", "entities", "resources", "byId"]), map$1(({
3422
+ const upgradeResources = R.over(R.lensPath(["resources", "entities", "resources", "byId"]), R.map(({
2648
3423
  files,
2649
3424
  ...resource
2650
- }) => ({ ...resource,
3425
+ }) => ({
3426
+ ...resource,
2651
3427
  props: {
2652
3428
  files
2653
3429
  }
2654
3430
  })));
2655
- const createTimingSlice = pipe(assocPath(["timing", "entities", "timing"], {
3431
+ const createTimingSlice = R.pipe(R.assocPath(["timing", "entities", "timing"], {
2656
3432
  ids: [],
2657
3433
  byId: {}
2658
- }), assocPath(["timing", "entities", "offset"], {
3434
+ }), R.assocPath(["timing", "entities", "offset"], {
2659
3435
  ids: [],
2660
3436
  byId: {}
2661
3437
  }));
2662
-
2663
3438
  const createFilesTimings = s => {
2664
- const timings = pipe(path(["files", "entities", "files"]), over(lensProp("byId"), map$1(pipe(pick(["id", "start", "end"]), timing => assoc("ref", {
3439
+ const timings = R.pipe(R.path(["files", "entities", "files"]), R.over(R.lensProp("byId"), R.map(R.pipe(R.pick(["id", "start", "end"]), timing => R.assoc("ref", {
2665
3440
  id: timing.id,
2666
3441
  type: "file"
2667
3442
  }, timing)))))(s);
2668
- return pipe(over(lensPath(["files", "entities", "files", "byId"]), map$1(omit(["start", "end"]))), over(lensPath(["timing", "entities", "timing"]), mergeDeepRight(timings)), over(lensPath(["timing", "entities", "timing"]), entities => assoc("ids", keys(entities.byId), entities)))(s);
3443
+ return R.pipe(R.over(R.lensPath(["files", "entities", "files", "byId"]), R.map(R.omit(["start", "end"]))), R.over(R.lensPath(["timing", "entities", "timing"]), R.mergeDeepRight(timings)), R.over(R.lensPath(["timing", "entities", "timing"]), entities => R.assoc("ids", R.keys(entities.byId), entities)))(s);
2669
3444
  };
2670
-
2671
- const createComments = unless(pipe(path(["timeline", "entities", "comments"]), complement(isNil)), assocPath(["timeline", "entities", "comments"], {
3445
+ const createComments = R.unless(R.pipe(R.path(["timeline", "entities", "comments"]), R.complement(R.isNil)), R.assocPath(["timeline", "entities", "comments"], {
2672
3446
  ids: [],
2673
3447
  byId: {}
2674
3448
  }));
2675
-
2676
3449
  const createCommentsTimings = s => {
2677
- const timings = pipe(path(["timeline", "entities", "comments"]), over(lensProp("byId"), map$1(pipe(pick(["id", "start", "end"]), timing => assoc("ref", {
3450
+ const timings = R.pipe(R.path(["timeline", "entities", "comments"]), R.over(R.lensProp("byId"), R.map(R.pipe(R.pick(["id", "start", "end"]), timing => R.assoc("ref", {
2678
3451
  id: timing.id,
2679
3452
  type: "comment"
2680
3453
  }, timing)))))(s);
2681
- return pipe(over(lensPath(["timeline", "entities", "comments", "byId"]), map$1(omit(["start", "end"]))), over(lensPath(["timing", "entities", "timing"]), mergeDeepRight(timings)), over(lensPath(["timing", "entities", "timing"]), entities => assoc("ids", keys(entities.byId), entities)))(s);
3454
+ return R.pipe(R.over(R.lensPath(["timeline", "entities", "comments", "byId"]), R.map(R.omit(["start", "end"]))), R.over(R.lensPath(["timing", "entities", "timing"]), R.mergeDeepRight(timings)), R.over(R.lensPath(["timing", "entities", "timing"]), entities => R.assoc("ids", R.keys(entities.byId), entities)))(s);
2682
3455
  };
2683
-
2684
- const removeOutlets = s => {
2685
- const outlets = path(["data", "entities", "outlets"], s);
2686
-
3456
+ const removeOutlets$1 = s => {
3457
+ const outlets = R.path(["data", "entities", "outlets"], s);
2687
3458
  if (outlets) {
2688
- return pipe(dissocPath(["data", "entities", "outlets"]), over(lensPath(["data", "entities", "dataViewers", "byId"]), map$1(({
3459
+ return R.pipe(R.dissocPath(["data", "entities", "outlets"]), R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.map(({
2689
3460
  outletId,
2690
3461
  ...dataViewer
2691
3462
  }) => {
2692
- const outlet = path(["byId", outletId], outlets) || {
3463
+ const outlet = R.path(["byId", outletId], outlets) || {
2693
3464
  streams: []
2694
3465
  };
2695
- return { ...dataViewer,
3466
+ return {
3467
+ ...dataViewer,
2696
3468
  streams: outlet.streams
2697
3469
  };
2698
3470
  })))(s);
2699
3471
  }
2700
-
2701
3472
  return s;
2702
3473
  };
2703
-
2704
3474
  const createSliceEntities = entityName => slice => {
2705
- const result = pipe(unless(has("entities"), assoc("entities", {})), unless(hasPath(["entities", entityName]), assocPath(["entities", entityName], {
3475
+ const result = R.pipe(R.unless(R.has("entities"), R.assoc("entities", {})), R.unless(R.hasPath(["entities", entityName]), R.assocPath(["entities", entityName], {
2706
3476
  ids: [],
2707
3477
  byId: {}
2708
3478
  })))(slice);
2709
3479
  return result;
2710
3480
  };
2711
-
2712
3481
  const createTimelineSlice = s => {
2713
- return pipe(over(lensProp("timeline"), pipe(createSliceEntities("axes"), createSliceEntities("groups"), createSliceEntities("timeline"), createSliceEntities("tracks"))))(s);
3482
+ return R.pipe(R.over(R.lensProp("timeline"), R.pipe(createSliceEntities("axes"), createSliceEntities("groups"), createSliceEntities("timeline"), createSliceEntities("tracks"))))(s);
2714
3483
  };
2715
-
2716
3484
  const createTimelineGroups = s => {
2717
- const groups = pipe(path(["timeline", "entities", "axes"]), over(lensProp("byId"), map$1(dissoc("resources"))))(s);
2718
- return pipe(dissocPath(["timeline", "entities", "axes"]), assocPath(["timeline", "entities", "groups"], groups))(s);
3485
+ const groups = R.pipe(R.path(["timeline", "entities", "axes"]), R.over(R.lensProp("byId"), R.map(R.dissoc("resources"))))(s);
3486
+ return R.pipe(R.dissocPath(["timeline", "entities", "axes"]), R.assocPath(["timeline", "entities", "groups"], groups))(s);
2719
3487
  };
2720
-
2721
- const createTimeline = s => pipe(assocPath(["timeline", "entities", "timeline", "byId", "1"], {
3488
+ const createTimeline = s => R.pipe(R.assocPath(["timeline", "entities", "timeline", "byId", "1"], {
2722
3489
  id: "1",
2723
3490
  groupOrder: ["video", "high-speed", "comment"],
2724
3491
  actions: {
2725
3492
  copyLink: true,
2726
3493
  addComment: true
2727
3494
  },
2728
- start: path(["timeline", "start"], s),
2729
- end: path(["timeline", "end"], s)
2730
- }), dissocPath(["timeline", "start"]), dissocPath(["timeline", "end"]), assocPath(["timeline", "entities", "timeline", "ids"], ["1"]), over(lensPath(["timeline", "entities", "tracks", "byId"]), map$1(pipe(assoc("timeline", "1")))), assocPath(["timeline", "masterTimeline"], "1"))(s);
2731
-
2732
- const fixTracks = s => pipe(over(lensPath(["timeline", "entities", "tracks", "byId"]), map$1(({
3495
+ start: R.path(["timeline", "start"], s),
3496
+ end: R.path(["timeline", "end"], s)
3497
+ }), R.dissocPath(["timeline", "start"]), R.dissocPath(["timeline", "end"]), R.assocPath(["timeline", "entities", "timeline", "ids"], ["1"]), R.over(R.lensPath(["timeline", "entities", "tracks", "byId"]), R.map(R.pipe(R.assoc("timeline", "1")))), R.assocPath(["timeline", "masterTimeline"], "1"))(s);
3498
+ const fixTracks = s => R.pipe(R.over(R.lensPath(["timeline", "entities", "tracks", "byId"]),
3499
+ // eslint-disable-next-line no-unused-vars
3500
+ R.map(({
2733
3501
  axisRef,
2734
3502
  type,
2735
3503
  ref,
2736
3504
  start,
2737
3505
  end,
2738
3506
  ...track
2739
- }) => ({ ...track,
3507
+ }) => ({
3508
+ ...track,
2740
3509
  group: axisRef,
2741
3510
  ref: {
2742
3511
  type: type === "video" || type === "image" ? "file" : type,
@@ -2745,16 +3514,15 @@ const fixTracks = s => pipe(over(lensPath(["timeline", "entities", "tracks", "by
2745
3514
  editable: type === "comment",
2746
3515
  timeline: "1"
2747
3516
  }))))(s);
2748
-
2749
- const dataStreamsToMeasurements = s => {
2750
- const streamsSlice = path(["data", "entities", "dataStreams"], s);
2751
-
2752
- if (!isEmpty(streamsSlice) && !isNil(streamsSlice)) {
2753
- const measurementsSlice = pipe(over(lensProp("byId"), pipe(map$1(measurement => ({ ...measurement,
3517
+ const dataStreamsToMeasurements$1 = s => {
3518
+ const streamsSlice = R.path(["data", "entities", "dataStreams"], s);
3519
+ if (!R.isEmpty(streamsSlice) && !R.isNil(streamsSlice)) {
3520
+ const measurementsSlice = R.pipe(R.over(R.lensProp("byId"), R.pipe(R.map(measurement => ({
3521
+ ...measurement,
2754
3522
  legacy: true,
2755
3523
  name: measurement.id
2756
3524
  })))))(streamsSlice);
2757
- return pipe(dissocPath(["data", "entities", "dataStreams"]), assocPath(["data", "entities", "measurements"], measurementsSlice), over(lensPath(["data", "entities", "dataViewers", "byId"]), map$1(({
3525
+ return R.pipe(R.dissocPath(["data", "entities", "dataStreams"]), R.assocPath(["data", "entities", "measurements"], measurementsSlice), R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.map(({
2758
3526
  streams = [],
2759
3527
  ...dataViewer
2760
3528
  }) => ({
@@ -2762,69 +3530,234 @@ const dataStreamsToMeasurements = s => {
2762
3530
  ...dataViewer
2763
3531
  }))))(s);
2764
3532
  }
2765
-
2766
3533
  return s;
2767
3534
  };
2768
-
2769
- const translateComponent = component => {
3535
+ const translateComponent$1 = component => {
2770
3536
  switch (component) {
2771
3537
  case "DataViewerComponent":
2772
3538
  return "DataViewerPanel";
2773
-
2774
3539
  case "VideoComponent":
2775
3540
  return "VideoPanel";
2776
-
2777
3541
  case "PlaylistComponent":
2778
3542
  return "PlaylistPanel";
2779
-
2780
3543
  default:
2781
3544
  return component;
2782
3545
  }
2783
3546
  };
2784
-
2785
- const fixPanels = s => {
2786
- if (hasPath(["layout", "entities", "layoutSections", "byId"], s)) {
2787
- return pipe(over(lensPath(["layout", "entities", "layoutSections", "byId"]), unless(isNil, map$1(when(has("component"), over(lensProp("component"), translateComponent))))))(s);
3547
+ const fixPanels$1 = s => {
3548
+ if (R.hasPath(["layout", "entities", "layoutSections", "byId"], s)) {
3549
+ return R.pipe(R.over(R.lensPath(["layout", "entities", "layoutSections", "byId"]), R.unless(R.isNil, R.map(R.when(R.has("component"), R.over(R.lensProp("component"), translateComponent$1))))))(s);
2788
3550
  }
2789
-
2790
3551
  return s;
2791
3552
  };
2792
-
2793
- const scaleZoomSteps = stage => {
3553
+ const scaleZoomSteps$1 = stage => {
2794
3554
  const {
2795
3555
  measurementScale
2796
3556
  } = stage.data;
2797
- return over(lensPath(["data", "entities", "dataViewers", "byId"]), unless(isNil, mapObjIndexed(({
3557
+ return R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.unless(R.isNil, R.mapObjIndexed(({
2798
3558
  zoomSteps = [],
2799
3559
  ...rest
2800
- }) => ({ ...rest,
3560
+ }) => ({
3561
+ ...rest,
2801
3562
  zoomSteps: rest.zoomStepsIsScaled ? zoomSteps : zoomSteps.map(step => step * Math.sqrt(measurementScale))
2802
3563
  }))))(stage);
2803
3564
  };
2804
-
2805
- const updateVersion = assoc("version", 3);
2806
- var v2ToV3 = pipe(tap(stage => {
3565
+ const updateVersion$2 = R.assoc("version", 3);
3566
+ var v2ToV3$1 = R.pipe(R.tap(stage => {
2807
3567
  console.log("upgrading ", stage, " from 2 to 3");
2808
- }), consolidate$1, unless(prop("error"), pipe(prop("stage"), removeOutlets, scaleZoomSteps, dataStreamsToMeasurements, createTimingSlice, createTimelineSlice, createFilesTimings, createComments, createCommentsTimings, createTimelineGroups, createTimeline, fixTracks, updateVersion, fixPanels, upgradeResources)));
3568
+ }), consolidate, R.unless(R.prop("error"), R.pipe(R.prop("stage"), removeOutlets$1, scaleZoomSteps$1, dataStreamsToMeasurements$1, createTimingSlice, createTimelineSlice, createFilesTimings, createComments, createCommentsTimings, createTimelineGroups, createTimeline, fixTracks, updateVersion$2, fixPanels$1, upgradeResources)));
2809
3569
 
2810
- var upgraders = (() => [[2, v1ToV2], [3, v2ToV3]]);
3570
+ /**
3571
+ * v3-to-v4 Stage Upgrader
3572
+ *
3573
+ * Converts Golden Layout (v3) to DockView layout (v4).
3574
+ *
3575
+ * Key changes:
3576
+ * - Converts layout.entities.layoutSections (flat structure) to layout.dockviewLayout (hierarchical tree)
3577
+ * - Maps component names: DataViewerComponent → DataViewerPanel, VideoComponent → VideoPanel, etc.
3578
+ * - Converts row/column/stack structure to branch/leaf DockView nodes
3579
+ * - Updates version to 4
3580
+ */
2811
3581
 
2812
- const resolveFrom = stage => detectVersion(stage);
3582
+ const DOCKVIEW_HORIZONTAL = "HORIZONTAL";
3583
+ const DOCKVIEW_VERTICAL = "VERTICAL";
3584
+ const LEGACY_COMPONENT_TO_DOCKVIEW = {
3585
+ DataViewerComponent: "DataViewerPanel",
3586
+ VideoComponent: "VideoPanel",
3587
+ PlaylistComponent: "PlaylistPanel"
3588
+ };
3589
+ const mapLegacyComponentToDockview = component => {
3590
+ return LEGACY_COMPONENT_TO_DOCKVIEW[component] || component;
3591
+ };
3592
+ const getSectionId = value => {
3593
+ if (Array.isArray(value)) {
3594
+ return value[0];
3595
+ }
3596
+ return value || "";
3597
+ };
3598
+ const getSection = (sections, value) => sections[getSectionId(value)];
3599
+ const isComponentSection = section => {
3600
+ return Boolean(section) && !["row", "column", "stack"].includes((section === null || section === void 0 ? void 0 : section.type) || "");
3601
+ };
3602
+ const getRootSection = (content, sections) => {
3603
+ const rootId = getSectionId(content && content[0]);
3604
+ return rootId ? sections[rootId] : undefined;
3605
+ };
3606
+ const getOrientationForSection = section => {
3607
+ return (section === null || section === void 0 ? void 0 : section.type) === "row" ? DOCKVIEW_HORIZONTAL : DOCKVIEW_VERTICAL;
3608
+ };
3609
+ const getChildSize = (parent, child) => {
3610
+ if (!parent || !child) {
3611
+ return undefined;
3612
+ }
3613
+ return parent.type === "row" ? child.width : child.height;
3614
+ };
3615
+ const flattenDirectionalChildren = (section, sections) => {
3616
+ const content = (section === null || section === void 0 ? void 0 : section.content) || [];
3617
+ return content.flatMap(childValue => {
3618
+ const child = getSection(sections, childValue);
3619
+ if ((child === null || child === void 0 ? void 0 : child.type) === section.type) {
3620
+ return flattenDirectionalChildren(child, sections);
3621
+ }
3622
+ return [childValue];
3623
+ });
3624
+ };
3625
+ const createDockviewPanelState = section => {
3626
+ var _section$props, _section$props2;
3627
+ return {
3628
+ id: section.id,
3629
+ contentComponent: mapLegacyComponentToDockview(section.component || ""),
3630
+ title: ((_section$props = section.props) === null || _section$props === void 0 ? void 0 : _section$props.title) || section.title || section.id,
3631
+ params: {
3632
+ ...section.props,
3633
+ wrapMode: section.wrapMode || ((_section$props2 = section.props) === null || _section$props2 === void 0 ? void 0 : _section$props2.wrapMode) || "over"
3634
+ }
3635
+ };
3636
+ };
3637
+ const createDockviewGroupId = section => {
3638
+ if (section.type === "stack") {
3639
+ return section.id;
3640
+ }
3641
+ return `${section.id}__group`;
3642
+ };
3643
+ const createDockviewLeaf = (section, sections) => {
3644
+ const childValues = section.type === "stack" ? section.content || [] : [section.id];
3645
+ const panelIds = childValues.map(getSectionId).filter(panelId => Boolean(sections[panelId]));
3646
+ const activeIndex = Math.max(0, Math.min(section.activeItemIndex || 0, Math.max(panelIds.length - 1, 0)));
3647
+ return {
3648
+ type: "leaf",
3649
+ data: {
3650
+ id: createDockviewGroupId(section),
3651
+ views: panelIds,
3652
+ activeView: panelIds[activeIndex]
3653
+ }
3654
+ };
3655
+ };
3656
+ const createDockviewGridNode = (section, sections) => {
3657
+ if (!section) {
3658
+ return null;
3659
+ }
3660
+ if (section.type === "stack" || isComponentSection(section)) {
3661
+ return createDockviewLeaf(section, sections);
3662
+ }
3663
+ const childValues = flattenDirectionalChildren(section, sections);
3664
+ const children = childValues.map(childValue => {
3665
+ const childSection = getSection(sections, childValue);
3666
+ const node = createDockviewGridNode(childSection, sections);
3667
+ if (!node) {
3668
+ return null;
3669
+ }
3670
+ return {
3671
+ ...node,
3672
+ size: getChildSize(section, childSection)
3673
+ };
3674
+ }).filter(n => n !== null);
3675
+ if (children.length === 0) {
3676
+ return null;
3677
+ }
3678
+ if (children.length === 1) {
3679
+ return children[0];
3680
+ }
3681
+ return {
3682
+ type: "branch",
3683
+ data: children
3684
+ };
3685
+ };
3686
+ const filterLayoutSectionsByAssets = (sectionsById, assetsById) => {
3687
+ return R.pipe(R.map(section => {
3688
+ const assetId = R.path(["props", "assetId"], section);
3689
+ if (assetId && !assetsById[assetId]) {
3690
+ return null;
3691
+ }
3692
+ return section;
3693
+ }), R.filter(R.identity))(sectionsById);
3694
+ };
3695
+ const createPanelsById = sections => {
3696
+ return R.pipe(R.values, R.filter(isComponentSection), R.reduce((acc, section) => {
3697
+ return {
3698
+ ...acc,
3699
+ [section.id]: createDockviewPanelState(section)
3700
+ };
3701
+ }, {}))(sections);
3702
+ };
3703
+ const convertLegacyLayoutToDockview = stage => {
3704
+ var _rootSection$content;
3705
+ const content = R.path(["layout", "content"], stage);
3706
+ const rawSections = R.pathOr({}, ["layout", "entities", "layoutSections", "byId"], stage);
3707
+ const assetsById = R.pathOr({}, ["assets", "entities", "assets", "byId"], stage);
3708
+ const sections = filterLayoutSectionsByAssets(rawSections, assetsById);
3709
+ const rootSection = getRootSection(content, sections);
3710
+ const rootNode = createDockviewGridNode(rootSection, sections);
3711
+ if (!rootSection || !rootNode) {
3712
+ return null;
3713
+ }
3714
+ return {
3715
+ grid: {
3716
+ root: rootNode,
3717
+ height: 100,
3718
+ width: 100,
3719
+ orientation: getOrientationForSection(rootSection)
3720
+ },
3721
+ panels: createPanelsById(sections),
3722
+ activeGroup: createDockviewGroupId(rootSection.type === "stack" ? rootSection : getSection(sections, (_rootSection$content = rootSection.content) === null || _rootSection$content === void 0 ? void 0 : _rootSection$content[0]) || rootSection)
3723
+ };
3724
+ };
3725
+ const upgradeToDockviewLayout = stage => {
3726
+ // If already has dockviewLayout, skip conversion
3727
+ if (R.hasPath(["layout", "dockviewLayout"], stage)) {
3728
+ return stage;
3729
+ }
2813
3730
 
2814
- const resolveTo = to => defaultTo(last(versions))(to);
3731
+ // If no legacy layout sections, nothing to convert
3732
+ if (!R.hasPath(["layout", "entities", "layoutSections"], stage)) {
3733
+ return stage;
3734
+ }
3735
+ const dockviewLayout = convertLegacyLayoutToDockview(stage);
2815
3736
 
2816
- const versionsCorrect = (from, to) => gte(to, from);
3737
+ // Remove legacy layout structure, keep other layout state
3738
+ return R.pipe(R.dissocPath(["layout", "entities"]), R.dissocPath(["layout", "content"]), R.assocPath(["layout", "dockviewLayout"], dockviewLayout),
3739
+ // Preserve these layout state properties if they exist
3740
+ R.when(R.hasPath(["layout", "focus"]), R.identity), R.when(R.hasPath(["layout", "dragging"]), R.identity), R.when(R.hasPath(["layout", "resizingPanels"]), R.identity))(stage);
3741
+ };
3742
+ const updateVersion$1 = R.assoc("version", 4);
3743
+ var v3ToV4 = R.pipe(R.tap(stage => {
3744
+ console.log("upgrading ", stage, " from 3 to 4");
3745
+ }), upgradeToDockviewLayout, updateVersion$1);
2817
3746
 
2818
- const upgradePipe = (from, to, stage) => pipe(filter(([v]) => v > from && v <= to), map$1(nth(1)), prepend(always(stage)), apply(pipe), applyTo(stage))(upgraders());
3747
+ var upgraders = () => [[2, v1ToV2], [3, v2ToV3$1], [4, v3ToV4]];
2819
3748
 
2820
- const optionsParser$1 = ({
3749
+ const resolveFrom = stage => detectVersion(stage);
3750
+ const resolveTo = to => defaultTo(last(versions))(to);
3751
+ const versionsCorrect = (from, to) => gte(to, from);
3752
+ const upgradePipe = (from, to, stage) => pipe(filter(([v]) => v > from && v <= to), map$1(nth(1)), prepend(always(stage)), apply(pipe), applyTo(stage))(upgraders());
3753
+ const optionsParser = ({
2821
3754
  upgradeFrom: from = undefined,
2822
3755
  upgradeTo: to = undefined
2823
3756
  }) => ({
2824
3757
  from,
2825
3758
  to
2826
3759
  });
2827
- var upgrade = ((stage, options = {}) => {
3760
+ var upgrade = (stage, options = {}) => {
2828
3761
  const {
2829
3762
  to = undefined
2830
3763
  } = options;
@@ -2833,18 +3766,16 @@ var upgrade = ((stage, options = {}) => {
2833
3766
  let upgraded = stage;
2834
3767
  let error;
2835
3768
  console.log(`upgrading from ${resolvedFrom} to ${resolvedTo}.`);
2836
-
2837
3769
  if (versionsCorrect(resolvedFrom, resolvedTo)) {
2838
3770
  upgraded = upgradePipe(resolvedFrom, resolvedTo, stage);
2839
3771
  } else {
2840
3772
  error = new Error(`Incorrect version: from: ${resolvedFrom} > to: ${resolvedTo}`);
2841
3773
  }
2842
-
2843
3774
  return {
2844
3775
  stage: upgraded,
2845
3776
  error
2846
3777
  };
2847
- });
3778
+ };
2848
3779
 
2849
3780
  var timezoneData = {
2850
3781
  version: "2018g",
@@ -2857,19 +3788,15 @@ const {
2857
3788
  setTimeZone,
2858
3789
  populateTimeZones
2859
3790
  } = require("timezone-support/dist/lookup-convert");
2860
-
2861
3791
  const {
2862
3792
  formatZonedTime
2863
3793
  } = require("timezone-support/dist/parse-format");
2864
-
2865
3794
  populateTimeZones(timezoneData);
2866
3795
  const dateWithoutTimeZoneExp = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})((\.)([0-9]{0,}))?$/;
2867
3796
  const dateWithWrongSeconds = /^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:)([0-9]{3,})((\.[0-9]+)?((Z|(\+|-)([0-9]{2}:[0-9]{2}|[0-9]+))))$/;
2868
3797
  const amsterdam = findTimeZone("Europe/Amsterdam");
2869
-
2870
3798
  const fixDateWithoutTimezone = d => {
2871
3799
  const matches = dateWithoutTimeZoneExp.exec(d);
2872
-
2873
3800
  if (matches) {
2874
3801
  const timeObj = {
2875
3802
  year: matches[1],
@@ -2886,89 +3813,79 @@ const fixDateWithoutTimezone = d => {
2886
3813
  const formattedTimezone = formatZonedTime(withTimezone, "Z");
2887
3814
  return `${formattedDate}T${formattedTime}${milliseconds || ""}${formattedTimezone}`;
2888
3815
  }
2889
-
2890
3816
  return d;
2891
3817
  };
2892
-
2893
3818
  const fixDateWithWrongSeconds = d => {
2894
3819
  const matches = dateWithWrongSeconds.exec(d);
2895
-
2896
3820
  if (matches) {
2897
3821
  const [, rest, seconds, timezone] = matches;
2898
3822
  const newDate = `${rest}${seconds.substring(seconds.length - 2)}${timezone}`;
2899
3823
  return newDate;
2900
3824
  }
2901
-
2902
3825
  return d;
2903
3826
  };
2904
-
2905
- const isIncorrectTime = input => both(is(String), pipe(anyPass([test(dateWithoutTimeZoneExp), test(dateWithWrongSeconds)])))(input);
2906
-
2907
- const fixDates = obj => pipe(map$1(ifElse(isIncorrectTime, pipe(tap(x => `${x} is incorrect date`), fixDateWithoutTimezone, fixDateWithWrongSeconds), when(is(Object), c => fixDates(c)))))(obj);
3827
+ const isIncorrectTime = input => R.both(R.is(String), R.pipe(R.anyPass([R.test(dateWithoutTimeZoneExp), R.test(dateWithWrongSeconds)])))(input);
3828
+ const fixDates = obj => R.pipe(R.map(R.ifElse(isIncorrectTime, R.pipe(R.tap(x => `${x} is incorrect date`), fixDateWithoutTimezone, fixDateWithWrongSeconds), R.when(R.is(Object), c => fixDates(c)))))(obj);
2908
3829
 
2909
3830
  const fixDatesWithOptions = (options, stage) => ({
2910
3831
  stage: fixDates(stage)
2911
3832
  });
2912
-
2913
3833
  const validateWithOptions = (options, stage) => {
2914
- const validated = validate(stage, optionsParser(options));
3834
+ const validated = validate(stage, optionsParser$1(options));
2915
3835
  return validated;
2916
3836
  };
2917
-
2918
- const upgradeWithOptions = (options, stage) => upgrade(stage, optionsParser$1(options));
2919
-
2920
- const consolidateWithOptions = (options, stage) => consolidate$1(stage);
2921
-
2922
- var steps = (() => [fixDatesWithOptions, validateWithOptions, consolidateWithOptions, upgradeWithOptions]);
3837
+ const upgradeWithOptions = (options, stage) => upgrade(stage, optionsParser(options));
3838
+ const consolidateWithOptions = (options, stage) => consolidate(stage);
3839
+ var steps = () => [fixDatesWithOptions, validateWithOptions, consolidateWithOptions, upgradeWithOptions];
2923
3840
 
2924
3841
  const hasError = prop("error");
2925
3842
  const doStep = curry((options, step, response) => {
2926
3843
  const normalizedStep = curry(nAry(2, step));
2927
3844
  return pipe(defaultTo({}), unless(hasError, pipe(prop("stage"), normalizedStep(options))))(response);
2928
3845
  });
2929
- const handler = curry((steps, options, stage) => pipe(defaultTo([]), map$1(doStep(options)), // Map all the steps to a doStep wrapper so they can be piped.
3846
+ const handler = curry((steps, options, stage) => pipe(defaultTo([]), map$1(doStep(options)),
3847
+ // Map all the steps to a doStep wrapper so they can be piped.
2930
3848
  prepend(always({
2931
3849
  stage
2932
- })), apply(pipe), // Create a pipe of all the steps.
3850
+ })), apply(pipe),
3851
+ // Create a pipe of all the steps.
2933
3852
  applyTo(stage) // Pipe the stage through the steps.
2934
3853
  )(steps));
2935
- var handlerFactory = ((steps, options) => handler(steps, options));
3854
+ var handlerFactory = (steps, options) => handler(steps, options);
2936
3855
 
2937
- var defaultOptions = (() => Object.freeze({
3856
+ var defaultOptions = () => Object.freeze({
2938
3857
  upgradeFrom: undefined,
2939
3858
  upgradeTo: undefined,
2940
3859
  validateVersion: undefined
2941
- }));
2942
-
2943
- const removeOutlets$1 = s => {
2944
- const outlets = path(["data", "entities", "outlets"], s);
3860
+ });
2945
3861
 
3862
+ const removeOutlets = s => {
3863
+ const outlets = R.path(["data", "entities", "outlets"], s);
2946
3864
  if (outlets) {
2947
- return pipe(dissocPath(["data", "entities", "outlets"]), over(lensPath(["data", "entities", "dataViewers", "byId"]), map$1(({
3865
+ return R.pipe(R.dissocPath(["data", "entities", "outlets"]), R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.map(({
2948
3866
  outletId,
2949
3867
  ...dataViewer
2950
3868
  }) => {
2951
- const outlet = path(["byId", outletId], outlets) || {
3869
+ const outlet = R.path(["byId", outletId], outlets) || {
2952
3870
  streams: []
2953
3871
  };
2954
- return { ...dataViewer,
3872
+ return {
3873
+ ...dataViewer,
2955
3874
  streams: outlet.streams
2956
3875
  };
2957
3876
  })))(s);
2958
3877
  }
2959
-
2960
3878
  return s;
2961
3879
  };
2962
-
2963
- const dataStreamsToMeasurements$1 = s => {
2964
- const streamsSlice = path(["data", "entities", "dataStreams"], s);
2965
-
2966
- if (!isEmpty(streamsSlice) && !isNil(streamsSlice)) {
2967
- const measurementsSlice = pipe(over(lensProp("byId"), pipe(map$1(measurement => ({ ...measurement,
3880
+ const dataStreamsToMeasurements = s => {
3881
+ const streamsSlice = R.path(["data", "entities", "dataStreams"], s);
3882
+ if (!R.isEmpty(streamsSlice) && !R.isNil(streamsSlice)) {
3883
+ const measurementsSlice = R.pipe(R.over(R.lensProp("byId"), R.pipe(R.map(measurement => ({
3884
+ ...measurement,
2968
3885
  legacy: true,
2969
3886
  name: measurement.id
2970
3887
  })))))(streamsSlice);
2971
- return pipe(dissocPath(["data", "entities", "dataStreams"]), assocPath(["data", "entities", "measurements"], measurementsSlice), over(lensPath(["data", "entities", "dataViewers", "byId"]), map$1(({
3888
+ return R.pipe(R.dissocPath(["data", "entities", "dataStreams"]), R.assocPath(["data", "entities", "measurements"], measurementsSlice), R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.map(({
2972
3889
  streams = [],
2973
3890
  ...dataViewer
2974
3891
  }) => ({
@@ -2976,64 +3893,56 @@ const dataStreamsToMeasurements$1 = s => {
2976
3893
  ...dataViewer
2977
3894
  }))))(s);
2978
3895
  }
2979
-
2980
3896
  return s;
2981
3897
  };
2982
-
2983
- const translateComponent$1 = component => {
3898
+ const translateComponent = component => {
2984
3899
  switch (component) {
2985
3900
  case "DataViewerComponent":
2986
3901
  return "DataViewerPanel";
2987
-
2988
3902
  case "VideoComponent":
2989
3903
  return "VideoPanel";
2990
-
2991
3904
  case "PlaylistComponent":
2992
3905
  return "PlaylistPanel";
2993
-
2994
3906
  default:
2995
3907
  return component;
2996
3908
  }
2997
3909
  };
2998
-
2999
- const fixPanels$1 = s => {
3000
- if (hasPath(["layout", "entities", "layoutSections", "byId"], s)) {
3001
- return pipe(over(lensPath(["layout", "entities", "layoutSections", "byId"]), unless(isNil, map$1(when(has("component"), over(lensProp("component"), translateComponent$1))))))(s);
3910
+ const fixPanels = s => {
3911
+ if (R.hasPath(["layout", "entities", "layoutSections", "byId"], s)) {
3912
+ return R.pipe(R.over(R.lensPath(["layout", "entities", "layoutSections", "byId"]), R.unless(R.isNil, R.map(R.when(R.has("component"), R.over(R.lensProp("component"), translateComponent))))))(s);
3002
3913
  }
3003
-
3004
3914
  return s;
3005
3915
  };
3006
-
3007
- const scaleZoomSteps$1 = stage => settings => {
3916
+ const scaleZoomSteps = stage => settings => {
3008
3917
  const {
3009
3918
  measurementScale
3010
3919
  } = stage.data;
3011
- return over(lensPath(["data", "entities", "dataViewers", "byId"]), unless(isNil, mapObjIndexed(({
3920
+ return R.over(R.lensPath(["data", "entities", "dataViewers", "byId"]), R.unless(R.isNil, R.mapObjIndexed(({
3012
3921
  zoomSteps = [],
3013
3922
  ...rest
3014
- }) => ({ ...rest,
3923
+ }) => ({
3924
+ ...rest,
3015
3925
  zoomSteps: rest.zoomStepsIsScaled ? zoomSteps : zoomSteps.map(step => step * Math.sqrt(measurementScale))
3016
3926
  }))))(settings);
3017
3927
  };
3018
-
3019
- const removeTimeline = dissoc("timeline");
3020
- const updateVersion$1 = assoc("version", 3);
3021
- var v2ToV3$1 = curry((stage, settings) => {
3022
- return pipe(tap(s => {
3928
+ const removeTimeline = R.dissoc("timeline");
3929
+ const updateVersion = R.assoc("version", 3);
3930
+ var v2ToV3 = R.curry((stage, settings) => {
3931
+ return R.pipe(R.tap(s => {
3023
3932
  console.log("upgrading settings", s, " from 2 to 3");
3024
- }), pipe(removeOutlets$1, dataStreamsToMeasurements$1, updateVersion$1, scaleZoomSteps$1(stage), fixPanels$1, removeTimeline))(settings);
3933
+ }), R.pipe(removeOutlets, dataStreamsToMeasurements, updateVersion, scaleZoomSteps(stage), fixPanels, removeTimeline))(settings);
3025
3934
  });
3026
3935
 
3027
- var settingsUpgrader = curry((stage, settings) => {
3028
- return pipe(unless(propEq("version", 3), v2ToV3$1(stage)))(settings);
3936
+ var settingsUpgrader = R.curry((stage, settings) => {
3937
+ return R.pipe(R.unless(R.propEq(3, "version"), v2ToV3(stage)))(settings);
3029
3938
  });
3030
3939
 
3031
- const settingsCleaner = pipe(dissocPath(["timer", "wantedTime"]));
3032
- var settingsHandler = ((stage, settings) => pipe(settingsUpgrader(stage), settingsCleaner)(settings));
3940
+ const settingsCleaner = R.pipe(R.dissocPath(["timer", "wantedTime"]));
3941
+ var settingsHandler = (stage, settings) => R.pipe(settingsUpgrader(stage), settingsCleaner)(settings);
3033
3942
 
3034
3943
  var name = "insync-stage-handler";
3035
- var version = "3.1.1";
3036
- var description$3 = "Handles stages files. This consists of validating, upgrading and consolodating them.";
3944
+ var version = "4.0.0-beta.1";
3945
+ var description = "Handles stages files. This consists of validating, upgrading and consolodating them.";
3037
3946
  var author = "David Ammeraal (Noterik B.V.)";
3038
3947
  var license = "MIT";
3039
3948
  var main = "dist/library.js";
@@ -3054,39 +3963,52 @@ var scripts = {
3054
3963
  "lint:fix": "yarn lint --fix"
3055
3964
  };
3056
3965
  var devDependencies = {
3057
- "@babel/core": "^7.10.5",
3058
- "@babel/preset-env": "^7.10.4",
3059
- "@rollup/plugin-babel": "^5.1.0",
3966
+ "@babel/core": "^7.29.7",
3967
+ "@babel/eslint-parser": "^7.25.0",
3968
+ "@babel/preset-env": "^7.29.7",
3969
+ "@eslint/js": "^10.0.1",
3970
+ "@rollup/plugin-babel": "^5.3.1",
3060
3971
  "@rollup/plugin-json": "^4.1.0",
3061
- "@rollup/plugin-node-resolve": "^8.4.0",
3062
- "babel-eslint": "^10.1.0",
3063
- "babel-jest": "^26.2.0",
3064
- "babel-plugin-module-resolver": "^4.0.0",
3065
- eslint: "6.8.0",
3066
- "eslint-config-airbnb-base": "14.2.0",
3067
- "eslint-config-prettier": "^6.11.0",
3068
- "eslint-import-resolver-babel-module": "^5.1.2",
3069
- "eslint-plugin-import": "2.21.2",
3070
- "eslint-plugin-jest": "^23.19.0",
3071
- "eslint-plugin-prettier": "^3.1.4",
3072
- jest: "^24.8.0",
3073
- prettier: "^2.0.5",
3074
- rollup: "^2.23.0",
3075
- "rollup-plugin-eslint": "^7.0.0"
3972
+ "@rollup/plugin-node-resolve": "^16.0.3",
3973
+ "babel-jest": "^30.0.0",
3974
+ "babel-plugin-module-resolver": "^4.1.0",
3975
+ eslint: "^10.0.0",
3976
+ "eslint-config-airbnb-base": "^15.0.0",
3977
+ "eslint-config-prettier": "^10.0.0",
3978
+ "eslint-import-resolver-babel-module": "^5.3.2",
3979
+ "eslint-plugin-import": "^2.32.0",
3980
+ "eslint-plugin-jest": "^29.0.0",
3981
+ "eslint-plugin-prettier": "^5.2.0",
3982
+ globals: "^17.6.0",
3983
+ jest: "^30.0.0",
3984
+ prettier: "^2.8.8",
3985
+ rollup: "^2.80.0"
3076
3986
  };
3077
3987
  var dependencies = {
3078
- ajv: "^6.9.1",
3988
+ ajv: "^6.15.0",
3079
3989
  "ajv-keywords": "^3.5.2",
3080
- "core-js": "^3.6.5",
3081
- "date-fns": "^2.15.0",
3990
+ "core-js": "^3.49.0",
3991
+ "date-fns": "^4.1.0",
3082
3992
  "object-hash": "^1.3.1",
3083
- ramda: "^0.26.1",
3993
+ ramda: "^0.32.0",
3084
3994
  "timezone-support": "^1.8.1"
3085
3995
  };
3996
+ var resolutions = {
3997
+ minimist: "^1.2.8",
3998
+ "ansi-regex": "^5.0.1",
3999
+ "brace-expansion": "^2.0.1",
4000
+ minimatch: "^3.1.4",
4001
+ "path-parse": "^1.0.7",
4002
+ json5: "^2.2.3",
4003
+ picomatch: "^2.3.1",
4004
+ lodash: "^4.17.21",
4005
+ "js-yaml": "^4.1.0",
4006
+ debug: "^4.3.5"
4007
+ };
3086
4008
  var pkg = {
3087
4009
  name: name,
3088
4010
  version: version,
3089
- description: description$3,
4011
+ description: description,
3090
4012
  author: author,
3091
4013
  license: license,
3092
4014
  main: main,
@@ -3095,7 +4017,8 @@ var pkg = {
3095
4017
  files: files,
3096
4018
  scripts: scripts,
3097
4019
  devDependencies: devDependencies,
3098
- dependencies: dependencies
4020
+ dependencies: dependencies,
4021
+ resolutions: resolutions
3099
4022
  };
3100
4023
 
3101
4024
  console.log("inSync StageHandler version", pkg.version);