@osmo.inc/cli 0.1.22 → 0.1.24

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/osmo.js CHANGED
@@ -1,36 +1,2854 @@
1
1
  // src/commands.ts
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
- import path6 from "node:path";
4
+ import path8 from "node:path";
5
5
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
6
6
  import { parseArgs } from "node:util";
7
7
 
8
- // src/auth.ts
9
- import { createHash, randomUUID } from "node:crypto";
10
- import {
11
- chmod,
12
- lstat,
13
- mkdir,
14
- readFile,
15
- rename,
16
- rm,
17
- writeFile
18
- } from "node:fs/promises";
19
- import os from "node:os";
20
- import path2 from "node:path";
8
+ // src/auth.ts
9
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
10
+ import {
11
+ chmod,
12
+ lstat,
13
+ mkdir as mkdir2,
14
+ readFile as readFile2,
15
+ rename as rename2,
16
+ rm as rm2,
17
+ writeFile as writeFile2
18
+ } from "node:fs/promises";
19
+ import os2 from "node:os";
20
+ import path3 from "node:path";
21
+
22
+ // ../render-protocol/src/film-store.node.mjs
23
+ import { createHash, randomUUID } from "node:crypto";
24
+ import { mkdir, readFile, writeFile, rename, rm, stat } from "node:fs/promises";
25
+ import os from "node:os";
26
+ import path from "node:path";
27
+ import { setTimeout as delay } from "node:timers/promises";
28
+
29
+ // ../render-protocol/src/film-catalog.json
30
+ var film_catalog_default = {
31
+ collections: [
32
+ "motion picture",
33
+ "discontinued",
34
+ "lab process",
35
+ "color negative",
36
+ "black and white negative",
37
+ "slide film",
38
+ "commercial",
39
+ "35mm negative",
40
+ "35mm print",
41
+ "16mm",
42
+ "super 8",
43
+ "low contrast",
44
+ "photographic",
45
+ "reference",
46
+ "period",
47
+ "black and white",
48
+ "experimental"
49
+ ],
50
+ items: [
51
+ {
52
+ number: 1,
53
+ id: "stock/Vision3/Default/50D.fbfilmneg",
54
+ hash: "1bec2446ee43b88c53f2",
55
+ sha256: "ddecdecdb915dfea695ce91245e6a40f0b5a0232e7719be0b59d9f6cb3a70b2a",
56
+ kind: "stock",
57
+ collection: "motion picture",
58
+ group: "",
59
+ label: "50d",
60
+ tables: {
61
+ logc4: {
62
+ hash: "1bec2446ee43b88c53f2-logc4",
63
+ sha256: "1460c599d4d36fc3849c31762d6a45f18a5e24cf1cae566e11d2c26ceeee4267"
64
+ },
65
+ slog3cine: {
66
+ hash: "1bec2446ee43b88c53f2-slog3cine",
67
+ sha256: "8f535c0b4ccd76bf0ee272b4b1e77b2c30053ba2cecb7b5d7a1f2cfe0e051529"
68
+ }
69
+ }
70
+ },
71
+ {
72
+ number: 2,
73
+ id: "stock/Vision3/Default/200T.fbfilmneg",
74
+ hash: "ecc51cfd5a5cede9cbae",
75
+ sha256: "3f619d5aa84d49ededf451721f716aa6f5c8bfdc57bbbe6e3cc9bcf62d276749",
76
+ kind: "stock",
77
+ collection: "motion picture",
78
+ group: "",
79
+ label: "200t",
80
+ tables: {
81
+ logc4: {
82
+ hash: "ecc51cfd5a5cede9cbae-logc4",
83
+ sha256: "a9ed9ea417cf51e92d46500c2c7d51876dee9e475430a2c06cc76c1723ada7ec"
84
+ },
85
+ slog3cine: {
86
+ hash: "ecc51cfd5a5cede9cbae-slog3cine",
87
+ sha256: "0c78e273ff7cfcbade740c4477bc1c138b88fcf1410db65c092ec32bbde59fbf"
88
+ }
89
+ }
90
+ },
91
+ {
92
+ number: 3,
93
+ id: "stock/Vision3/Default/250D.fbfilmneg",
94
+ hash: "20ca38314cfd587b78fc",
95
+ sha256: "20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811",
96
+ kind: "stock",
97
+ collection: "motion picture",
98
+ group: "",
99
+ label: "250d",
100
+ tables: {
101
+ logc4: {
102
+ hash: "20ca38314cfd587b78fc-logc4",
103
+ sha256: "a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"
104
+ },
105
+ slog3cine: {
106
+ hash: "20ca38314cfd587b78fc-slog3cine",
107
+ sha256: "01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"
108
+ }
109
+ }
110
+ },
111
+ {
112
+ number: 4,
113
+ id: "stock/Vision3/Default/500T.fbfilmneg",
114
+ hash: "f10310ad81957c25fc48",
115
+ sha256: "35101b3d7bbdf914b940aacaedc7aeab2755080147f144444c78437f8788c033",
116
+ kind: "stock",
117
+ collection: "motion picture",
118
+ group: "",
119
+ label: "500t",
120
+ tables: {
121
+ logc4: {
122
+ hash: "f10310ad81957c25fc48-logc4",
123
+ sha256: "55592fe58ff6f4ac4e6151ac293198bcf9e41079e10780872ff4bf1220a8e2f0"
124
+ },
125
+ slog3cine: {
126
+ hash: "f10310ad81957c25fc48-slog3cine",
127
+ sha256: "c8a4dd3b841e15630d0267a96afeeb821102ac9b2e5a20dc1e9a5ec53d707725"
128
+ }
129
+ }
130
+ },
131
+ {
132
+ number: 5,
133
+ id: "stock/Expired/Vision2/Vision2 50D - 5201.fbfilmneg",
134
+ hash: "7ddd94e5d0799d57d43c",
135
+ sha256: "396988be0b3e7ce76a8dd12d998f6e681cc43c5bcc8caf34195c11e653c77745",
136
+ kind: "stock",
137
+ collection: "discontinued",
138
+ group: "",
139
+ label: "vision2 50d",
140
+ tables: {
141
+ logc4: {
142
+ hash: "7ddd94e5d0799d57d43c-logc4",
143
+ sha256: "5d4ab49669ef118375aa741b46be69a91ddd44fd4a422ffb864cb4f28c452b06"
144
+ },
145
+ slog3cine: {
146
+ hash: "7ddd94e5d0799d57d43c-slog3cine",
147
+ sha256: "db5cedad66e2909127c6c1f15d82fbc89ea3280f7ce9ef6bf9a177ae2102d4d1"
148
+ }
149
+ }
150
+ },
151
+ {
152
+ number: 6,
153
+ id: "stock/Expired/Vision2/Vision2 200T - 5217.fbfilmneg",
154
+ hash: "4580449bf3580df15a24",
155
+ sha256: "1c1f2014d17bf771d2a6f00bf8f59b5f10d1f236566bccc3c8dd45f54e3ad360",
156
+ kind: "stock",
157
+ collection: "discontinued",
158
+ group: "",
159
+ label: "vision2 200t",
160
+ tables: {
161
+ logc4: {
162
+ hash: "4580449bf3580df15a24-logc4",
163
+ sha256: "3f3a5594427517540a19236f93714471307976951bceac909ea92387dabd9399"
164
+ },
165
+ slog3cine: {
166
+ hash: "4580449bf3580df15a24-slog3cine",
167
+ sha256: "2b35ad024b27259ee9f7c0ca954e2bca5ef1579527138a53ba59a65399945bd5"
168
+ }
169
+ }
170
+ },
171
+ {
172
+ number: 7,
173
+ id: "stock/Expired/Vision2/Vision2 250D - 5205.fbfilmneg",
174
+ hash: "219833e83f5b03cca36c",
175
+ sha256: "be5dc3517c210da399293202de6a2296d2306c98afa4394af0b639c7bc97d858",
176
+ kind: "stock",
177
+ collection: "discontinued",
178
+ group: "",
179
+ label: "vision2 250d",
180
+ tables: {
181
+ logc4: {
182
+ hash: "219833e83f5b03cca36c-logc4",
183
+ sha256: "0776f6c9b404bb79f7bf47bb4629c29b73ef944bf9e8eb7773f0b2411f02a5ca"
184
+ },
185
+ slog3cine: {
186
+ hash: "219833e83f5b03cca36c-slog3cine",
187
+ sha256: "993769f0c92debbd346406054afda65cfe220f1680186cb1b007b7031de71730"
188
+ }
189
+ }
190
+ },
191
+ {
192
+ number: 8,
193
+ id: "stock/Expired/Vision2/Vision2 500T - 5260 5218.fbfilmneg",
194
+ hash: "bea529b58c1d7367060b",
195
+ sha256: "1894699667db0e7ae7902a0bdf3cf63d422c9600a5be18c3160b371417c03e8d",
196
+ kind: "stock",
197
+ collection: "discontinued",
198
+ group: "",
199
+ label: "vision2 500t",
200
+ tables: {
201
+ logc4: {
202
+ hash: "bea529b58c1d7367060b-logc4",
203
+ sha256: "08a7de80a3d436b78cc36250fd7ac4c929050b3738e6826dbaa4024bf4aa6367"
204
+ },
205
+ slog3cine: {
206
+ hash: "bea529b58c1d7367060b-slog3cine",
207
+ sha256: "168857a78f1c0c4c17745b8602108407fc2e307ece0f1486d4416a9090946ff3"
208
+ }
209
+ }
210
+ },
211
+ {
212
+ number: 9,
213
+ id: "stock/Expired/Vision/Vision 250D - 5246.fbfilmneg",
214
+ hash: "5dbbbe0bc3402ac432ef",
215
+ sha256: "55ca19c348d6c8c6adfb07f6ccfd9e1891f06c6373fffe2964b45a0828872adc",
216
+ kind: "stock",
217
+ collection: "discontinued",
218
+ group: "",
219
+ label: "vision 250d",
220
+ tables: {
221
+ logc4: {
222
+ hash: "5dbbbe0bc3402ac432ef-logc4",
223
+ sha256: "1eefbb8c9b168f76c2ca6838e13480b41781200a91040dbb40c20db94b4f9b02"
224
+ },
225
+ slog3cine: {
226
+ hash: "5dbbbe0bc3402ac432ef-slog3cine",
227
+ sha256: "93870ed95db1793d22db1fbd3e92572d4728e7251de57851138d78e9859fdeae"
228
+ }
229
+ }
230
+ },
231
+ {
232
+ number: 10,
233
+ id: "stock/Expired/Vision/Vision 500T - 5279.fbfilmneg",
234
+ hash: "651bc5d68b55c63d2209",
235
+ sha256: "ebc7605bc69f3843275c4441eab2149d8698a75f4d5b29249df5f00bb4a4b216",
236
+ kind: "stock",
237
+ collection: "discontinued",
238
+ group: "",
239
+ label: "vision 500t",
240
+ tables: {
241
+ logc4: {
242
+ hash: "651bc5d68b55c63d2209-logc4",
243
+ sha256: "7f8fc4223eb54ffbb492bdaa8d80adbca125e82f4e67f867c443ebd6d9b6ac32"
244
+ },
245
+ slog3cine: {
246
+ hash: "651bc5d68b55c63d2209-slog3cine",
247
+ sha256: "cbbdefec443780cf601796a6e766145368fc5d02ad8ee7deb86c7c5885006748"
248
+ }
249
+ }
250
+ },
251
+ {
252
+ number: 11,
253
+ id: "stock/Expired/EXR/EXR 100T - 5248.fbfilmneg",
254
+ hash: "b408aaad6a6b268cc31f",
255
+ sha256: "c89b9e24496d2cfb637829bf7441170901526df8fbecc0feb0872be1b1b0bcca",
256
+ kind: "stock",
257
+ collection: "discontinued",
258
+ group: "",
259
+ label: "exr 100t",
260
+ tables: {
261
+ logc4: {
262
+ hash: "b408aaad6a6b268cc31f-logc4",
263
+ sha256: "5416b18636ee7a0f24d6dd59e996b6bdf17f8ded5649b1df07cc6bb8d10b612f"
264
+ },
265
+ slog3cine: {
266
+ hash: "b408aaad6a6b268cc31f-slog3cine",
267
+ sha256: "32d474f721c26c74ab9c6b042fc19da9f4e1254cfe2fb986376ead354c4413c4"
268
+ }
269
+ }
270
+ },
271
+ {
272
+ number: 12,
273
+ id: "stock/Expired/EXR/EXR 50D - 5245.fbfilmneg",
274
+ hash: "dbfcf75f65364f300865",
275
+ sha256: "ab35fa37e82dd216c772f7f1c6621c55d2360e6a22bfbf81b626f6ef19a7c316",
276
+ kind: "stock",
277
+ collection: "discontinued",
278
+ group: "",
279
+ label: "exr 50d",
280
+ tables: {
281
+ logc4: {
282
+ hash: "dbfcf75f65364f300865-logc4",
283
+ sha256: "6244d992d217cf445a755d6960aaef7d12c571c82fc891d3f151dda1958c3d79"
284
+ },
285
+ slog3cine: {
286
+ hash: "dbfcf75f65364f300865-slog3cine",
287
+ sha256: "d69e50ecbe59f222a4c0747c1f3b014b7aa1acae2de19190b7a08508eac35c7b"
288
+ }
289
+ }
290
+ },
291
+ {
292
+ number: 13,
293
+ id: "stock/Expired/EXR/EXR 500T - 5298.fbfilmneg",
294
+ hash: "b48affdfe23da47091f9",
295
+ sha256: "30b7cd4e6e280844101034e9a7e40c521541c78e2c3daf8a9e52e778846ac941",
296
+ kind: "stock",
297
+ collection: "discontinued",
298
+ group: "",
299
+ label: "exr 500t",
300
+ tables: {
301
+ logc4: {
302
+ hash: "b48affdfe23da47091f9-logc4",
303
+ sha256: "54004242f20d22bc68622e1be479fcc41685a4137fa0f46c7e4ba41122d48f6f"
304
+ },
305
+ slog3cine: {
306
+ hash: "b48affdfe23da47091f9-slog3cine",
307
+ sha256: "4c0195829c042b101aed9c26f601d4f09f2104654101272408c62a8d680b9ca6"
308
+ }
309
+ }
310
+ },
311
+ {
312
+ number: 14,
313
+ id: "stock/Expired/Eterna/Eterna 250D - 8563.fbfilmneg",
314
+ hash: "ef47355ccc6c71d56c07",
315
+ sha256: "d0293c0409df012218f53cec44332680e5544cea8f9306596598cd8c7a9ac6b4",
316
+ kind: "stock",
317
+ collection: "discontinued",
318
+ group: "",
319
+ label: "eterna 250d",
320
+ tables: {
321
+ logc4: {
322
+ hash: "ef47355ccc6c71d56c07-logc4",
323
+ sha256: "85328a7b6dc2b5746ba70101d063be859fa791347b568e719fb18b46d6e75d61"
324
+ },
325
+ slog3cine: {
326
+ hash: "ef47355ccc6c71d56c07-slog3cine",
327
+ sha256: "a8e5fedbd3801a857ee23f9eac28c76f13ce85b8633a6d136eec15be9291ef76"
328
+ }
329
+ }
330
+ },
331
+ {
332
+ number: 15,
333
+ id: "stock/Expired/Eterna/Eterna 500T - 8573.fbfilmneg",
334
+ hash: "03e20bcdbf816cbc2705",
335
+ sha256: "267c62f7ca7a02dc9e917e6ead14f30600fc0868565fb004cc8c69ca75abd8c8",
336
+ kind: "stock",
337
+ collection: "discontinued",
338
+ group: "",
339
+ label: "eterna 500t",
340
+ tables: {
341
+ logc4: {
342
+ hash: "03e20bcdbf816cbc2705-logc4",
343
+ sha256: "3c4fb57d4a35addd93c7c3f1877e9b45aa40219e6976db22afcba8cd23921de8"
344
+ },
345
+ slog3cine: {
346
+ hash: "03e20bcdbf816cbc2705-slog3cine",
347
+ sha256: "9c1db859909ae4f100d52aecbf2f3a7b896c7db441bda24b70da13c67024d703"
348
+ }
349
+ }
350
+ },
351
+ {
352
+ number: 16,
353
+ id: "stock/Expired/Eterna Vivid/Eterna Vivid 250D - 8546.fbfilmneg",
354
+ hash: "19e71cdeaec2f28d22ed",
355
+ sha256: "bfe8e64339b9b9b8bf43d94dda6c92889c818d9d7b435903a87c0ae4cc80d741",
356
+ kind: "stock",
357
+ collection: "discontinued",
358
+ group: "",
359
+ label: "eterna vivid 250d",
360
+ tables: {
361
+ logc4: {
362
+ hash: "19e71cdeaec2f28d22ed-logc4",
363
+ sha256: "a2021b3cf8df60d5cd5aa194aa941f0c88ed0551065929d2989874da3d63156c"
364
+ },
365
+ slog3cine: {
366
+ hash: "19e71cdeaec2f28d22ed-slog3cine",
367
+ sha256: "536e038df383269259af2c757bfeca5899c9b037d7182663383eb8c34d7e286c"
368
+ }
369
+ }
370
+ },
371
+ {
372
+ number: 17,
373
+ id: "stock/Expired/Super-F/Super-F 64D - 8621.fbfilmneg",
374
+ hash: "e9a41978b31155132d19",
375
+ sha256: "2c240c8049050818df417169f422a4cf4d88734103ddaab23f7550d409327b64",
376
+ kind: "stock",
377
+ collection: "discontinued",
378
+ group: "",
379
+ label: "super-f 64d",
380
+ tables: {
381
+ logc4: {
382
+ hash: "e9a41978b31155132d19-logc4",
383
+ sha256: "74ee43f73c8c961022502325542e3489a4767da1d8c640f744515acba70582f3"
384
+ },
385
+ slog3cine: {
386
+ hash: "e9a41978b31155132d19-slog3cine",
387
+ sha256: "6ffde4f76a9a6e207946610fc44702927d1af53c3780c291c9631e3b04d3f803"
388
+ }
389
+ }
390
+ },
391
+ {
392
+ number: 18,
393
+ id: "stock/Expired/Other/Reala 500D - 8592.fbfilmneg",
394
+ hash: "b5a5b1d2f15133dbbd40",
395
+ sha256: "fcb024fd39012665dde3f2cedfce48fbb686863d3f4f7d02e334e3d5bfe37f88",
396
+ kind: "stock",
397
+ collection: "discontinued",
398
+ group: "",
399
+ label: "reala 500d",
400
+ tables: {
401
+ logc4: {
402
+ hash: "b5a5b1d2f15133dbbd40-logc4",
403
+ sha256: "d4b026a232a67622e5d7a75f3d71d1cfa5f890e2c5b7457bc97027e822649538"
404
+ },
405
+ slog3cine: {
406
+ hash: "b5a5b1d2f15133dbbd40-slog3cine",
407
+ sha256: "fef3e60b41ba6b7246ac4d4f6afd8f370f27e2cc8bb8000a7ea1f782b12e0311"
408
+ }
409
+ }
410
+ },
411
+ {
412
+ number: 19,
413
+ id: "stock/Expired/Other/Plus-X - 5231.fbfilmneg",
414
+ hash: "01646d0ebdea130feeb0",
415
+ sha256: "95df160d3412192d6d840ae9a79008ad0880d60772a069b1a2c730886324fd63",
416
+ kind: "stock",
417
+ collection: "discontinued",
418
+ group: "",
419
+ label: "plus-x",
420
+ tables: {
421
+ logc4: {
422
+ hash: "01646d0ebdea130feeb0-logc4",
423
+ sha256: "2edfcfe37f61ecd3aa471628fc730b6bf76b7c536e346ea3680730c57f1de71f"
424
+ },
425
+ slog3cine: {
426
+ hash: "01646d0ebdea130feeb0-slog3cine",
427
+ sha256: "97476d0a31a72eb7b5f08f79100f7442f243726b16d9d3879d87c3337bd65b01"
428
+ }
429
+ }
430
+ },
431
+ {
432
+ number: 20,
433
+ id: "stock/EktachromeCross/Default/Ektachrome.fbfilmneg",
434
+ hash: "ea4a6fc70e60b72de85d",
435
+ sha256: "682527e690a30717568a08b588a1ae13ec09b39b1b9c2904029cf0be0b706b3b",
436
+ kind: "stock",
437
+ collection: "lab process",
438
+ group: "",
439
+ label: "ektachrome cross process",
440
+ tables: {
441
+ logc4: {
442
+ hash: "ea4a6fc70e60b72de85d-logc4",
443
+ sha256: "6dfae05dea7b59c73ec19b73c4246fc9a1affb598eae92e207011778edf142fe"
444
+ },
445
+ slog3cine: {
446
+ hash: "ea4a6fc70e60b72de85d-slog3cine",
447
+ sha256: "b7163211d24ca6cf130b2ca23eca0bdc6f7e72784ce0d17767eca1f5a50f03c3"
448
+ }
449
+ }
450
+ },
451
+ {
452
+ number: 21,
453
+ id: "stock/BleachBypass/Default/Bleach Bypass Full.fbfilmneg",
454
+ hash: "ebf8e027214208da802d",
455
+ sha256: "bc69f0ef78bba9221302f73c0dbdd956c775e40bb5aa65833159d896756ad282",
456
+ kind: "stock",
457
+ collection: "lab process",
458
+ group: "",
459
+ label: "bleach bypass full",
460
+ tables: {
461
+ logc4: {
462
+ hash: "ebf8e027214208da802d-logc4",
463
+ sha256: "e14326889b137b2cdede1ababe0bbcf41a35900ff842460b5a47ca3e75bdf92e"
464
+ },
465
+ slog3cine: {
466
+ hash: "ebf8e027214208da802d-slog3cine",
467
+ sha256: "e0909c31f58a340e1d3c2987d795f6345ffb79223bb3d032efc5c1ec30720a47"
468
+ }
469
+ }
470
+ },
471
+ {
472
+ number: 22,
473
+ id: "stock/BleachBypass/Default/Bleach Bypass Half.fbfilmneg",
474
+ hash: "33279d836190f8d0ac43",
475
+ sha256: "9ae0fa355f54cc772368d28cdc1ba342388d5855297d5bcf0f6b058bbe36eb8d",
476
+ kind: "stock",
477
+ collection: "lab process",
478
+ group: "",
479
+ label: "bleach bypass 50%",
480
+ tables: {
481
+ logc4: {
482
+ hash: "33279d836190f8d0ac43-logc4",
483
+ sha256: "632993d0b36a6320172d4b19a109ce90450b8cd3d79d575850fc4e2f9af7bfef"
484
+ },
485
+ slog3cine: {
486
+ hash: "33279d836190f8d0ac43-slog3cine",
487
+ sha256: "3ff5b18d862575c8203d49a93edf04af53b4e6b56b651845e582ceb27705cbdb"
488
+ }
489
+ }
490
+ },
491
+ {
492
+ number: 23,
493
+ id: "stock/BleachBypass/Default/Bleach Bypass 30%.fbfilmneg",
494
+ hash: "362fe9e15e5b3e8a3712",
495
+ sha256: "efda5afdd954b7a0dc51edbf47e7bc1c03b5f98153f947872a6ec7f111810186",
496
+ kind: "stock",
497
+ collection: "lab process",
498
+ group: "",
499
+ label: "bleach bypass 30%",
500
+ tables: {
501
+ logc4: {
502
+ hash: "362fe9e15e5b3e8a3712-logc4",
503
+ sha256: "ad78fd6b96ee1375d45dff4fc0fb6aaee067714fe0635cec7dc2c379127dddac"
504
+ },
505
+ slog3cine: {
506
+ hash: "362fe9e15e5b3e8a3712-slog3cine",
507
+ sha256: "79234637f94187208a77aa9f4d7dfe8e04b50a44cba8a6912dc4fec923e602e3"
508
+ }
509
+ }
510
+ },
511
+ {
512
+ number: 24,
513
+ id: "stock/PhotoColor/Portrait/Pro 400H.fbfilmneg",
514
+ hash: "9702f45a667b36529557",
515
+ sha256: "6780a9fa3b04624eaaed4e2a9c5f55654fda4d7999663fd5c4c5b217ad90bc9b",
516
+ kind: "stock",
517
+ collection: "color negative",
518
+ group: "portrait",
519
+ label: "pro 400h",
520
+ tables: {
521
+ logc4: {
522
+ hash: "9702f45a667b36529557-logc4",
523
+ sha256: "6472860b63370f6627ca3d928b7b1089631d59a94f2ba6e912b7212c8063700a"
524
+ },
525
+ slog3cine: {
526
+ hash: "9702f45a667b36529557-slog3cine",
527
+ sha256: "db42b57a3a401eae0a994290ab77970924c3a99456c96a2c7ca2b58e7db63337"
528
+ }
529
+ }
530
+ },
531
+ {
532
+ number: 25,
533
+ id: "stock/PhotoColor/Portrait/Portra 160.fbfilmneg",
534
+ hash: "1c7192956b1166b7dc57",
535
+ sha256: "8ea8c14ba4e1007883cf721af01945acc1e9b895c3d73849258f1bedbcdfbfc4",
536
+ kind: "stock",
537
+ collection: "color negative",
538
+ group: "portrait",
539
+ label: "portra 160",
540
+ tables: {
541
+ logc4: {
542
+ hash: "1c7192956b1166b7dc57-logc4",
543
+ sha256: "2128360480122aece81f0042d1d5ef7de07a4044027d5527074cb5031f6db050"
544
+ },
545
+ slog3cine: {
546
+ hash: "1c7192956b1166b7dc57-slog3cine",
547
+ sha256: "517456d35e73cbbfb680ad65c81fae66221ee1777d014f45a57d6c28caae3cf5"
548
+ }
549
+ }
550
+ },
551
+ {
552
+ number: 26,
553
+ id: "stock/PhotoColor/Portrait/Portra 400.fbfilmneg",
554
+ hash: "307d051c9f3a84b9cd47",
555
+ sha256: "560a83d5a265933aab77d1834b12741d1d3602f686fcf0e26739a5abe209f1af",
556
+ kind: "stock",
557
+ collection: "color negative",
558
+ group: "portrait",
559
+ label: "portra 400",
560
+ tables: {
561
+ logc4: {
562
+ hash: "307d051c9f3a84b9cd47-logc4",
563
+ sha256: "ad235ea9c8b5d5f60756ff021d11c1bd16d3ffa9755ae4f008759dd505d315d5"
564
+ },
565
+ slog3cine: {
566
+ hash: "307d051c9f3a84b9cd47-slog3cine",
567
+ sha256: "8531cf2e1e42931ac1c46c4910fd7dc006ce6805716fa19ace268831b9070204"
568
+ }
569
+ }
570
+ },
571
+ {
572
+ number: 27,
573
+ id: "stock/PhotoColor/Portrait/Portra 800.fbfilmneg",
574
+ hash: "50617f9a14935e1dc16a",
575
+ sha256: "3ae27d6e659eabc89f1eb56c7c30f6afa43dc92c9798c1edcc3eb33e3a2a2cea",
576
+ kind: "stock",
577
+ collection: "color negative",
578
+ group: "portrait",
579
+ label: "portra 800",
580
+ tables: {
581
+ logc4: {
582
+ hash: "50617f9a14935e1dc16a-logc4",
583
+ sha256: "fdabfb438877c1c24d1d837050793c34cbe8b7c32f8393e58e4d4db85642ae97"
584
+ },
585
+ slog3cine: {
586
+ hash: "50617f9a14935e1dc16a-slog3cine",
587
+ sha256: "c9478032369a0522aee17cd53c0ff411b22274fe1eae3c0fd64a8939296df373"
588
+ }
589
+ }
590
+ },
591
+ {
592
+ number: 28,
593
+ id: "stock/PhotoColor/Classic/Superia 400.fbfilmneg",
594
+ hash: "2bf389827db8fc7409b2",
595
+ sha256: "e05e8b7de7e3c5b2bca868cf55f5357ba164e2a0cb92f231e1816ac78d4204d8",
596
+ kind: "stock",
597
+ collection: "color negative",
598
+ group: "classic",
599
+ label: "superia 400",
600
+ tables: {
601
+ logc4: {
602
+ hash: "2bf389827db8fc7409b2-logc4",
603
+ sha256: "58e8b1aa84365274e80a31882b4c8369b43708f38b6a1df18d286c0aedda71a0"
604
+ },
605
+ slog3cine: {
606
+ hash: "2bf389827db8fc7409b2-slog3cine",
607
+ sha256: "54a109b35168024a2e603eaf04a7bb851520e8dade1a8d0c565567df69132263"
608
+ }
609
+ }
610
+ },
611
+ {
612
+ number: 29,
613
+ id: "stock/PhotoColor/Classic/ColorPlus 200.fbfilmneg",
614
+ hash: "0bf9634cd9251686f2f1",
615
+ sha256: "dd24df8d9f1b90c021fef1ad4064351a07bea394c1ae2a5f35e8d37219418400",
616
+ kind: "stock",
617
+ collection: "color negative",
618
+ group: "classic",
619
+ label: "colorplus 200",
620
+ tables: {
621
+ logc4: {
622
+ hash: "0bf9634cd9251686f2f1-logc4",
623
+ sha256: "bc9932eedc61df8af664831228dfe9217065a9f734fc99bb4097317dcec83a12"
624
+ },
625
+ slog3cine: {
626
+ hash: "0bf9634cd9251686f2f1-slog3cine",
627
+ sha256: "47f03ccdb9e440e95993f98542d3cca6e7701b51c5db807647b54dde67213ef0"
628
+ }
629
+ }
630
+ },
631
+ {
632
+ number: 30,
633
+ id: "stock/PhotoColor/Classic/Gold 200.fbfilmneg",
634
+ hash: "15f259e9968a7c0f40c5",
635
+ sha256: "5639e09392aa3edc58151cab69d7371ffd38c1bccf12e808716b1ceee4583e18",
636
+ kind: "stock",
637
+ collection: "color negative",
638
+ group: "classic",
639
+ label: "gold 200",
640
+ tables: {
641
+ logc4: {
642
+ hash: "15f259e9968a7c0f40c5-logc4",
643
+ sha256: "9ada80fd0827c34c9101aea7be5305dd944afe52e824183c988f13850dc8cb1a"
644
+ },
645
+ slog3cine: {
646
+ hash: "15f259e9968a7c0f40c5-slog3cine",
647
+ sha256: "af1b22b0bdadf271477f597a5d61bdf2c54c4f5580be7b418f233beaa53ff366"
648
+ }
649
+ }
650
+ },
651
+ {
652
+ number: 31,
653
+ id: "stock/PhotoColor/Classic/UltraMax 400.fbfilmneg",
654
+ hash: "0f1546383584ffbf0c6d",
655
+ sha256: "581336e3b530df7534468f4db97746b3b5cf16ff9b9ff8fce09f6f7e6bf52794",
656
+ kind: "stock",
657
+ collection: "color negative",
658
+ group: "classic",
659
+ label: "ultramax 400",
660
+ tables: {
661
+ logc4: {
662
+ hash: "0f1546383584ffbf0c6d-logc4",
663
+ sha256: "60da1e43f7c1bdd8d1960369326c788696049a206cf5105cad455aadb3784e98"
664
+ },
665
+ slog3cine: {
666
+ hash: "0f1546383584ffbf0c6d-slog3cine",
667
+ sha256: "ae9fc1afb3356465fbe7f808187dbaec1b0a80b1d2f5e9c217af09aeda8dbc2e"
668
+ }
669
+ }
670
+ },
671
+ {
672
+ number: 32,
673
+ id: "stock/PhotoColor/Classic/Fujicolor 200.fbfilmneg",
674
+ hash: "614d18ad0fa6cbb3b310",
675
+ sha256: "1827564e621ab41a6cc573fbe6e8e44a506ef4f4f9f22b9858bcd2866f898f5e",
676
+ kind: "stock",
677
+ collection: "color negative",
678
+ group: "classic",
679
+ label: "fujicolor 200",
680
+ tables: {
681
+ logc4: {
682
+ hash: "614d18ad0fa6cbb3b310-logc4",
683
+ sha256: "e4e949e1e6a94238d4424b0ab66cc3f7747534a2cb37c41226b8b9b64325de4e"
684
+ },
685
+ slog3cine: {
686
+ hash: "614d18ad0fa6cbb3b310-slog3cine",
687
+ sha256: "8e0e999a508e9e7c388c3339fd36e805a8d76d0163b5f3140b713f90130407fa"
688
+ }
689
+ }
690
+ },
691
+ {
692
+ number: 33,
693
+ id: "stock/PhotoColor/Vivid/Ektar 100.fbfilmneg",
694
+ hash: "37b39e23eeed891943a2",
695
+ sha256: "6d917845ad42af0069a90c9411ad92e888e801672d7808a60368177ab05004f8",
696
+ kind: "stock",
697
+ collection: "color negative",
698
+ group: "vivid",
699
+ label: "ektar 100",
700
+ tables: {
701
+ logc4: {
702
+ hash: "37b39e23eeed891943a2-logc4",
703
+ sha256: "b9e1c78fb15f5cfdae9fe3a3dd88c485e36df3a14724deb56f3c98eebb849a6e"
704
+ },
705
+ slog3cine: {
706
+ hash: "37b39e23eeed891943a2-slog3cine",
707
+ sha256: "8d0676ddc23c99cc0a709e16e8c6bfcc27084fbf15f9748674997dd9c553f23e"
708
+ }
709
+ }
710
+ },
711
+ {
712
+ number: 34,
713
+ id: "stock/PhotoColor/Vivid/Lomo Color 100.fbfilmneg",
714
+ hash: "28c58b21901ffafb8026",
715
+ sha256: "18e50eb5f6e0c820be78d434776d57d29c979493d6b054298b5a856391db304d",
716
+ kind: "stock",
717
+ collection: "color negative",
718
+ group: "vivid",
719
+ label: "lomo color 100",
720
+ tables: {
721
+ logc4: {
722
+ hash: "28c58b21901ffafb8026-logc4",
723
+ sha256: "1cb3597192dc02aaeb3b6d2f18cb3053786acc7ed006854e817b155e3506975b"
724
+ },
725
+ slog3cine: {
726
+ hash: "28c58b21901ffafb8026-slog3cine",
727
+ sha256: "73c928d02509d1f1d1efab6dc32b924e0854db599c2f4d500c9f27dcb90ffb94"
728
+ }
729
+ }
730
+ },
731
+ {
732
+ number: 35,
733
+ id: "stock/PhotoColor/Vivid/Aerocolor 100.fbfilmneg",
734
+ hash: "a673d3c69731d85b86c4",
735
+ sha256: "828872cf3851e56027d84381c7aebd3c4f3ec4fe6bb083e90d89ee13d8271623",
736
+ kind: "stock",
737
+ collection: "color negative",
738
+ group: "vivid",
739
+ label: "aerocolor 100",
740
+ tables: {
741
+ logc4: {
742
+ hash: "a673d3c69731d85b86c4-logc4",
743
+ sha256: "449f3b65f8618469ed9e8b2cd51e46b758e95f77d54d61742d2ce4cd61e18e54"
744
+ },
745
+ slog3cine: {
746
+ hash: "a673d3c69731d85b86c4-slog3cine",
747
+ sha256: "ef86ceab34e252299e0897b0220c5d8b7ac4f042529ad57cb8e456bae6a03c93"
748
+ }
749
+ }
750
+ },
751
+ {
752
+ number: 36,
753
+ id: "stock/PhotoColor/Vivid/Phoenix.fbfilmneg",
754
+ hash: "e7d7536754674c35aa49",
755
+ sha256: "1cabbd28e88f4c8bee4e0011232d6a217c870848476c702c0518a8ac46d9682d",
756
+ kind: "stock",
757
+ collection: "color negative",
758
+ group: "vivid",
759
+ label: "phoenix",
760
+ tables: {
761
+ logc4: {
762
+ hash: "e7d7536754674c35aa49-logc4",
763
+ sha256: "f0d46d982eb5488daf6b92e3d021053466ac063cf384141bcba90790c8428715"
764
+ },
765
+ slog3cine: {
766
+ hash: "e7d7536754674c35aa49-slog3cine",
767
+ sha256: "383720b40b78db0de52b70caa7959ebdf34f2044c5017abf4e32dedacc25a161"
768
+ }
769
+ }
770
+ },
771
+ {
772
+ number: 37,
773
+ id: "stock/PhotoColor/Cine/CineStill 800T.fbfilmneg",
774
+ hash: "0b8e1ff254ee8e2a45c1",
775
+ sha256: "6732af8710649bb4887110caa4fe552e83fa61dc4a1b1e19a7794181416b0f1a",
776
+ kind: "stock",
777
+ collection: "color negative",
778
+ group: "cinestill",
779
+ label: "cinestill 800t",
780
+ tables: {
781
+ logc4: {
782
+ hash: "0b8e1ff254ee8e2a45c1-logc4",
783
+ sha256: "77ff93b03b695ab2dc588605cbe41604a7a7deaaa85b6b1c53eead74dd535f70"
784
+ },
785
+ slog3cine: {
786
+ hash: "0b8e1ff254ee8e2a45c1-slog3cine",
787
+ sha256: "fa7bc0eef6a4b68c3c76ca17fbd5d117be5134f4d3eea9f148af0162b2855368"
788
+ }
789
+ }
790
+ },
791
+ {
792
+ number: 38,
793
+ id: "stock/PhotoColor/Cine/CineStill 400D.fbfilmneg",
794
+ hash: "069f33c0011b2c68718a",
795
+ sha256: "b451c0a3f32b7d32ef409cffb511db023223beb602a60e6a6caff1c4ac1ea490",
796
+ kind: "stock",
797
+ collection: "color negative",
798
+ group: "cinestill",
799
+ label: "cinestill 400d",
800
+ tables: {
801
+ logc4: {
802
+ hash: "069f33c0011b2c68718a-logc4",
803
+ sha256: "63ee60ec1749e781785b679b33986c0be287b2198980bef946dfc6c5389dede8"
804
+ },
805
+ slog3cine: {
806
+ hash: "069f33c0011b2c68718a-slog3cine",
807
+ sha256: "2de7348f29263ba2428789a421cc9fd1cf6e4ab9ca381bde0c2d69981c45acc0"
808
+ }
809
+ }
810
+ },
811
+ {
812
+ number: 39,
813
+ id: "stock/PhotoColor/Cine/CineStill 50D.fbfilmneg",
814
+ hash: "8cf8926463e3e909a835",
815
+ sha256: "a681cd2f758ec66171a0b8494ed4f5d496599e69da7cc49103868efbf806113a",
816
+ kind: "stock",
817
+ collection: "color negative",
818
+ group: "cinestill",
819
+ label: "cinestill 50d",
820
+ tables: {
821
+ logc4: {
822
+ hash: "8cf8926463e3e909a835-logc4",
823
+ sha256: "ee105a5a5cfbef1a10b065092ffd630b764067e70a0548866a7d0cefdf06aa7c"
824
+ },
825
+ slog3cine: {
826
+ hash: "8cf8926463e3e909a835-slog3cine",
827
+ sha256: "1fb2f9bc4aa487e0575637b005b685f0d87ab3a6a1e16d1491b284bd50f8863f"
828
+ }
829
+ }
830
+ },
831
+ {
832
+ number: 40,
833
+ id: "stock/PhotoColor/Stylized/Ektachrome C41.fbfilmneg",
834
+ hash: "b0402bf8f5591e219177",
835
+ sha256: "2616ac31325d743c0212edfe81fe01ffb61a173db393baacfc7ef4053ffdafa9",
836
+ kind: "stock",
837
+ collection: "color negative",
838
+ group: "specialty",
839
+ label: "ektachrome c41",
840
+ tables: {
841
+ logc4: {
842
+ hash: "b0402bf8f5591e219177-logc4",
843
+ sha256: "94e041fb3c7face91aa01f3601c4996dc9fe57284f1af3b3014bfc2eff46871e"
844
+ },
845
+ slog3cine: {
846
+ hash: "b0402bf8f5591e219177-slog3cine",
847
+ sha256: "3fa275094cf2349b51351e1393dd1a1ceb87304fc2715e3044c7c4f1604d2d39"
848
+ }
849
+ }
850
+ },
851
+ {
852
+ number: 41,
853
+ id: "stock/PhotoColor/Stylized/Purple XR.fbfilmneg",
854
+ hash: "fc75a210efb408479f7c",
855
+ sha256: "025d1a543fe3bb58ea9488ca0504bb544ec4af55769066a5b06979ddd5e5ec7e",
856
+ kind: "stock",
857
+ collection: "color negative",
858
+ group: "specialty",
859
+ label: "purple xr",
860
+ tables: {
861
+ logc4: {
862
+ hash: "fc75a210efb408479f7c-logc4",
863
+ sha256: "373e08ba3c2af5e8a850f8430fc2f91656df2981e20423a2f27e3635a7fdb6c3"
864
+ },
865
+ slog3cine: {
866
+ hash: "fc75a210efb408479f7c-slog3cine",
867
+ sha256: "f0b5ebcac3206c4235e45be5eeef099cf1e61edca8b809dfce6d18cbcc3a604f"
868
+ }
869
+ }
870
+ },
871
+ {
872
+ number: 42,
873
+ id: "stock/PhotoColor/Stylized/Redscale XR.fbfilmneg",
874
+ hash: "b478a4b37293e1cd7271",
875
+ sha256: "78230c65977e7415c914caa1c4f3196b08f8d82be4d45502a31092e1067dd471",
876
+ kind: "stock",
877
+ collection: "color negative",
878
+ group: "specialty",
879
+ label: "redscale xr",
880
+ tables: {
881
+ logc4: {
882
+ hash: "b478a4b37293e1cd7271-logc4",
883
+ sha256: "8a362587350be2f87f777449fd44816a64f5a5866236b8f1919a9e685270ac36"
884
+ },
885
+ slog3cine: {
886
+ hash: "b478a4b37293e1cd7271-slog3cine",
887
+ sha256: "8cd5ce8f841f901d50b87fde5588fe1c151da5ce7381810b5ea4a382745f2551"
888
+ }
889
+ }
890
+ },
891
+ {
892
+ number: 43,
893
+ id: "stock/PhotoColor/Stylized/XP2 400.fbfilmneg",
894
+ hash: "21bc8e616c71bdd3dc26",
895
+ sha256: "c44c6b2fdd8c6cbeca0c2793d70c07ae2edad1468d548787a1a45f673009eaf6",
896
+ kind: "stock",
897
+ collection: "color negative",
898
+ group: "specialty",
899
+ label: "xp2 400",
900
+ tables: {
901
+ logc4: {
902
+ hash: "21bc8e616c71bdd3dc26-logc4",
903
+ sha256: "fa2466898ff33948a53624f5b3124f810abf8d3dddb6e2c9f406820150b80453"
904
+ },
905
+ slog3cine: {
906
+ hash: "21bc8e616c71bdd3dc26-slog3cine",
907
+ sha256: "3ee1772a45afd64c91e07ee378ce0c5ea8c48036a50d87e5579e84a696123e0f"
908
+ }
909
+ }
910
+ },
911
+ {
912
+ number: 44,
913
+ id: "stock/PhotoBW/Classic/HP5 400.fbfilmneg",
914
+ hash: "14cf96e62ee81f239566",
915
+ sha256: "be24f71bb06129ab0553cc70b9831b7b16311576d26d6fe26d3b5b3a68d132d7",
916
+ kind: "stock",
917
+ collection: "black and white negative",
918
+ group: "classic",
919
+ label: "hp5 400",
920
+ tables: {
921
+ logc4: {
922
+ hash: "14cf96e62ee81f239566-logc4",
923
+ sha256: "a73c789501877a27a9c0ed42a62b1f5a1b40fea3bb8e0829bef5419429457642"
924
+ },
925
+ slog3cine: {
926
+ hash: "14cf96e62ee81f239566-slog3cine",
927
+ sha256: "b66dcb2d948d919eb31d58a5b0de1a9388fbc5d774261ba051b33110b6143b6e"
928
+ }
929
+ }
930
+ },
931
+ {
932
+ number: 45,
933
+ id: "stock/PhotoBW/Classic/Delta 400.fbfilmneg",
934
+ hash: "7f87b4fbfed571ae7362",
935
+ sha256: "03fc29256153562a77243787c8220b7454a97b2c4f528cd81d64fc6570a9dd80",
936
+ kind: "stock",
937
+ collection: "black and white negative",
938
+ group: "classic",
939
+ label: "delta 400",
940
+ tables: {
941
+ logc4: {
942
+ hash: "7f87b4fbfed571ae7362-logc4",
943
+ sha256: "c7588b4c108a6bd168f8f0dffdf4ff408b7b9d090f12ee305cfd982c9da9f5c7"
944
+ },
945
+ slog3cine: {
946
+ hash: "7f87b4fbfed571ae7362-slog3cine",
947
+ sha256: "fee7f970c5d007acd33b3cdf5bb909d3da1f9edd144ff7bff70d42d742345091"
948
+ }
949
+ }
950
+ },
951
+ {
952
+ number: 46,
953
+ id: "stock/PhotoBW/Classic/T-MAX 400.fbfilmneg",
954
+ hash: "f5ba00a6e5039e797f4c",
955
+ sha256: "28a7a45815962a43997cd77ccbde1322f75c30d4727cda74f8e20cadeb10e97d",
956
+ kind: "stock",
957
+ collection: "black and white negative",
958
+ group: "classic",
959
+ label: "t-max 400",
960
+ tables: {
961
+ logc4: {
962
+ hash: "f5ba00a6e5039e797f4c-logc4",
963
+ sha256: "d43d7aee516569f54c5853ea6af6d27604ee107f9368af389a1e41edf81d5ea8"
964
+ },
965
+ slog3cine: {
966
+ hash: "f5ba00a6e5039e797f4c-slog3cine",
967
+ sha256: "5122aaa711ed16d99d904173cb7489fe5dd10af2cd98eee8e719206d5cd0ef84"
968
+ }
969
+ }
970
+ },
971
+ {
972
+ number: 47,
973
+ id: "stock/PhotoBW/Classic/Tri-X 400.fbfilmneg",
974
+ hash: "ed440fc1337cdfdc86e3",
975
+ sha256: "55702591f916cec4bc2ca90a76a52996eae449b84937f161f7f91080d311223c",
976
+ kind: "stock",
977
+ collection: "black and white negative",
978
+ group: "classic",
979
+ label: "tri-x 400",
980
+ tables: {
981
+ logc4: {
982
+ hash: "ed440fc1337cdfdc86e3-logc4",
983
+ sha256: "cbbc87cc7829d04d00b60a75bbbff66226c2051f2746b83e72c4cc6f33fa2044"
984
+ },
985
+ slog3cine: {
986
+ hash: "ed440fc1337cdfdc86e3-slog3cine",
987
+ sha256: "66a7e7fb3649918dd77492369ed5f657bb8ca35e50ddfdf4efab0e930f83e166"
988
+ }
989
+ }
990
+ },
991
+ {
992
+ number: 48,
993
+ id: "stock/PhotoBW/Retro/Fomapan 400.fbfilmneg",
994
+ hash: "0bb5ef0935f2d6fb31d2",
995
+ sha256: "fbc0c0e6db037c58b7dd5cd52c4836c1fb7bd9ccd77293dc9d49c30fc69a8e9a",
996
+ kind: "stock",
997
+ collection: "black and white negative",
998
+ group: "retro",
999
+ label: "fomapan 400",
1000
+ tables: {
1001
+ logc4: {
1002
+ hash: "0bb5ef0935f2d6fb31d2-logc4",
1003
+ sha256: "b9989889e9be17ad1619acfa68d0fe2e2d90a727123b825d074e57c8918f5686"
1004
+ },
1005
+ slog3cine: {
1006
+ hash: "0bb5ef0935f2d6fb31d2-slog3cine",
1007
+ sha256: "b5f49e0a48f59512a50ec7db512f164dc5667b96b3598cb8a4f561ed1da0dbe7"
1008
+ }
1009
+ }
1010
+ },
1011
+ {
1012
+ number: 49,
1013
+ id: "stock/PhotoBW/High ISO/T-MAX 3200.fbfilmneg",
1014
+ hash: "1571a8b82ac80b2bf7ff",
1015
+ sha256: "95da1d2edddf50bc8698b09f212c19c297cf36a8304e7c90c9e2be85f2cce8bd",
1016
+ kind: "stock",
1017
+ collection: "black and white negative",
1018
+ group: "fast",
1019
+ label: "t-max 3200",
1020
+ tables: {
1021
+ logc4: {
1022
+ hash: "1571a8b82ac80b2bf7ff-logc4",
1023
+ sha256: "ecfbbd8b79983078cb853574b9264597bd2f7cc8f446ab8a4507ce5aadaa9095"
1024
+ },
1025
+ slog3cine: {
1026
+ hash: "1571a8b82ac80b2bf7ff-slog3cine",
1027
+ sha256: "de9fe45107208cf18db3108470b81e74c06354dac0db624066800e06af3aea4f"
1028
+ }
1029
+ }
1030
+ },
1031
+ {
1032
+ number: 50,
1033
+ id: "stock/PhotoBW/High ISO/Delta 3200.fbfilmneg",
1034
+ hash: "4c340b0c7f42d917e66f",
1035
+ sha256: "8295d557f4e4eca9711e21334b83fde2b4b03a2765d1ef23309b6f2a7917a917",
1036
+ kind: "stock",
1037
+ collection: "black and white negative",
1038
+ group: "fast",
1039
+ label: "delta 3200",
1040
+ tables: {
1041
+ logc4: {
1042
+ hash: "4c340b0c7f42d917e66f-logc4",
1043
+ sha256: "0450330fe2cf6c85bbb22d5e6d4dea923219a91f8a753317f6f3e234e22dcaa3"
1044
+ },
1045
+ slog3cine: {
1046
+ hash: "4c340b0c7f42d917e66f-slog3cine",
1047
+ sha256: "17282b8d8c236a0bcca6d948c0bb211bb4c257a1913201da10283bc179224765"
1048
+ }
1049
+ }
1050
+ },
1051
+ {
1052
+ number: 51,
1053
+ id: "stock/PhotoBW/Low ISO/Acros 100II.fbfilmneg",
1054
+ hash: "cbd839be59a0a508fb8f",
1055
+ sha256: "cb63d53e511569b86600a08053f0dbf503e0a6d8fd2deeb59d4298e5af96cc1e",
1056
+ kind: "stock",
1057
+ collection: "black and white negative",
1058
+ group: "slow",
1059
+ label: "acros 100ii",
1060
+ tables: {
1061
+ logc4: {
1062
+ hash: "cbd839be59a0a508fb8f-logc4",
1063
+ sha256: "9e7612d978dcf69f0b8f516c792da24417d32db52f421c7477caaf69bbbfeded"
1064
+ },
1065
+ slog3cine: {
1066
+ hash: "cbd839be59a0a508fb8f-slog3cine",
1067
+ sha256: "4cc57b907828362c0bb59e93660e234318c329e7b831d2f0016ac381397b4324"
1068
+ }
1069
+ }
1070
+ },
1071
+ {
1072
+ number: 52,
1073
+ id: "stock/PhotoBW/Low ISO/FP4 125.fbfilmneg",
1074
+ hash: "ec4978838b35b503bf0c",
1075
+ sha256: "6e65df53d13f683fbd1fe2c48039252a3b3f6e6175c2155d4ad69f809bf7bfd9",
1076
+ kind: "stock",
1077
+ collection: "black and white negative",
1078
+ group: "slow",
1079
+ label: "fp4 125",
1080
+ tables: {
1081
+ logc4: {
1082
+ hash: "ec4978838b35b503bf0c-logc4",
1083
+ sha256: "f10003f5126bac5ae8275a9934c6a19b2ddd8c6de9513006a23456cf32f21d2a"
1084
+ },
1085
+ slog3cine: {
1086
+ hash: "ec4978838b35b503bf0c-slog3cine",
1087
+ sha256: "61fcceebd980eff5fc7bc5230d19a3d29bc2c987d3b109099d3231d71b6f512e"
1088
+ }
1089
+ }
1090
+ },
1091
+ {
1092
+ number: 53,
1093
+ id: "stock/PhotoBW/Low ISO/T-MAX 100.fbfilmneg",
1094
+ hash: "8d4afdf51b4abcc95c69",
1095
+ sha256: "458146bb6a8bf7f0ecec71d28f9254c726560f88e9eca53efaa66cecc900d265",
1096
+ kind: "stock",
1097
+ collection: "black and white negative",
1098
+ group: "slow",
1099
+ label: "t-max 100",
1100
+ tables: {
1101
+ logc4: {
1102
+ hash: "8d4afdf51b4abcc95c69-logc4",
1103
+ sha256: "20196bd247cfab9f9e6d9cbb79972650ecfe439fe8de0c08bea56834a7a6f785"
1104
+ },
1105
+ slog3cine: {
1106
+ hash: "8d4afdf51b4abcc95c69-slog3cine",
1107
+ sha256: "1cec3a29383a51b914827634cb7265b1f3cb5a654750df1c4fdecea773efc1f4"
1108
+ }
1109
+ }
1110
+ },
1111
+ {
1112
+ number: 54,
1113
+ id: "stock/PhotoBW/Low ISO/PanF 50.fbfilmneg",
1114
+ hash: "d66760fc9df2eef31948",
1115
+ sha256: "435301549b1f67756fb5c199ba433d103bed9a255c19f9dac95a17658539e522",
1116
+ kind: "stock",
1117
+ collection: "black and white negative",
1118
+ group: "slow",
1119
+ label: "pan f 50",
1120
+ tables: {
1121
+ logc4: {
1122
+ hash: "d66760fc9df2eef31948-logc4",
1123
+ sha256: "090407f5d39f3a275a89503aaedaa155061381de63b57041fcfe113216178421"
1124
+ },
1125
+ slog3cine: {
1126
+ hash: "d66760fc9df2eef31948-slog3cine",
1127
+ sha256: "c42f69cb8d6989255ffbefc2df46e583aeedf5105af77f2a226ca458864c6ec3"
1128
+ }
1129
+ }
1130
+ },
1131
+ {
1132
+ number: 55,
1133
+ id: "stock/PhotoBW/Low ISO/CineStill XX 250.fbfilmneg",
1134
+ hash: "93509be7dd8e65c2b385",
1135
+ sha256: "57a95c33826127d995ae1789952dc5c5a7089e69f2f36e429a70e6712e27da56",
1136
+ kind: "stock",
1137
+ collection: "black and white negative",
1138
+ group: "slow",
1139
+ label: "cinestill xx 250",
1140
+ tables: {
1141
+ logc4: {
1142
+ hash: "93509be7dd8e65c2b385-logc4",
1143
+ sha256: "b2ea65f23778b570d8e6db3ec96f3a17184d3b38fc2e1f12932c1ca543bafff4"
1144
+ },
1145
+ slog3cine: {
1146
+ hash: "93509be7dd8e65c2b385-slog3cine",
1147
+ sha256: "8d5af6e18b8fc41c298a12b43e721a3c3a1a6520ae9d7cf4b60f14c2b362aefa"
1148
+ }
1149
+ }
1150
+ },
1151
+ {
1152
+ number: 56,
1153
+ id: "stock/PhotoBW/High Contrast/Delta 100.fbfilmneg",
1154
+ hash: "830844c886c0e9bf833d",
1155
+ sha256: "721afdd1bc074111c6ddbde9347bd3698d73046d74613323b6895614f4b5d66b",
1156
+ kind: "stock",
1157
+ collection: "black and white negative",
1158
+ group: "high contrast",
1159
+ label: "delta 100",
1160
+ tables: {
1161
+ logc4: {
1162
+ hash: "830844c886c0e9bf833d-logc4",
1163
+ sha256: "d445ef21910889ab36db1313cd5ea4773b735af0e4d129508734db6b9ab7bff6"
1164
+ },
1165
+ slog3cine: {
1166
+ hash: "830844c886c0e9bf833d-slog3cine",
1167
+ sha256: "c59104a255b7ad0b10756f31af9126792a5add203eeca0fcbd63cfa82678d001"
1168
+ }
1169
+ }
1170
+ },
1171
+ {
1172
+ number: 57,
1173
+ id: "stock/PhotoBW/High Contrast/Ortho 80.fbfilmneg",
1174
+ hash: "fe924a23dc3c01cfbfa3",
1175
+ sha256: "d91a0999eb4aa341c152ad989ef7979cefba4276f0436cea63bf9a55496b6373",
1176
+ kind: "stock",
1177
+ collection: "black and white negative",
1178
+ group: "high contrast",
1179
+ label: "ortho 80",
1180
+ tables: {
1181
+ logc4: {
1182
+ hash: "fe924a23dc3c01cfbfa3-logc4",
1183
+ sha256: "bba5d2a83f2e7cf0bd9da591b3f594deacb12931bab92ea227db66c72f294aed"
1184
+ },
1185
+ slog3cine: {
1186
+ hash: "fe924a23dc3c01cfbfa3-slog3cine",
1187
+ sha256: "6e3120cf56a56b1978087eb29c15c815b30ee33f30bb6a9a6744bb04bd7ac708"
1188
+ }
1189
+ }
1190
+ },
1191
+ {
1192
+ number: 58,
1193
+ id: "stock/PhotoBW/High Contrast/Monolit 3 (Ortho).fbfilmneg",
1194
+ hash: "0b3664d1c804807a2a86",
1195
+ sha256: "7328dc985f64a6280d70fea7a5e0e22a0dd0ad68218ac718ca4c59bf8d5c255a",
1196
+ kind: "stock",
1197
+ collection: "black and white negative",
1198
+ group: "high contrast",
1199
+ label: "monolit 3 ortho",
1200
+ tables: {
1201
+ logc4: {
1202
+ hash: "0b3664d1c804807a2a86-logc4",
1203
+ sha256: "ed98e07b03d98df513a38c9067fa5107c3f3a21e203ded87dc80b21d31667436"
1204
+ },
1205
+ slog3cine: {
1206
+ hash: "0b3664d1c804807a2a86-slog3cine",
1207
+ sha256: "abd8e16c295a571af61aa564c0b728041019059fba49a7066168af98c327c9db"
1208
+ }
1209
+ }
1210
+ },
1211
+ {
1212
+ number: 59,
1213
+ id: "stock/PhotoReversal/Default/Ektachrome 100.fbfilmneg",
1214
+ hash: "df3fa738d2990c6895ac",
1215
+ sha256: "2d647cace6241dacda9262c2218bdd5b5b6f4f2508836c80d3a308e903ce3d30",
1216
+ kind: "stock",
1217
+ collection: "slide film",
1218
+ group: "",
1219
+ label: "ektachrome 100",
1220
+ tables: {
1221
+ logc4: {
1222
+ hash: "df3fa738d2990c6895ac-logc4",
1223
+ sha256: "defbdaaacbb12f107c2b23f0cc65900d160279c71c7433a8dd34aeccad778ac2"
1224
+ },
1225
+ slog3cine: {
1226
+ hash: "df3fa738d2990c6895ac-slog3cine",
1227
+ sha256: "87b4b1ad94a2b321c6fe297f788515ede8171b72d76d43b0eef31f089e699e59"
1228
+ }
1229
+ }
1230
+ },
1231
+ {
1232
+ number: 60,
1233
+ id: "stock/PhotoReversal/Default/Velvia 100.fbfilmneg",
1234
+ hash: "6c8e2ae3d5460b683667",
1235
+ sha256: "ccc8c446c5bc5eb0cb85520a7cbe1cb9678c374ebfc19f1ebdd23f13f145e300",
1236
+ kind: "stock",
1237
+ collection: "slide film",
1238
+ group: "",
1239
+ label: "velvia 100",
1240
+ tables: {
1241
+ logc4: {
1242
+ hash: "6c8e2ae3d5460b683667-logc4",
1243
+ sha256: "0fbac2290d9968b5365e898404ba826cebb5a7f49aa64f52d347273300fc8b60"
1244
+ },
1245
+ slog3cine: {
1246
+ hash: "6c8e2ae3d5460b683667-slog3cine",
1247
+ sha256: "dbb272749e76e10f541f9e20b42103e9d4f46d1ac3ec959b71781379ddeea1d9"
1248
+ }
1249
+ }
1250
+ },
1251
+ {
1252
+ number: 61,
1253
+ id: "stock/PhotoReversal/Default/Velvia 50.fbfilmneg",
1254
+ hash: "7be6303ad7f58d4d373e",
1255
+ sha256: "d11507543860e9a75a293a85b254926467dd811359081893fab78726aa776f0c",
1256
+ kind: "stock",
1257
+ collection: "slide film",
1258
+ group: "",
1259
+ label: "velvia 50",
1260
+ tables: {
1261
+ logc4: {
1262
+ hash: "7be6303ad7f58d4d373e-logc4",
1263
+ sha256: "b31c4bd661051c1ef4a3bd063e29b4256617348dc3f9abb11840b311ea98b9e7"
1264
+ },
1265
+ slog3cine: {
1266
+ hash: "7be6303ad7f58d4d373e-slog3cine",
1267
+ sha256: "3834b7ef7f8a2db7c05c073aaa17e2f3d39d3d1d0a5fd84485f095070a8b138a"
1268
+ }
1269
+ }
1270
+ },
1271
+ {
1272
+ number: 62,
1273
+ id: "stock/PhotoReversal/Default/Provia 100F.fbfilmneg",
1274
+ hash: "0b0c68912f7e500ce1f6",
1275
+ sha256: "63fa05e22bfc0b51e740072761a34474310105f4835dfe5bbc63a5e9dd67545c",
1276
+ kind: "stock",
1277
+ collection: "slide film",
1278
+ group: "",
1279
+ label: "provia 100f",
1280
+ tables: {
1281
+ logc4: {
1282
+ hash: "0b0c68912f7e500ce1f6-logc4",
1283
+ sha256: "ad2d4366ff909654c74f87ae53e6d3cd12b2cbd46b0a9aea5289769f361ea3bd"
1284
+ },
1285
+ slog3cine: {
1286
+ hash: "0b0c68912f7e500ce1f6-slog3cine",
1287
+ sha256: "ed523ed814a280e7b8a6bfd847a020c5e94a2788727ec4915186feb8c3d838d7"
1288
+ }
1289
+ }
1290
+ },
1291
+ {
1292
+ number: 63,
1293
+ id: "stock/PhotoReversal/Default/Instax Color.fbfilmneg",
1294
+ hash: "3ccea9e523a25f683011",
1295
+ sha256: "96c7c5ade8b9e41303353903a31aceebc3ba0106d53e1c33d5caace2a8faf2b4",
1296
+ kind: "stock",
1297
+ collection: "slide film",
1298
+ group: "",
1299
+ label: "instax color",
1300
+ tables: {
1301
+ logc4: {
1302
+ hash: "3ccea9e523a25f683011-logc4",
1303
+ sha256: "3f698af32a6f5159cdc7b0e474d6f21fbb8d82d3cec9cd1d88e46e72d2343874"
1304
+ },
1305
+ slog3cine: {
1306
+ hash: "3ccea9e523a25f683011-slog3cine",
1307
+ sha256: "7485f4e2117bf608fb7486669abeef80fd82e69cc2655ef44bcbfe77ee3e6e30"
1308
+ }
1309
+ }
1310
+ },
1311
+ {
1312
+ number: 64,
1313
+ id: "stock/PhotoReversal/Default/Instax Monochrome.fbfilmneg",
1314
+ hash: "91377ee33a6217f78b21",
1315
+ sha256: "39b20deccce70a71aef34b6c8bab022ab65434f4930b75ce8567ed20552c1195",
1316
+ kind: "stock",
1317
+ collection: "slide film",
1318
+ group: "",
1319
+ label: "instax monochrome",
1320
+ tables: {
1321
+ logc4: {
1322
+ hash: "91377ee33a6217f78b21-logc4",
1323
+ sha256: "0fbdb7ba979642d8120d1e128be595ea324f76b21dc94b41cab5b965e9da9129"
1324
+ },
1325
+ slog3cine: {
1326
+ hash: "91377ee33a6217f78b21-slog3cine",
1327
+ sha256: "2089188df2505e26533408861d2d318ad24e27551d183d7dba98f8ec3e00637f"
1328
+ }
1329
+ }
1330
+ },
1331
+ {
1332
+ number: 65,
1333
+ id: "look/1 Clean & Commercial/video.fblook",
1334
+ hash: "d5f23a096058cd3cc682",
1335
+ sha256: "0fb2859c9d4aa45886725e7851e5187080db2198da76ec44a9ebd7935a24c922",
1336
+ kind: "look",
1337
+ collection: "commercial",
1338
+ group: "",
1339
+ label: "broadcast",
1340
+ tables: {
1341
+ logc4: {
1342
+ hash: "d5f23a096058cd3cc682-logc4",
1343
+ sha256: "6447fc2fcef830696e8eb869ad90b5da0b8c23b22144b8917c1f72899f985d13"
1344
+ },
1345
+ slog3cine: {
1346
+ hash: "d5f23a096058cd3cc682-slog3cine",
1347
+ sha256: "88efe861f730a7fe3f6ce3d7a4336e48b82ba1a341353952341fdfbb2677a42b"
1348
+ }
1349
+ }
1350
+ },
1351
+ {
1352
+ number: 66,
1353
+ id: "look/1 Clean & Commercial/cine_like.fblook",
1354
+ hash: "b994bde23b45792033f2",
1355
+ sha256: "ce975f810fa67de34197725a0abad1935a19849296249a9262f0050dd60aca63",
1356
+ kind: "look",
1357
+ collection: "commercial",
1358
+ group: "",
1359
+ label: "cinema",
1360
+ tables: {
1361
+ logc4: {
1362
+ hash: "b994bde23b45792033f2-logc4",
1363
+ sha256: "68ff591cd0efd313885e8c1d8e16b7ce7d46f0957fe407c85a24145bafd186a2"
1364
+ },
1365
+ slog3cine: {
1366
+ hash: "b994bde23b45792033f2-slog3cine",
1367
+ sha256: "d04a7968a97932f4b5d232ba4e87bbc1e075d0438332f545af1a4cc9b9607d6c"
1368
+ }
1369
+ }
1370
+ },
1371
+ {
1372
+ number: 67,
1373
+ id: "look/1 Clean & Commercial/telecine_like.fblook",
1374
+ hash: "dafa166447af00368af8",
1375
+ sha256: "a614e60718037a3fa7cab21d0663e54f31480f9339a985361c8f83429ea68fa4",
1376
+ kind: "look",
1377
+ collection: "commercial",
1378
+ group: "",
1379
+ label: "dailies",
1380
+ tables: {
1381
+ logc4: {
1382
+ hash: "dafa166447af00368af8-logc4",
1383
+ sha256: "e2d76bccaf1e8873819e497dcd31c59f13d3b6b779b55b38837b8515008f05e3"
1384
+ },
1385
+ slog3cine: {
1386
+ hash: "dafa166447af00368af8-slog3cine",
1387
+ sha256: "3bccc724b7bfb1f59556d161a5617d8d6c1212e52a0af36bf1ce64d2e13c97af"
1388
+ }
1389
+ }
1390
+ },
1391
+ {
1392
+ number: 68,
1393
+ id: "look/1 Clean & Commercial/cine_like_beauty.fblook",
1394
+ hash: "664dcc1e5ff63b7a3602",
1395
+ sha256: "c69f05c7774dc8e22db7741a4cae19ada672e656550e014c3c5bd3f8dc5bfae2",
1396
+ kind: "look",
1397
+ collection: "commercial",
1398
+ group: "",
1399
+ label: "beauty",
1400
+ tables: {
1401
+ logc4: {
1402
+ hash: "664dcc1e5ff63b7a3602-logc4",
1403
+ sha256: "98af8cf53cb5d5b5d16b42aef52017c99fe7fa7d15d9bfad5015a7c873243604"
1404
+ },
1405
+ slog3cine: {
1406
+ hash: "664dcc1e5ff63b7a3602-slog3cine",
1407
+ sha256: "1c2000e5567bdb056274ef81e6f3103e9adc58027f37d7cc1e8a1c8202ecfa9f"
1408
+ }
1409
+ }
1410
+ },
1411
+ {
1412
+ number: 69,
1413
+ id: "look/1 Clean & Commercial/cine_like_pop.fblook",
1414
+ hash: "d32059d2b20806c100ce",
1415
+ sha256: "043cb70e56bd75c87f074568d5da9c04f8641d8e79dbd5a3a0dd3bc6d4d65eea",
1416
+ kind: "look",
1417
+ collection: "commercial",
1418
+ group: "",
1419
+ label: "product",
1420
+ tables: {
1421
+ logc4: {
1422
+ hash: "d32059d2b20806c100ce-logc4",
1423
+ sha256: "606f83ad1ac58d3196c3755398f5dff0f47b5ce71fd62cd0811120707a72d9be"
1424
+ },
1425
+ slog3cine: {
1426
+ hash: "d32059d2b20806c100ce-slog3cine",
1427
+ sha256: "388e426bcea5c52d46e99ccdaa511c1d19700034069f00d43968c554b9241e3e"
1428
+ }
1429
+ }
1430
+ },
1431
+ {
1432
+ number: 70,
1433
+ id: "look/1 Clean & Commercial/photo_like_pop.fblook",
1434
+ hash: "ec965532f423dcebf743",
1435
+ sha256: "0fbac8c797145f6d06ccca198be486aac883b0528dd46b46352e62351ef6b651",
1436
+ kind: "look",
1437
+ collection: "commercial",
1438
+ group: "",
1439
+ label: "packshot",
1440
+ tables: {
1441
+ logc4: {
1442
+ hash: "ec965532f423dcebf743-logc4",
1443
+ sha256: "d501699d3776a72addaff1f3e9d86b2ae29348674ce6d1aa7d2a3e6d7068d9f2"
1444
+ },
1445
+ slog3cine: {
1446
+ hash: "ec965532f423dcebf743-slog3cine",
1447
+ sha256: "c3b4759c95b26e0d98646a9a89400cac757f3e35fe4bfe4049b7e489860845a3"
1448
+ }
1449
+ }
1450
+ },
1451
+ {
1452
+ number: 71,
1453
+ id: "look/2 Idealized 35mm/standard.fblook",
1454
+ hash: "7a74db9c3c4b3bb33627",
1455
+ sha256: "20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811",
1456
+ kind: "look",
1457
+ collection: "35mm negative",
1458
+ group: "",
1459
+ label: "standard",
1460
+ tables: {
1461
+ logc4: {
1462
+ hash: "7a74db9c3c4b3bb33627-logc4",
1463
+ sha256: "a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"
1464
+ },
1465
+ slog3cine: {
1466
+ hash: "7a74db9c3c4b3bb33627-slog3cine",
1467
+ sha256: "01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"
1468
+ }
1469
+ }
1470
+ },
1471
+ {
1472
+ number: 72,
1473
+ id: "look/2 Idealized 35mm/extended.fblook",
1474
+ hash: "8620eb33a2388c072557",
1475
+ sha256: "2e606fb12130af9ac49336fd83bbf123577ad3683dc2a7cebf3ca5abf24fb772",
1476
+ kind: "look",
1477
+ collection: "35mm negative",
1478
+ group: "",
1479
+ label: "latitude",
1480
+ tables: {
1481
+ logc4: {
1482
+ hash: "8620eb33a2388c072557-logc4",
1483
+ sha256: "2fbac3933b5214d5aa38034c2767a4a7162ee97ea8abc6798b58b000a3deac4e"
1484
+ },
1485
+ slog3cine: {
1486
+ hash: "8620eb33a2388c072557-slog3cine",
1487
+ sha256: "eebf4d3d7cd0bdd1dce965fe7da02c685a7c888aa86b4451ad87c93def7eabab"
1488
+ }
1489
+ }
1490
+ },
1491
+ {
1492
+ number: 73,
1493
+ id: "look/2 Idealized 35mm/rich.fblook",
1494
+ hash: "4da55be1202c100cd58d",
1495
+ sha256: "b2bb8f07d3541ea7172f6fac5bbfbe12f0e041599a7d64f802365589f8f7f102",
1496
+ kind: "look",
1497
+ collection: "35mm negative",
1498
+ group: "",
1499
+ label: "dense",
1500
+ tables: {
1501
+ logc4: {
1502
+ hash: "4da55be1202c100cd58d-logc4",
1503
+ sha256: "e5f97cc9c7ece67fdf8f103dbe95cc0e1bcff44d1abeb9d914dd2a3246d4f4c0"
1504
+ },
1505
+ slog3cine: {
1506
+ hash: "4da55be1202c100cd58d-slog3cine",
1507
+ sha256: "cbf5d14eee61c9585d949face1c2b1da282cffa66c60b075db1f65d155145d70"
1508
+ }
1509
+ }
1510
+ },
1511
+ {
1512
+ number: 74,
1513
+ id: "look/2 Idealized 35mm/neutral.fblook",
1514
+ hash: "4b71ed8e0c53638831fd",
1515
+ sha256: "03fc174fbe34b4d9bbc0896db235c507800711bab17d1a06bea486d13543cfe1",
1516
+ kind: "look",
1517
+ collection: "35mm negative",
1518
+ group: "",
1519
+ label: "neutral",
1520
+ tables: {
1521
+ logc4: {
1522
+ hash: "4b71ed8e0c53638831fd-logc4",
1523
+ sha256: "4a5bc48f0bb70e2caac2ac9bdf037fae731adf2358f9eb87fb5e87274f40d8ab"
1524
+ },
1525
+ slog3cine: {
1526
+ hash: "4b71ed8e0c53638831fd-slog3cine",
1527
+ sha256: "11fd83e422bf130962551bbdc137514cbf94c6fdbefbdb71e8320e9f4455b7ef"
1528
+ }
1529
+ }
1530
+ },
1531
+ {
1532
+ number: 75,
1533
+ id: "look/2 Idealized 35mm/proimage.fblook",
1534
+ hash: "de8ad75a1a2cae5af794",
1535
+ sha256: "9d40662d863b147c16b765ce344dfd9ef30b3535ecdee46fb805980764761d0e",
1536
+ kind: "look",
1537
+ collection: "35mm negative",
1538
+ group: "",
1539
+ label: "restrained",
1540
+ tables: {
1541
+ logc4: {
1542
+ hash: "de8ad75a1a2cae5af794-logc4",
1543
+ sha256: "5e78226b6e20d0f3ca3232f071bae57a76d1fdaf5ece3637a4849b6ff3a15d3a"
1544
+ },
1545
+ slog3cine: {
1546
+ hash: "de8ad75a1a2cae5af794-slog3cine",
1547
+ sha256: "fd141039022eaf0680870df7977f2f2f2ca708a00a1bbec37eee5525859b4772"
1548
+ }
1549
+ }
1550
+ },
1551
+ {
1552
+ number: 76,
1553
+ id: "look/2 Idealized 35mm/reversal.fblook",
1554
+ hash: "1b5ef1413df1448377a5",
1555
+ sha256: "085c64e8656bdc72f6df3ea87cbdc3cecad5ea2822ef7bdbf785f1a0b5ec6af4",
1556
+ kind: "look",
1557
+ collection: "35mm negative",
1558
+ group: "",
1559
+ label: "reversal",
1560
+ tables: {
1561
+ logc4: {
1562
+ hash: "1b5ef1413df1448377a5-logc4",
1563
+ sha256: "26f045fe3350c28e5c869318e05a08fbad34d254cfd01e6a43c58590a387cca7"
1564
+ },
1565
+ slog3cine: {
1566
+ hash: "1b5ef1413df1448377a5-slog3cine",
1567
+ sha256: "3e7bdda5552525ff585f6485161d735b87669d2a7b51dfaa9ce45fc65bbe05fe"
1568
+ }
1569
+ }
1570
+ },
1571
+ {
1572
+ number: 77,
1573
+ id: "look/3 Full 35mm/full.fblook",
1574
+ hash: "bde7a8dae9f0029c08a7",
1575
+ sha256: "7a1ed86c0b48c9eab14cdc78864380c11ee7d80d2e7520748cd64fdccd18d922",
1576
+ kind: "look",
1577
+ collection: "35mm print",
1578
+ group: "",
1579
+ label: "answer print",
1580
+ tables: {
1581
+ logc4: {
1582
+ hash: "bde7a8dae9f0029c08a7-logc4",
1583
+ sha256: "35b0e18b70d51fc7ef711d579daa41ba089d46e017e144d2ff2d0a4ac50fe875"
1584
+ },
1585
+ slog3cine: {
1586
+ hash: "bde7a8dae9f0029c08a7-slog3cine",
1587
+ sha256: "616e96e27643fd36122aa01a598ba703ed4dda1a27b6c5336d93e12516600e55"
1588
+ }
1589
+ }
1590
+ },
1591
+ {
1592
+ number: 78,
1593
+ id: "look/3 Full 35mm/telecine.fblook",
1594
+ hash: "e3069ca7edaf6e8a6871",
1595
+ sha256: "d4c1cc26898c7fb3a28d4c9f309ae77a86c2b0690c1abaf1abbcdfc2cf0bd656",
1596
+ kind: "look",
1597
+ collection: "35mm print",
1598
+ group: "",
1599
+ label: "telecine",
1600
+ tables: {
1601
+ logc4: {
1602
+ hash: "e3069ca7edaf6e8a6871-logc4",
1603
+ sha256: "047c850627c7b61646557dce1e1b3a9bf0b98a2da844d2bd7e57127e4feed76a"
1604
+ },
1605
+ slog3cine: {
1606
+ hash: "e3069ca7edaf6e8a6871-slog3cine",
1607
+ sha256: "f6f0ac7f8fe900484f598e803a6a6f88da6705f747a426552aba5a11a9edb59c"
1608
+ }
1609
+ }
1610
+ },
1611
+ {
1612
+ number: 79,
1613
+ id: "look/3 Full 35mm/tungsten.fblook",
1614
+ hash: "793e629dd23f07625a52",
1615
+ sha256: "ae60b8cdbefcd0b6809e89c6267f42dda5354b919f434c16d5603859e07a94b5",
1616
+ kind: "look",
1617
+ collection: "35mm print",
1618
+ group: "",
1619
+ label: "tungsten",
1620
+ tables: {
1621
+ logc4: {
1622
+ hash: "793e629dd23f07625a52-logc4",
1623
+ sha256: "f12a449cf02d547d67b7ce97dc5a54848dd70dd4fcb2f8989fe66536dc492b5f"
1624
+ },
1625
+ slog3cine: {
1626
+ hash: "793e629dd23f07625a52-slog3cine",
1627
+ sha256: "e9935030e4d08ee0756c8415473486069edbf270278fcc58373f67cc46734488"
1628
+ }
1629
+ }
1630
+ },
1631
+ {
1632
+ number: 80,
1633
+ id: "look/3 Full 35mm/warm.fblook",
1634
+ hash: "d1afcf1071126af0ea36",
1635
+ sha256: "4f3d64b8f49481c34c6d75eda843a0966b6d4bfd20fe12456aba81553def5b93",
1636
+ kind: "look",
1637
+ collection: "35mm print",
1638
+ group: "",
1639
+ label: "warm print",
1640
+ tables: {
1641
+ logc4: {
1642
+ hash: "d1afcf1071126af0ea36-logc4",
1643
+ sha256: "c6d6605131784961e58a035a50cb62d45a4fdc1ae3fb1cb14123f73caa20be86"
1644
+ },
1645
+ slog3cine: {
1646
+ hash: "d1afcf1071126af0ea36-slog3cine",
1647
+ sha256: "a4661000ab05dbe7c124e8708eea42158a1fe09eb2920c9d03f91a82c9ebf8fe"
1648
+ }
1649
+ }
1650
+ },
1651
+ {
1652
+ number: 81,
1653
+ id: "look/3 Full 35mm/bleach.fblook",
1654
+ hash: "e332d3996f57fbaae72b",
1655
+ sha256: "a7c9159808c235f331dd44d6dbce638ae5000c4605de0413f316f1918b8ca602",
1656
+ kind: "look",
1657
+ collection: "35mm print",
1658
+ group: "",
1659
+ label: "silver retention",
1660
+ tables: {
1661
+ logc4: {
1662
+ hash: "e332d3996f57fbaae72b-logc4",
1663
+ sha256: "57d4e5e0b52bd2e219bac8e02a503eda4f3b000c9c793a70bad2dad48ac2350a"
1664
+ },
1665
+ slog3cine: {
1666
+ hash: "e332d3996f57fbaae72b-slog3cine",
1667
+ sha256: "db5735b664e15cfbdfda63b0773008d11f170394fc0538cad450ce2398eb3a9b"
1668
+ }
1669
+ }
1670
+ },
1671
+ {
1672
+ number: 82,
1673
+ id: "look/3 Full 35mm/chill.fblook",
1674
+ hash: "ea2011e1dd170763346c",
1675
+ sha256: "1f852c23916f35a53101922aa97bf1496a7bbf497227dd5adaa05041686e3c5f",
1676
+ kind: "look",
1677
+ collection: "35mm print",
1678
+ group: "",
1679
+ label: "cool print",
1680
+ tables: {
1681
+ logc4: {
1682
+ hash: "ea2011e1dd170763346c-logc4",
1683
+ sha256: "11a174a275ba60484b3cf46912331b861c8299e8418e727c709c96cddf9ef9a4"
1684
+ },
1685
+ slog3cine: {
1686
+ hash: "ea2011e1dd170763346c-slog3cine",
1687
+ sha256: "8007cf44ab45aab5de5a9c00d605b540c71fcdf0bf544b312011885c012072a5"
1688
+ }
1689
+ }
1690
+ },
1691
+ {
1692
+ number: 83,
1693
+ id: "look/4 16mm/standard_16mm.fblook",
1694
+ hash: "c925caba596086362636",
1695
+ sha256: "20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811",
1696
+ kind: "look",
1697
+ collection: "16mm",
1698
+ group: "",
1699
+ label: "documentary",
1700
+ tables: {
1701
+ logc4: {
1702
+ hash: "c925caba596086362636-logc4",
1703
+ sha256: "a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"
1704
+ },
1705
+ slog3cine: {
1706
+ hash: "c925caba596086362636-slog3cine",
1707
+ sha256: "01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"
1708
+ }
1709
+ }
1710
+ },
1711
+ {
1712
+ number: 84,
1713
+ id: "look/4 16mm/spicy.fblook",
1714
+ hash: "96722d8fea88d16f44e6",
1715
+ sha256: "cf977b4ad1d284d543a620a06a948bbf3c18e9c1a422a51212f5450806526ece",
1716
+ kind: "look",
1717
+ collection: "16mm",
1718
+ group: "",
1719
+ label: "saturated",
1720
+ tables: {
1721
+ logc4: {
1722
+ hash: "96722d8fea88d16f44e6-logc4",
1723
+ sha256: "569ac53061295652bc0ffb15470b11bdaa2d451461bde0dd49c43f4e0c95ed8f"
1724
+ },
1725
+ slog3cine: {
1726
+ hash: "96722d8fea88d16f44e6-slog3cine",
1727
+ sha256: "38325af0627c9b6b488e0989204f93942bf24361370422cda84fde669b3ec8c6"
1728
+ }
1729
+ }
1730
+ },
1731
+ {
1732
+ number: 85,
1733
+ id: "look/4 16mm/notmoonlight.fblook",
1734
+ hash: "1bc5b2876e983f9abd58",
1735
+ sha256: "c8154c6b3299af6b4b8f6250a39b7baf80f8c20ef462086272a05a41fdc12ca2",
1736
+ kind: "look",
1737
+ collection: "16mm",
1738
+ group: "",
1739
+ label: "day for night",
1740
+ tables: {
1741
+ logc4: {
1742
+ hash: "1bc5b2876e983f9abd58-logc4",
1743
+ sha256: "55450587e41a53b2fbfd9ee6e0f55ae423d8b03b7567e34edac9df209bcb134d"
1744
+ },
1745
+ slog3cine: {
1746
+ hash: "1bc5b2876e983f9abd58-slog3cine",
1747
+ sha256: "595c89c6617ecd8152aeb0584339cd3f66a8c454491c8b2f96c6760423a947de"
1748
+ }
1749
+ }
1750
+ },
1751
+ {
1752
+ number: 86,
1753
+ id: "look/4 16mm/flat scan.fblook",
1754
+ hash: "6bbded22dcdba51d1da0",
1755
+ sha256: "de67d8f582c5f011b459b592d9312cb9c4036b71774edecbe2023a9fbd2925e0",
1756
+ kind: "look",
1757
+ collection: "16mm",
1758
+ group: "",
1759
+ label: "flat scan",
1760
+ tables: {
1761
+ logc4: {
1762
+ hash: "6bbded22dcdba51d1da0-logc4",
1763
+ sha256: "072fb36276368fabb7128af202c5b0657a40ce7be32efd5c2f8eb03cfa0bd64d"
1764
+ },
1765
+ slog3cine: {
1766
+ hash: "6bbded22dcdba51d1da0-slog3cine",
1767
+ sha256: "ca084c654162c9b8588cfe1bae67c62c07875215fc91e4e71840f9956a468165"
1768
+ }
1769
+ }
1770
+ },
1771
+ {
1772
+ number: 87,
1773
+ id: "look/4 16mm/indie scan.fblook",
1774
+ hash: "4dc360d9777f84b038c7",
1775
+ sha256: "d3c645f393e5f63812b8067fbfe5dcd032ec71b051ab9a255371ee0c877e2e86",
1776
+ kind: "look",
1777
+ collection: "16mm",
1778
+ group: "",
1779
+ label: "indie",
1780
+ tables: {
1781
+ logc4: {
1782
+ hash: "4dc360d9777f84b038c7-logc4",
1783
+ sha256: "5ded82c763469d7cd28af7e6f4f0c64a28869f6f119bd8fcc51fc09a1a89765c"
1784
+ },
1785
+ slog3cine: {
1786
+ hash: "4dc360d9777f84b038c7-slog3cine",
1787
+ sha256: "ce5c2e35d511c2d76416540bd997bdf99ac45e7f59a2bdd808026718244ac97a"
1788
+ }
1789
+ }
1790
+ },
1791
+ {
1792
+ number: 88,
1793
+ id: "look/4 16mm/scrubs.fblook",
1794
+ hash: "354181100a0eb296a46f",
1795
+ sha256: "28a392ffe91ed0e6f87daee6b3c177d4b6b3a3442705023db0b88ddefe634062",
1796
+ kind: "look",
1797
+ collection: "16mm",
1798
+ group: "",
1799
+ label: "tape transfer",
1800
+ tables: {
1801
+ logc4: {
1802
+ hash: "354181100a0eb296a46f-logc4",
1803
+ sha256: "7955fc62f1b935b7b931a7cc1e7e45f18390bb5c9a8319e4cf6d41555f013130"
1804
+ },
1805
+ slog3cine: {
1806
+ hash: "354181100a0eb296a46f-slog3cine",
1807
+ sha256: "00e458e1de34b8270dabbaa6011b4e665264fa174ad4bdbcd62463467140ad55"
1808
+ }
1809
+ }
1810
+ },
1811
+ {
1812
+ number: 89,
1813
+ id: "look/5 8mm/typical.fblook",
1814
+ hash: "1748cb5dba4ee4b6cf14",
1815
+ sha256: "20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811",
1816
+ kind: "look",
1817
+ collection: "super 8",
1818
+ group: "",
1819
+ label: "home movie",
1820
+ tables: {
1821
+ logc4: {
1822
+ hash: "1748cb5dba4ee4b6cf14-logc4",
1823
+ sha256: "a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"
1824
+ },
1825
+ slog3cine: {
1826
+ hash: "1748cb5dba4ee4b6cf14-slog3cine",
1827
+ sha256: "01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"
1828
+ }
1829
+ }
1830
+ },
1831
+ {
1832
+ number: 90,
1833
+ id: "look/5 8mm/lifted.fblook",
1834
+ hash: "07093d8ade0bf83ababf",
1835
+ sha256: "c8b4ba2c0b9d40400832dc2ea15fad3d6c59f460760fb06ca1c7dfb423baaa2b",
1836
+ kind: "look",
1837
+ collection: "super 8",
1838
+ group: "",
1839
+ label: "projected",
1840
+ tables: {
1841
+ logc4: {
1842
+ hash: "07093d8ade0bf83ababf-logc4",
1843
+ sha256: "1e8e4bd55dad23965b66280ae930f5746a04e8f4e0a2927886deef72223a878f"
1844
+ },
1845
+ slog3cine: {
1846
+ hash: "07093d8ade0bf83ababf-slog3cine",
1847
+ sha256: "c368965baa62e868b97def41776a4d59f9f9c6e91aae6f7314de479123daae03"
1848
+ }
1849
+ }
1850
+ },
1851
+ {
1852
+ number: 91,
1853
+ id: "look/5 8mm/fuzz.fblook",
1854
+ hash: "9a27ce046063628613a9",
1855
+ sha256: "d0bd619c3bc55eeb041827d3bd1c60b0b86e8d53af718cd218a5a9315a24f963",
1856
+ kind: "look",
1857
+ collection: "super 8",
1858
+ group: "",
1859
+ label: "diffused",
1860
+ tables: {
1861
+ logc4: {
1862
+ hash: "9a27ce046063628613a9-logc4",
1863
+ sha256: "edf8f4dbbe936d873b3c10e7cf14cd46f2758e609ce572e1e51f6a9812ca4681"
1864
+ },
1865
+ slog3cine: {
1866
+ hash: "9a27ce046063628613a9-slog3cine",
1867
+ sha256: "518b88dbaf5f21ac573fbbd2aed291a7c475cb1b6fe242571ca36792e11dd830"
1868
+ }
1869
+ }
1870
+ },
1871
+ {
1872
+ number: 92,
1873
+ id: "look/5 8mm/summer.fblook",
1874
+ hash: "df4643ebdb04850d6940",
1875
+ sha256: "ebe014ec3af62081e5dc8ec1fea489d3e687ea7d839913e1a0a1cc44158d0fe7",
1876
+ kind: "look",
1877
+ collection: "super 8",
1878
+ group: "",
1879
+ label: "sun faded",
1880
+ tables: {
1881
+ logc4: {
1882
+ hash: "df4643ebdb04850d6940-logc4",
1883
+ sha256: "2a0cfdad26f2ba0b5206fdd639f11e66ced0bac7332305a8c2c2de1c37adc117"
1884
+ },
1885
+ slog3cine: {
1886
+ hash: "df4643ebdb04850d6940-slog3cine",
1887
+ sha256: "ff766044f1326586b1e3d194069f846ddf1ff8d3919560a066df78555f6686f9"
1888
+ }
1889
+ }
1890
+ },
1891
+ {
1892
+ number: 93,
1893
+ id: "look/5 8mm/trash.fblook",
1894
+ hash: "b5d4f1f8790caa0124ba",
1895
+ sha256: "f694f45d12b4ed77f66e08697bb7171db9c7712e638bc3d714501e1d902fc292",
1896
+ kind: "look",
1897
+ collection: "super 8",
1898
+ group: "",
1899
+ label: "found footage",
1900
+ tables: {
1901
+ logc4: {
1902
+ hash: "b5d4f1f8790caa0124ba-logc4",
1903
+ sha256: "d8fe007fa0192692e7758517f809841cb747977b65be8c9b24f7a13e78367b32"
1904
+ },
1905
+ slog3cine: {
1906
+ hash: "b5d4f1f8790caa0124ba-slog3cine",
1907
+ sha256: "a806dfdd5ed162238e29bc967c7fe9993949feb22f47a90d6744285d1d80a5dd"
1908
+ }
1909
+ }
1910
+ },
1911
+ {
1912
+ number: 94,
1913
+ id: "look/Pastel & Low-Contrast/easy.fblook",
1914
+ hash: "d5f75230b10228ebc4e5",
1915
+ sha256: "d3d7c350f28b78a55fcaf9a6e4146147b46e16f5daf3f691d0a7b354e2379e9d",
1916
+ kind: "look",
1917
+ collection: "low contrast",
1918
+ group: "",
1919
+ label: "overcast",
1920
+ tables: {
1921
+ logc4: {
1922
+ hash: "d5f75230b10228ebc4e5-logc4",
1923
+ sha256: "34cc0eaf73144a77b473c90a005c218df1c02b3216e4b99a359eaab269e4edd0"
1924
+ },
1925
+ slog3cine: {
1926
+ hash: "d5f75230b10228ebc4e5-slog3cine",
1927
+ sha256: "48a59dba191609fe68d2412972b42769fd4b2010eaa12523c321c73c1fea939a"
1928
+ }
1929
+ }
1930
+ },
1931
+ {
1932
+ number: 95,
1933
+ id: "look/Pastel & Low-Contrast/wes_2.fblook",
1934
+ hash: "e4441dc735a9ba2007f0",
1935
+ sha256: "dd532aafd868c9a2f7279969c5d5799e56a27354fc3cec61de5bd0b6e427e9d4",
1936
+ kind: "look",
1937
+ collection: "low contrast",
1938
+ group: "",
1939
+ label: "pastel",
1940
+ tables: {
1941
+ logc4: {
1942
+ hash: "e4441dc735a9ba2007f0-logc4",
1943
+ sha256: "95b33caeadf9416196c4226214a40a58fe80a89592f971186113bffc2d8015ff"
1944
+ },
1945
+ slog3cine: {
1946
+ hash: "e4441dc735a9ba2007f0-slog3cine",
1947
+ sha256: "a30cf208e29c9cb3e49dbfbe5b93ba6c619e87e0ec3658383b161664851f6721"
1948
+ }
1949
+ }
1950
+ },
1951
+ {
1952
+ number: 96,
1953
+ id: "look/Pastel & Low-Contrast/log.fblook",
1954
+ hash: "28f04ac4b5617492a043",
1955
+ sha256: "fd5e0f3f0145f92a1bf93e84e0d591d5abd4393f4ae1d40d9af6494d14c4d1db",
1956
+ kind: "look",
1957
+ collection: "low contrast",
1958
+ group: "",
1959
+ label: "marine layer",
1960
+ tables: {
1961
+ logc4: {
1962
+ hash: "28f04ac4b5617492a043-logc4",
1963
+ sha256: "089a6fa621544921fed07adbae2c276b68bf6a2e5872d772b8dbb66d4a4e3698"
1964
+ },
1965
+ slog3cine: {
1966
+ hash: "28f04ac4b5617492a043-slog3cine",
1967
+ sha256: "dc328a0b45a16f628c77e33b1e0d816cd0a4bb7b776f1cdb6e7001e062840371"
1968
+ }
1969
+ }
1970
+ },
1971
+ {
1972
+ number: 97,
1973
+ id: "look/Pastel & Low-Contrast/warmie.fblook",
1974
+ hash: "96d755f0b92fba69ec40",
1975
+ sha256: "957e3d8f434a3c16aefb107d6d134eb200b4590a249b6e7371926c228355df15",
1976
+ kind: "look",
1977
+ collection: "low contrast",
1978
+ group: "",
1979
+ label: "golden",
1980
+ tables: {
1981
+ logc4: {
1982
+ hash: "96d755f0b92fba69ec40-logc4",
1983
+ sha256: "c8b97b4bc89dd817ff6f3e91e4205687bdaab9de21c0f85df20cd6e9c5419ea7"
1984
+ },
1985
+ slog3cine: {
1986
+ hash: "96d755f0b92fba69ec40-slog3cine",
1987
+ sha256: "716ceac0e80cc23dd5a0ddb4c7b9cf1000e6af2d8ca4d51a24a70310e3b65f18"
1988
+ }
1989
+ }
1990
+ },
1991
+ {
1992
+ number: 98,
1993
+ id: "look/Still Photography/portrait_c.fblook",
1994
+ hash: "21f566ca8d150a57fda9",
1995
+ sha256: "cadc9bbb04df1c77613620c37d6d063f21752fad6e7cd1276fe881df12989754",
1996
+ kind: "look",
1997
+ collection: "photographic",
1998
+ group: "",
1999
+ label: "portrait",
2000
+ tables: {
2001
+ logc4: {
2002
+ hash: "21f566ca8d150a57fda9-logc4",
2003
+ sha256: "eb9058f52554f3eebbb8ba275b8b041cf19ab7d80dc87666d697fecd8358d15f"
2004
+ },
2005
+ slog3cine: {
2006
+ hash: "21f566ca8d150a57fda9-slog3cine",
2007
+ sha256: "86bf919e57805addd0fde53181eb59910a748ebc286ae2439efb809c8bd3e8f6"
2008
+ }
2009
+ }
2010
+ },
2011
+ {
2012
+ number: 99,
2013
+ id: "look/Still Photography/slide.fblook",
2014
+ hash: "cdc85a160ee50230fd9f",
2015
+ sha256: "4c12fa6ad360f02bba2f00619ceb0e9cb17c39bcc9e090cf25732636d1fb79b0",
2016
+ kind: "look",
2017
+ collection: "photographic",
2018
+ group: "",
2019
+ label: "slide",
2020
+ tables: {
2021
+ logc4: {
2022
+ hash: "cdc85a160ee50230fd9f-logc4",
2023
+ sha256: "2108dc78393d5c341dd7abd195e62490725a60625d275294287e0a201ff0c5f5"
2024
+ },
2025
+ slog3cine: {
2026
+ hash: "cdc85a160ee50230fd9f-slog3cine",
2027
+ sha256: "8680b5b1dd1d57eaf28fe400a11db2acc1a431e609b1ad68601c5909cbe645fd"
2028
+ }
2029
+ }
2030
+ },
2031
+ {
2032
+ number: 100,
2033
+ id: "look/Still Photography/pushed.fblook",
2034
+ hash: "db580ae8d4e13222988d",
2035
+ sha256: "f63f4d39793f807b2e4720ec64e262ebcfc5d5398a73c9752899c91de518e7c8",
2036
+ kind: "look",
2037
+ collection: "photographic",
2038
+ group: "",
2039
+ label: "push two",
2040
+ tables: {
2041
+ logc4: {
2042
+ hash: "db580ae8d4e13222988d-logc4",
2043
+ sha256: "12b2c21f021bf3b48679cb57dafc5f50f32479c0f28dd7e1a6bcf8f9d969e000"
2044
+ },
2045
+ slog3cine: {
2046
+ hash: "db580ae8d4e13222988d-slog3cine",
2047
+ sha256: "ab554e3fa554b3fff17c8a50204b803834f6f1b39d2b2192b2e5c0ce633681a3"
2048
+ }
2049
+ }
2050
+ },
2051
+ {
2052
+ number: 101,
2053
+ id: "look/Still Photography/remjet_a.fblook",
2054
+ hash: "0bfdbdc03660c69b2d61",
2055
+ sha256: "313550933e02336035dee847373d198963026a8fdb30d5ce7c8a3deee013dbd4",
2056
+ kind: "look",
2057
+ collection: "photographic",
2058
+ group: "",
2059
+ label: "halation",
2060
+ tables: {
2061
+ logc4: {
2062
+ hash: "0bfdbdc03660c69b2d61-logc4",
2063
+ sha256: "094d1ee2e487a63f1dd3f5f9e8b013566add055c52df7ad74e9c9b76443c83a5"
2064
+ },
2065
+ slog3cine: {
2066
+ hash: "0bfdbdc03660c69b2d61-slog3cine",
2067
+ sha256: "c78da8f059f5825ecee525747f6ae1964ba77dcf877670e6a201704b30eae9f1"
2068
+ }
2069
+ }
2070
+ },
2071
+ {
2072
+ number: 102,
2073
+ id: "look/Still Photography/punchy.fblook",
2074
+ hash: "366a5666efe55a758980",
2075
+ sha256: "ef951fdd857f8ac8997fc918d8344038e0fd974904e048d0e555b36d71c256bb",
2076
+ kind: "look",
2077
+ collection: "photographic",
2078
+ group: "",
2079
+ label: "flash",
2080
+ tables: {
2081
+ logc4: {
2082
+ hash: "366a5666efe55a758980-logc4",
2083
+ sha256: "c09d98a4c3b5ae1c4ca93a319993352bed1c07344547f49537998fb12c3f1f65"
2084
+ },
2085
+ slog3cine: {
2086
+ hash: "366a5666efe55a758980-slog3cine",
2087
+ sha256: "d51784c05addd44e1a1fe254a49b1caed57565dba239f671165ac4777d9719d6"
2088
+ }
2089
+ }
2090
+ },
2091
+ {
2092
+ number: 103,
2093
+ id: "look/Iconic Looks/seven.fblook",
2094
+ hash: "e3cdb2cbc9079391543e",
2095
+ sha256: "e9aaaf7f96d9e7adf9c7e48537ab780b77574ff8d7121c9613678badd0fb237e",
2096
+ kind: "look",
2097
+ collection: "reference",
2098
+ group: "",
2099
+ label: "fluorescent",
2100
+ tables: {
2101
+ logc4: {
2102
+ hash: "e3cdb2cbc9079391543e-logc4",
2103
+ sha256: "655a011cab20767a28ef26720ef2416bdcd7e1afe6ba713bc7f537739c84c43d"
2104
+ },
2105
+ slog3cine: {
2106
+ hash: "e3cdb2cbc9079391543e-slog3cine",
2107
+ sha256: "20a2076ceccf0b2215709ff2c55f1d1e7c1bc55b98ced8a2f4e605ede82aa50e"
2108
+ }
2109
+ }
2110
+ },
2111
+ {
2112
+ number: 104,
2113
+ id: "look/Iconic Looks/the_wrestler.fblook",
2114
+ hash: "1c837b47572c211e376e",
2115
+ sha256: "e607e9d9f20cc52c6db1f010f1aa69341e43aba0c9207438b99dbda54ef05f82",
2116
+ kind: "look",
2117
+ collection: "reference",
2118
+ group: "",
2119
+ label: "grit",
2120
+ tables: {
2121
+ logc4: {
2122
+ hash: "1c837b47572c211e376e-logc4",
2123
+ sha256: "4bc54f353deb9ad6e668d9efd7c27fea53ed39524c490c12d7fedc0d9b961087"
2124
+ },
2125
+ slog3cine: {
2126
+ hash: "1c837b47572c211e376e-slog3cine",
2127
+ sha256: "3e9caf59518b92abcdf978aae27c84a12f323514a1abb42c4fb1df3801bee34b"
2128
+ }
2129
+ }
2130
+ },
2131
+ {
2132
+ number: 105,
2133
+ id: "look/Iconic Looks/euphoria.fblook",
2134
+ hash: "b3b5fb4a2d1e7795d48b",
2135
+ sha256: "529ece7d8991ac4dee8df844fdbda943a095d113a8c810c623f86ace7a283162",
2136
+ kind: "look",
2137
+ collection: "reference",
2138
+ group: "",
2139
+ label: "neon",
2140
+ tables: {
2141
+ logc4: {
2142
+ hash: "b3b5fb4a2d1e7795d48b-logc4",
2143
+ sha256: "2f8ab2afb9ae2d22cdf4a465ada05969f4aec39a45c04aecd79df203239b3c32"
2144
+ },
2145
+ slog3cine: {
2146
+ hash: "b3b5fb4a2d1e7795d48b-slog3cine",
2147
+ sha256: "2d02bc2f9613888da17b35e2ea9bbaea43cad53acf7a06ffa8e6db5229e82114"
2148
+ }
2149
+ }
2150
+ },
2151
+ {
2152
+ number: 106,
2153
+ id: "look/Iconic Looks/minority_report.fblook",
2154
+ hash: "2f15c11407d3a10053a5",
2155
+ sha256: "a178374748c605d43b5fcbac39a542491a039f21de7fc8dbf0291bddd5615f76",
2156
+ kind: "look",
2157
+ collection: "reference",
2158
+ group: "",
2159
+ label: "clinical",
2160
+ tables: {
2161
+ logc4: {
2162
+ hash: "2f15c11407d3a10053a5-logc4",
2163
+ sha256: "1d4f86741bbb20b0bcb3671b5e7c2d9034448c0885916450b2c47b9e337fa2b4"
2164
+ },
2165
+ slog3cine: {
2166
+ hash: "2f15c11407d3a10053a5-slog3cine",
2167
+ sha256: "f0c6500e39beef6d1baffa9f6a8841408134cd81af78e59581869eaeb192bf3e"
2168
+ }
2169
+ }
2170
+ },
2171
+ {
2172
+ number: 107,
2173
+ id: "look/Iconic Looks/orange_and_teal.fblook",
2174
+ hash: "69467c32c23d52d88afa",
2175
+ sha256: "5029c787be90d68ee97c8b139c2d3004d36dd756dabc418dd66005364d51bac7",
2176
+ kind: "look",
2177
+ collection: "reference",
2178
+ group: "",
2179
+ label: "orange and teal",
2180
+ tables: {
2181
+ logc4: {
2182
+ hash: "69467c32c23d52d88afa-logc4",
2183
+ sha256: "1cabef428a1e57442ee22fe848ef384ff68c0ba4d60711fc196151d247a77db0"
2184
+ },
2185
+ slog3cine: {
2186
+ hash: "69467c32c23d52d88afa-slog3cine",
2187
+ sha256: "226fbc06457541bbe57de13204c6264fe57cb201a2b913baf43a603be4439abf"
2188
+ }
2189
+ }
2190
+ },
2191
+ {
2192
+ number: 108,
2193
+ id: "look/Iconic Looks/amelie.fblook",
2194
+ hash: "f04c4b3553463dae85f0",
2195
+ sha256: "b8585ceec58f795976c83ba948859b704984de8b0ded1561b996f35a5e4a3d5e",
2196
+ kind: "look",
2197
+ collection: "reference",
2198
+ group: "",
2199
+ label: "warm green",
2200
+ tables: {
2201
+ logc4: {
2202
+ hash: "f04c4b3553463dae85f0-logc4",
2203
+ sha256: "6b6aa04a9d8daa313348c8d4f0c76903e6e2e9ee2d6c4f882e83ecb36b095818"
2204
+ },
2205
+ slog3cine: {
2206
+ hash: "f04c4b3553463dae85f0-slog3cine",
2207
+ sha256: "fc5b77ebf930c64364ce506655d45f77dea10561fe00602456da704ef38c83f6"
2208
+ }
2209
+ }
2210
+ },
2211
+ {
2212
+ number: 109,
2213
+ id: "look/Iconic Looks/kingdom.fblook",
2214
+ hash: "ad8a751daf364dab2622",
2215
+ sha256: "e10ef6f84df98f34d93ff655ec0ea307a99b6d48e7579ab96fbf192a512a4de4",
2216
+ kind: "look",
2217
+ collection: "reference",
2218
+ group: "",
2219
+ label: "storybook",
2220
+ tables: {
2221
+ logc4: {
2222
+ hash: "ad8a751daf364dab2622-logc4",
2223
+ sha256: "19877a0fd5f7a0435f6faed9d1911d3aa922ee25211e80a488cbb765e431af2e"
2224
+ },
2225
+ slog3cine: {
2226
+ hash: "ad8a751daf364dab2622-slog3cine",
2227
+ sha256: "af472ac796684391ecb8bdea35d10b1b6c768a4dc3d977983b886011392b1c46"
2228
+ }
2229
+ }
2230
+ },
2231
+ {
2232
+ number: 110,
2233
+ id: "look/Iconic Looks/fincher.fblook",
2234
+ hash: "33a6846cc763bf518e06",
2235
+ sha256: "b3f9d6ba2d6e43a52dac4675e511886f633d8f36ecbc983f5385ff17768fbb1d",
2236
+ kind: "look",
2237
+ collection: "reference",
2238
+ group: "",
2239
+ label: "tobacco",
2240
+ tables: {
2241
+ logc4: {
2242
+ hash: "33a6846cc763bf518e06-logc4",
2243
+ sha256: "c3200dfc6266440dcdf08de03258899eb7a83fc3904073ec1c24d5e15b6321d1"
2244
+ },
2245
+ slog3cine: {
2246
+ hash: "33a6846cc763bf518e06-slog3cine",
2247
+ sha256: "7780f6a0bd386253e1e4817867bd74c10317bc62ef795f3605d85a4d177a1e56"
2248
+ }
2249
+ }
2250
+ },
2251
+ {
2252
+ number: 111,
2253
+ id: "look/Vintage Cinema/sergio.fblook",
2254
+ hash: "70d72ce15d3955091bda",
2255
+ sha256: "e5e8b1cd458eefc7053e563a7ecbd240e9f8ab93a15e2bfcb30711a264f112a8",
2256
+ kind: "look",
2257
+ collection: "period",
2258
+ group: "",
2259
+ label: "dust",
2260
+ tables: {
2261
+ logc4: {
2262
+ hash: "70d72ce15d3955091bda-logc4",
2263
+ sha256: "e8fb2adab0791394d7d97c27f95a7598bbc7c14b904796dfa717b5487edbb268"
2264
+ },
2265
+ slog3cine: {
2266
+ hash: "70d72ce15d3955091bda-slog3cine",
2267
+ sha256: "0be7bd7049d4bc3079eaafa0f3e2760e23079ab3769174a152545ace350c02b5"
2268
+ }
2269
+ }
2270
+ },
2271
+ {
2272
+ number: 112,
2273
+ id: "look/Vintage Cinema/smoke.fblook",
2274
+ hash: "c14dda43a784de7c3700",
2275
+ sha256: "bd228142081fed590d816ece1f96afbbcd09ffa0a9384ab617e39f001e9a9f26",
2276
+ kind: "look",
2277
+ collection: "period",
2278
+ group: "",
2279
+ label: "smoke",
2280
+ tables: {
2281
+ logc4: {
2282
+ hash: "c14dda43a784de7c3700-logc4",
2283
+ sha256: "1bd1133c5f9a3d67edb80cc8c3eeac088463fcb0825374b9c50b6355367787e7"
2284
+ },
2285
+ slog3cine: {
2286
+ hash: "c14dda43a784de7c3700-slog3cine",
2287
+ sha256: "7311df0d0e2503dafd1152d4d75448cc55737bc839dfc60d55036f6e51d129b1"
2288
+ }
2289
+ }
2290
+ },
2291
+ {
2292
+ number: 113,
2293
+ id: "look/Vintage Cinema/telecine_1999.fblook",
2294
+ hash: "99f762c374bf4514bf8a",
2295
+ sha256: "5bf6721bf3d2a5af6e1b2f12917e6531fe1d6e6d991690ca69f7d17fa9d2a05e",
2296
+ kind: "look",
2297
+ collection: "period",
2298
+ group: "",
2299
+ label: "late nineties",
2300
+ tables: {
2301
+ logc4: {
2302
+ hash: "99f762c374bf4514bf8a-logc4",
2303
+ sha256: "b8b5762a0204998d1ab145a3adf5ff4dfd3721839895cd52fa63ba0341d34c16"
2304
+ },
2305
+ slog3cine: {
2306
+ hash: "99f762c374bf4514bf8a-slog3cine",
2307
+ sha256: "a375f840d9548de46e9b5549259eaca6a7373ed4cbe3fa1b7cbaa7f18739490b"
2308
+ }
2309
+ }
2310
+ },
2311
+ {
2312
+ number: 114,
2313
+ id: "look/Vintage Cinema/old1.fblook",
2314
+ hash: "505498bd2c1c0304488c",
2315
+ sha256: "e8a4dd595c46a9304b4ef0853477ca2c52193dbdc27dd357f420422241f90829",
2316
+ kind: "look",
2317
+ collection: "period",
2318
+ group: "",
2319
+ label: "seventies",
2320
+ tables: {
2321
+ logc4: {
2322
+ hash: "505498bd2c1c0304488c-logc4",
2323
+ sha256: "c748b60aa640501b02f16c6294d3cff09a93e69683da8dfb8bffeaf9bd6562c7"
2324
+ },
2325
+ slog3cine: {
2326
+ hash: "505498bd2c1c0304488c-slog3cine",
2327
+ sha256: "d49cd5bf76fd27e5cb7cdd0a9da41bf9c77e20edb27f498c979e2413c51024a7"
2328
+ }
2329
+ }
2330
+ },
2331
+ {
2332
+ number: 115,
2333
+ id: "look/Vintage Cinema/old2.fblook",
2334
+ hash: "4618354776df37902ba5",
2335
+ sha256: "64b749b9860d9fe2b898ce9a802e51cffb227fbead70f3c22ec14a43a37fefb6",
2336
+ kind: "look",
2337
+ collection: "period",
2338
+ group: "",
2339
+ label: "faded print",
2340
+ tables: {
2341
+ logc4: {
2342
+ hash: "4618354776df37902ba5-logc4",
2343
+ sha256: "bece3d02ab6a53cb805ce828c5dbee48042a43037bafa9a456fcd92445826f58"
2344
+ },
2345
+ slog3cine: {
2346
+ hash: "4618354776df37902ba5-slog3cine",
2347
+ sha256: "4ec5404d85f8aea3a727c43bd676f40a3467d266ef63ff060c1457aab5aca9de"
2348
+ }
2349
+ }
2350
+ },
2351
+ {
2352
+ number: 116,
2353
+ id: "look/Black & White/nice pan.fblook",
2354
+ hash: "eb80fb6951b9b1abf2e1",
2355
+ sha256: "61f5620c43ae6467e15f978d45c997a22e9582c924e387855df87800bfe0716f",
2356
+ kind: "look",
2357
+ collection: "black and white",
2358
+ group: "",
2359
+ label: "panchromatic",
2360
+ tables: {
2361
+ logc4: {
2362
+ hash: "eb80fb6951b9b1abf2e1-logc4",
2363
+ sha256: "9df05346e03df176a8c25f982172564227a5bf64c0a291ba5e7df5b32e4c5ed8"
2364
+ },
2365
+ slog3cine: {
2366
+ hash: "eb80fb6951b9b1abf2e1-slog3cine",
2367
+ sha256: "e7e1110999730f5b124c20d1e2bf59779131c5f9a168b95f9354bcab58be83c2"
2368
+ }
2369
+ }
2370
+ },
2371
+ {
2372
+ number: 117,
2373
+ id: "look/Black & White/citizen kane.fblook",
2374
+ hash: "937b5b8d569c6a0c3677",
2375
+ sha256: "fe82d9cacbe8de3feb8da64b51b8f0bd5dee0df82df5fba69fe8eb0e4ba365b5",
2376
+ kind: "look",
2377
+ collection: "black and white",
2378
+ group: "",
2379
+ label: "studio era",
2380
+ tables: {
2381
+ logc4: {
2382
+ hash: "937b5b8d569c6a0c3677-logc4",
2383
+ sha256: "30c34728ab7af0e857b3e8506b10b7fc24632201bd5bbef6848cbbef479a0e12"
2384
+ },
2385
+ slog3cine: {
2386
+ hash: "937b5b8d569c6a0c3677-slog3cine",
2387
+ sha256: "ab5a46426a84d9df85c6ecf744bc574d4b9876f91b5dc8bde2fb545d779fc3ee"
2388
+ }
2389
+ }
2390
+ },
2391
+ {
2392
+ number: 118,
2393
+ id: "look/Black & White/glamour.fblook",
2394
+ hash: "020d6dbc263a98761a7b",
2395
+ sha256: "d908f9d739668ac9dfa4670143aa5e91865988cd80cf0fb6fd56a8d52b1e9627",
2396
+ kind: "look",
2397
+ collection: "black and white",
2398
+ group: "",
2399
+ label: "soft key",
2400
+ tables: {
2401
+ logc4: {
2402
+ hash: "020d6dbc263a98761a7b-logc4",
2403
+ sha256: "fe136199906b80c26d186c1f2985c9e5d43bcbc27be1073d48107a8e396a12e8"
2404
+ },
2405
+ slog3cine: {
2406
+ hash: "020d6dbc263a98761a7b-slog3cine",
2407
+ sha256: "dc4593ad9edd785a87022cb093ed5f9ce0d6bfe854104fa18ef3ef1c24dbdf2a"
2408
+ }
2409
+ }
2410
+ },
2411
+ {
2412
+ number: 119,
2413
+ id: "look/Black & White/old.fblook",
2414
+ hash: "a10ab4ab9e0473d20fb4",
2415
+ sha256: "b5bce10d22c0b6d978c0da8698b1ff383ea3b1914c26eb4c8bee8acf33731e57",
2416
+ kind: "look",
2417
+ collection: "black and white",
2418
+ group: "",
2419
+ label: "nitrate",
2420
+ tables: {
2421
+ logc4: {
2422
+ hash: "a10ab4ab9e0473d20fb4-logc4",
2423
+ sha256: "1a4769c3b7243cad95f7c1cf554ff0665f0b01aeff9d79e64a811b176f551f29"
2424
+ },
2425
+ slog3cine: {
2426
+ hash: "a10ab4ab9e0473d20fb4-slog3cine",
2427
+ sha256: "f8569bc223dab55686246f01500a4b3d1dfa8709653c6db2148151a9014471ea"
2428
+ }
2429
+ }
2430
+ },
2431
+ {
2432
+ number: 120,
2433
+ id: "look/Black & White/Sepia.fblook",
2434
+ hash: "c995c945c090bca69166",
2435
+ sha256: "2f6b862650994c68f045ade4d3d7795305b93459241d5a6999226d1183a37d12",
2436
+ kind: "look",
2437
+ collection: "black and white",
2438
+ group: "",
2439
+ label: "toned",
2440
+ tables: {
2441
+ logc4: {
2442
+ hash: "c995c945c090bca69166-logc4",
2443
+ sha256: "9756502d6f8a25fe8a1a83610015aec49b2c1ad59ca12bb65993464b6d117389"
2444
+ },
2445
+ slog3cine: {
2446
+ hash: "c995c945c090bca69166-slog3cine",
2447
+ sha256: "0ae84e1a4d37befc5c88d108d1b5accd6cf05a2d9ec94109c660d54f4818548e"
2448
+ }
2449
+ }
2450
+ },
2451
+ {
2452
+ number: 121,
2453
+ id: "look/Black & White/nice ortho.fblook",
2454
+ hash: "9387a3c737cc0fd101d2",
2455
+ sha256: "a7e9e24bc246b84ce6f3a3fa8abfbcb62c90867870f5167dec542f090ef79faf",
2456
+ kind: "look",
2457
+ collection: "black and white",
2458
+ group: "",
2459
+ label: "orthochromatic",
2460
+ tables: {
2461
+ logc4: {
2462
+ hash: "9387a3c737cc0fd101d2-logc4",
2463
+ sha256: "b9d941f8d575b7072acebe563aca04ce4c1e81536adc035e8887173165f6dbd7"
2464
+ },
2465
+ slog3cine: {
2466
+ hash: "9387a3c737cc0fd101d2-slog3cine",
2467
+ sha256: "0989dafc139e58fd8ba2f1a4118be36e7383c919f7f201bdc8d3056467adb889"
2468
+ }
2469
+ }
2470
+ },
2471
+ {
2472
+ number: 122,
2473
+ id: "look/Black & White/mono.fblook",
2474
+ hash: "4692285fd84f9d250d3b",
2475
+ sha256: "4e7b206ac61649cfd7cfb834e983f92e0d0f7c025565d4853b7cae853b25c77b",
2476
+ kind: "look",
2477
+ collection: "black and white",
2478
+ group: "",
2479
+ label: "hard contrast",
2480
+ tables: {
2481
+ logc4: {
2482
+ hash: "4692285fd84f9d250d3b-logc4",
2483
+ sha256: "f4fb0446043c7f8d74d48785ec076feef717284625a34f53409335e375eec77d"
2484
+ },
2485
+ slog3cine: {
2486
+ hash: "4692285fd84f9d250d3b-slog3cine",
2487
+ sha256: "eb5ccd8c5773b5c4e94154f1e69e2ae64be438e9f7df2d3f91ec82ac237bb36e"
2488
+ }
2489
+ }
2490
+ },
2491
+ {
2492
+ number: 123,
2493
+ id: "look/Extreme Looks/phoneix.fblook",
2494
+ hash: "2b3e96623a2b3dc3c616",
2495
+ sha256: "f2562ddd4716330e4b71118c4ec907f56c631dc66bf1ac060d87234b637b4cb0",
2496
+ kind: "look",
2497
+ collection: "experimental",
2498
+ group: "",
2499
+ label: "burnout",
2500
+ tables: {
2501
+ logc4: {
2502
+ hash: "2b3e96623a2b3dc3c616-logc4",
2503
+ sha256: "d961fe54aeaea1be1612b00d819e55d6345461cd45f13d3388c1bbb115aaec8c"
2504
+ },
2505
+ slog3cine: {
2506
+ hash: "2b3e96623a2b3dc3c616-slog3cine",
2507
+ sha256: "769c9381843200a7fe00146f66d5c04d20fb1f750fb6ef0f52e9bfa789097118"
2508
+ }
2509
+ }
2510
+ },
2511
+ {
2512
+ number: 124,
2513
+ id: "look/Extreme Looks/purp.fblook",
2514
+ hash: "02af9ff3db82f755c7df",
2515
+ sha256: "342979d459fc3d15387fe56c77e2b213b163e923078dfcdeb1419a55391b17ee",
2516
+ kind: "look",
2517
+ collection: "experimental",
2518
+ group: "",
2519
+ label: "violet",
2520
+ tables: {
2521
+ logc4: {
2522
+ hash: "02af9ff3db82f755c7df-logc4",
2523
+ sha256: "1b55fad5fa9b1f28cbe35093a409a0263e1f6184dc821b2bb0218c16fcc82c32"
2524
+ },
2525
+ slog3cine: {
2526
+ hash: "02af9ff3db82f755c7df-slog3cine",
2527
+ sha256: "9a6f2f114cf859435795ca240ce16eaf52219b2ba0da6cee7254809cbc0bd93b"
2528
+ }
2529
+ }
2530
+ },
2531
+ {
2532
+ number: 125,
2533
+ id: "look/Extreme Looks/blasted.fblook",
2534
+ hash: "7d599929461225300cae",
2535
+ sha256: "fd51c12e64fbd6526e256d0fcc9a00a1bf487914a802b0377032bee28778befa",
2536
+ kind: "look",
2537
+ collection: "experimental",
2538
+ group: "",
2539
+ label: "overexposed",
2540
+ tables: {
2541
+ logc4: {
2542
+ hash: "7d599929461225300cae-logc4",
2543
+ sha256: "cd64d9c2bac509a7e359cec3729b8626812a377744e6b6102c891126904c45e9"
2544
+ },
2545
+ slog3cine: {
2546
+ hash: "7d599929461225300cae-slog3cine",
2547
+ sha256: "fa575c421c5bf845e62e370f0bc139496c8f9fadeafef965058711ecdfa8797c"
2548
+ }
2549
+ }
2550
+ },
2551
+ {
2552
+ number: 126,
2553
+ id: "look/Extreme Looks/instacolor.fblook",
2554
+ hash: "028ee89f15bdd058347f",
2555
+ sha256: "fce844465246ea55f465a99d18b22ca4a97257df08245f58706a87eaf11ed4d2",
2556
+ kind: "look",
2557
+ collection: "experimental",
2558
+ group: "",
2559
+ label: "instant",
2560
+ tables: {
2561
+ logc4: {
2562
+ hash: "028ee89f15bdd058347f-logc4",
2563
+ sha256: "da46549a5ad5ba3cc1f321e289e732d792a3b1791c46ce58ab24c3243f76510d"
2564
+ },
2565
+ slog3cine: {
2566
+ hash: "028ee89f15bdd058347f-slog3cine",
2567
+ sha256: "1dd7e2b03e37e46189cdf2e724946733a90c964db606e839ba5d9278d7ba0ed8"
2568
+ }
2569
+ }
2570
+ }
2571
+ ]
2572
+ };
2573
+
2574
+ // ../render-protocol/src/film-resources.mjs
2575
+ var FILM_RESOURCE_VERSION = "1.0.0";
2576
+ var FILM_TABLE_BYTES = 65 ** 3 * 12;
2577
+ var FILM_TABLE_BASE = "https://osmo.inc/api/35mm/tables";
2578
+ var filmStocks = film_catalog_default.items;
2579
+ var filmTables = [
2580
+ ...new Map(
2581
+ filmStocks.flatMap(
2582
+ (stock) => [stock, ...Object.values(stock.tables)].map((table2) => [
2583
+ table2.hash,
2584
+ {
2585
+ hash: table2.hash,
2586
+ sha256: table2.sha256,
2587
+ bytes: FILM_TABLE_BYTES,
2588
+ url: `${FILM_TABLE_BASE}/${table2.hash}.bin`
2589
+ }
2590
+ ])
2591
+ )
2592
+ ).values()
2593
+ ];
2594
+ function filmResource(name = "film", version2 = FILM_RESOURCE_VERSION) {
2595
+ if (version2 !== FILM_RESOURCE_VERSION) return void 0;
2596
+ const stocks = name === "film" ? filmStocks : filmStocks.filter((s) => name === `film-${s.number}`);
2597
+ if (!stocks.length) return void 0;
2598
+ const hashes = new Set(
2599
+ stocks.flatMap((s) => [
2600
+ s.hash,
2601
+ ...Object.values(s.tables).map((t) => t.hash)
2602
+ ])
2603
+ );
2604
+ return {
2605
+ id: `osmo/${name}`,
2606
+ title: name === "film" ? "Film looks" : `Film look: ${stocks[0].label}`,
2607
+ summary: name === "film" ? "All film looks, installed once for every local project." : `${stocks[0].label}, with all camera variants. Installed once for every local project.`,
2608
+ use: (
2609
+ /** @type {const} */
2610
+ "get"
2611
+ ),
2612
+ kind: (
2613
+ /** @type {const} */
2614
+ "film"
2615
+ ),
2616
+ tags: [
2617
+ "film",
2618
+ "color",
2619
+ "offline",
2620
+ ...new Set(stocks.map((s) => s.collection))
2621
+ ],
2622
+ version: version2,
2623
+ package: {
2624
+ folder: name,
2625
+ version: version2,
2626
+ primitive: "Film",
2627
+ installScope: (
2628
+ /** @type {const} */
2629
+ "global"
2630
+ ),
2631
+ compatibility: { scene: "0.1.0" },
2632
+ files: filmTables.filter((t) => hashes.has(t.hash)).map((t) => ({ path: `${t.hash}.bin`, ...t })),
2633
+ presets: stocks.map((s) => ({ id: s.id, title: s.label })),
2634
+ defaultPreset: stocks[0].id,
2635
+ previews: [],
2636
+ requiresLogin: false,
2637
+ notes: [
2638
+ "Film data is shared by all projects and preserved across CLI updates. Missing tables also install automatically when used."
2639
+ ]
2640
+ }
2641
+ };
2642
+ }
2643
+ var filmResourceItems = [
2644
+ filmResource(),
2645
+ ...filmStocks.map((s) => filmResource(`film-${s.number}`))
2646
+ ].map((detail) => {
2647
+ const { package: _package, ...item } = detail;
2648
+ return item;
2649
+ });
2650
+
2651
+ // ../render-protocol/src/film-store.node.mjs
2652
+ function filmDirectory(env = process.env, platform = process.platform, home = os.homedir()) {
2653
+ if (env.OSMO_FILM_TABLES) return path.resolve(env.OSMO_FILM_TABLES);
2654
+ const base = platform === "darwin" ? path.join(home, "Library/Application Support/Osmo") : platform === "win32" ? path.join(
2655
+ env.LOCALAPPDATA || path.join(home, "AppData/Local"),
2656
+ "Osmo"
2657
+ ) : path.join(
2658
+ env.XDG_DATA_HOME || path.join(home, ".local/share"),
2659
+ "osmo"
2660
+ );
2661
+ return path.join(base, "resources/film");
2662
+ }
2663
+ var digest = (bytes2) => createHash("sha256").update(bytes2).digest("hex");
2664
+ var valid = (bytes2, table2) => bytes2?.length === table2.bytes && digest(bytes2) === table2.sha256;
2665
+ function createFilmStore(options = {}) {
2666
+ const directory = options.directory ?? filmDirectory();
2667
+ const tables = new Map(
2668
+ (options.tables ?? filmTables).map((t) => [`film:${t.hash}`, t])
2669
+ );
2670
+ const pending = /* @__PURE__ */ new Map();
2671
+ const progress = /* @__PURE__ */ new Map();
2672
+ function tableFor(key) {
2673
+ const table2 = tables.get(key);
2674
+ if (!table2) throw new Error(`Unknown film table: ${key}`);
2675
+ return table2;
2676
+ }
2677
+ function report2(key, state, received = 0, error = void 0) {
2678
+ const value = {
2679
+ key,
2680
+ state,
2681
+ received,
2682
+ total: tableFor(key).bytes,
2683
+ ...error ? { error } : {}
2684
+ };
2685
+ progress.set(key, value);
2686
+ options.onProgress?.(value);
2687
+ }
2688
+ async function cached(table2) {
2689
+ const file = path.join(directory, `${table2.hash}.bin`);
2690
+ try {
2691
+ if ((await stat(file)).size !== table2.bytes) return null;
2692
+ const bytes2 = await readFile(file);
2693
+ return valid(bytes2, table2) ? bytes2 : null;
2694
+ } catch (error) {
2695
+ if (error.code === "ENOENT") return null;
2696
+ throw error;
2697
+ }
2698
+ }
2699
+ async function install(key) {
2700
+ const table2 = tableFor(key), file = path.join(directory, `${table2.hash}.bin`);
2701
+ report2(key, "checking");
2702
+ const previous = await cached(table2);
2703
+ if (previous) {
2704
+ report2(key, "installed", table2.bytes);
2705
+ return previous;
2706
+ }
2707
+ await mkdir(directory, { recursive: true });
2708
+ const lock = `${file}.lock`, started = Date.now();
2709
+ let held = false;
2710
+ const temporary = `${file}.${randomUUID()}.tmp`;
2711
+ try {
2712
+ while (!held) {
2713
+ try {
2714
+ await mkdir(lock);
2715
+ held = true;
2716
+ } catch (error) {
2717
+ if (error.code !== "EEXIST") throw error;
2718
+ const bytes3 = await cached(table2);
2719
+ if (bytes3) {
2720
+ report2(key, "installed", table2.bytes);
2721
+ return bytes3;
2722
+ }
2723
+ const info = await stat(lock).catch(() => null);
2724
+ if (info && Date.now() - info.mtimeMs > 18e4) {
2725
+ await rm(lock, { recursive: true, force: true });
2726
+ continue;
2727
+ }
2728
+ if (Date.now() - started > 21e4)
2729
+ throw new Error(
2730
+ "Another film installation is still running. Retry shortly."
2731
+ );
2732
+ report2(key, "downloading");
2733
+ await delay(200);
2734
+ }
2735
+ }
2736
+ const bytes2 = await cached(table2);
2737
+ if (bytes2) {
2738
+ report2(key, "installed", table2.bytes);
2739
+ return bytes2;
2740
+ }
2741
+ report2(key, "downloading");
2742
+ const response = await (options.fetch ?? globalThis.fetch)(table2.url, {
2743
+ signal: AbortSignal.timeout(12e4),
2744
+ redirect: "error"
2745
+ });
2746
+ if (!response.ok || !response.body) {
2747
+ await response.body?.cancel();
2748
+ throw new Error(`HTTP ${response.status}`);
2749
+ }
2750
+ const reader = response.body.getReader(), data = Buffer.alloc(table2.bytes);
2751
+ let received = 0;
2752
+ try {
2753
+ for (; ; ) {
2754
+ const { done, value } = await reader.read();
2755
+ if (done) break;
2756
+ if (received + value.length > data.length)
2757
+ throw new Error("Film table exceeds its declared size");
2758
+ data.set(value, received);
2759
+ received += value.length;
2760
+ report2(key, "downloading", received);
2761
+ }
2762
+ } finally {
2763
+ await reader.cancel().catch(() => {
2764
+ });
2765
+ }
2766
+ if (received !== data.length || !valid(data, table2))
2767
+ throw new Error("Film table checksum or size mismatch");
2768
+ await writeFile(temporary, data, { flag: "wx" });
2769
+ await rename(temporary, file);
2770
+ report2(key, "installed", table2.bytes);
2771
+ return data;
2772
+ } finally {
2773
+ await rm(temporary, { force: true });
2774
+ if (held) await rm(lock, { recursive: true, force: true });
2775
+ }
2776
+ }
2777
+ function ensure(key) {
2778
+ tableFor(key);
2779
+ if (pending.has(key)) return pending.get(key);
2780
+ const task = install(key).catch((cause) => {
2781
+ const error = new Error(
2782
+ `Film resource unavailable: ${key}. ${cause.message}. Check your connection and retry, or run osmo resources get film while online.`
2783
+ );
2784
+ report2(key, "failed", 0, error.message);
2785
+ throw error;
2786
+ }).finally(() => pending.delete(key));
2787
+ pending.set(key, task);
2788
+ return task;
2789
+ }
2790
+ async function status(keys) {
2791
+ const result = [];
2792
+ for (const key of new Set(keys)) {
2793
+ const table2 = tableFor(key);
2794
+ if (pending.has(key)) result.push(progress.get(key));
2795
+ else if (await cached(table2))
2796
+ result.push({
2797
+ key,
2798
+ state: "installed",
2799
+ received: table2.bytes,
2800
+ total: table2.bytes
2801
+ });
2802
+ else
2803
+ result.push(
2804
+ progress.get(key)?.state === "failed" ? progress.get(key) : { key, state: "missing", received: 0, total: table2.bytes }
2805
+ );
2806
+ }
2807
+ return result;
2808
+ }
2809
+ async function ensureAll(keys, onDone = (_done, _total) => {
2810
+ }) {
2811
+ const unique = [...new Set(keys)];
2812
+ unique.forEach(tableFor);
2813
+ const queue = [...unique];
2814
+ let done = 0, failed = false;
2815
+ const results = await Promise.allSettled(
2816
+ Array.from({ length: Math.min(4, queue.length) }, async () => {
2817
+ while (queue.length && !failed) {
2818
+ try {
2819
+ await ensure(queue.shift());
2820
+ onDone(++done, unique.length);
2821
+ } catch (error) {
2822
+ failed = true;
2823
+ throw error;
2824
+ }
2825
+ }
2826
+ })
2827
+ );
2828
+ const failure2 = results.find((result) => result.status === "rejected");
2829
+ if (failure2?.status === "rejected") throw failure2.reason;
2830
+ return { directory, tables: unique.length };
2831
+ }
2832
+ return { directory, ensure, ensureAll, status };
2833
+ }
2834
+ var shared;
2835
+ function filmStore() {
2836
+ shared ??= createFilmStore();
2837
+ return shared;
2838
+ }
21
2839
 
