@promptbook/remote-server 0.112.0-73 → 0.112.0-80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/esm/index.es.js +823 -374
- package/esm/index.es.js.map +1 -1
- package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/esm/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/esm/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/esm/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/esm/src/book-components/Chat/save/index.d.ts +2 -2
- package/esm/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/esm/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/esm/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/esm/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/esm/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/esm/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/esm/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/esm/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/esm/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/esm/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/esm/src/utils/color/Color.d.ts +4 -44
- package/esm/src/utils/color/ColorValue.d.ts +55 -0
- package/esm/src/utils/color/isHexColorString.d.ts +10 -0
- package/esm/src/utils/color/parseColorString.d.ts +11 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +823 -374
- package/umd/index.umd.js.map +1 -1
- package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/umd/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/umd/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/umd/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/umd/src/book-components/Chat/save/index.d.ts +2 -2
- package/umd/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/umd/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/umd/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/umd/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/umd/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/umd/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/umd/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/umd/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/umd/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/umd/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/umd/src/utils/color/Color.d.ts +4 -44
- package/umd/src/utils/color/ColorValue.d.ts +55 -0
- package/umd/src/utils/color/isHexColorString.d.ts +10 -0
- package/umd/src/utils/color/parseColorString.d.ts +11 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/esm/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
package/umd/index.umd.js
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
* @generated
|
|
51
51
|
* @see https://github.com/webgptorg/promptbook
|
|
52
52
|
*/
|
|
53
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
53
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-80';
|
|
54
54
|
/**
|
|
55
55
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
56
56
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -300,6 +300,111 @@
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
305
|
+
*
|
|
306
|
+
* @private base class of Color
|
|
307
|
+
*/
|
|
308
|
+
class ColorValue {
|
|
309
|
+
constructor(red, green, blue, alpha = 255) {
|
|
310
|
+
this.red = red;
|
|
311
|
+
this.green = green;
|
|
312
|
+
this.blue = blue;
|
|
313
|
+
this.alpha = alpha;
|
|
314
|
+
checkChannelValue('Red', red);
|
|
315
|
+
checkChannelValue('Green', green);
|
|
316
|
+
checkChannelValue('Blue', blue);
|
|
317
|
+
checkChannelValue('Alpha', alpha);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Shortcut for `red` property
|
|
321
|
+
* Number from 0 to 255
|
|
322
|
+
* @alias red
|
|
323
|
+
*/
|
|
324
|
+
get r() {
|
|
325
|
+
return this.red;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Shortcut for `green` property
|
|
329
|
+
* Number from 0 to 255
|
|
330
|
+
* @alias green
|
|
331
|
+
*/
|
|
332
|
+
get g() {
|
|
333
|
+
return this.green;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Shortcut for `blue` property
|
|
337
|
+
* Number from 0 to 255
|
|
338
|
+
* @alias blue
|
|
339
|
+
*/
|
|
340
|
+
get b() {
|
|
341
|
+
return this.blue;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Shortcut for `alpha` property
|
|
345
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
346
|
+
* @alias alpha
|
|
347
|
+
*/
|
|
348
|
+
get a() {
|
|
349
|
+
return this.alpha;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Shortcut for `alpha` property
|
|
353
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
354
|
+
* @alias alpha
|
|
355
|
+
*/
|
|
356
|
+
get opacity() {
|
|
357
|
+
return this.alpha;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Shortcut for 1-`alpha` property
|
|
361
|
+
*/
|
|
362
|
+
get transparency() {
|
|
363
|
+
return 255 - this.alpha;
|
|
364
|
+
}
|
|
365
|
+
clone() {
|
|
366
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
367
|
+
}
|
|
368
|
+
toString() {
|
|
369
|
+
return this.toHex();
|
|
370
|
+
}
|
|
371
|
+
toHex() {
|
|
372
|
+
if (this.alpha === 255) {
|
|
373
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
374
|
+
.toString(16)
|
|
375
|
+
.padStart(2, '0')}`;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
379
|
+
.toString(16)
|
|
380
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
toRgb() {
|
|
384
|
+
if (this.alpha === 255) {
|
|
385
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
toHsl() {
|
|
392
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Checks if the given value is a valid hex color string
|
|
398
|
+
*
|
|
399
|
+
* @param value - value to check
|
|
400
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
401
|
+
*
|
|
402
|
+
* @private function of Color
|
|
403
|
+
*/
|
|
404
|
+
function isHexColorString(value) {
|
|
405
|
+
return (typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
406
|
+
}
|
|
407
|
+
|
|
303
408
|
/**
|
|
304
409
|
* Constant for short hex lengths.
|
|
305
410
|
*/
|
|
@@ -511,16 +616,53 @@
|
|
|
511
616
|
|
|
512
617
|
/**
|
|
513
618
|
* Pattern matching hsl regex.
|
|
619
|
+
*
|
|
620
|
+
* @private function of Color
|
|
514
621
|
*/
|
|
515
622
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
516
623
|
/**
|
|
517
624
|
* Pattern matching RGB regex.
|
|
625
|
+
*
|
|
626
|
+
* @private function of Color
|
|
518
627
|
*/
|
|
519
628
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
520
629
|
/**
|
|
521
630
|
* Pattern matching rgba regex.
|
|
631
|
+
*
|
|
632
|
+
* @private function of Color
|
|
522
633
|
*/
|
|
523
634
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
635
|
+
/**
|
|
636
|
+
* Parses a supported color string into RGBA channels.
|
|
637
|
+
*
|
|
638
|
+
* @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...
|
|
639
|
+
* @returns RGBA channel values.
|
|
640
|
+
*
|
|
641
|
+
* @private function of Color
|
|
642
|
+
*/
|
|
643
|
+
function parseColorString(color) {
|
|
644
|
+
const trimmed = color.trim();
|
|
645
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
646
|
+
if (cssColor) {
|
|
647
|
+
return parseColorString(cssColor);
|
|
648
|
+
}
|
|
649
|
+
else if (isHexColorString(trimmed)) {
|
|
650
|
+
return parseHexColor(trimmed);
|
|
651
|
+
}
|
|
652
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
653
|
+
return parseHslColor(trimmed);
|
|
654
|
+
}
|
|
655
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
656
|
+
return parseRgbColor(trimmed);
|
|
657
|
+
}
|
|
658
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
659
|
+
return parseRgbaColor(trimmed);
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
524
666
|
/**
|
|
525
667
|
* Color object represents an RGB color with alpha channel
|
|
526
668
|
*
|
|
@@ -528,7 +670,7 @@
|
|
|
528
670
|
*
|
|
529
671
|
* @public exported from `@promptbook/color`
|
|
530
672
|
*/
|
|
531
|
-
class Color {
|
|
673
|
+
class Color extends ColorValue {
|
|
532
674
|
/**
|
|
533
675
|
* Creates a new Color instance from miscellaneous formats
|
|
534
676
|
* - It can receive Color instance and just return the same instance
|
|
@@ -601,25 +743,7 @@
|
|
|
601
743
|
* @returns Color object
|
|
602
744
|
*/
|
|
603
745
|
static fromString(color) {
|
|
604
|
-
|
|
605
|
-
if (CSS_COLORS[trimmed]) {
|
|
606
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
607
|
-
}
|
|
608
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
609
|
-
return Color.fromHex(trimmed);
|
|
610
|
-
}
|
|
611
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
612
|
-
return Color.fromHsl(trimmed);
|
|
613
|
-
}
|
|
614
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
615
|
-
return Color.fromRgbString(trimmed);
|
|
616
|
-
}
|
|
617
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
618
|
-
return Color.fromRgbaString(trimmed);
|
|
619
|
-
}
|
|
620
|
-
else {
|
|
621
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
622
|
-
}
|
|
746
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
623
747
|
}
|
|
624
748
|
/**
|
|
625
749
|
* Gets common color
|
|
@@ -649,8 +773,7 @@
|
|
|
649
773
|
* @returns Color object
|
|
650
774
|
*/
|
|
651
775
|
static fromHex(hex) {
|
|
652
|
-
|
|
653
|
-
return take(new Color(red, green, blue, alpha));
|
|
776
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
654
777
|
}
|
|
655
778
|
/**
|
|
656
779
|
* Creates a new Color instance from color in hsl format
|
|
@@ -659,8 +782,7 @@
|
|
|
659
782
|
* @returns Color object
|
|
660
783
|
*/
|
|
661
784
|
static fromHsl(hsl) {
|
|
662
|
-
|
|
663
|
-
return take(new Color(red, green, blue, alpha));
|
|
785
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
664
786
|
}
|
|
665
787
|
/**
|
|
666
788
|
* Creates a new Color instance from color in rgb format
|
|
@@ -669,8 +791,7 @@
|
|
|
669
791
|
* @returns Color object
|
|
670
792
|
*/
|
|
671
793
|
static fromRgbString(rgb) {
|
|
672
|
-
|
|
673
|
-
return take(new Color(red, green, blue, alpha));
|
|
794
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
674
795
|
}
|
|
675
796
|
/**
|
|
676
797
|
* Creates a new Color instance from color in rbga format
|
|
@@ -679,8 +800,7 @@
|
|
|
679
800
|
* @returns Color object
|
|
680
801
|
*/
|
|
681
802
|
static fromRgbaString(rgba) {
|
|
682
|
-
|
|
683
|
-
return take(new Color(red, green, blue, alpha));
|
|
803
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
684
804
|
}
|
|
685
805
|
/**
|
|
686
806
|
* Creates a new Color for color channels values
|
|
@@ -692,7 +812,7 @@
|
|
|
692
812
|
* @returns Color object
|
|
693
813
|
*/
|
|
694
814
|
static fromValues(red, green, blue, alpha = 255) {
|
|
695
|
-
return
|
|
815
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
696
816
|
}
|
|
697
817
|
/**
|
|
698
818
|
* Checks if the given value is a valid Color object.
|
|
@@ -725,8 +845,7 @@
|
|
|
725
845
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
726
846
|
*/
|
|
727
847
|
static isHexColorString(value) {
|
|
728
|
-
return (
|
|
729
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
848
|
+
return isHexColorString(value);
|
|
730
849
|
}
|
|
731
850
|
/**
|
|
732
851
|
* Creates new Color object
|
|
@@ -739,89 +858,13 @@
|
|
|
739
858
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
740
859
|
*/
|
|
741
860
|
constructor(red, green, blue, alpha = 255) {
|
|
742
|
-
|
|
743
|
-
this.green = green;
|
|
744
|
-
this.blue = blue;
|
|
745
|
-
this.alpha = alpha;
|
|
746
|
-
checkChannelValue('Red', red);
|
|
747
|
-
checkChannelValue('Green', green);
|
|
748
|
-
checkChannelValue('Blue', blue);
|
|
749
|
-
checkChannelValue('Alpha', alpha);
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Shortcut for `red` property
|
|
753
|
-
* Number from 0 to 255
|
|
754
|
-
* @alias red
|
|
755
|
-
*/
|
|
756
|
-
get r() {
|
|
757
|
-
return this.red;
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Shortcut for `green` property
|
|
761
|
-
* Number from 0 to 255
|
|
762
|
-
* @alias green
|
|
763
|
-
*/
|
|
764
|
-
get g() {
|
|
765
|
-
return this.green;
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Shortcut for `blue` property
|
|
769
|
-
* Number from 0 to 255
|
|
770
|
-
* @alias blue
|
|
771
|
-
*/
|
|
772
|
-
get b() {
|
|
773
|
-
return this.blue;
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Shortcut for `alpha` property
|
|
777
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
778
|
-
* @alias alpha
|
|
779
|
-
*/
|
|
780
|
-
get a() {
|
|
781
|
-
return this.alpha;
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Shortcut for `alpha` property
|
|
785
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
786
|
-
* @alias alpha
|
|
787
|
-
*/
|
|
788
|
-
get opacity() {
|
|
789
|
-
return this.alpha;
|
|
790
|
-
}
|
|
791
|
-
/**
|
|
792
|
-
* Shortcut for 1-`alpha` property
|
|
793
|
-
*/
|
|
794
|
-
get transparency() {
|
|
795
|
-
return 255 - this.alpha;
|
|
796
|
-
}
|
|
797
|
-
clone() {
|
|
798
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
799
|
-
}
|
|
800
|
-
toString() {
|
|
801
|
-
return this.toHex();
|
|
802
|
-
}
|
|
803
|
-
toHex() {
|
|
804
|
-
if (this.alpha === 255) {
|
|
805
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
806
|
-
.toString(16)
|
|
807
|
-
.padStart(2, '0')}`;
|
|
808
|
-
}
|
|
809
|
-
else {
|
|
810
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
811
|
-
.toString(16)
|
|
812
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
813
|
-
}
|
|
861
|
+
super(red, green, blue, alpha);
|
|
814
862
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
818
|
-
}
|
|
819
|
-
else {
|
|
820
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
821
|
-
}
|
|
863
|
+
createColor(red, green, blue, alpha) {
|
|
864
|
+
return new Color(red, green, blue, alpha);
|
|
822
865
|
}
|
|
823
|
-
|
|
824
|
-
|
|
866
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
867
|
+
return take(new Color(red, green, blue, alpha));
|
|
825
868
|
}
|
|
826
869
|
}
|
|
827
870
|
|
|
@@ -2181,120 +2224,183 @@
|
|
|
2181
2224
|
* @public exported from `@promptbook/utils`
|
|
2182
2225
|
*/
|
|
2183
2226
|
function checkSerializableAsJson(options) {
|
|
2184
|
-
|
|
2227
|
+
checkSerializableValue(options);
|
|
2228
|
+
}
|
|
2229
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
2230
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
2231
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
2232
|
+
/**
|
|
2233
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
2234
|
+
*
|
|
2235
|
+
* @private function of `checkSerializableAsJson`
|
|
2236
|
+
*/
|
|
2237
|
+
function checkSerializableValue(options) {
|
|
2238
|
+
const { value } = options;
|
|
2239
|
+
if (isSerializablePrimitive(value)) {
|
|
2240
|
+
return;
|
|
2241
|
+
}
|
|
2185
2242
|
if (value === undefined) {
|
|
2186
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
2243
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
2187
2244
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2245
|
+
if (typeof value === 'symbol') {
|
|
2246
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
2190
2247
|
}
|
|
2191
|
-
|
|
2192
|
-
|
|
2248
|
+
if (typeof value === 'function') {
|
|
2249
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
2193
2250
|
}
|
|
2194
|
-
|
|
2251
|
+
if (Array.isArray(value)) {
|
|
2252
|
+
checkSerializableArray(options, value);
|
|
2195
2253
|
return;
|
|
2196
2254
|
}
|
|
2197
|
-
|
|
2255
|
+
if (value !== null && typeof value === 'object') {
|
|
2256
|
+
checkSerializableObject(options, value);
|
|
2198
2257
|
return;
|
|
2199
2258
|
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2259
|
+
throwUnknownTypeError(options);
|
|
2260
|
+
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
2263
|
+
*
|
|
2264
|
+
* @private function of `checkSerializableAsJson`
|
|
2265
|
+
*/
|
|
2266
|
+
function isSerializablePrimitive(value) {
|
|
2267
|
+
return (value === null ||
|
|
2268
|
+
typeof value === 'boolean' ||
|
|
2269
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
2270
|
+
typeof value === 'string');
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Recursively checks JSON array items.
|
|
2274
|
+
*
|
|
2275
|
+
* @private function of `checkSerializableAsJson`
|
|
2276
|
+
*/
|
|
2277
|
+
function checkSerializableArray(context, arrayValue) {
|
|
2278
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
2279
|
+
checkSerializableAsJson({
|
|
2280
|
+
...context,
|
|
2281
|
+
name: `${context.name}[${index}]`,
|
|
2282
|
+
value: arrayValue[index],
|
|
2283
|
+
});
|
|
2210
2284
|
}
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
2288
|
+
*
|
|
2289
|
+
* @private function of `checkSerializableAsJson`
|
|
2290
|
+
*/
|
|
2291
|
+
function checkSerializableObject(context, objectValue) {
|
|
2292
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
2293
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
2294
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
2298
|
+
*
|
|
2299
|
+
* @private function of `checkSerializableAsJson`
|
|
2300
|
+
*/
|
|
2301
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
2302
|
+
if (objectValue instanceof Date) {
|
|
2303
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim((block) => `
|
|
2304
|
+
\`${context.name}\` is Date
|
|
2215
2305
|
|
|
2216
|
-
|
|
2306
|
+
Use \`string_date_iso8601\` instead
|
|
2217
2307
|
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2308
|
+
Additional message for \`${context.name}\`:
|
|
2309
|
+
${block(context.message || '(nothing)')}
|
|
2310
|
+
`));
|
|
2311
|
+
}
|
|
2312
|
+
if (objectValue instanceof Map) {
|
|
2313
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
2314
|
+
}
|
|
2315
|
+
if (objectValue instanceof Set) {
|
|
2316
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
2317
|
+
}
|
|
2318
|
+
if (objectValue instanceof RegExp) {
|
|
2319
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
2320
|
+
}
|
|
2321
|
+
if (objectValue instanceof Error) {
|
|
2322
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim((block) => `
|
|
2323
|
+
\`${context.name}\` is unserialized Error
|
|
2234
2324
|
|
|
2235
|
-
|
|
2325
|
+
Use function \`serializeError\`
|
|
2236
2326
|
|
|
2237
|
-
|
|
2238
|
-
|
|
2327
|
+
Additional message for \`${context.name}\`:
|
|
2328
|
+
${block(context.message || '(nothing)')}
|
|
2239
2329
|
|
|
2240
|
-
|
|
2330
|
+
`));
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
2335
|
+
*
|
|
2336
|
+
* @private function of `checkSerializableAsJson`
|
|
2337
|
+
*/
|
|
2338
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
2339
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
2340
|
+
if (subValue === undefined) {
|
|
2341
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
2342
|
+
continue;
|
|
2241
2343
|
}
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2344
|
+
checkSerializableAsJson({
|
|
2345
|
+
...context,
|
|
2346
|
+
name: `${context.name}.${subName}`,
|
|
2347
|
+
value: subValue,
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
2353
|
+
*
|
|
2354
|
+
* @private function of `checkSerializableAsJson`
|
|
2355
|
+
*/
|
|
2356
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
2357
|
+
try {
|
|
2358
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
2359
|
+
}
|
|
2360
|
+
catch (error) {
|
|
2361
|
+
assertsError(error);
|
|
2362
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim((block) => `
|
|
2363
|
+
\`${context.name}\` is not serializable
|
|
2257
2364
|
|
|
2258
|
-
|
|
2365
|
+
${block(error.stack || error.message)}
|
|
2259
2366
|
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2367
|
+
Additional message for \`${context.name}\`:
|
|
2368
|
+
${block(context.message || '(nothing)')}
|
|
2369
|
+
`));
|
|
2370
|
+
}
|
|
2371
|
+
/*
|
|
2372
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
2373
|
+
const seen = new Set();
|
|
2374
|
+
const stack = [{ value }];
|
|
2375
|
+
while (stack.length > 0) {
|
|
2376
|
+
const { value } = stack.pop()!;
|
|
2377
|
+
if (typeof value === 'object' && value !== null) {
|
|
2378
|
+
if (seen.has(value)) {
|
|
2379
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
2263
2380
|
}
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
const { value } = stack.pop()!;
|
|
2270
|
-
if (typeof value === 'object' && value !== null) {
|
|
2271
|
-
if (seen.has(value)) {
|
|
2272
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
2273
|
-
}
|
|
2274
|
-
seen.add(value);
|
|
2275
|
-
if (Array.isArray(value)) {
|
|
2276
|
-
stack.push(...value.map((value) => ({ value })));
|
|
2277
|
-
} else {
|
|
2278
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2381
|
+
seen.add(value);
|
|
2382
|
+
if (Array.isArray(value)) {
|
|
2383
|
+
stack.push(...value.map((value) => ({ value })));
|
|
2384
|
+
} else {
|
|
2385
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
2281
2386
|
}
|
|
2282
|
-
*/
|
|
2283
|
-
return;
|
|
2284
2387
|
}
|
|
2285
2388
|
}
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2389
|
+
*/
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
2393
|
+
*
|
|
2394
|
+
* @private function of `checkSerializableAsJson`
|
|
2395
|
+
*/
|
|
2396
|
+
function throwUnknownTypeError(context) {
|
|
2397
|
+
throw new UnexpectedError(_spaceTrim.spaceTrim((block) => `
|
|
2398
|
+
\`${context.name}\` is unknown type
|
|
2289
2399
|
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
}
|
|
2400
|
+
Additional message for \`${context.name}\`:
|
|
2401
|
+
${block(context.message || '(nothing)')}
|
|
2402
|
+
`));
|
|
2294
2403
|
}
|
|
2295
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
2296
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
2297
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
2298
2404
|
|
|
2299
2405
|
/**
|
|
2300
2406
|
* Creates a deep clone of the given object
|
|
@@ -2927,8 +3033,7 @@
|
|
|
2927
3033
|
* @private internal utility of `validatePipeline`
|
|
2928
3034
|
*/
|
|
2929
3035
|
function validateTaskSupportsJokers(task, pipelineIdentification) {
|
|
2930
|
-
if (task.format ||
|
|
2931
|
-
task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
3036
|
+
if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
2932
3037
|
return;
|
|
2933
3038
|
}
|
|
2934
3039
|
throw new PipelineLogicError(_spaceTrim.spaceTrim((block) => `
|
|
@@ -4045,7 +4150,7 @@
|
|
|
4045
4150
|
*/
|
|
4046
4151
|
function createPostprocessingCommands(task) {
|
|
4047
4152
|
var _a;
|
|
4048
|
-
return ((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || [];
|
|
4153
|
+
return (((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || []);
|
|
4049
4154
|
}
|
|
4050
4155
|
/**
|
|
4051
4156
|
* Collects expectation commands.
|
|
@@ -7476,9 +7581,7 @@
|
|
|
7476
7581
|
${block(quoteMultilineText(((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message) || ''))}
|
|
7477
7582
|
|
|
7478
7583
|
Result:
|
|
7479
|
-
${block(failure.result === null
|
|
7480
|
-
? 'null'
|
|
7481
|
-
: quoteMultilineText(_spaceTrim.spaceTrim(failure.result)))}
|
|
7584
|
+
${block(failure.result === null ? 'null' : quoteMultilineText(_spaceTrim.spaceTrim(failure.result)))}
|
|
7482
7585
|
`;
|
|
7483
7586
|
}))
|
|
7484
7587
|
.join('\n\n---\n\n');
|
|
@@ -9060,10 +9163,7 @@
|
|
|
9060
9163
|
* @private internal function of `$registeredLlmToolsMessage`
|
|
9061
9164
|
*/
|
|
9062
9165
|
function createProviderStatusMessages(llmToolStatus, env) {
|
|
9063
|
-
return [
|
|
9064
|
-
createInstallationStatusMessage(llmToolStatus),
|
|
9065
|
-
createConfigurationStatusMessage(llmToolStatus, env),
|
|
9066
|
-
];
|
|
9166
|
+
return [createInstallationStatusMessage(llmToolStatus), createConfigurationStatusMessage(llmToolStatus, env)];
|
|
9067
9167
|
}
|
|
9068
9168
|
/**
|
|
9069
9169
|
* Creates the installation-status sentence for one provider.
|
|
@@ -14626,7 +14726,7 @@
|
|
|
14626
14726
|
*
|
|
14627
14727
|
* @private helper of `minecraft2AvatarVisual`
|
|
14628
14728
|
*/
|
|
14629
|
-
const LIGHT_DIRECTION$
|
|
14729
|
+
const LIGHT_DIRECTION$2 = normalizeVector3({
|
|
14630
14730
|
x: 0.4,
|
|
14631
14731
|
y: -0.65,
|
|
14632
14732
|
z: 0.92,
|
|
@@ -14838,7 +14938,7 @@
|
|
|
14838
14938
|
corners: projectedCorners,
|
|
14839
14939
|
texture: faceDefinition.texture,
|
|
14840
14940
|
averageDepth: transformedCorners.reduce((depthSum, corner) => depthSum + corner.z, 0) / transformedCorners.length,
|
|
14841
|
-
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$
|
|
14941
|
+
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$2), -1, 1),
|
|
14842
14942
|
outlineColor: cuboid.outlineColor,
|
|
14843
14943
|
};
|
|
14844
14944
|
});
|
|
@@ -15898,13 +15998,138 @@
|
|
|
15898
15998
|
context.restore();
|
|
15899
15999
|
}
|
|
15900
16000
|
|
|
16001
|
+
/* eslint-disable no-magic-numbers */
|
|
16002
|
+
/**
|
|
16003
|
+
* Draws one projected eye on a rotated octopus surface.
|
|
16004
|
+
*
|
|
16005
|
+
* @private helper of the 3D octopus avatar visuals
|
|
16006
|
+
*/
|
|
16007
|
+
function drawProjectedOrganicEye(context, localCenter, radiusX, radiusY, center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, phase, interaction, eyeStyle) {
|
|
16008
|
+
const centerScenePoint = transformScenePoint(localCenter, center, rotationX, rotationY);
|
|
16009
|
+
if (centerScenePoint.z <= center.z) {
|
|
16010
|
+
return;
|
|
16011
|
+
}
|
|
16012
|
+
const horizontalScenePoint = transformScenePoint({ x: localCenter.x + radiusX, y: localCenter.y, z: localCenter.z }, center, rotationX, rotationY);
|
|
16013
|
+
const verticalScenePoint = transformScenePoint({ x: localCenter.x, y: localCenter.y + radiusY, z: localCenter.z }, center, rotationX, rotationY);
|
|
16014
|
+
const projectedCenterPoint = projectScenePoint(centerScenePoint, size, sceneCenterX, sceneCenterY);
|
|
16015
|
+
const projectedHorizontalPoint = projectScenePoint(horizontalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
16016
|
+
const projectedVerticalPoint = projectScenePoint(verticalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
16017
|
+
const projectedRadiusX = Math.hypot(projectedHorizontalPoint.x - projectedCenterPoint.x, projectedHorizontalPoint.y - projectedCenterPoint.y);
|
|
16018
|
+
const projectedRadiusY = Math.hypot(projectedVerticalPoint.x - projectedCenterPoint.x, projectedVerticalPoint.y - projectedCenterPoint.y);
|
|
16019
|
+
if (projectedRadiusX < size * 0.008 || projectedRadiusY < size * 0.008) {
|
|
16020
|
+
return;
|
|
16021
|
+
}
|
|
16022
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
16023
|
+
radiusX: projectedRadiusX,
|
|
16024
|
+
radiusY: projectedRadiusY,
|
|
16025
|
+
timeMs,
|
|
16026
|
+
phase,
|
|
16027
|
+
interaction,
|
|
16028
|
+
});
|
|
16029
|
+
const rotation = Math.atan2(projectedHorizontalPoint.y - projectedCenterPoint.y, projectedHorizontalPoint.x - projectedCenterPoint.x);
|
|
16030
|
+
context.save();
|
|
16031
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
16032
|
+
context.rotate(rotation);
|
|
16033
|
+
context.beginPath();
|
|
16034
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
16035
|
+
context.fillStyle = '#f8fbff';
|
|
16036
|
+
context.fill();
|
|
16037
|
+
context.clip();
|
|
16038
|
+
const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
|
|
16039
|
+
irisGradient.addColorStop(0, palette.highlight);
|
|
16040
|
+
irisGradient.addColorStop(0.56, palette.secondary);
|
|
16041
|
+
irisGradient.addColorStop(1, palette.shadow);
|
|
16042
|
+
context.beginPath();
|
|
16043
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
|
|
16044
|
+
context.fillStyle = irisGradient;
|
|
16045
|
+
context.fill();
|
|
16046
|
+
context.beginPath();
|
|
16047
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.15 * eyeStyle.pupilWidthScale, projectedRadiusY * 0.48 * eyeStyle.pupilHeightScale, 0, 0, Math.PI * 2);
|
|
16048
|
+
context.fillStyle = palette.ink;
|
|
16049
|
+
context.fill();
|
|
16050
|
+
context.beginPath();
|
|
16051
|
+
context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
|
|
16052
|
+
context.fillStyle = '#ffffff';
|
|
16053
|
+
context.fill();
|
|
16054
|
+
context.restore();
|
|
16055
|
+
context.save();
|
|
16056
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
16057
|
+
context.rotate(rotation);
|
|
16058
|
+
context.beginPath();
|
|
16059
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
16060
|
+
context.strokeStyle = `${palette.shadow}cc`;
|
|
16061
|
+
context.lineWidth = projectedRadiusX * 0.16;
|
|
16062
|
+
context.stroke();
|
|
16063
|
+
context.beginPath();
|
|
16064
|
+
context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
16065
|
+
context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
16066
|
+
context.strokeStyle = `${palette.shadow}73`;
|
|
16067
|
+
context.lineWidth = projectedRadiusX * 0.14;
|
|
16068
|
+
context.lineCap = 'round';
|
|
16069
|
+
context.stroke();
|
|
16070
|
+
if (eyeStyle.lowerLidOpacity > 0) {
|
|
16071
|
+
context.beginPath();
|
|
16072
|
+
context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
16073
|
+
context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
16074
|
+
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
16075
|
+
context.lineWidth = projectedRadiusX * 0.08;
|
|
16076
|
+
context.lineCap = 'round';
|
|
16077
|
+
context.stroke();
|
|
16078
|
+
}
|
|
16079
|
+
context.restore();
|
|
16080
|
+
}
|
|
16081
|
+
/**
|
|
16082
|
+
* Draws a subtle projected mouth arc across the front of a rotated octopus surface.
|
|
16083
|
+
*
|
|
16084
|
+
* @private helper of the 3D octopus avatar visuals
|
|
16085
|
+
*/
|
|
16086
|
+
function drawProjectedOrganicMouth(context, localPoints, center, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size) {
|
|
16087
|
+
const scenePoints = localPoints.map((localPoint) => transformScenePoint(localPoint, center, rotationX, rotationY));
|
|
16088
|
+
if (scenePoints.some((scenePoint) => scenePoint.z <= center.z)) {
|
|
16089
|
+
return;
|
|
16090
|
+
}
|
|
16091
|
+
const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
|
|
16092
|
+
context.beginPath();
|
|
16093
|
+
context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
|
|
16094
|
+
context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
|
|
16095
|
+
context.strokeStyle = `${palette.ink}b8`;
|
|
16096
|
+
context.lineWidth = Math.max(1.1, size * 0.009);
|
|
16097
|
+
context.lineCap = 'round';
|
|
16098
|
+
context.stroke();
|
|
16099
|
+
}
|
|
16100
|
+
/**
|
|
16101
|
+
* Draws one filled projected quad.
|
|
16102
|
+
*
|
|
16103
|
+
* @private helper of the 3D octopus avatar visuals
|
|
16104
|
+
*/
|
|
16105
|
+
function drawProjectedQuad(context, corners, fillStyle) {
|
|
16106
|
+
context.beginPath();
|
|
16107
|
+
context.moveTo(corners[0].x, corners[0].y);
|
|
16108
|
+
context.lineTo(corners[1].x, corners[1].y);
|
|
16109
|
+
context.lineTo(corners[2].x, corners[2].y);
|
|
16110
|
+
context.lineTo(corners[3].x, corners[3].y);
|
|
16111
|
+
context.closePath();
|
|
16112
|
+
context.fillStyle = fillStyle;
|
|
16113
|
+
context.fill();
|
|
16114
|
+
}
|
|
16115
|
+
/**
|
|
16116
|
+
* Converts an opacity ratio into a two-digit hexadecimal alpha suffix.
|
|
16117
|
+
*
|
|
16118
|
+
* @private helper of the 3D octopus avatar visuals
|
|
16119
|
+
*/
|
|
16120
|
+
function formatAlphaHex(opacity) {
|
|
16121
|
+
return Math.round(clampNumber$1(opacity, 0, 1) * 255)
|
|
16122
|
+
.toString(16)
|
|
16123
|
+
.padStart(2, '0');
|
|
16124
|
+
}
|
|
16125
|
+
|
|
15901
16126
|
/* eslint-disable no-magic-numbers */
|
|
15902
16127
|
/**
|
|
15903
16128
|
* Light direction used by the organic 3D octopus shading.
|
|
15904
16129
|
*
|
|
15905
16130
|
* @private helper of `octopus3dAvatarVisual`
|
|
15906
16131
|
*/
|
|
15907
|
-
const LIGHT_DIRECTION = normalizeVector3({
|
|
16132
|
+
const LIGHT_DIRECTION$1 = normalizeVector3({
|
|
15908
16133
|
x: 0.48,
|
|
15909
16134
|
y: -0.62,
|
|
15910
16135
|
z: 0.94,
|
|
@@ -16017,17 +16242,17 @@
|
|
|
16017
16242
|
for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
|
|
16018
16243
|
drawTentacleStroke(context, tentacleStroke, palette);
|
|
16019
16244
|
}
|
|
16020
|
-
|
|
16245
|
+
drawProjectedOrganicEye(context, {
|
|
16021
16246
|
x: -faceEyeSpacing,
|
|
16022
16247
|
y: faceEyeYOffset,
|
|
16023
16248
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
16024
16249
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
16025
|
-
|
|
16250
|
+
drawProjectedOrganicEye(context, {
|
|
16026
16251
|
x: faceEyeSpacing,
|
|
16027
16252
|
y: faceEyeYOffset,
|
|
16028
16253
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
16029
16254
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
16030
|
-
|
|
16255
|
+
drawProjectedOrganicMouth(context, [
|
|
16031
16256
|
{
|
|
16032
16257
|
x: -mouthHalfWidth,
|
|
16033
16258
|
y: mouthY,
|
|
@@ -16114,7 +16339,7 @@
|
|
|
16114
16339
|
corners: projectedCorners,
|
|
16115
16340
|
averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
|
|
16116
16341
|
transformedCorners.length,
|
|
16117
|
-
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
16342
|
+
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
|
|
16118
16343
|
fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
|
|
16119
16344
|
outlineColor,
|
|
16120
16345
|
});
|
|
@@ -16296,128 +16521,260 @@
|
|
|
16296
16521
|
const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
|
|
16297
16522
|
return Math.sqrt(remainingDepthRatio) * radiusZ;
|
|
16298
16523
|
}
|
|
16524
|
+
|
|
16525
|
+
/* eslint-disable no-magic-numbers */
|
|
16299
16526
|
/**
|
|
16300
|
-
*
|
|
16527
|
+
* Light direction used by the single-mesh octopus shading.
|
|
16301
16528
|
*
|
|
16302
|
-
* @private helper of `
|
|
16529
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16303
16530
|
*/
|
|
16304
|
-
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16308
|
-
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
|
|
16324
|
-
|
|
16325
|
-
|
|
16326
|
-
|
|
16531
|
+
const LIGHT_DIRECTION = normalizeVector3({
|
|
16532
|
+
x: 0.38,
|
|
16533
|
+
y: -0.6,
|
|
16534
|
+
z: 0.98,
|
|
16535
|
+
});
|
|
16536
|
+
/**
|
|
16537
|
+
* Octopus 3D 2 avatar visual.
|
|
16538
|
+
*
|
|
16539
|
+
* @private built-in avatar visual
|
|
16540
|
+
*/
|
|
16541
|
+
const octopus3d2AvatarVisual = {
|
|
16542
|
+
id: 'octopus3d2',
|
|
16543
|
+
title: 'Octopus 3D 2',
|
|
16544
|
+
description: 'Continuous blobby 3D octopus portrait with one soft mesh, turning silhouette, and cursor-aware eyes.',
|
|
16545
|
+
isAnimated: true,
|
|
16546
|
+
supportsPointerTracking: true,
|
|
16547
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
16548
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
16549
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
16550
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
16551
|
+
const animationPhase = animationRandom() * Math.PI * 2;
|
|
16552
|
+
const sceneCenterX = size * 0.5;
|
|
16553
|
+
const sceneCenterY = size * 0.575;
|
|
16554
|
+
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
16555
|
+
const meshCenter = {
|
|
16556
|
+
x: interaction.bodyOffsetX * size * 0.044 + size * morphologyProfile.body.centerXJitterRatio * 0.5,
|
|
16557
|
+
y: -size * 0.03 + interaction.bodyOffsetY * size * 0.026 + bob,
|
|
16558
|
+
z: interaction.intensity * size * 0.018,
|
|
16559
|
+
};
|
|
16560
|
+
const rotationY = -0.14 +
|
|
16561
|
+
Math.sin(timeMs / 2600 + animationPhase) * 0.04 +
|
|
16562
|
+
interaction.bodyOffsetX * 0.2 +
|
|
16563
|
+
interaction.gazeX * 0.78;
|
|
16564
|
+
const rotationX = -0.06 +
|
|
16565
|
+
Math.cos(timeMs / 3000 + animationPhase * 0.7) * 0.02 -
|
|
16566
|
+
interaction.bodyOffsetY * 0.08 -
|
|
16567
|
+
interaction.gazeY * 0.34;
|
|
16568
|
+
const surfaceOptions = {
|
|
16569
|
+
radiusX: size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch * 1.02,
|
|
16570
|
+
radiusY: size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.22,
|
|
16571
|
+
radiusZ: size *
|
|
16572
|
+
morphologyProfile.body.bodyRadiusRatio *
|
|
16573
|
+
(0.98 + (morphologyProfile.body.horizontalStretch - 1) * 0.2),
|
|
16574
|
+
morphologyProfile,
|
|
16575
|
+
timeMs,
|
|
16576
|
+
animationPhase,
|
|
16577
|
+
};
|
|
16578
|
+
const surfacePatches = resolveVisibleBlobbyOctopusPatches({
|
|
16579
|
+
...surfaceOptions,
|
|
16580
|
+
center: meshCenter,
|
|
16581
|
+
rotationX,
|
|
16582
|
+
rotationY,
|
|
16583
|
+
sceneCenterX,
|
|
16584
|
+
sceneCenterY,
|
|
16585
|
+
size,
|
|
16586
|
+
palette,
|
|
16587
|
+
});
|
|
16588
|
+
const eyeLatitude = clampNumber$1(morphologyProfile.face.eyeCenterYOffsetRatio * 4.4, -0.16, 0.11);
|
|
16589
|
+
const eyeLongitude = clampNumber$1(morphologyProfile.face.eyeSpacingRatio * 3.25, 0.2, 0.34);
|
|
16590
|
+
const mouthLatitude = clampNumber$1(eyeLatitude + 0.19 + morphologyProfile.face.mouthYOffsetRatio * 1.08, 0.08, 0.34);
|
|
16591
|
+
const mouthCenterLongitude = clampNumber$1(morphologyProfile.face.mouthCenterOffsetRatio * 5.8, -0.08, 0.08);
|
|
16592
|
+
const mouthHalfLongitude = clampNumber$1(eyeLongitude * 0.82, 0.16, 0.29);
|
|
16593
|
+
const mouthCurveLatitude = clampNumber$1(mouthLatitude + morphologyProfile.face.mouthCurveDepthRatio * 0.85, mouthLatitude + 0.03, 0.42);
|
|
16594
|
+
drawAvatarFrame(context, size, palette);
|
|
16595
|
+
drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
|
|
16596
|
+
drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile);
|
|
16597
|
+
for (const surfacePatch of surfacePatches.sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
|
|
16598
|
+
drawBlobbySurfacePatch(context, surfacePatch);
|
|
16599
|
+
}
|
|
16600
|
+
const leftEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude);
|
|
16601
|
+
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
16602
|
+
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
16603
|
+
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
16604
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
|
|
16605
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
|
|
16606
|
+
drawProjectedOrganicMouth(context, [
|
|
16607
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
16608
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
16609
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude + mouthHalfLongitude),
|
|
16610
|
+
], meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size);
|
|
16611
|
+
},
|
|
16612
|
+
};
|
|
16613
|
+
/**
|
|
16614
|
+
* Draws the deep-water glow behind the continuous octopus mesh.
|
|
16615
|
+
*
|
|
16616
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16617
|
+
*/
|
|
16618
|
+
function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
|
|
16619
|
+
const glowGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.11, sceneCenterY - size * 0.17 + interaction.gazeY * size * 0.05, size * 0.05, sceneCenterX, sceneCenterY - size * 0.03, size * 0.66);
|
|
16620
|
+
glowGradient.addColorStop(0, `${palette.highlight}5e`);
|
|
16621
|
+
glowGradient.addColorStop(0.38, `${palette.accent}26`);
|
|
16622
|
+
glowGradient.addColorStop(1, `${palette.highlight}00`);
|
|
16623
|
+
context.fillStyle = glowGradient;
|
|
16624
|
+
context.fillRect(0, 0, size, size);
|
|
16625
|
+
const lowerGradient = context.createRadialGradient(sceneCenterX + Math.sin(timeMs / 1650) * size * 0.045, sceneCenterY + size * 0.28, size * 0.06, sceneCenterX, sceneCenterY + size * 0.28, size * 0.52);
|
|
16626
|
+
lowerGradient.addColorStop(0, `${palette.secondary}22`);
|
|
16627
|
+
lowerGradient.addColorStop(1, `${palette.secondary}00`);
|
|
16628
|
+
context.fillStyle = lowerGradient;
|
|
16629
|
+
context.fillRect(0, 0, size, size);
|
|
16630
|
+
}
|
|
16631
|
+
/**
|
|
16632
|
+
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
16633
|
+
*
|
|
16634
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16635
|
+
*/
|
|
16636
|
+
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
16327
16637
|
context.save();
|
|
16328
|
-
context.
|
|
16329
|
-
context.
|
|
16330
|
-
context.beginPath();
|
|
16331
|
-
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
16332
|
-
context.fillStyle = '#f8fbff';
|
|
16333
|
-
context.fill();
|
|
16334
|
-
context.clip();
|
|
16335
|
-
const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
|
|
16336
|
-
irisGradient.addColorStop(0, palette.highlight);
|
|
16337
|
-
irisGradient.addColorStop(0.56, palette.secondary);
|
|
16338
|
-
irisGradient.addColorStop(1, palette.shadow);
|
|
16339
|
-
context.beginPath();
|
|
16340
|
-
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
|
|
16341
|
-
context.fillStyle = irisGradient;
|
|
16342
|
-
context.fill();
|
|
16638
|
+
context.fillStyle = `${palette.shadow}66`;
|
|
16639
|
+
context.filter = `blur(${size * 0.024}px)`;
|
|
16343
16640
|
context.beginPath();
|
|
16344
|
-
context.ellipse(
|
|
16345
|
-
context.fillStyle = palette.ink;
|
|
16641
|
+
context.ellipse(size * 0.5 + interaction.gazeX * size * 0.045, size * 0.88 + Math.sin(timeMs / 940) * size * 0.008, size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018), size * 0.062, 0, 0, Math.PI * 2);
|
|
16346
16642
|
context.fill();
|
|
16347
|
-
context.beginPath();
|
|
16348
|
-
context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
|
|
16349
|
-
context.fillStyle = '#ffffff';
|
|
16350
|
-
context.fill();
|
|
16351
|
-
context.restore();
|
|
16352
|
-
context.save();
|
|
16353
|
-
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
16354
|
-
context.rotate(rotation);
|
|
16355
|
-
context.beginPath();
|
|
16356
|
-
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
16357
|
-
context.strokeStyle = `${palette.shadow}cc`;
|
|
16358
|
-
context.lineWidth = projectedRadiusX * 0.16;
|
|
16359
|
-
context.stroke();
|
|
16360
|
-
context.beginPath();
|
|
16361
|
-
context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
16362
|
-
context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
16363
|
-
context.strokeStyle = `${palette.shadow}73`;
|
|
16364
|
-
context.lineWidth = projectedRadiusX * 0.14;
|
|
16365
|
-
context.lineCap = 'round';
|
|
16366
|
-
context.stroke();
|
|
16367
|
-
if (eyeStyle.lowerLidOpacity > 0) {
|
|
16368
|
-
context.beginPath();
|
|
16369
|
-
context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
16370
|
-
context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
16371
|
-
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
16372
|
-
context.lineWidth = projectedRadiusX * 0.08;
|
|
16373
|
-
context.lineCap = 'round';
|
|
16374
|
-
context.stroke();
|
|
16375
|
-
}
|
|
16376
16643
|
context.restore();
|
|
16377
16644
|
}
|
|
16378
16645
|
/**
|
|
16379
|
-
*
|
|
16646
|
+
* Resolves all visible projected patches for the single blobby octopus mesh.
|
|
16380
16647
|
*
|
|
16381
|
-
* @private helper of `
|
|
16648
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16382
16649
|
*/
|
|
16383
|
-
function
|
|
16384
|
-
const
|
|
16385
|
-
|
|
16386
|
-
|
|
16650
|
+
function resolveVisibleBlobbyOctopusPatches(options) {
|
|
16651
|
+
const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, morphologyProfile, animationPhase, timeMs, } = options;
|
|
16652
|
+
const latitudePatchCount = 12;
|
|
16653
|
+
const longitudePatchCount = 24;
|
|
16654
|
+
const surfacePatches = [];
|
|
16655
|
+
for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
|
|
16656
|
+
const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
|
|
16657
|
+
const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
|
|
16658
|
+
const centerLatitude = (startLatitude + endLatitude) / 2;
|
|
16659
|
+
const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
|
|
16660
|
+
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
16661
|
+
const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
|
|
16662
|
+
const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
|
|
16663
|
+
const centerLongitude = (startLongitude + endLongitude) / 2;
|
|
16664
|
+
const localCorners = [
|
|
16665
|
+
sampleBlobbyOctopusSurfacePoint(options, startLatitude, startLongitude),
|
|
16666
|
+
sampleBlobbyOctopusSurfacePoint(options, startLatitude, endLongitude),
|
|
16667
|
+
sampleBlobbyOctopusSurfacePoint(options, endLatitude, endLongitude),
|
|
16668
|
+
sampleBlobbyOctopusSurfacePoint(options, endLatitude, startLongitude),
|
|
16669
|
+
];
|
|
16670
|
+
const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
|
|
16671
|
+
const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
|
|
16672
|
+
if (surfaceNormal.z <= 0.01) {
|
|
16673
|
+
continue;
|
|
16674
|
+
}
|
|
16675
|
+
const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
|
|
16676
|
+
surfacePatches.push({
|
|
16677
|
+
corners: projectedCorners,
|
|
16678
|
+
averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
|
|
16679
|
+
transformedCorners.length,
|
|
16680
|
+
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
16681
|
+
fillStyle: resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
|
|
16682
|
+
outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
|
|
16683
|
+
});
|
|
16684
|
+
}
|
|
16387
16685
|
}
|
|
16388
|
-
|
|
16389
|
-
context.beginPath();
|
|
16390
|
-
context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
|
|
16391
|
-
context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
|
|
16392
|
-
context.strokeStyle = `${palette.ink}b8`;
|
|
16393
|
-
context.lineWidth = Math.max(1.1, size * 0.009);
|
|
16394
|
-
context.lineCap = 'round';
|
|
16395
|
-
context.stroke();
|
|
16686
|
+
return surfacePatches;
|
|
16396
16687
|
}
|
|
16397
16688
|
/**
|
|
16398
|
-
*
|
|
16689
|
+
* Samples one point on the continuous Octopus 3D 2 surface.
|
|
16690
|
+
*
|
|
16691
|
+
* The lower hemisphere widens and falls into soft lobe waves so the octopus stays one connected mesh
|
|
16692
|
+
* instead of switching to separately rendered tentacles.
|
|
16693
|
+
*
|
|
16694
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16695
|
+
*/
|
|
16696
|
+
function sampleBlobbyOctopusSurfacePoint(options, latitude, longitude) {
|
|
16697
|
+
const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
|
|
16698
|
+
const cosineLatitude = Math.max(0, Math.cos(latitude));
|
|
16699
|
+
const verticalProgress = (Math.sin(latitude) + 1) / 2;
|
|
16700
|
+
const upperBlend = Math.pow(1 - verticalProgress, 1.2);
|
|
16701
|
+
const lowerBlend = Math.pow(verticalProgress, 1.42);
|
|
16702
|
+
const lowerLobeWave = resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs);
|
|
16703
|
+
const skirtEnvelope = Math.pow(cosineLatitude, 0.5) * lowerBlend;
|
|
16704
|
+
const horizontalScale = 1.02 +
|
|
16705
|
+
skirtEnvelope * (0.34 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.22 + lowerLobeWave * 0.22) -
|
|
16706
|
+
upperBlend * 0.08;
|
|
16707
|
+
const depthScale = 1.04 +
|
|
16708
|
+
upperBlend * 0.16 +
|
|
16709
|
+
Math.max(0, Math.cos(longitude)) * 0.1 +
|
|
16710
|
+
skirtEnvelope * (0.08 + lowerLobeWave * 0.06) -
|
|
16711
|
+
Math.max(0, -Math.cos(longitude)) * 0.04;
|
|
16712
|
+
const lowerDrop = skirtEnvelope *
|
|
16713
|
+
radiusY *
|
|
16714
|
+
(0.28 + lowerLobeWave * 0.14 + (morphologyProfile.tentacles.flowLengthScale - 1) * 0.12);
|
|
16715
|
+
const swayX = Math.sin(timeMs / 1250 + longitude * 1.8 + animationPhase) * skirtEnvelope * radiusX * 0.05;
|
|
16716
|
+
const swayZ = Math.cos(timeMs / 1480 + longitude * 1.2 - animationPhase * 0.7) * skirtEnvelope * radiusZ * 0.03;
|
|
16717
|
+
return {
|
|
16718
|
+
x: Math.sin(longitude) * cosineLatitude * radiusX * horizontalScale + swayX,
|
|
16719
|
+
y: Math.sin(latitude) * radiusY * (1 + upperBlend * 0.14) -
|
|
16720
|
+
upperBlend * radiusY * 0.1 +
|
|
16721
|
+
lowerDrop +
|
|
16722
|
+
Math.sin(timeMs / 1780 + animationPhase + latitude * 1.4) * skirtEnvelope * radiusY * 0.02,
|
|
16723
|
+
z: Math.cos(longitude) * cosineLatitude * radiusZ * depthScale + swayZ,
|
|
16724
|
+
};
|
|
16725
|
+
}
|
|
16726
|
+
/**
|
|
16727
|
+
* Resolves the soft lower-lobe wave that makes the silhouette read more like a real octopus.
|
|
16399
16728
|
*
|
|
16400
|
-
* @private helper of `
|
|
16729
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16401
16730
|
*/
|
|
16402
|
-
function
|
|
16403
|
-
|
|
16404
|
-
|
|
16405
|
-
context.lineTo(corners[1].x, corners[1].y);
|
|
16406
|
-
context.lineTo(corners[2].x, corners[2].y);
|
|
16407
|
-
context.lineTo(corners[3].x, corners[3].y);
|
|
16408
|
-
context.closePath();
|
|
16409
|
-
context.fillStyle = fillStyle;
|
|
16410
|
-
context.fill();
|
|
16731
|
+
function resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs) {
|
|
16732
|
+
const lobeCount = Math.max(4, Math.round((morphologyProfile.body.lobeCount + morphologyProfile.tentacles.count) / 2));
|
|
16733
|
+
return (Math.cos(longitude * lobeCount + animationPhase + timeMs / 1040) + 1) / 2;
|
|
16411
16734
|
}
|
|
16412
16735
|
/**
|
|
16413
|
-
*
|
|
16736
|
+
* Resolves one base fill tone for a surface patch on the single octopus mesh.
|
|
16414
16737
|
*
|
|
16415
|
-
* @private helper of `
|
|
16738
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16416
16739
|
*/
|
|
16417
|
-
function
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
.
|
|
16740
|
+
function resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, forwardness, lowerLobeWave) {
|
|
16741
|
+
const tonalProgress = clampNumber$1(verticalProgress + lowerLobeWave * 0.12 - forwardness * 0.07, 0, 1);
|
|
16742
|
+
if (tonalProgress < 0.16) {
|
|
16743
|
+
return palette.highlight;
|
|
16744
|
+
}
|
|
16745
|
+
if (tonalProgress < 0.34) {
|
|
16746
|
+
return palette.secondary;
|
|
16747
|
+
}
|
|
16748
|
+
if (tonalProgress < 0.72) {
|
|
16749
|
+
return forwardness > 0.58 ? palette.secondary : palette.primary;
|
|
16750
|
+
}
|
|
16751
|
+
return `${palette.shadow}f2`;
|
|
16752
|
+
}
|
|
16753
|
+
/**
|
|
16754
|
+
* Draws one projected patch with soft octopus shading.
|
|
16755
|
+
*
|
|
16756
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
16757
|
+
*/
|
|
16758
|
+
function drawBlobbySurfacePatch(context, surfacePatch) {
|
|
16759
|
+
drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
|
|
16760
|
+
if (surfacePatch.lightIntensity > 0) {
|
|
16761
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.16 * surfacePatch.lightIntensity})`);
|
|
16762
|
+
}
|
|
16763
|
+
else if (surfacePatch.lightIntensity < 0) {
|
|
16764
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
|
|
16765
|
+
}
|
|
16766
|
+
context.save();
|
|
16767
|
+
context.beginPath();
|
|
16768
|
+
context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
|
|
16769
|
+
for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
|
|
16770
|
+
context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
|
|
16771
|
+
}
|
|
16772
|
+
context.closePath();
|
|
16773
|
+
context.strokeStyle = surfacePatch.outlineColor;
|
|
16774
|
+
context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0042);
|
|
16775
|
+
context.lineJoin = 'round';
|
|
16776
|
+
context.stroke();
|
|
16777
|
+
context.restore();
|
|
16421
16778
|
}
|
|
16422
16779
|
|
|
16423
16780
|
/* eslint-disable no-magic-numbers */
|
|
@@ -17189,6 +17546,7 @@
|
|
|
17189
17546
|
octopus2AvatarVisual,
|
|
17190
17547
|
octopus3AvatarVisual,
|
|
17191
17548
|
octopus3dAvatarVisual,
|
|
17549
|
+
octopus3d2AvatarVisual,
|
|
17192
17550
|
asciiOctopusAvatarVisual,
|
|
17193
17551
|
minecraftAvatarVisual,
|
|
17194
17552
|
minecraft2AvatarVisual,
|
|
@@ -22764,11 +23122,11 @@
|
|
|
22764
23122
|
});
|
|
22765
23123
|
}
|
|
22766
23124
|
/**
|
|
22767
|
-
*
|
|
23125
|
+
* Prepares one attachment for best-effort text decoding.
|
|
22768
23126
|
*
|
|
22769
|
-
* @private
|
|
23127
|
+
* @private function of decodeAttachmentAsText
|
|
22770
23128
|
*/
|
|
22771
|
-
function
|
|
23129
|
+
function createDecodeAttachmentPreparation(input, options) {
|
|
22772
23130
|
var _a;
|
|
22773
23131
|
const maxBytes = Math.max(1, Math.floor((_a = options.maxBytes) !== null && _a !== void 0 ? _a : DEFAULT_ATTACHMENT_TEXT_DECODE_BYTES));
|
|
22774
23132
|
const forceText = options.forceText === true;
|
|
@@ -22782,54 +23140,102 @@
|
|
|
22782
23140
|
const inspection = inspectBytes(truncatedBytes);
|
|
22783
23141
|
const trustedTextMime = isTrustedTextMimeType(mimeType);
|
|
22784
23142
|
const trustedBinaryMime = isTrustedBinaryMimeType(mimeType);
|
|
23143
|
+
const shouldTreatAsBinary = (trustedBinaryMime || inspection.looksBinary) && !trustedTextMime;
|
|
22785
23144
|
if (isTruncated) {
|
|
22786
23145
|
warnings.push(`Decoded only the first ${maxBytes} bytes of \`${input.filename}\` because the attachment exceeded the text preview limit.`);
|
|
22787
23146
|
}
|
|
22788
|
-
|
|
22789
|
-
|
|
22790
|
-
|
|
22791
|
-
|
|
22792
|
-
|
|
22793
|
-
|
|
22794
|
-
|
|
22795
|
-
|
|
22796
|
-
|
|
22797
|
-
|
|
22798
|
-
|
|
23147
|
+
return {
|
|
23148
|
+
warnings,
|
|
23149
|
+
charset,
|
|
23150
|
+
bom,
|
|
23151
|
+
inspection,
|
|
23152
|
+
truncatedBytes,
|
|
23153
|
+
isTruncated,
|
|
23154
|
+
forceText,
|
|
23155
|
+
shouldTreatAsBinary,
|
|
23156
|
+
};
|
|
23157
|
+
}
|
|
23158
|
+
/**
|
|
23159
|
+
* Returns an early result when the attachment should stay classified as binary.
|
|
23160
|
+
*
|
|
23161
|
+
* @private function of decodeAttachmentAsText
|
|
23162
|
+
*/
|
|
23163
|
+
function createBinaryDecodeResult(preparation) {
|
|
23164
|
+
if (!preparation.shouldTreatAsBinary) {
|
|
23165
|
+
return null;
|
|
22799
23166
|
}
|
|
22800
|
-
if (
|
|
22801
|
-
warnings.push('File content looks binary, but text decoding was forced with `forceText`.');
|
|
23167
|
+
if (preparation.forceText) {
|
|
23168
|
+
preparation.warnings.push('File content looks binary, but text decoding was forced with `forceText`.');
|
|
23169
|
+
return null;
|
|
22802
23170
|
}
|
|
22803
|
-
|
|
22804
|
-
|
|
23171
|
+
preparation.warnings.push('File content looks binary, so text decoding was skipped.');
|
|
23172
|
+
return {
|
|
23173
|
+
text: '',
|
|
23174
|
+
encodingUsed: 'binary',
|
|
23175
|
+
confidence: 1,
|
|
23176
|
+
warnings: preparation.warnings,
|
|
23177
|
+
wasBinary: true,
|
|
23178
|
+
isTruncated: preparation.isTruncated,
|
|
23179
|
+
};
|
|
23180
|
+
}
|
|
23181
|
+
/**
|
|
23182
|
+
* Warns when the declared charset cannot be used by the runtime decoder.
|
|
23183
|
+
*
|
|
23184
|
+
* @private function of decodeAttachmentAsText
|
|
23185
|
+
*/
|
|
23186
|
+
function addUnsupportedCharsetWarning(preparation) {
|
|
23187
|
+
if (preparation.charset && !isSupportedEncoding(preparation.charset)) {
|
|
23188
|
+
preparation.warnings.push(`Ignored unsupported declared charset \`${preparation.charset}\` and used best-effort detection instead.`);
|
|
22805
23189
|
}
|
|
22806
|
-
|
|
22807
|
-
|
|
22808
|
-
|
|
22809
|
-
|
|
22810
|
-
|
|
22811
|
-
|
|
22812
|
-
|
|
22813
|
-
|
|
23190
|
+
}
|
|
23191
|
+
/**
|
|
23192
|
+
* Returns the byte slice that should actually be decoded as text.
|
|
23193
|
+
*
|
|
23194
|
+
* @private function of decodeAttachmentAsText
|
|
23195
|
+
*/
|
|
23196
|
+
function getBytesToDecode(preparation) {
|
|
23197
|
+
return preparation.bom ? preparation.truncatedBytes.subarray(preparation.bom.offset) : preparation.truncatedBytes;
|
|
23198
|
+
}
|
|
23199
|
+
/**
|
|
23200
|
+
* Decodes all candidate encodings and sorts the successful results by score.
|
|
23201
|
+
*
|
|
23202
|
+
* @private function of decodeAttachmentAsText
|
|
23203
|
+
*/
|
|
23204
|
+
function decodeAttachmentCandidates(preparation) {
|
|
23205
|
+
return buildCandidateEncodings({
|
|
23206
|
+
charset: preparation.charset && isSupportedEncoding(preparation.charset) ? preparation.charset : null,
|
|
23207
|
+
bom: preparation.bom,
|
|
23208
|
+
inspection: preparation.inspection,
|
|
23209
|
+
})
|
|
22814
23210
|
.map(({ encoding, source }) => {
|
|
22815
|
-
const decoded = decodeWithEncoding(
|
|
23211
|
+
const decoded = decodeWithEncoding(getBytesToDecode(preparation), encoding);
|
|
22816
23212
|
return decoded ? { ...decoded, source } : null;
|
|
22817
23213
|
})
|
|
22818
23214
|
.filter((candidate) => candidate !== null)
|
|
22819
23215
|
.sort((left, right) => left.score - right.score);
|
|
22820
|
-
|
|
22821
|
-
|
|
22822
|
-
|
|
22823
|
-
|
|
22824
|
-
|
|
22825
|
-
|
|
22826
|
-
|
|
22827
|
-
|
|
22828
|
-
|
|
22829
|
-
|
|
22830
|
-
|
|
22831
|
-
|
|
22832
|
-
|
|
23216
|
+
}
|
|
23217
|
+
/**
|
|
23218
|
+
* Returns the fallback result used when no text decoder could be applied.
|
|
23219
|
+
*
|
|
23220
|
+
* @private function of decodeAttachmentAsText
|
|
23221
|
+
*/
|
|
23222
|
+
function createNoDecoderAvailableResult(preparation) {
|
|
23223
|
+
preparation.warnings.push('No supported text decoder was available.');
|
|
23224
|
+
return {
|
|
23225
|
+
text: '',
|
|
23226
|
+
encodingUsed: 'binary',
|
|
23227
|
+
confidence: 0,
|
|
23228
|
+
warnings: preparation.warnings,
|
|
23229
|
+
wasBinary: true,
|
|
23230
|
+
isTruncated: preparation.isTruncated,
|
|
23231
|
+
};
|
|
23232
|
+
}
|
|
23233
|
+
/**
|
|
23234
|
+
* Estimates confidence for the winning decoded text candidate.
|
|
23235
|
+
*
|
|
23236
|
+
* @private function of decodeAttachmentAsText
|
|
23237
|
+
*/
|
|
23238
|
+
function computeDecodeConfidence(bestCandidate, secondBestCandidate, preparation) {
|
|
22833
23239
|
const baseConfidence = bestCandidate.source === 'bom'
|
|
22834
23240
|
? 1
|
|
22835
23241
|
: bestCandidate.source === 'charset'
|
|
@@ -22842,27 +23248,62 @@
|
|
|
22842
23248
|
? 0.82
|
|
22843
23249
|
: 0.62;
|
|
22844
23250
|
const scoreMargin = secondBestCandidate ? Math.max(0, secondBestCandidate.score - bestCandidate.score) : 0.2;
|
|
22845
|
-
|
|
23251
|
+
return Math.max(0.2, Math.min(preparation.shouldTreatAsBinary && preparation.forceText ? 0.45 : 1, baseConfidence + Math.min(0.18, scoreMargin / 2)));
|
|
23252
|
+
}
|
|
23253
|
+
/**
|
|
23254
|
+
* Appends user-facing warnings derived from the chosen decoded text candidate.
|
|
23255
|
+
*
|
|
23256
|
+
* @private function of decodeAttachmentAsText
|
|
23257
|
+
*/
|
|
23258
|
+
function addDecodeWarnings(bestCandidate, confidence, preparation) {
|
|
22846
23259
|
if (bestCandidate.source === 'heuristic' && bestCandidate.encoding !== 'utf-8') {
|
|
22847
|
-
warnings.push(`Encoding was guessed as \`${bestCandidate.encoding}\`.`);
|
|
23260
|
+
preparation.warnings.push(`Encoding was guessed as \`${bestCandidate.encoding}\`.`);
|
|
22848
23261
|
}
|
|
22849
23262
|
if (bestCandidate.source === 'heuristic' &&
|
|
22850
23263
|
bestCandidate.encoding === 'utf-8' &&
|
|
22851
23264
|
bestCandidate.replacementCount > 0) {
|
|
22852
|
-
warnings.push('UTF-8 decoding produced replacement characters, so the extracted text may contain errors.');
|
|
23265
|
+
preparation.warnings.push('UTF-8 decoding produced replacement characters, so the extracted text may contain errors.');
|
|
22853
23266
|
}
|
|
22854
23267
|
if (confidence < 0.6) {
|
|
22855
|
-
warnings.push('Decoding confidence is low, so the extracted text may contain errors.');
|
|
23268
|
+
preparation.warnings.push('Decoding confidence is low, so the extracted text may contain errors.');
|
|
22856
23269
|
}
|
|
23270
|
+
}
|
|
23271
|
+
/**
|
|
23272
|
+
* Creates the final decoded-text result from the chosen candidate and accumulated metadata.
|
|
23273
|
+
*
|
|
23274
|
+
* @private function of decodeAttachmentAsText
|
|
23275
|
+
*/
|
|
23276
|
+
function createDecodedTextResult(bestCandidate, confidence, preparation) {
|
|
22857
23277
|
return {
|
|
22858
|
-
text: isTruncated ? appendTruncatedMarker(bestCandidate.text) : bestCandidate.text,
|
|
23278
|
+
text: preparation.isTruncated ? appendTruncatedMarker(bestCandidate.text) : bestCandidate.text,
|
|
22859
23279
|
encodingUsed: bestCandidate.encoding,
|
|
22860
23280
|
confidence,
|
|
22861
|
-
warnings,
|
|
23281
|
+
warnings: preparation.warnings,
|
|
22862
23282
|
wasBinary: false,
|
|
22863
|
-
isTruncated,
|
|
23283
|
+
isTruncated: preparation.isTruncated,
|
|
22864
23284
|
};
|
|
22865
23285
|
}
|
|
23286
|
+
/**
|
|
23287
|
+
* Best-effort decoder for uploaded or remote file bytes whose extension or encoding may be unknown.
|
|
23288
|
+
*
|
|
23289
|
+
* @private internal utility for shared text decoding
|
|
23290
|
+
*/
|
|
23291
|
+
function decodeAttachmentAsText(input, options = {}) {
|
|
23292
|
+
const preparation = createDecodeAttachmentPreparation(input, options);
|
|
23293
|
+
const binaryResult = createBinaryDecodeResult(preparation);
|
|
23294
|
+
if (binaryResult) {
|
|
23295
|
+
return binaryResult;
|
|
23296
|
+
}
|
|
23297
|
+
addUnsupportedCharsetWarning(preparation);
|
|
23298
|
+
const decodedCandidates = decodeAttachmentCandidates(preparation);
|
|
23299
|
+
const bestCandidate = decodedCandidates[0];
|
|
23300
|
+
if (!bestCandidate) {
|
|
23301
|
+
return createNoDecoderAvailableResult(preparation);
|
|
23302
|
+
}
|
|
23303
|
+
const confidence = computeDecodeConfidence(bestCandidate, decodedCandidates[1], preparation);
|
|
23304
|
+
addDecodeWarnings(bestCandidate, confidence, preparation);
|
|
23305
|
+
return createDecodedTextResult(bestCandidate, confidence, preparation);
|
|
23306
|
+
}
|
|
22866
23307
|
|
|
22867
23308
|
/**
|
|
22868
23309
|
* Base GitHub API URL.
|
|
@@ -34761,7 +35202,10 @@
|
|
|
34761
35202
|
Cannot find model in ${this.options.getTitle()} models with name "${defaultModelName}" which should be used as default.
|
|
34762
35203
|
|
|
34763
35204
|
Available models:
|
|
34764
|
-
${block(this.options
|
|
35205
|
+
${block(this.options
|
|
35206
|
+
.getHardcodedModels()
|
|
35207
|
+
.map(({ modelName }) => `- "${modelName}"`)
|
|
35208
|
+
.join('\n'))}
|
|
34765
35209
|
|
|
34766
35210
|
Model "${defaultModelName}" is probably not available anymore, not installed, inaccessible or misconfigured.
|
|
34767
35211
|
|
|
@@ -35115,7 +35559,8 @@
|
|
|
35115
35559
|
};
|
|
35116
35560
|
let rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
35117
35561
|
if ('attachments' in prompt && Array.isArray(prompt.attachments) && prompt.attachments.length > 0) {
|
|
35118
|
-
rawPromptContent +=
|
|
35562
|
+
rawPromptContent +=
|
|
35563
|
+
'\n\n' + prompt.attachments.map((attachment) => `Image attachment: ${attachment.url}`).join('\n');
|
|
35119
35564
|
}
|
|
35120
35565
|
const rawRequest = {
|
|
35121
35566
|
...modelSettings,
|
|
@@ -35220,7 +35665,9 @@
|
|
|
35220
35665
|
* Schedules one request through the shared limiter and retry policy.
|
|
35221
35666
|
*/
|
|
35222
35667
|
async executeRateLimitedRequest(requestFn) {
|
|
35223
|
-
return this.limiter
|
|
35668
|
+
return this.limiter
|
|
35669
|
+
.schedule(() => this.makeRequestWithNetworkRetry(requestFn))
|
|
35670
|
+
.catch((error) => {
|
|
35224
35671
|
assertsError(error);
|
|
35225
35672
|
if (this.options.isVerbose) {
|
|
35226
35673
|
console.info(colors__default["default"].bgRed('error'), error);
|
|
@@ -36427,7 +36874,9 @@
|
|
|
36427
36874
|
pollingState.lastProgressAtMs = nowMs;
|
|
36428
36875
|
pollingState.lastProgressKey = progressKey;
|
|
36429
36876
|
}
|
|
36430
|
-
if (this.options.isVerbose &&
|
|
36877
|
+
if (this.options.isVerbose &&
|
|
36878
|
+
(statusCountsKey !== pollingState.lastCountsKey ||
|
|
36879
|
+
nowMs - pollingState.lastLogAtMs >= progressLogIntervalMs)) {
|
|
36431
36880
|
console.info('[🤰]', 'Vector store file batch status', {
|
|
36432
36881
|
vectorStoreId,
|
|
36433
36882
|
batchId,
|