22
2840
  // src/runtime.ts
23
2841
  import fs from "node:fs";
24
- import path from "node:path";
2842
+ import path2 from "node:path";
25
2843
  import { fileURLToPath } from "node:url";
26
2844
  var packageRoot = fileURLToPath(new URL("../", import.meta.url));
27
2845
  var manifest = JSON.parse(
28
- fs.readFileSync(path.join(packageRoot, "package.json"), "utf8")
2846
+ fs.readFileSync(path2.join(packageRoot, "package.json"), "utf8")
29
2847
  );
30
2848
  var version = manifest.version;
31
2849
  var sceneVersion = manifest.osmo.sceneVersion;
32
- var runtimeRoot = fs.existsSync(path.join(packageRoot, "runtime")) ? path.join(packageRoot, "runtime") : path.resolve(packageRoot, "../..");
33
- var studioRoot = fs.existsSync(path.join(packageRoot, "studio")) ? path.join(packageRoot, "studio") : path.join(runtimeRoot, "packages/studio/dist");
2850
+ var runtimeRoot = fs.existsSync(path2.join(packageRoot, "runtime")) ? path2.join(packageRoot, "runtime") : path2.resolve(packageRoot, "../..");
2851
+ var studioRoot = fs.existsSync(path2.join(packageRoot, "studio")) ? path2.join(packageRoot, "studio") : path2.join(runtimeRoot, "packages/studio/dist");
34
2852
 
35
2853
  // src/osmo-fetch.ts
36
2854
  var INSTALL = "npm install -g @osmo.inc/cli";
@@ -174,31 +2992,31 @@ var alive = (pid) => {
174
2992
  }
175
2993
  };
176
2994
  async function withCredentials(origin, action) {
177
- const folder = path2.join(
2995
+ const folder = path3.join(
178
2996
  // Empty counts as unset, or the credentials would land in ./auth.
179
- process.env.OSMO_CONFIG_DIR || path2.join(os.homedir(), ".osmo"),
2997
+ process.env.OSMO_CONFIG_DIR || path3.join(os2.homedir(), ".osmo"),
180
2998
  "auth"
181
2999
  );
182
- await mkdir(folder, { recursive: true, mode: 448 });
3000
+ await mkdir2(folder, { recursive: true, mode: 448 });
183
3001
  if (!(await lstat(folder)).isDirectory())
184
3002
  throw new AuthError(
185
3003
  "invalid_storage",
186
3004
  "Auth storage must be a real directory."
187
3005
  );
188
3006
  await chmod(folder, 448);
189
- const id = createHash("sha256").update(origin).digest("hex").slice(0, 24);
190
- const file = path2.join(folder, `${id}.json`);
3007
+ const id = createHash2("sha256").update(origin).digest("hex").slice(0, 24);
3008
+ const file = path3.join(folder, `${id}.json`);
191
3009
  const lock = `${file}.lock`;
192
3010
  const start = Date.now();
193
3011
  installSignalHandlers();
194
3012
  while (true) {
195
3013
  acquiring++;
196
3014
  try {
197
- await mkdir(lock, { mode: 448 });
3015
+ await mkdir2(lock, { mode: 448 });
198
3016
  try {
199
- await writeFile(path2.join(lock, "pid"), String(process.pid));
3017
+ await writeFile2(path3.join(lock, "pid"), String(process.pid));
200
3018
  } catch (error) {
201
- await rm(lock, { recursive: true, force: true });
3019
+ await rm2(lock, { recursive: true, force: true });
202
3020
  throw error;
203
3021
  }
204
3022
  activeLocks.add(lock);
@@ -206,10 +3024,10 @@ async function withCredentials(origin, action) {
206
3024
  } catch (error) {
207
3025
  if (error.code !== "EEXIST") throw error;
208
3026
  const holder = Number(
209
- await readFile(path2.join(lock, "pid"), "utf8").catch(() => "")
3027
+ await readFile2(path3.join(lock, "pid"), "utf8").catch(() => "")
210
3028
  );
211
3029
  if (holder && holder !== process.pid && !alive(holder)) {
212
- await rm(lock, { recursive: true, force: true });
3030
+ await rm2(lock, { recursive: true, force: true });
213
3031
  continue;
214
3032
  }
215
3033
  if (Date.now() - start > 1e4)
@@ -224,20 +3042,20 @@ async function withCredentials(origin, action) {
224
3042
  }
225
3043
  }
226
3044
  let state = { version: 1, origin };
227
- const temporary = `${file}.${randomUUID()}.tmp`;
3045
+ const temporary = `${file}.${randomUUID2()}.tmp`;
228
3046
  async function save3() {
229
- await writeFile(temporary, JSON.stringify(state) + "\n", {
3047
+ await writeFile2(temporary, JSON.stringify(state) + "\n", {
230
3048
  mode: 384,
231
3049
  flag: "wx"
232
3050
  });
233
- await rename(temporary, file);
3051
+ await rename2(temporary, file);
234
3052
  }
235
3053
  try {
236
3054
  try {
237
- const stat4 = await lstat(file);
238
- if (!stat4.isFile()) throw new Error("Not a regular file");
3055
+ const stat5 = await lstat(file);
3056
+ if (!stat5.isFile()) throw new Error("Not a regular file");
239
3057
  await chmod(file, 384);
240
- state = JSON.parse(await readFile(file, "utf8"));
3058
+ state = JSON.parse(await readFile2(file, "utf8"));
241
3059
  if (state.version !== 1 || state.origin !== origin || state.credentials && !validCredentials(state.credentials) || state.pending && (!validClient(state.pending.client) || typeof state.pending.sessionId !== "string" || typeof state.pending.deviceCode !== "string" || typeof state.pending.code !== "string" || !Number.isFinite(state.pending.expiresAt) || !Number.isFinite(state.pending.nextPollAt) || !Number.isFinite(state.pending.interval) || state.pending.interval < 5 || !validApprovalUrl(state.pending.url, origin)))
242
3060
  throw new Error("Invalid credentials");
243
3061
  } catch (error) {
@@ -249,8 +3067,8 @@ async function withCredentials(origin, action) {
249
3067
  }
250
3068
  return await action(state, save3);
251
3069
  } finally {
252
- await rm(temporary, { force: true });
253
- await rm(lock, { recursive: true, force: true });
3070
+ await rm2(temporary, { force: true });
3071
+ await rm2(lock, { recursive: true, force: true });
254
3072
  activeLocks.delete(lock);
255
3073
  exitIfRequested();
256
3074
  }
@@ -500,8 +3318,8 @@ async function revoke(origin, state, save3) {
500
3318
  await save3();
501
3319
  return signedIn;
502
3320
  }
503
- async function authCommand(args, flags = {}) {
504
- const origin = authOrigin();
3321
+ async function authCommand(args, flags = {}, requestedOrigin = authOrigin()) {
3322
+ const origin = authOrigin({ OSMO_BASE_URL: requestedOrigin });
505
3323
  const scope = [
506
3324
  ...IDENTITY_SCOPES,
507
3325
  ...PERMISSIONS.filter(
@@ -544,7 +3362,7 @@ async function authCommand(args, flags = {}) {
544
3362
  }
545
3363
  if (state.pending && Date.now() < state.pending.expiresAt && (state.pending.scope ?? scope) === scope)
546
3364
  return poll(origin, state, save3, state.pending.sessionId);
547
- const deviceName = flags.name ?? os.hostname();
3365
+ const deviceName = flags.name ?? os2.hostname();
548
3366
  if (!deviceName.trim() || deviceName.length > 80 || /[\x00-\x1f\x7f]/.test(deviceName))
549
3367
  throw new AuthError(
550
3368
  "invalid_name",
@@ -577,7 +3395,7 @@ async function authCommand(args, flags = {}) {
577
3395
  "Osmo returned an invalid device request."
578
3396
  );
579
3397
  state.pending = {
580
- sessionId: randomUUID().slice(0, 8),
3398
+ sessionId: randomUUID2().slice(0, 8),
581
3399
  client,
582
3400
  scope,
583
3401
  deviceCode: device.device_code,
@@ -729,21 +3547,21 @@ Node 22 or later. Cloud commands need osmo login; OSMO_BASE_URL picks the cloud
729
3547
  }
730
3548
 
731
3549
  // src/resources.ts
732
- import { createHash as createHash2 } from "node:crypto";
3550
+ import { createHash as createHash3 } from "node:crypto";
733
3551
  import { constants } from "node:fs";
734
3552
  import {
735
3553
  copyFile,
736
3554
  lstat as lstat2,
737
- mkdir as mkdir2,
3555
+ mkdir as mkdir3,
738
3556
  mkdtemp,
739
3557
  readdir,
740
- readFile as readFile2,
3558
+ readFile as readFile3,
741
3559
  realpath,
742
- rename as rename2,
743
- rm as rm2,
744
- writeFile as writeFile2
3560
+ rename as rename3,
3561
+ rm as rm3,
3562
+ writeFile as writeFile3
745
3563
  } from "node:fs/promises";
746
- import path3 from "node:path";
3564
+ import path4 from "node:path";
747
3565
  import { unzipSync } from "fflate";
748
3566
  var CATALOG_OWNER = "osmo";
749
3567
  var COST = {
@@ -761,7 +3579,7 @@ var DOWNLOAD_MS = 30 * 6e4;
761
3579
  var ownerPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
762
3580
  var namePattern = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
763
3581
  var versionPattern = /^\d+\.\d+\.\d+$/;
764
- var digest = (bytes2) => createHash2("sha256").update(bytes2).digest("hex");
3582
+ var digest2 = (bytes2) => createHash3("sha256").update(bytes2).digest("hex");
765
3583
  var fail = (code, message, next) => {
766
3584
  throw new AuthError(code, message, next);
767
3585
  };
@@ -867,15 +3685,25 @@ function validItem(item) {
867
3685
  return !!item && text(item.id) && text(item.title) && typeof item.summary === "string" && (item.use === "run" || item.use === "get") && text(item.kind) && strings(item.tags) && (item.tasks === void 0 || strings(item.tasks));
868
3686
  }
869
3687
  function compatibility(pkg) {
870
- const supported = (pkg.primitive === "Shader" || pkg.primitive === "Model") && pkg.compatibility?.scene === sceneVersion;
3688
+ const supported = ["Shader", "Model", "Film"].includes(pkg.primitive) && pkg.compatibility?.scene === sceneVersion;
871
3689
  return {
872
3690
  supported,
873
3691
  scene: pkg.compatibility?.scene,
874
3692
  cliVersion: version,
875
- note: !supported ? "This CLI cannot use this resource. Update the CLI before downloading it." : pkg.primitive === "Model" ? "For use in an Osmo project: <Model src> takes model.glb, with scene content on its surfaces. The file is a standard GLB." : "For use in an Osmo project: <Shader src> takes shader.wgsl, with every uniform passed. The file is plain WGSL: an effect(uv, time) function and its Uniforms struct."
3693
+ note: !supported ? "This CLI cannot use this resource. Update the CLI before downloading it." : pkg.primitive === "Film" ? "Installed globally for all local Osmo projects. Film effects resolve their tables automatically." : pkg.primitive === "Model" ? "For use in an Osmo project: <Model src> takes model.glb, with scene content on its surfaces. The file is a standard GLB." : "For use in an Osmo project: <Shader src> takes shader.wgsl, with every uniform passed. The file is plain WGSL: an effect(uv, time) function and its Uniforms struct."
876
3694
  };
877
3695
  }
878
3696
  async function catalogDetail(ref) {
3697
+ if (ref.owner === "osmo" && (ref.name === "film" || /^film-\d+$/.test(ref.name))) {
3698
+ const detail2 = filmResource(ref.name, ref.version);
3699
+ if (!detail2)
3700
+ fail(
3701
+ "resource_not_found",
3702
+ `Film resource/version is not supported by this CLI (catalogue ${FILM_RESOURCE_VERSION}).`,
3703
+ "osmo resources list --type film"
3704
+ );
3705
+ return detail2;
3706
+ }
879
3707
  const query = ref.version ? `?${new URLSearchParams({ version: ref.version })}` : "";
880
3708
  const detail = await publicGet(
881
3709
  `/api/resources/${ref.owner}/${ref.name}${query}`
@@ -905,6 +3733,26 @@ async function list(query, flags) {
905
3733
  if (flags.limit !== void 0)
906
3734
  params.set("limit", String(Number(flags.limit)));
907
3735
  if (flags.cursor) params.set("cursor", flags.cursor);
3736
+ if (flags.type?.includes("film")) {
3737
+ const words2 = q.toLowerCase().split(/\s+/).filter(Boolean);
3738
+ const items2 = filmResourceItems.filter(
3739
+ (item) => flags.type.every((type) => type === "film") && words2.every(
3740
+ (word) => [item.id, item.title, item.summary, ...item.tags].join(" ").toLowerCase().includes(word)
3741
+ )
3742
+ );
3743
+ const offset = Number(flags.cursor ?? 0), limit = Number(flags.limit ?? 50);
3744
+ if (!Number.isSafeInteger(offset) || offset < 0)
3745
+ throw new UsageError("Invalid resource cursor.");
3746
+ return {
3747
+ status: "ok",
3748
+ ...q ? { query: q } : {},
3749
+ items: items2.slice(offset, offset + limit),
3750
+ total: items2.length,
3751
+ types: ["film"],
3752
+ nextCursor: offset + limit < items2.length ? String(offset + limit) : null,
3753
+ next: "osmo resources get film"
3754
+ };
3755
+ }
908
3756
  const page = await publicGet(
909
3757
  `/api/resources${params.size ? `?${params}` : ""}`
910
3758
  );
@@ -968,7 +3816,7 @@ function unpack(zip, pkg) {
968
3816
  const files = {};
969
3817
  for (const expected of pkg.files) {
970
3818
  const content = extracted[prefix + expected.path];
971
- if (!content || content.length !== expected.bytes || digest(content) !== expected.sha256)
3819
+ if (!content || content.length !== expected.bytes || digest2(content) !== expected.sha256)
972
3820
  fail(
973
3821
  "integrity_error",
974
3822
  "Resource checksum verification failed. No files were written."
@@ -985,7 +3833,7 @@ function unpack(zip, pkg) {
985
3833
  invalid();
986
3834
  return { files, manifest: manifest2, names };
987
3835
  }
988
- async function stat(file) {
3836
+ async function stat2(file) {
989
3837
  try {
990
3838
  return await lstat2(file);
991
3839
  } catch (error) {
@@ -994,12 +3842,12 @@ async function stat(file) {
994
3842
  }
995
3843
  }
996
3844
  async function save(destination, shown, files, names) {
997
- const parent = path3.dirname(destination), base = path3.basename(destination);
998
- const inside = (await stat(destination))?.isDirectory() ?? false;
999
- if (!inside) await mkdir2(parent, { recursive: true });
1000
- const lock = inside ? path3.join(destination, LOCK) : path3.join(parent, `.${base}.osmo-get.lock`);
3845
+ const parent = path4.dirname(destination), base = path4.basename(destination);
3846
+ const inside = (await stat2(destination))?.isDirectory() ?? false;
3847
+ if (!inside) await mkdir3(parent, { recursive: true });
3848
+ const lock = inside ? path4.join(destination, LOCK) : path4.join(parent, `.${base}.osmo-get.lock`);
1001
3849
  try {
1002
- await mkdir2(lock);
3850
+ await mkdir3(lock);
1003
3851
  } catch (error) {
1004
3852
  if (error.code === "EEXIST")
1005
3853
  fail(
@@ -1010,7 +3858,7 @@ async function save(destination, shown, files, names) {
1010
3858
  }
1011
3859
  let stage;
1012
3860
  try {
1013
- const existing = await stat(destination);
3861
+ const existing = await stat2(destination);
1014
3862
  if (existing) {
1015
3863
  if (!existing.isDirectory())
1016
3864
  fail("resource_conflict", `${shown} must be a real folder.`);
@@ -1018,8 +3866,8 @@ async function save(destination, shown, files, names) {
1018
3866
  if (entries.length) {
1019
3867
  const same = entries.join(",") === names.join(",") && (await Promise.all(
1020
3868
  names.map(async (name) => {
1021
- const file = path3.join(destination, name);
1022
- return (await stat(file))?.isFile() && (await readFile2(file)).equals(Buffer.from(files[name]));
3869
+ const file = path4.join(destination, name);
3870
+ return (await stat2(file))?.isFile() && (await readFile3(file)).equals(Buffer.from(files[name]));
1023
3871
  })
1024
3872
  )).every(Boolean);
1025
3873
  if (same) return "already_downloaded";
@@ -1028,21 +3876,21 @@ async function save(destination, shown, files, names) {
1028
3876
  `${shown} already holds other files, which were left alone. Download somewhere else with --out DIR.`
1029
3877
  );
1030
3878
  }
1031
- stage = await mkdtemp(path3.join(destination, ".osmo-get-"));
3879
+ stage = await mkdtemp(path4.join(destination, ".osmo-get-"));
1032
3880
  for (const name of names)
1033
- await writeFile2(path3.join(stage, name), files[name], { flag: "wx" });
3881
+ await writeFile3(path4.join(stage, name), files[name], { flag: "wx" });
1034
3882
  const copied = [];
1035
3883
  try {
1036
3884
  for (const name of names) {
1037
3885
  await copyFile(
1038
- path3.join(stage, name),
1039
- path3.join(destination, name),
3886
+ path4.join(stage, name),
3887
+ path4.join(destination, name),
1040
3888
  constants.COPYFILE_EXCL
1041
3889
  );
1042
- copied.push(path3.join(destination, name));
3890
+ copied.push(path4.join(destination, name));
1043
3891
  }
1044
3892
  } catch (error) {
1045
- for (const file of copied) await rm2(file, { force: true });
3893
+ for (const file of copied) await rm3(file, { force: true });
1046
3894
  if (error.code !== "EEXIST") throw error;
1047
3895
  fail(
1048
3896
  "resource_conflict",
@@ -1051,23 +3899,23 @@ async function save(destination, shown, files, names) {
1051
3899
  }
1052
3900
  return "downloaded";
1053
3901
  }
1054
- stage = await mkdtemp(path3.join(parent, `.${base}-`));
3902
+ stage = await mkdtemp(path4.join(parent, `.${base}-`));
1055
3903
  for (const name of names)
1056
- await writeFile2(path3.join(stage, name), files[name], { flag: "wx" });
1057
- if (await stat(destination))
3904
+ await writeFile3(path4.join(stage, name), files[name], { flag: "wx" });
3905
+ if (await stat2(destination))
1058
3906
  fail(
1059
3907
  "resource_conflict",
1060
3908
  `${shown} appeared during the download. Existing files were left alone.`
1061
3909
  );
1062
- await rename2(stage, destination);
3910
+ await rename3(stage, destination);
1063
3911
  stage = void 0;
1064
3912
  return "downloaded";
1065
3913
  } finally {
1066
- if (stage) await rm2(stage, { recursive: true, force: true });
1067
- await rm2(lock, { recursive: true, force: true });
3914
+ if (stage) await rm3(stage, { recursive: true, force: true });
3915
+ await rm3(lock, { recursive: true, force: true });
1068
3916
  }
1069
3917
  }
1070
- async function get(ref, flags) {
3918
+ async function get(ref, flags, io) {
1071
3919
  const detail = await catalogDetail(ref);
1072
3920
  if (detail.use === "run")
1073
3921
  throw new OsmoError(
@@ -1078,7 +3926,38 @@ async function get(ref, flags) {
1078
3926
  const pkg = detail.package;
1079
3927
  const compat = compatibility(pkg);
1080
3928
  if (!compat.supported) fail("incompatible_resource", compat.note);
1081
- const destination = path3.resolve(flags.out ?? pkg.folder);
3929
+ if (pkg.primitive === "Film") {
3930
+ if (flags.out !== void 0)
3931
+ throw new UsageError(
3932
+ "Film resources install into the shared Osmo data folder; --out is only for project resources."
3933
+ );
3934
+ const keys = pkg.files.map((file) => `film:${file.path.slice(0, -4)}`), store = filmStore();
3935
+ const before = await store.status(keys);
3936
+ const already = before.every((file) => file.state === "installed");
3937
+ if (!already)
3938
+ io?.log(
3939
+ `Installing film resources (${(pkg.files.reduce((n, f) => n + f.bytes, 0) / 1024 / 1024).toFixed(1)} MiB) to ${store.directory}`
3940
+ );
3941
+ await store.ensureAll(
3942
+ keys,
3943
+ (done, total) => io?.log(`Film resources: ${done}/${total} tables ready`)
3944
+ );
3945
+ return {
3946
+ status: already ? "already_downloaded" : "downloaded",
3947
+ id: detail.id,
3948
+ version: pkg.version,
3949
+ scope: "global",
3950
+ folder: store.directory,
3951
+ files: pkg.files.map((f) => path4.join(store.directory, f.path)),
3952
+ presets: pkg.presets,
3953
+ defaultPreset: pkg.defaultPreset,
3954
+ usage: {},
3955
+ notes: [],
3956
+ compatibility: compat,
3957
+ guide: "Ready for offline use in every local project. Apply a film effect in Studio or use film({stock: ...}) in a scene."
3958
+ };
3959
+ }
3960
+ const destination = path4.resolve(flags.out ?? pkg.folder);
1082
3961
  checkFiles(pkg);
1083
3962
  const declared = pkg.files.reduce((sum, file) => sum + file.bytes, 0);
1084
3963
  const zip = await responseBody(
@@ -1091,9 +3970,9 @@ async function get(ref, flags) {
1091
3970
  );
1092
3971
  const { files, manifest: manifest2, names } = unpack(zip, pkg);
1093
3972
  const status = await save(destination, flags.out ?? pkg.folder, files, names);
1094
- const relative = path3.relative(await realpath(process.cwd()), await realpath(destination)).split(path3.sep).join("/");
3973
+ const relative = path4.relative(await realpath(process.cwd()), await realpath(destination)).split(path4.sep).join("/");
1095
3974
  const folder = relative === "" ? "." : relative;
1096
- const src = path3.isAbsolute(folder) || folder.startsWith("../") || folder === "." ? folder : `./${folder}`;
3975
+ const src = path4.isAbsolute(folder) || folder.startsWith("../") || folder === "." ? folder : `./${folder}`;
1097
3976
  return {
1098
3977
  status,
1099
3978
  id: detail.id,
@@ -1118,10 +3997,10 @@ async function get(ref, flags) {
1118
3997
  guide: pkg.primitive === "Model" ? "Use a usage snippet, and put your scene content inside its Surface." : `Read ${folder}/shader.d.ts for what each uniform does, then use a usage snippet.`
1119
3998
  };
1120
3999
  }
1121
- async function resourcesCommand(verb, args, flags = {}) {
4000
+ async function resourcesCommand(verb, args, flags = {}, io) {
1122
4001
  if (verb === "list") return list(args, flags);
1123
4002
  const ref = catalogRef(args[0]);
1124
- return verb === "show" ? show(ref) : get(ref, flags);
4003
+ return verb === "show" ? show(ref) : get(ref, flags, io);
1125
4004
  }
1126
4005
  function describeInput(schema) {
1127
4006
  if (schema.anyOf) return schema.anyOf.map(describeInput).join(", or ");
@@ -1184,6 +4063,9 @@ function formatResources(result) {
1184
4063
  lines2.push("", `Types: ${r.types.join(", ")}`, `Next: ${r.next}`);
1185
4064
  return lines2.join("\n");
1186
4065
  }
4066
+ if ("scope" in r && r.scope === "global")
4067
+ return `${r.id}@${r.version}: ${r.files.length} film tables ready in ${r.folder}
4068
+ ${r.guide}`;
1187
4069
  if ("usage" in r) {
1188
4070
  const usage = Object.entries(r.usage).map(
1189
4071
  ([preset, snippet]) => `${preset}:
@@ -1259,13 +4141,43 @@ function formatResources(result) {
1259
4141
  }
1260
4142
 
1261
4143
  // src/run.ts
1262
- import { randomUUID as randomUUID2 } from "node:crypto";
1263
- import { createWriteStream, openAsBlob, rmSync } from "node:fs";
1264
- import { mkdir as mkdir3, readFile as readFile3, rename as rename3, rm as rm3, stat as stat2 } from "node:fs/promises";
1265
- import path4 from "node:path";
4144
+ import { spawnSync as spawnSync2 } from "node:child_process";
4145
+ import { randomUUID as randomUUID3 } from "node:crypto";
4146
+ import { createWriteStream, existsSync as existsSync2, openAsBlob, rmSync as rmSync2 } from "node:fs";
4147
+ import { mkdir as mkdir4, readFile as readFile4, rename as rename4, rm as rm4, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
4148
+ import path6 from "node:path";
1266
4149
  import { Readable } from "node:stream";
1267
4150
  import { pipeline } from "node:stream/promises";
1268
4151
 
4152
+ // src/cloud-pointer.ts
4153
+ import { spawnSync } from "node:child_process";
4154
+
4155
+ // src/git.ts
4156
+ import {
4157
+ existsSync,
4158
+ mkdirSync,
4159
+ readFileSync,
4160
+ renameSync,
4161
+ rmSync,
4162
+ writeFileSync
4163
+ } from "node:fs";
4164
+ import path5 from "node:path";
4165
+ var hasRepo = (root) => existsSync(path5.join(root, ".git"));
4166
+
4167
+ // src/cloud-pointer.ts
4168
+ var PROJECT_ID = /^[a-z0-9]{10,40}$/;
4169
+ function pointerFromGit(root) {
4170
+ const read = (key) => {
4171
+ const r = spawnSync("git", ["-C", root, "config", "--get", key], {
4172
+ encoding: "utf8"
4173
+ });
4174
+ return r.status === 0 ? r.stdout.trim() : "";
4175
+ };
4176
+ const origin = read("osmo.cloud.origin"), id = read("osmo.cloud.id");
4177
+ return origin && id ? { origin, id } : null;
4178
+ }
4179
+ var cloudPointer = (root) => hasRepo(root) ? pointerFromGit(root) : null;
4180
+
1269
4181
  // src/cloud-request.ts
1270
4182
  var PERMISSION_DOES = {
1271
4183
  "projects:write": "change projects",
@@ -1318,12 +4230,17 @@ var UPLOAD_MAX_BYTES = 100 * 1024 * 1024;
1318
4230
  var TRANSFER_MS = 15 * 6e4;
1319
4231
  var EXTENSIONS = {
1320
4232
  "video/mp4": "mp4",
4233
+ "video/quicktime": "mov",
4234
+ "video/webm": "webm",
1321
4235
  "image/png": "png",
1322
4236
  "image/jpeg": "jpg",
1323
4237
  "image/webp": "webp",
4238
+ "image/gif": "gif",
1324
4239
  "image/svg+xml": "svg",
1325
4240
  "audio/mpeg": "mp3",
1326
- "audio/wav": "wav"
4241
+ "audio/wav": "wav",
4242
+ "audio/mp4": "m4a",
4243
+ "audio/ogg": "ogg"
1327
4244
  };
1328
4245
  var jobPattern = /^run_[a-z0-9]{8,40}$/;
1329
4246
  var invalidInput = (detail, issues) => new OsmoError(
@@ -1569,7 +4486,7 @@ function fileSource(value) {
1569
4486
  return { kind: "local", file: value };
1570
4487
  }
1571
4488
  function uploadType(name) {
1572
- return UPLOAD_TYPES[path4.extname(name).slice(1).toLowerCase()];
4489
+ return UPLOAD_TYPES[path6.extname(name).slice(1).toLowerCase()];
1573
4490
  }
1574
4491
  var megabytes = (n) => n < 1048576 ? `${Math.max(1, Math.round(n / 1024))} KB` : `${(n / 1048576).toFixed(1)} MB`;
1575
4492
  async function resolveFiles(schema, input, issues, io) {
@@ -1599,18 +4516,18 @@ async function resolveFiles(schema, input, issues, io) {
1599
4516
  for (const job of jobs) {
1600
4517
  if (job.source.kind === "ours") job.set(job.source.url);
1601
4518
  if (job.source.kind !== "local") continue;
1602
- const info = await stat2(job.source.file).catch(() => null);
4519
+ const info = await stat3(job.source.file).catch(() => null);
1603
4520
  if (!info?.isFile())
1604
4521
  issues.push({ path: job.path, message: `no file at ${job.source.file}` });
1605
4522
  else if (!uploadType(job.source.file))
1606
4523
  issues.push({
1607
4524
  path: job.path,
1608
- message: `${path4.basename(job.source.file)} isn't a type runs take (${Object.keys(UPLOAD_TYPES).join(", ")})`
4525
+ message: `${path6.basename(job.source.file)} isn't a type runs take (${Object.keys(UPLOAD_TYPES).join(", ")})`
1609
4526
  });
1610
4527
  else if (info.size > UPLOAD_MAX_BYTES || info.size === 0)
1611
4528
  issues.push({
1612
4529
  path: job.path,
1613
- message: `${path4.basename(job.source.file)} must be 1 byte to ${megabytes(UPLOAD_MAX_BYTES)}`
4530
+ message: `${path6.basename(job.source.file)} must be 1 byte to ${megabytes(UPLOAD_MAX_BYTES)}`
1614
4531
  });
1615
4532
  }
1616
4533
  return async () => {
@@ -1619,7 +4536,7 @@ async function resolveFiles(schema, input, issues, io) {
1619
4536
  const { file } = job.source;
1620
4537
  const type = uploadType(file);
1621
4538
  const blob = await openAsBlob(file, { type });
1622
- io.log(`uploading ${path4.basename(file)} (${megabytes(blob.size)})`);
4539
+ io.log(`uploading ${path6.basename(file)} (${megabytes(blob.size)})`);
1623
4540
  job.set(await upload(blob, type));
1624
4541
  } else if (job.source.kind === "web") {
1625
4542
  io.log(`fetching ${job.source.url}`);
@@ -1702,7 +4619,7 @@ async function readInputsFile(file) {
1702
4619
  try {
1703
4620
  text2 = file === "-" ? await new Response(
1704
4621
  Readable.toWeb(process.stdin)
1705
- ).text() : await readFile3(file, "utf8");
4622
+ ).text() : await readFile4(file, "utf8");
1706
4623
  } catch {
1707
4624
  throw new OsmoError("invalid_input", `Can't read ${file}.`);
1708
4625
  }
@@ -1807,34 +4724,71 @@ Next: ${next}`
1807
4724
  stop();
1808
4725
  }
1809
4726
  }
4727
+ function projectFolder(start = process.cwd()) {
4728
+ for (let dir = path6.resolve(start); ; dir = path6.dirname(dir)) {
4729
+ if (existsSync2(path6.join(dir, ".osmo/project.json"))) return dir;
4730
+ if (path6.dirname(dir) === dir) return null;
4731
+ }
4732
+ }
4733
+ function here() {
4734
+ const root = projectFolder();
4735
+ if (!root) return null;
4736
+ const pointer = cloudPointer(root);
4737
+ let same = false;
4738
+ try {
4739
+ same = !!pointer && PROJECT_ID.test(pointer.id) && new URL(pointer.origin).origin === new URL(authOrigin()).origin;
4740
+ } catch {
4741
+ }
4742
+ return same && pointer ? { root, project: pointer.id } : { root };
4743
+ }
4744
+ async function generationsFolder(root) {
4745
+ const ours = path6.join(root, "generations");
4746
+ const listed = hasRepo(root) ? spawnSync2("git", ["-C", root, "ls-files", "--", "generations"], {
4747
+ encoding: "utf8"
4748
+ }) : null;
4749
+ const tracked = listed?.status === 0 && listed.stdout.trim() !== "";
4750
+ const theirs = tracked || existsSync2(ours) && !existsSync2(path6.join(ours, ".gitignore"));
4751
+ const folder = theirs ? path6.join(root, "osmo-generations") : ours;
4752
+ await mkdir4(folder, { recursive: true });
4753
+ const ignore = path6.join(folder, ".gitignore");
4754
+ if (!existsSync2(ignore)) await writeFile4(ignore, "*\n");
4755
+ return folder;
4756
+ }
1810
4757
  async function targets(run, out2) {
1811
4758
  const model = (run.model.split("/").pop() ?? "").replace(/[^A-Za-z0-9.-]/g, "-").replace(/^[.-]+/, "") || "output";
1812
4759
  const name = `${model}-${run.job.slice(4, 12)}`;
1813
4760
  const extension = (o) => {
1814
- const fromUrl = path4.extname(new URL(o.url).pathname).slice(1);
4761
+ const fromUrl = path6.extname(new URL(o.url).pathname).slice(1);
1815
4762
  return EXTENSIONS[o.mime] ?? (/^[A-Za-z0-9]{1,5}$/.test(fromUrl) ? fromUrl : "bin");
1816
4763
  };
1817
4764
  const several = run.outputs.length > 1;
1818
4765
  const named = run.outputs.map(
1819
4766
  (o, i) => `${name}${several ? `-${i + 1}` : ""}.${extension(o)}`
1820
4767
  );
1821
- if (out2 === void 0) return named;
1822
- const folder = /[/\\]$/.test(out2) || (await stat2(out2).catch(() => null))?.isDirectory() || several && !path4.extname(out2);
4768
+ if (out2 === void 0) {
4769
+ const project = here();
4770
+ if (!project) return named;
4771
+ const folder2 = await generationsFolder(project.root);
4772
+ return named.map(
4773
+ (n) => path6.relative(process.cwd(), path6.join(folder2, n)) || n
4774
+ );
4775
+ }
4776
+ const folder = /[/\\]$/.test(out2) || (await stat3(out2).catch(() => null))?.isDirectory() || several && !path6.extname(out2);
1823
4777
  if (!folder) {
1824
4778
  if (!several)
1825
4779
  return run.outputs.map(
1826
- (o) => path4.extname(out2) ? out2 : `${out2}.${extension(o)}`
4780
+ (o) => path6.extname(out2) ? out2 : `${out2}.${extension(o)}`
1827
4781
  );
1828
- const stem = out2.slice(0, -path4.extname(out2).length);
4782
+ const stem = out2.slice(0, -path6.extname(out2).length);
1829
4783
  return run.outputs.map((o, i) => `${stem}-${i + 1}.${extension(o)}`);
1830
4784
  }
1831
- await mkdir3(out2, { recursive: true });
1832
- return named.map((file) => path4.join(out2, file));
4785
+ await mkdir4(out2, { recursive: true });
4786
+ return named.map((file) => path6.join(out2, file));
1833
4787
  }
1834
4788
  async function save2(run, out2, io) {
1835
4789
  let partial;
1836
4790
  const stop = onInterrupt(() => {
1837
- if (partial) rmSync(partial, { force: true });
4791
+ if (partial) rmSync2(partial, { force: true });
1838
4792
  writeNow(
1839
4793
  io.json ? 1 : 2,
1840
4794
  io.json ? JSON.stringify({
@@ -1863,7 +4817,7 @@ Next: ${pickUp(run.job, out2)}`
1863
4817
  gone ? `${run.job}'s outputs are no longer kept. Outputs last 30 days.` : `Couldn't download ${run.job}'s output${response ? ` (${response.status})` : ""}.`,
1864
4818
  gone ? void 0 : pickUp(run.job, out2)
1865
4819
  );
1866
- await mkdir3(path4.dirname(path4.resolve(file)), { recursive: true });
4820
+ await mkdir4(path6.dirname(path6.resolve(file)), { recursive: true });
1867
4821
  partial = `${file}.part-${process.pid}`;
1868
4822
  try {
1869
4823
  await pipeline(
@@ -1872,15 +4826,15 @@ Next: ${pickUp(run.job, out2)}`
1872
4826
  ),
1873
4827
  createWriteStream(partial)
1874
4828
  );
1875
- await rename3(partial, file);
4829
+ await rename4(partial, file);
1876
4830
  } catch (error) {
1877
- await rm3(partial, { force: true });
4831
+ await rm4(partial, { force: true });
1878
4832
  throw error;
1879
4833
  } finally {
1880
4834
  partial = void 0;
1881
4835
  }
1882
- const bytes2 = (await stat2(file)).size;
1883
- const said = path4.extname(file).slice(1).toLowerCase();
4836
+ const bytes2 = (await stat3(file)).size;
4837
+ const said = path6.extname(file).slice(1).toLowerCase();
1884
4838
  const made = EXTENSIONS[output.mime];
1885
4839
  if (out2 !== void 0 && said && made && (said === "jpeg" ? "jpg" : said) !== made)
1886
4840
  io.log(`${file} holds ${output.mime}, which its name doesn't say.`);
@@ -1969,7 +4923,7 @@ async function runCommand(id, flags, io) {
1969
4923
  const schema = detail.run.inputSchema;
1970
4924
  const base = flags.inputs ? await readInputsFile(flags.inputs) : {};
1971
4925
  const { input, issues } = buildInputs(schema, flags.input ?? [], base);
1972
- const wanted = path4.extname(flags.out ?? "").slice(1).toLowerCase();
4926
+ const wanted = path6.extname(flags.out ?? "").slice(1).toLowerCase();
1973
4927
  const formats = schema.properties?.format?.enum;
1974
4928
  if (wanted && formats && input.format === void 0 && !issues.length) {
1975
4929
  const format = wanted === "jpeg" ? "jpg" : wanted;
@@ -2002,7 +4956,8 @@ Osmo: ${error.message}
2002
4956
  Next: ${error.next}`
2003
4957
  );
2004
4958
  });
2005
- const key = randomUUID2();
4959
+ const key = randomUUID3();
4960
+ const linked = here()?.project;
2006
4961
  const refusedFirst = (code) => ["runs_disabled", "model_unavailable"].includes(code ?? "");
2007
4962
  let started;
2008
4963
  try {
@@ -2014,7 +4969,9 @@ Next: ${error.next}`
2014
4969
  body: {
2015
4970
  model: detail.id,
2016
4971
  inputs: input,
2017
- ...flags.workspace ? { workspace: flags.workspace } : {}
4972
+ ...flags.workspace ? { workspace: flags.workspace } : {},
4973
+ // The linked project this runs in: the run is listed with it.
4974
+ ...linked ? { project: linked } : {}
2018
4975
  },
2019
4976
  wait: 0,
2020
4977
  headers: { "Idempotency-Key": key }
@@ -2074,6 +5031,8 @@ async function jobsCommand(job, flags, io) {
2074
5031
  if (job === void 0) {
2075
5032
  const params = new URLSearchParams({ limit: flags.limit ?? "20" });
2076
5033
  if (flags.cursor) params.set("cursor", flags.cursor);
5034
+ const project = flags.all ? void 0 : here()?.project;
5035
+ if (project) params.set("project", project);
2077
5036
  const page = await api(`/api/runs?${params}`);
2078
5037
  if (page.status === 400 && page.data.error === "invalid_cursor")
2079
5038
  throw new UsageError(
@@ -2091,7 +5050,9 @@ async function jobsCommand(job, flags, io) {
2091
5050
  status: "ok",
2092
5051
  runs: page.data.runs,
2093
5052
  nextCursor: page.data.nextCursor ?? null,
2094
- next: page.data.runs.length ? "osmo jobs JOB" : "osmo resources list --type model"
5053
+ ...project ? { inProject: true } : {},
5054
+ ...flags.all ? { all: true } : {},
5055
+ next: page.data.runs.length ? "osmo jobs JOB" : project ? "osmo jobs --all" : "osmo resources list --type model"
2095
5056
  };
2096
5057
  }
2097
5058
  if (!jobPattern.test(job))
@@ -2175,7 +5136,9 @@ Next: ${r.next}`;
2175
5136
  }
2176
5137
  function formatJobs(result) {
2177
5138
  const r = result;
2178
- if (!r.runs.length) return `No runs yet.
5139
+ if (!r.runs.length)
5140
+ return r.inProject ? `No runs in this project yet. osmo jobs --all lists all of yours.
5141
+ Next: ${r.next}` : `No runs yet.
2179
5142
  Next: ${r.next}`;
2180
5143
  const when = (iso) => {
2181
5144
  const d = new Date(iso);
@@ -2194,7 +5157,9 @@ Next: ${r.next}`;
2194
5157
  ...rows.map(
2195
5158
  (row) => row.map((cell, i) => i < 3 ? cell.padEnd(widths[i]) : cell).join(" ")
2196
5159
  ),
2197
- ...r.nextCursor ? [`\u2026 and older runs. Continue with: osmo jobs --cursor ${r.nextCursor}`] : [],
5160
+ ...r.nextCursor ? [
5161
+ `\u2026 and older runs. Continue with: osmo jobs --cursor ${r.nextCursor}${r.all ? " --all" : ""}`
5162
+ ] : [],
2198
5163
  "",
2199
5164
  `Next: ${r.next}`
2200
5165
  ].join("\n");
@@ -2264,7 +5229,10 @@ async function listShares(limit) {
2264
5229
  })),
2265
5230
  total: data.total,
2266
5231
  limit: limit ?? 50,
2267
- next: first ? `osmo share FILE.mp4 --to ${first.id}` : "osmo share FILE.mp4"
5232
+ // A video share's next names the share, so it is safe from any folder.
5233
+ // A Studio project's would be a deploy, which acts on whatever folder
5234
+ // the command runs in: the second share this list is meant to prevent.
5235
+ ...first?.kind === "repo" ? {} : { next: first ? newVersion(first) : "osmo share FILE.mp4" }
2268
5236
  };
2269
5237
  }
2270
5238
  function formatShares(result) {
@@ -2273,7 +5241,7 @@ function formatShares(result) {
2273
5241
  const more = result.total - result.shares.length;
2274
5242
  return [
2275
5243
  ...result.shares.map(
2276
- (s) => `${s.id} ${printable(s.name)}
5244
+ (s) => `${s.id} ${printable(s.name)}${s.kind === "repo" ? " (Studio project)" : ""}
2277
5245
  ${s.versions} version${s.versions === 1 ? "" : "s"}, last ${s.updatedAt.slice(0, 10)} ${s.shared ? s.link : "unshared"}`
2278
5246
  ),
2279
5247
  ...more > 0 ? [
@@ -2344,24 +5312,27 @@ async function deleteShare(value, yes = false) {
2344
5312
  async function unshare(value) {
2345
5313
  const share = await resolveShare(value);
2346
5314
  const origin = authOrigin();
5315
+ await unshareProject(share.id, origin);
5316
+ const restore = newVersion(share);
5317
+ return {
5318
+ status: "unshared",
5319
+ share: share.id,
5320
+ ...restore ? { restore } : {}
5321
+ };
5322
+ }
5323
+ async function unshareProject(projectId, origin) {
2347
5324
  const done = await call(
2348
5325
  origin,
2349
- `/api/projects/${share.id}/share`,
5326
+ `/api/projects/${projectId}/share`,
2350
5327
  { method: "DELETE", allow: [403] }
2351
5328
  );
2352
5329
  if (done.error === "scope_required") throw scopeRequired(origin, done.scope);
2353
5330
  if (done.error)
2354
5331
  throw new OsmoError(
2355
5332
  "forbidden",
2356
- `Only an owner of share ${share.id} can unshare it.`,
5333
+ `Only an owner of share ${projectId} can unshare it.`,
2357
5334
  "osmo shares"
2358
5335
  );
2359
- const restore = newVersion(share);
2360
- return {
2361
- status: "unshared",
2362
- share: share.id,
2363
- ...restore ? { restore } : {}
2364
- };
2365
5336
  }
2366
5337
  async function shareComments(value, {
2367
5338
  open = false,
@@ -2482,25 +5453,23 @@ async function commentAction(id, verb, text2, origin = authOrigin()) {
2482
5453
  "not_found",
2483
5454
  `No comment ${id} that you can answer. osmo comments list SHARE shows the comments on a share.`
2484
5455
  );
2485
- if (typeof done.id !== "string" || typeof done.render !== "string")
5456
+ if (typeof done.id !== "string" || done.render !== null && typeof done.render !== "string")
2486
5457
  throw new OsmoError(
2487
5458
  "invalid_response",
2488
5459
  `The cloud answered oddly, so ${id} may not have changed. osmo comments list SHARE shows it.`
2489
5460
  );
2490
- const versionLink = `${origin}/share/${done.render}`;
5461
+ const shown = done.render ? { version: done.render, versionLink: `${origin}/share/${done.render}` } : {};
2491
5462
  if (verb === "reply")
2492
5463
  return {
2493
5464
  status: "replied",
2494
5465
  id: done.parentId ?? id,
2495
5466
  reply: done.id,
2496
- version: done.render,
2497
- versionLink
5467
+ ...shown
2498
5468
  };
2499
5469
  return {
2500
5470
  status: verb === "resolve" ? "resolved" : "reopened",
2501
5471
  id: done.id,
2502
- version: done.render,
2503
- versionLink
5472
+ ...shown
2504
5473
  };
2505
5474
  }
2506
5475
 
@@ -2596,8 +5565,8 @@ function formatUsage(result, now = Date.now()) {
2596
5565
 
2597
5566
  // src/video-deploy.ts
2598
5567
  import { execFile } from "node:child_process";
2599
- import { stat as stat3 } from "node:fs/promises";
2600
- import path5 from "node:path";
5568
+ import { stat as stat4 } from "node:fs/promises";
5569
+ import path7 from "node:path";
2601
5570
  import { promisify } from "node:util";
2602
5571
 
2603
5572
  // src/upload-render.ts
@@ -2702,7 +5671,7 @@ async function uploadRender(origin, project, file, metadata, log = () => {
2702
5671
  // src/video-deploy.ts
2703
5672
  var exec = promisify(execFile);
2704
5673
  async function probeVideo(file) {
2705
- const info = await stat3(file).catch(() => null);
5674
+ const info = await stat4(file).catch(() => null);
2706
5675
  if (!info?.isFile() || !info.size || info.size > 2 * 1024 ** 3)
2707
5676
  throw new Error(
2708
5677
  "Video must be an existing, non-empty file no larger than 2 GiB."
@@ -2766,9 +5735,9 @@ async function shareVideo(file, {
2766
5735
  if (to !== void 0) parseShare(to, origin);
2767
5736
  if (name !== void 0 && (!name.trim() || name.trim().length > 200))
2768
5737
  throw new Error("--name takes 1 to 200 characters.");
2769
- const source = path5.resolve(file), metadata = await probeVideo(source);
5738
+ const source = path7.resolve(file), metadata = await probeVideo(source);
2770
5739
  await currentAccount(origin);
2771
- const title = name?.trim() ?? path5.basename(source).slice(0, 200);
5740
+ const title = name?.trim() ?? path7.basename(source).slice(0, 200);
2772
5741
  const target = to === void 0 ? void 0 : await resolveShare(to);
2773
5742
  if (target?.kind === "repo")
2774
5743
  throw new OsmoError(
@@ -2811,14 +5780,14 @@ Retry with --to ${share} to add it to the same share.`,
2811
5780
  }
2812
5781
 
2813
5782
  // src/commands.ts
2814
- var auth = (path7, usage, about, args, flags) => ({
2815
- path: path7,
5783
+ var auth = (path9, usage, about, args, flags) => ({
5784
+ path: path9,
2816
5785
  group: "Account",
2817
5786
  usage,
2818
5787
  about,
2819
5788
  args,
2820
5789
  flags,
2821
- run: (rest, flags2) => authCommand([...path7, ...rest], flags2),
5790
+ run: (rest, flags2) => authCommand([...path9, ...rest], flags2),
2822
5791
  text: (result) => formatAuth(result),
2823
5792
  failed: (result) => ["denied", "expired"].includes(result.status)
2824
5793
  });
@@ -3013,15 +5982,16 @@ var COMMANDS = [
3013
5982
  },
3014
5983
  {
3015
5984
  path: ["resources", "get"],
5985
+ aliases: [["resources", "install"]],
3016
5986
  group: "Resources and models",
3017
5987
  usage: "resources get ID[@VERSION] [--out DIR]",
3018
- about: "Downloads a package into a folder and checks every file against the catalog's checksums: a shader's WGSL source and typed uniforms, or a 3D model's GLB. It prints a usage snippet per preset, for a scene in an Osmo project. Needs osmo login.",
5988
+ about: "Downloads a package into a folder and checks every file against the catalog's checksums: a shader's WGSL source and typed uniforms, or a 3D model's GLB. It prints a usage snippet per preset, for a scene in an Osmo project. Film resources install globally for every project without login: osmo resources get film installs the full library. Other downloads need osmo login.",
3019
5989
  args: [1, 1],
3020
5990
  flags: {
3021
5991
  out: out("DIR", "Where to put the files. Default: ./NAME, as in ./silk.")
3022
5992
  },
3023
5993
  example: "osmo resources get osmo/silk",
3024
- run: (args, flags) => resourcesCommand("get", args, flags),
5994
+ run: (args, flags, io) => resourcesCommand("get", args, flags, io),
3025
5995
  text: formatResources
3026
5996
  },
3027
5997
  {
@@ -3044,7 +6014,7 @@ var COMMANDS = [
3044
6014
  },
3045
6015
  out: out(
3046
6016
  "PATH",
3047
- "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT here."
6017
+ "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT in the project's generations/ (kept out of its versions), or here outside a project."
3048
6018
  ),
3049
6019
  "no-wait": {
3050
6020
  type: "boolean",
@@ -3065,13 +6035,13 @@ var COMMANDS = [
3065
6035
  {
3066
6036
  path: ["jobs"],
3067
6037
  group: "Resources and models",
3068
- usage: "jobs [JOB] [--out PATH] [--limit N]",
3069
- about: "Lists your recent runs, newest first. With a JOB, waits for it and saves its outputs, which are kept for 30 days.",
6038
+ usage: "jobs [JOB] [--out PATH] [--limit N] [--all]",
6039
+ about: "Lists your recent runs, newest first: in a project linked to the cloud, that project's. With a JOB, waits for it and saves its outputs, which are kept for 30 days.",
3070
6040
  args: [0, 1],
3071
6041
  flags: {
3072
6042
  out: out(
3073
6043
  "PATH",
3074
- "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT here."
6044
+ "A file for one output, replacing one of that name, or a folder. A file name with no extension gets the output's. Default: MODEL-JOB.EXT in the project's generations/ (kept out of its versions), or here outside a project."
3075
6045
  ),
3076
6046
  limit: {
3077
6047
  type: "string",
@@ -3082,6 +6052,10 @@ var COMMANDS = [
3082
6052
  type: "string",
3083
6053
  value: "CURSOR",
3084
6054
  help: "Continue a cut-off list from its nextCursor."
6055
+ },
6056
+ all: {
6057
+ type: "boolean",
6058
+ help: "List all your runs, not only this project's."
3085
6059
  }
3086
6060
  },
3087
6061
  example: "osmo jobs run_abc12345",
@@ -3096,6 +6070,11 @@ var COMMANDS = [
3096
6070
  "--out needs a job: osmo jobs JOB --out PATH.",
3097
6071
  "osmo jobs --help"
3098
6072
  );
6073
+ if (args.length && flags.all)
6074
+ throw new UsageError(
6075
+ "--all widens the list, which osmo jobs prints without a JOB.",
6076
+ "osmo jobs --help"
6077
+ );
3099
6078
  if (args.length && (flags.limit !== void 0 || flags.cursor !== void 0))
3100
6079
  throw new UsageError(
3101
6080
  "--limit and --cursor page the list, which osmo jobs prints without a JOB.",
@@ -3289,7 +6268,7 @@ Version: ${r.versionLink}`;
3289
6268
  studio(
3290
6269
  "clone",
3291
6270
  "PROJECT [FOLDER]",
3292
- "Copies a project from the cloud into a new folder, with its history. PROJECT is the project's ID, or the link to its page or its review. FOLDER defaults to the project's name. Needs osmo login and access to the project.",
6271
+ "Copies a cloud project and its history into a new folder. Legacy web-editor projects download as text exports with asset URLs and require conversion before local editing. PROJECT is an ID or project/review link. FOLDER defaults to the project name, or legacy-<id> for legacy exports. Needs osmo login and source access.",
3293
6272
  [1, 2],
3294
6273
  { example: "osmo studio clone https://studio.osmo.inc/app/projects/ID" }
3295
6274
  ),
@@ -3345,11 +6324,15 @@ Version: ${r.versionLink}`;
3345
6324
  ),
3346
6325
  studio(
3347
6326
  "render",
3348
- "[SCENE] [--at SECONDS] [--out FILE]",
3349
- "Renders a scene to an MP4, or with --at to one PNG of the frame at that time. It saves into the project's exports folder unless --out names the file, and replaces a file already there. An MP4 needs FFmpeg. No login needed.",
6327
+ "[SCENE] [--at SECONDS] [--out FILE] [--original]",
6328
+ "Renders a scene to MP4, MOV (ProRes 4444), WebM, or with --at to one PNG. Uses Video.src by default. Add --original to use Video.originalSrc where set; missing originals fail. The editor and cloud use Video.src. It saves into the project's exports folder unless --out names the file, and replaces a file already there. Video export needs FFmpeg. BRAW needs Blackmagic RAW 6 on macOS. No login needed.",
3350
6329
  [0, 1],
3351
6330
  {
3352
6331
  flags: {
6332
+ original: {
6333
+ type: "boolean",
6334
+ help: "Use local Video.originalSrc where set; recommended for final RAW renders. Fails if an original is missing."
6335
+ },
3353
6336
  at: {
3354
6337
  type: "string",
3355
6338
  value: "SECONDS",
@@ -3490,9 +6473,9 @@ var GLOBAL_FLAGS = {
3490
6473
  function findCommand(words2) {
3491
6474
  let found;
3492
6475
  for (const command of COMMANDS)
3493
- for (const path7 of [command.path, ...command.aliases ?? []])
3494
- if (path7.length <= words2.length && path7.every((word, i) => words2[i] === word) && path7.length > (found?.length ?? 0))
3495
- found = { command, length: path7.length };
6476
+ for (const path9 of [command.path, ...command.aliases ?? []])
6477
+ if (path9.length <= words2.length && path9.every((word, i) => words2[i] === word) && path9.length > (found?.length ?? 0))
6478
+ found = { command, length: path9.length };
3496
6479
  return found && { command: found.command, rest: words2.slice(found.length) };
3497
6480
  }
3498
6481
  function commandHelp(command) {
@@ -3504,7 +6487,7 @@ function commandHelp(command) {
3504
6487
  );
3505
6488
  const width = Math.max(...names.map((name) => name.length));
3506
6489
  const aliases = (command.aliases ?? []).map(
3507
- (path7) => `osmo ${path7.join(" ")}`
6490
+ (path9) => `osmo ${path9.join(" ")}`
3508
6491
  );
3509
6492
  return [
3510
6493
  `osmo ${command.usage}`,
@@ -3684,17 +6667,17 @@ async function loadStudio() {
3684
6667
  manifest2 = createRequire(import.meta.url).resolve(
3685
6668
  `@osmo.inc/cli-${platform}/package.json`
3686
6669
  );
3687
- entry = path6.join(path6.dirname(manifest2), "dist/studio.js");
6670
+ entry = path8.join(path8.dirname(manifest2), "dist/studio.js");
3688
6671
  } catch {
3689
6672
  }
3690
- if (!existsSync(entry))
6673
+ if (!existsSync3(entry))
3691
6674
  throw new OsmoError(
3692
6675
  "studio_unavailable",
3693
6676
  PLATFORMS.includes(platform) ? `Osmo Studio and its renderer aren't installed: @osmo.inc/cli-${platform} is missing. Reinstall @osmo.inc/cli with optional dependencies; if that doesn't add it, this release has no package for ${platform}.` : `Osmo Studio's renderer isn't available for ${platform} yet. It runs on ${PLATFORMS.join(", ")}.`,
3694
6677
  PLATFORMS.includes(platform) ? "npm install -g @osmo.inc/cli" : void 0
3695
6678
  );
3696
6679
  if (manifest2) {
3697
- const installed = JSON.parse(readFileSync(manifest2, "utf8")).version;
6680
+ const installed = JSON.parse(readFileSync2(manifest2, "utf8")).version;
3698
6681
  if (installed !== version)
3699
6682
  throw new OsmoError(
3700
6683
  "studio_mismatch",