@promptbook/core 0.112.0-69 → 0.112.0-70

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.
Files changed (27) hide show
  1. package/esm/index.es.js +847 -302
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  4. package/esm/src/avatars/visuals/avatar3dProjectionShared.d.ts +141 -0
  5. package/esm/src/avatars/visuals/octopus3dAvatarVisual.d.ts +7 -0
  6. package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +2 -2
  7. package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +22 -0
  8. package/esm/src/cli/cli-commands/agent/runMultiple.d.ts +10 -0
  9. package/esm/src/cli/cli-commands/agent.d.ts +3 -2
  10. package/esm/src/cli/other/install.test.d.ts +1 -0
  11. package/esm/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +1 -1
  12. package/esm/src/commitments/WALLET/WALLET.d.ts +1 -1
  13. package/esm/src/version.d.ts +1 -1
  14. package/package.json +1 -1
  15. package/umd/index.umd.js +847 -302
  16. package/umd/index.umd.js.map +1 -1
  17. package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  18. package/umd/src/avatars/visuals/avatar3dProjectionShared.d.ts +141 -0
  19. package/umd/src/avatars/visuals/octopus3dAvatarVisual.d.ts +7 -0
  20. package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +2 -2
  21. package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +22 -0
  22. package/umd/src/cli/cli-commands/agent/runMultiple.d.ts +10 -0
  23. package/umd/src/cli/cli-commands/agent.d.ts +3 -2
  24. package/umd/src/cli/other/install.test.d.ts +1 -0
  25. package/umd/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +1 -1
  26. package/umd/src/commitments/WALLET/WALLET.d.ts +1 -1
  27. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-69';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-70';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -1827,11 +1827,11 @@ function capitalize(word) {
1827
1827
  */
1828
1828
  function pipelineJsonToString(pipelineJson) {
1829
1829
  const { title, pipelineUrl, bookVersion, description, parameters, tasks } = pipelineJson;
1830
- let pipelineString = `# ${title}`;
1831
- if (description) {
1832
- pipelineString += '\n\n';
1833
- pipelineString += description;
1834
- }
1830
+ let pipelineString = spaceTrim$1((block) => `
1831
+ # ${title}
1832
+
1833
+ ${block(description || '')}
1834
+ `);
1835
1835
  const commands = [];
1836
1836
  if (pipelineUrl) {
1837
1837
  commands.push(`PIPELINE URL ${pipelineUrl}`);
@@ -1847,20 +1847,17 @@ function pipelineJsonToString(pipelineJson) {
1847
1847
  for (const parameter of parameters.filter(({ isOutput }) => isOutput)) {
1848
1848
  commands.push(`OUTPUT PARAMETER ${taskParameterJsonToString(parameter)}`);
1849
1849
  }
1850
- pipelineString += '\n\n';
1851
- pipelineString += commands.map((command) => `- ${command}`).join('\n');
1850
+ pipelineString = spaceTrim$1((block) => `
1851
+ ${block(pipelineString)}
1852
+
1853
+ ${block(commands.map((command) => `- ${command}`).join('\n'))}
1854
+ `);
1852
1855
  for (const task of tasks) {
1853
1856
  const {
1854
1857
  /* Note: Not using:> name, */
1855
1858
  title, description,
1856
1859
  /* Note: dependentParameterNames, */
1857
1860
  jokerParameterNames: jokers, taskType, content, postprocessingFunctionNames: postprocessing, expectations, format, resultingParameterName, } = task;
1858
- pipelineString += '\n\n';
1859
- pipelineString += `## ${title}`;
1860
- if (description) {
1861
- pipelineString += '\n\n';
1862
- pipelineString += description;
1863
- }
1864
1861
  const commands = [];
1865
1862
  let contentLanguage = 'text';
1866
1863
  if (taskType === 'PROMPT_TASK') {
@@ -1923,18 +1920,23 @@ function pipelineJsonToString(pipelineJson) {
1923
1920
  commands.push(`FORMAT JSON`);
1924
1921
  }
1925
1922
  } /* not else */
1926
- pipelineString += '\n\n';
1927
- pipelineString += commands.map((command) => `- ${command}`).join('\n');
1928
- pipelineString += '\n\n';
1929
- pipelineString += '```' + contentLanguage;
1930
- pipelineString += '\n';
1931
- pipelineString += spaceTrim$1(content);
1932
- // <- TODO: [main] !!3 Escape
1933
- // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
1934
- pipelineString += '\n';
1935
- pipelineString += '```';
1936
- pipelineString += '\n\n';
1937
- pipelineString += `\`-> {${resultingParameterName}}\``; // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
1923
+ pipelineString = spaceTrim$1((block) => `
1924
+ ${block(pipelineString)}
1925
+
1926
+ ## ${title}
1927
+
1928
+ ${block(description || '')}
1929
+
1930
+ ${block(commands.map((command) => `- ${command}`).join('\n'))}
1931
+
1932
+ \`\`\`${contentLanguage}
1933
+ ${block(spaceTrim$1(content))}
1934
+ \`\`\`
1935
+
1936
+ \`-> {${resultingParameterName}}\`
1937
+ `); // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
1938
+ // <- TODO: [main] !!3 Escape
1939
+ // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
1938
1940
  }
1939
1941
  return validatePipelineString(pipelineString);
1940
1942
  }
@@ -12453,6 +12455,184 @@ function drawFractalCore(context, size, palette, timeMs, corePhase) {
12453
12455
  context.restore();
12454
12456
  }
12455
12457
 
12458
+ /* eslint-disable no-magic-numbers */
12459
+ /**
12460
+ * Default camera distance ratio shared by the proper-3D avatar visuals.
12461
+ *
12462
+ * @private helper of the 3D avatar visuals
12463
+ */
12464
+ const DEFAULT_3D_CAMERA_DISTANCE_RATIO = 1.4;
12465
+ /**
12466
+ * Clamps one number into the provided range.
12467
+ *
12468
+ * @param value Input value.
12469
+ * @param minimumValue Inclusive lower bound.
12470
+ * @param maximumValue Inclusive upper bound.
12471
+ * @returns Clamped value.
12472
+ *
12473
+ * @private helper of the 3D avatar visuals
12474
+ */
12475
+ function clampNumber$1(value, minimumValue, maximumValue) {
12476
+ return Math.min(maximumValue, Math.max(minimumValue, value));
12477
+ }
12478
+ /**
12479
+ * Rotates one point around the local Y axis.
12480
+ *
12481
+ * @param point Source point.
12482
+ * @param angle Rotation angle in radians.
12483
+ * @returns Rotated point.
12484
+ *
12485
+ * @private helper of the 3D avatar visuals
12486
+ */
12487
+ function rotatePointAroundY(point, angle) {
12488
+ const cosine = Math.cos(angle);
12489
+ const sine = Math.sin(angle);
12490
+ return {
12491
+ x: point.x * cosine + point.z * sine,
12492
+ y: point.y,
12493
+ z: -point.x * sine + point.z * cosine,
12494
+ };
12495
+ }
12496
+ /**
12497
+ * Rotates one point around the local X axis.
12498
+ *
12499
+ * @param point Source point.
12500
+ * @param angle Rotation angle in radians.
12501
+ * @returns Rotated point.
12502
+ *
12503
+ * @private helper of the 3D avatar visuals
12504
+ */
12505
+ function rotatePointAroundX(point, angle) {
12506
+ const cosine = Math.cos(angle);
12507
+ const sine = Math.sin(angle);
12508
+ return {
12509
+ x: point.x,
12510
+ y: point.y * cosine - point.z * sine,
12511
+ z: point.y * sine + point.z * cosine,
12512
+ };
12513
+ }
12514
+ /**
12515
+ * Applies the local rotations and translation to one scene point.
12516
+ *
12517
+ * @param localPoint Point in local object space.
12518
+ * @param center Object center in scene space.
12519
+ * @param rotationX Object pitch in radians.
12520
+ * @param rotationY Object yaw in radians.
12521
+ * @returns Transformed scene-space point.
12522
+ *
12523
+ * @private helper of the 3D avatar visuals
12524
+ */
12525
+ function transformScenePoint(localPoint, center, rotationX, rotationY) {
12526
+ const yawedPoint = rotatePointAroundY(localPoint, rotationY);
12527
+ const pitchedPoint = rotatePointAroundX(yawedPoint, rotationX);
12528
+ return {
12529
+ x: center.x + pitchedPoint.x,
12530
+ y: center.y + pitchedPoint.y,
12531
+ z: center.z + pitchedPoint.z,
12532
+ };
12533
+ }
12534
+ /**
12535
+ * Projects one scene point into canvas coordinates.
12536
+ *
12537
+ * @param point Scene-space point.
12538
+ * @param size Canvas size in CSS pixels.
12539
+ * @param sceneCenterX Horizontal scene center.
12540
+ * @param sceneCenterY Vertical scene center.
12541
+ * @param cameraDistanceRatio Optional camera distance ratio.
12542
+ * @returns Projected point.
12543
+ *
12544
+ * @private helper of the 3D avatar visuals
12545
+ */
12546
+ function projectScenePoint(point, size, sceneCenterX, sceneCenterY, cameraDistanceRatio = DEFAULT_3D_CAMERA_DISTANCE_RATIO) {
12547
+ const cameraDistance = size * cameraDistanceRatio;
12548
+ const perspectiveScale = cameraDistance / Math.max(cameraDistance - point.z, cameraDistance * 0.35);
12549
+ return {
12550
+ x: sceneCenterX + point.x * perspectiveScale,
12551
+ y: sceneCenterY + point.y * perspectiveScale,
12552
+ z: point.z,
12553
+ };
12554
+ }
12555
+ /**
12556
+ * Subtracts one 3D point from another.
12557
+ *
12558
+ * @param leftPoint Left point.
12559
+ * @param rightPoint Right point.
12560
+ * @returns Difference vector.
12561
+ *
12562
+ * @private helper of the 3D avatar visuals
12563
+ */
12564
+ function subtractPoint3D(leftPoint, rightPoint) {
12565
+ return {
12566
+ x: leftPoint.x - rightPoint.x,
12567
+ y: leftPoint.y - rightPoint.y,
12568
+ z: leftPoint.z - rightPoint.z,
12569
+ };
12570
+ }
12571
+ /**
12572
+ * Computes the 3D cross product of two vectors.
12573
+ *
12574
+ * @param leftVector Left vector.
12575
+ * @param rightVector Right vector.
12576
+ * @returns Cross product.
12577
+ *
12578
+ * @private helper of the 3D avatar visuals
12579
+ */
12580
+ function crossProduct3D(leftVector, rightVector) {
12581
+ return {
12582
+ x: leftVector.y * rightVector.z - leftVector.z * rightVector.y,
12583
+ y: leftVector.z * rightVector.x - leftVector.x * rightVector.z,
12584
+ z: leftVector.x * rightVector.y - leftVector.y * rightVector.x,
12585
+ };
12586
+ }
12587
+ /**
12588
+ * Computes the 3D dot product of two vectors.
12589
+ *
12590
+ * @param leftVector Left vector.
12591
+ * @param rightVector Right vector.
12592
+ * @returns Dot product.
12593
+ *
12594
+ * @private helper of the 3D avatar visuals
12595
+ */
12596
+ function dotProduct3D(leftVector, rightVector) {
12597
+ return leftVector.x * rightVector.x + leftVector.y * rightVector.y + leftVector.z * rightVector.z;
12598
+ }
12599
+ /**
12600
+ * Normalizes one 3D vector while keeping zero vectors stable.
12601
+ *
12602
+ * @param vector Source vector.
12603
+ * @returns Normalized vector.
12604
+ *
12605
+ * @private helper of the 3D avatar visuals
12606
+ */
12607
+ function normalizeVector3(vector) {
12608
+ const length = Math.hypot(vector.x, vector.y, vector.z);
12609
+ if (length === 0) {
12610
+ return vector;
12611
+ }
12612
+ return {
12613
+ x: vector.x / length,
12614
+ y: vector.y / length,
12615
+ z: vector.z / length,
12616
+ };
12617
+ }
12618
+ /**
12619
+ * Measures the perimeter of one projected quad.
12620
+ *
12621
+ * @param corners Quad corners.
12622
+ * @returns Perimeter length.
12623
+ *
12624
+ * @private helper of the 3D avatar visuals
12625
+ */
12626
+ function getProjectedQuadPerimeter(corners) {
12627
+ let perimeter = 0;
12628
+ for (let cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
12629
+ const currentCorner = corners[cornerIndex];
12630
+ const nextCorner = corners[(cornerIndex + 1) % corners.length];
12631
+ perimeter += Math.hypot(nextCorner.x - currentCorner.x, nextCorner.y - currentCorner.y);
12632
+ }
12633
+ return perimeter;
12634
+ }
12635
+
12456
12636
  /* eslint-disable no-magic-numbers */
12457
12637
  /**
12458
12638
  * Builds the seeded six-face texture pack used by the Minecraft-style head cuboid.
@@ -12625,18 +12805,12 @@ function fillTextureRect(texture, x, y, width, height, color) {
12625
12805
  }
12626
12806
 
12627
12807
  /* eslint-disable no-magic-numbers */
12628
- /**
12629
- * Fixed scene camera distance used for the proper-3D projection.
12630
- *
12631
- * @private helper of `minecraft2AvatarVisual`
12632
- */
12633
- const CAMERA_DISTANCE_RATIO = 1.4;
12634
12808
  /**
12635
12809
  * Shared light direction used to shade projected cuboid faces.
12636
12810
  *
12637
12811
  * @private helper of `minecraft2AvatarVisual`
12638
12812
  */
12639
- const LIGHT_DIRECTION = normalizeVector3({
12813
+ const LIGHT_DIRECTION$1 = normalizeVector3({
12640
12814
  x: 0.4,
12641
12815
  y: -0.65,
12642
12816
  z: 0.92,
@@ -12848,7 +13022,7 @@ function resolveVisibleCuboidFaces(cuboid, size, sceneCenterX, sceneCenterY) {
12848
13022
  corners: projectedCorners,
12849
13023
  texture: faceDefinition.texture,
12850
13024
  averageDepth: transformedCorners.reduce((depthSum, corner) => depthSum + corner.z, 0) / transformedCorners.length,
12851
- lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION), -1, 1),
13025
+ lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$1), -1, 1),
12852
13026
  outlineColor: cuboid.outlineColor,
12853
13027
  };
12854
13028
  });
@@ -12875,7 +13049,7 @@ function drawTexturedProjectedFace(context, face) {
12875
13049
  const endX = (columnIndex + 1) / columns;
12876
13050
  const startY = rowIndex / rows;
12877
13051
  const endY = (rowIndex + 1) / rows;
12878
- drawProjectedQuad(context, [
13052
+ drawProjectedQuad$1(context, [
12879
13053
  interpolateProjectedQuad(face.corners, startX, startY),
12880
13054
  interpolateProjectedQuad(face.corners, endX, startY),
12881
13055
  interpolateProjectedQuad(face.corners, endX, endY),
@@ -12884,10 +13058,10 @@ function drawTexturedProjectedFace(context, face) {
12884
13058
  }
12885
13059
  }
12886
13060
  if (face.lightIntensity > 0) {
12887
- drawProjectedQuad(context, face.corners, `rgba(255, 255, 255, ${0.15 * face.lightIntensity})`);
13061
+ drawProjectedQuad$1(context, face.corners, `rgba(255, 255, 255, ${0.15 * face.lightIntensity})`);
12888
13062
  }
12889
13063
  else if (face.lightIntensity < 0) {
12890
- drawProjectedQuad(context, face.corners, `rgba(0, 0, 0, ${0.22 * Math.abs(face.lightIntensity)})`);
13064
+ drawProjectedQuad$1(context, face.corners, `rgba(0, 0, 0, ${0.22 * Math.abs(face.lightIntensity)})`);
12891
13065
  }
12892
13066
  context.save();
12893
13067
  context.beginPath();
@@ -12911,7 +13085,7 @@ function drawTexturedProjectedFace(context, face) {
12911
13085
  *
12912
13086
  * @private helper of `minecraft2AvatarVisual`
12913
13087
  */
12914
- function drawProjectedQuad(context, corners, fillStyle) {
13088
+ function drawProjectedQuad$1(context, corners, fillStyle) {
12915
13089
  context.beginPath();
12916
13090
  context.moveTo(corners[0].x, corners[0].y);
12917
13091
  context.lineTo(corners[1].x, corners[1].y);
@@ -12953,175 +13127,6 @@ function interpolateProjectedPoint(startPoint, endPoint, ratio) {
12953
13127
  z: startPoint.z + (endPoint.z - startPoint.z) * ratio,
12954
13128
  };
12955
13129
  }
12956
- /**
12957
- * Projects one rotated scene point into canvas coordinates.
12958
- *
12959
- * @param point Scene point.
12960
- * @param size Canvas size in CSS pixels.
12961
- * @param sceneCenterX Horizontal scene center.
12962
- * @param sceneCenterY Vertical scene center.
12963
- * @returns Projected point.
12964
- *
12965
- * @private helper of `minecraft2AvatarVisual`
12966
- */
12967
- function projectScenePoint(point, size, sceneCenterX, sceneCenterY) {
12968
- const cameraDistance = size * CAMERA_DISTANCE_RATIO;
12969
- const perspectiveScale = cameraDistance / Math.max(cameraDistance - point.z, cameraDistance * 0.35);
12970
- return {
12971
- x: sceneCenterX + point.x * perspectiveScale,
12972
- y: sceneCenterY + point.y * perspectiveScale,
12973
- z: point.z,
12974
- };
12975
- }
12976
- /**
12977
- * Applies the local cuboid rotations and translation to one scene point.
12978
- *
12979
- * @param localPoint Point in cuboid-local space.
12980
- * @param center Cuboid center in scene space.
12981
- * @param rotationX Cuboid pitch in radians.
12982
- * @param rotationY Cuboid yaw in radians.
12983
- * @returns Transformed scene-space point.
12984
- *
12985
- * @private helper of `minecraft2AvatarVisual`
12986
- */
12987
- function transformScenePoint(localPoint, center, rotationX, rotationY) {
12988
- const yawedPoint = rotatePointAroundY(localPoint, rotationY);
12989
- const pitchedPoint = rotatePointAroundX(yawedPoint, rotationX);
12990
- return {
12991
- x: center.x + pitchedPoint.x,
12992
- y: center.y + pitchedPoint.y,
12993
- z: center.z + pitchedPoint.z,
12994
- };
12995
- }
12996
- /**
12997
- * Rotates one point around the local Y axis.
12998
- *
12999
- * @param point Source point.
13000
- * @param angle Rotation angle in radians.
13001
- * @returns Rotated point.
13002
- *
13003
- * @private helper of `minecraft2AvatarVisual`
13004
- */
13005
- function rotatePointAroundY(point, angle) {
13006
- const cosine = Math.cos(angle);
13007
- const sine = Math.sin(angle);
13008
- return {
13009
- x: point.x * cosine + point.z * sine,
13010
- y: point.y,
13011
- z: -point.x * sine + point.z * cosine,
13012
- };
13013
- }
13014
- /**
13015
- * Rotates one point around the local X axis.
13016
- *
13017
- * @param point Source point.
13018
- * @param angle Rotation angle in radians.
13019
- * @returns Rotated point.
13020
- *
13021
- * @private helper of `minecraft2AvatarVisual`
13022
- */
13023
- function rotatePointAroundX(point, angle) {
13024
- const cosine = Math.cos(angle);
13025
- const sine = Math.sin(angle);
13026
- return {
13027
- x: point.x,
13028
- y: point.y * cosine - point.z * sine,
13029
- z: point.y * sine + point.z * cosine,
13030
- };
13031
- }
13032
- /**
13033
- * Subtracts one 3D point from another.
13034
- *
13035
- * @param leftPoint Left point.
13036
- * @param rightPoint Right point.
13037
- * @returns Difference vector.
13038
- *
13039
- * @private helper of `minecraft2AvatarVisual`
13040
- */
13041
- function subtractPoint3D(leftPoint, rightPoint) {
13042
- return {
13043
- x: leftPoint.x - rightPoint.x,
13044
- y: leftPoint.y - rightPoint.y,
13045
- z: leftPoint.z - rightPoint.z,
13046
- };
13047
- }
13048
- /**
13049
- * Computes the 3D cross product of two vectors.
13050
- *
13051
- * @param leftVector Left vector.
13052
- * @param rightVector Right vector.
13053
- * @returns Cross product.
13054
- *
13055
- * @private helper of `minecraft2AvatarVisual`
13056
- */
13057
- function crossProduct3D(leftVector, rightVector) {
13058
- return {
13059
- x: leftVector.y * rightVector.z - leftVector.z * rightVector.y,
13060
- y: leftVector.z * rightVector.x - leftVector.x * rightVector.z,
13061
- z: leftVector.x * rightVector.y - leftVector.y * rightVector.x,
13062
- };
13063
- }
13064
- /**
13065
- * Computes the 3D dot product of two vectors.
13066
- *
13067
- * @param leftVector Left vector.
13068
- * @param rightVector Right vector.
13069
- * @returns Dot product.
13070
- *
13071
- * @private helper of `minecraft2AvatarVisual`
13072
- */
13073
- function dotProduct3D(leftVector, rightVector) {
13074
- return leftVector.x * rightVector.x + leftVector.y * rightVector.y + leftVector.z * rightVector.z;
13075
- }
13076
- /**
13077
- * Normalizes one 3D vector while keeping zero vectors stable.
13078
- *
13079
- * @param vector Source vector.
13080
- * @returns Normalized vector.
13081
- *
13082
- * @private helper of `minecraft2AvatarVisual`
13083
- */
13084
- function normalizeVector3(vector) {
13085
- const length = Math.hypot(vector.x, vector.y, vector.z);
13086
- if (length === 0) {
13087
- return vector;
13088
- }
13089
- return {
13090
- x: vector.x / length,
13091
- y: vector.y / length,
13092
- z: vector.z / length,
13093
- };
13094
- }
13095
- /**
13096
- * Clamps one number into the provided range.
13097
- *
13098
- * @param value Input value.
13099
- * @param minimumValue Inclusive lower bound.
13100
- * @param maximumValue Inclusive upper bound.
13101
- * @returns Clamped value.
13102
- *
13103
- * @private helper of `minecraft2AvatarVisual`
13104
- */
13105
- function clampNumber$1(value, minimumValue, maximumValue) {
13106
- return Math.min(maximumValue, Math.max(minimumValue, value));
13107
- }
13108
- /**
13109
- * Measures the perimeter of one projected quad.
13110
- *
13111
- * @param corners Quad corners.
13112
- * @returns Perimeter length.
13113
- *
13114
- * @private helper of `minecraft2AvatarVisual`
13115
- */
13116
- function getProjectedQuadPerimeter(corners) {
13117
- let perimeter = 0;
13118
- for (let cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
13119
- const currentCorner = corners[cornerIndex];
13120
- const nextCorner = corners[(cornerIndex + 1) % corners.length];
13121
- perimeter += Math.hypot(nextCorner.x - currentCorner.x, nextCorner.y - currentCorner.y);
13122
- }
13123
- return perimeter;
13124
- }
13125
13130
 
13126
13131
  /* eslint-disable no-magic-numbers */
13127
13132
  /**
@@ -13690,7 +13695,7 @@ function resolveSeededIntegerRange(random, minimumValue, maximumValue) {
13690
13695
  *
13691
13696
  * @private helper of `octopus3AvatarVisual`
13692
13697
  */
13693
- function formatAlphaHex(opacity) {
13698
+ function formatAlphaHex$1(opacity) {
13694
13699
  return Math.round(Math.min(1, Math.max(0, opacity)) * 255)
13695
13700
  .toString(16)
13696
13701
  .padStart(2, '0');
@@ -14069,7 +14074,7 @@ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, pa
14069
14074
  context.beginPath();
14070
14075
  context.moveTo(-radiusX * 0.74, radiusY * 0.2);
14071
14076
  context.quadraticCurveTo(0, radiusY * 0.38, radiusX * 0.74, radiusY * 0.2);
14072
- context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
14077
+ context.strokeStyle = `${palette.highlight}${formatAlphaHex$1(eyeStyle.lowerLidOpacity)}`;
14073
14078
  context.lineWidth = radiusX * 0.08;
14074
14079
  context.lineCap = 'round';
14075
14080
  context.stroke();
@@ -14077,6 +14082,518 @@ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, pa
14077
14082
  context.restore();
14078
14083
  }
14079
14084
 
14085
+ /* eslint-disable no-magic-numbers */
14086
+ /**
14087
+ * Light direction used by the organic 3D octopus shading.
14088
+ *
14089
+ * @private helper of `octopus3dAvatarVisual`
14090
+ */
14091
+ const LIGHT_DIRECTION = normalizeVector3({
14092
+ x: 0.48,
14093
+ y: -0.62,
14094
+ z: 0.94,
14095
+ });
14096
+ /**
14097
+ * Proper 3D Octopus visual built from projected organic meshes and tentacles.
14098
+ *
14099
+ * @private built-in avatar visual
14100
+ */
14101
+ const octopus3dAvatarVisual = {
14102
+ id: 'octopus3d',
14103
+ title: 'Octopus 3D',
14104
+ description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
14105
+ isAnimated: true,
14106
+ supportsPointerTracking: true,
14107
+ render({ context, size, palette, createRandom, timeMs, interaction }) {
14108
+ const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
14109
+ const animationRandom = createRandom('octopus3d-animation-profile');
14110
+ const eyeRandom = createRandom('octopus3d-eye-profile');
14111
+ const animationPhase = animationRandom() * Math.PI * 2;
14112
+ const sceneCenterX = size * 0.5;
14113
+ const sceneCenterY = size * 0.56;
14114
+ const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
14115
+ const mantleCenter = {
14116
+ x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
14117
+ y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
14118
+ z: interaction.intensity * size * 0.012,
14119
+ };
14120
+ const underbodyCenter = {
14121
+ x: mantleCenter.x * 0.86,
14122
+ y: mantleCenter.y + size * 0.168,
14123
+ z: mantleCenter.z - size * 0.018,
14124
+ };
14125
+ const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
14126
+ const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
14127
+ const mantleRadiusZ = size * morphologyProfile.body.bodyRadiusRatio * (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
14128
+ const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
14129
+ const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
14130
+ const underbodyRadiusZ = mantleRadiusZ * 0.78;
14131
+ const bodyYaw = -0.18 +
14132
+ Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
14133
+ interaction.bodyOffsetX * 0.18 +
14134
+ interaction.gazeX * 0.22;
14135
+ const bodyPitch = -0.08 +
14136
+ Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
14137
+ interaction.bodyOffsetY * 0.08 -
14138
+ interaction.gazeY * 0.08;
14139
+ const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
14140
+ const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
14141
+ const mantlePatches = resolveVisibleEllipsoidPatches({
14142
+ center: mantleCenter,
14143
+ radiusX: mantleRadiusX,
14144
+ radiusY: mantleRadiusY,
14145
+ radiusZ: mantleRadiusZ,
14146
+ rotationX: headPitch,
14147
+ rotationY: headYaw,
14148
+ sceneCenterX,
14149
+ sceneCenterY,
14150
+ size,
14151
+ palette,
14152
+ verticalColorBias: 0,
14153
+ outlineColor: `${palette.highlight}7a`,
14154
+ });
14155
+ const underbodyPatches = resolveVisibleEllipsoidPatches({
14156
+ center: underbodyCenter,
14157
+ radiusX: underbodyRadiusX,
14158
+ radiusY: underbodyRadiusY,
14159
+ radiusZ: underbodyRadiusZ,
14160
+ rotationX: bodyPitch,
14161
+ rotationY: bodyYaw,
14162
+ sceneCenterX,
14163
+ sceneCenterY,
14164
+ size,
14165
+ palette,
14166
+ verticalColorBias: 0.18,
14167
+ outlineColor: `${palette.shadow}8f`,
14168
+ });
14169
+ const tentacleStrokes = createOctopusTentacleStrokes({
14170
+ createRandom,
14171
+ morphologyProfile,
14172
+ timeMs,
14173
+ size,
14174
+ center: underbodyCenter,
14175
+ radiusX: underbodyRadiusX,
14176
+ radiusY: underbodyRadiusY,
14177
+ radiusZ: underbodyRadiusZ,
14178
+ rotationX: bodyPitch,
14179
+ rotationY: bodyYaw,
14180
+ sceneCenterX,
14181
+ sceneCenterY,
14182
+ animationPhase,
14183
+ });
14184
+ const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
14185
+ const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
14186
+ const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
14187
+ const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
14188
+ const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
14189
+ const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
14190
+ drawAvatarFrame(context, size, palette);
14191
+ drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
14192
+ drawOctopus3dShadow(context, size, palette, interaction, timeMs);
14193
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
14194
+ drawTentacleStroke(context, tentacleStroke, palette);
14195
+ }
14196
+ for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
14197
+ drawSurfacePatch(context, surfacePatch);
14198
+ }
14199
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
14200
+ drawTentacleStroke(context, tentacleStroke, palette);
14201
+ }
14202
+ drawProjectedEye(context, {
14203
+ x: -faceEyeSpacing,
14204
+ y: faceEyeYOffset,
14205
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
14206
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
14207
+ drawProjectedEye(context, {
14208
+ x: faceEyeSpacing,
14209
+ y: faceEyeYOffset,
14210
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
14211
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
14212
+ drawProjectedMouth(context, [
14213
+ { x: -mouthHalfWidth, y: mouthY, z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY) },
14214
+ {
14215
+ x: size * morphologyProfile.face.mouthCenterOffsetRatio,
14216
+ y: mouthY +
14217
+ size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
14218
+ Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
14219
+ interaction.gazeY * size * 0.01,
14220
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
14221
+ },
14222
+ { x: mouthHalfWidth, y: mouthY, z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY) },
14223
+ ], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
14224
+ },
14225
+ };
14226
+ /**
14227
+ * Draws the atmospheric underwater glow behind the octopus mesh.
14228
+ *
14229
+ * @private helper of `octopus3dAvatarVisual`
14230
+ */
14231
+ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
14232
+ const glowGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.1, sceneCenterY - size * 0.2 + interaction.gazeY * size * 0.05, size * 0.04, sceneCenterX, sceneCenterY - size * 0.04, size * 0.62);
14233
+ glowGradient.addColorStop(0, `${palette.highlight}5c`);
14234
+ glowGradient.addColorStop(0.36, `${palette.accent}24`);
14235
+ glowGradient.addColorStop(1, `${palette.highlight}00`);
14236
+ context.fillStyle = glowGradient;
14237
+ context.fillRect(0, 0, size, size);
14238
+ const lowerGradient = context.createRadialGradient(sceneCenterX + Math.sin(timeMs / 1700) * size * 0.05, sceneCenterY + size * 0.23, size * 0.08, sceneCenterX, sceneCenterY + size * 0.28, size * 0.5);
14239
+ lowerGradient.addColorStop(0, `${palette.secondary}1d`);
14240
+ lowerGradient.addColorStop(1, `${palette.secondary}00`);
14241
+ context.fillStyle = lowerGradient;
14242
+ context.fillRect(0, 0, size, size);
14243
+ }
14244
+ /**
14245
+ * Draws the soft ground shadow below the octopus.
14246
+ *
14247
+ * @private helper of `octopus3dAvatarVisual`
14248
+ */
14249
+ function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
14250
+ context.save();
14251
+ context.fillStyle = `${palette.shadow}66`;
14252
+ context.filter = `blur(${size * 0.022}px)`;
14253
+ context.beginPath();
14254
+ context.ellipse(size * 0.5 + interaction.gazeX * size * 0.04, size * 0.87 + Math.sin(timeMs / 920) * size * 0.008, size * (0.18 + interaction.intensity * 0.02), size * 0.06, 0, 0, Math.PI * 2);
14255
+ context.fill();
14256
+ context.restore();
14257
+ }
14258
+ /**
14259
+ * Resolves visible projected patches for one rotated ellipsoid mesh.
14260
+ *
14261
+ * @private helper of `octopus3dAvatarVisual`
14262
+ */
14263
+ function resolveVisibleEllipsoidPatches(options) {
14264
+ const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
14265
+ const latitudePatchCount = 10;
14266
+ const longitudePatchCount = 18;
14267
+ const surfacePatches = [];
14268
+ for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
14269
+ const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
14270
+ const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
14271
+ const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
14272
+ for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
14273
+ const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
14274
+ const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
14275
+ const localCorners = [
14276
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
14277
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
14278
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
14279
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
14280
+ ];
14281
+ const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
14282
+ const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
14283
+ if (surfaceNormal.z <= 0.01) {
14284
+ continue;
14285
+ }
14286
+ const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
14287
+ surfacePatches.push({
14288
+ corners: projectedCorners,
14289
+ averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
14290
+ transformedCorners.length,
14291
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
14292
+ fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
14293
+ outlineColor,
14294
+ });
14295
+ }
14296
+ }
14297
+ return surfacePatches;
14298
+ }
14299
+ /**
14300
+ * Samples one point on an ellipsoid aligned to the local axes.
14301
+ *
14302
+ * @private helper of `octopus3dAvatarVisual`
14303
+ */
14304
+ function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
14305
+ const cosineLatitude = Math.cos(latitude);
14306
+ return {
14307
+ x: Math.sin(longitude) * cosineLatitude * radiusX,
14308
+ y: Math.sin(latitude) * radiusY,
14309
+ z: Math.cos(longitude) * cosineLatitude * radiusZ,
14310
+ };
14311
+ }
14312
+ /**
14313
+ * Resolves one base fill tone for a surface patch across the octopus body.
14314
+ *
14315
+ * @private helper of `octopus3dAvatarVisual`
14316
+ */
14317
+ function resolveSurfacePatchFillStyle(palette, verticalProgress) {
14318
+ const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
14319
+ if (clampedVerticalProgress < 0.2) {
14320
+ return palette.highlight;
14321
+ }
14322
+ if (clampedVerticalProgress < 0.45) {
14323
+ return palette.secondary;
14324
+ }
14325
+ if (clampedVerticalProgress < 0.8) {
14326
+ return palette.primary;
14327
+ }
14328
+ return `${palette.shadow}f2`;
14329
+ }
14330
+ /**
14331
+ * Draws one projected mesh patch with organic shading.
14332
+ *
14333
+ * @private helper of `octopus3dAvatarVisual`
14334
+ */
14335
+ function drawSurfacePatch(context, surfacePatch) {
14336
+ drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
14337
+ if (surfacePatch.lightIntensity > 0) {
14338
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
14339
+ }
14340
+ else if (surfacePatch.lightIntensity < 0) {
14341
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
14342
+ }
14343
+ context.save();
14344
+ context.beginPath();
14345
+ context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
14346
+ for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
14347
+ context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
14348
+ }
14349
+ context.closePath();
14350
+ context.strokeStyle = surfacePatch.outlineColor;
14351
+ context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
14352
+ context.lineJoin = 'round';
14353
+ context.stroke();
14354
+ context.restore();
14355
+ }
14356
+ /**
14357
+ * Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
14358
+ *
14359
+ * @private helper of `octopus3dAvatarVisual`
14360
+ */
14361
+ function createOctopusTentacleStrokes(options) {
14362
+ const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
14363
+ return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
14364
+ const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
14365
+ const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
14366
+ const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
14367
+ const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
14368
+ const lateralReach = size *
14369
+ (0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
14370
+ const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
14371
+ const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
14372
+ const anchorPoint = {
14373
+ x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
14374
+ y: radiusY * (0.22 + tentacleRandom() * 0.18),
14375
+ z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
14376
+ };
14377
+ const controlPointOne = {
14378
+ x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
14379
+ y: anchorPoint.y + flowLength * 0.26,
14380
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
14381
+ };
14382
+ const controlPointTwo = {
14383
+ x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
14384
+ y: anchorPoint.y + flowLength * 0.66,
14385
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
14386
+ };
14387
+ const endPoint = {
14388
+ x: anchorPoint.x +
14389
+ Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
14390
+ sway * size * 0.028,
14391
+ y: anchorPoint.y + flowLength,
14392
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
14393
+ };
14394
+ const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
14395
+ const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
14396
+ const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
14397
+ return {
14398
+ projectedPoints,
14399
+ averageDepth,
14400
+ isFrontFacing: averageDepth >= center.z - size * 0.006,
14401
+ baseWidth: size *
14402
+ (0.019 +
14403
+ morphologyProfile.tentacles.baseWidthScale * 0.007 +
14404
+ tentacleRandom() * 0.003 +
14405
+ Math.abs(Math.sin(orbitAngle)) * 0.002),
14406
+ tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
14407
+ colorBias: tentacleRandom(),
14408
+ };
14409
+ });
14410
+ }
14411
+ /**
14412
+ * Samples one point on a cubic Bezier curve in 3D.
14413
+ *
14414
+ * @private helper of `octopus3dAvatarVisual`
14415
+ */
14416
+ function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
14417
+ const inverseProgress = 1 - progress;
14418
+ return {
14419
+ x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
14420
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
14421
+ 3 * inverseProgress * progress * progress * controlPointTwo.x +
14422
+ progress * progress * progress * endPoint.x,
14423
+ y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
14424
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
14425
+ 3 * inverseProgress * progress * progress * controlPointTwo.y +
14426
+ progress * progress * progress * endPoint.y,
14427
+ z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
14428
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
14429
+ 3 * inverseProgress * progress * progress * controlPointTwo.z +
14430
+ progress * progress * progress * endPoint.z,
14431
+ };
14432
+ }
14433
+ /**
14434
+ * Draws one projected tentacle stroke with a slim highlight ridge.
14435
+ *
14436
+ * @private helper of `octopus3dAvatarVisual`
14437
+ */
14438
+ function drawTentacleStroke(context, tentacleStroke, palette) {
14439
+ const projectedSegments = tentacleStroke.projectedPoints.length - 1;
14440
+ for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
14441
+ const startPoint = tentacleStroke.projectedPoints[segmentIndex];
14442
+ const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
14443
+ const progress = segmentIndex / projectedSegments;
14444
+ const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
14445
+ context.beginPath();
14446
+ context.moveTo(startPoint.x, startPoint.y);
14447
+ context.lineTo(endPoint.x, endPoint.y);
14448
+ context.strokeStyle =
14449
+ tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
14450
+ context.lineWidth = width;
14451
+ context.lineCap = 'round';
14452
+ context.stroke();
14453
+ context.beginPath();
14454
+ context.moveTo(startPoint.x, startPoint.y);
14455
+ context.lineTo(endPoint.x, endPoint.y);
14456
+ context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
14457
+ context.lineWidth = Math.max(1, width * 0.34);
14458
+ context.lineCap = 'round';
14459
+ context.stroke();
14460
+ }
14461
+ }
14462
+ /**
14463
+ * Resolves the front surface depth on an ellipsoid for one local face point.
14464
+ *
14465
+ * @private helper of `octopus3dAvatarVisual`
14466
+ */
14467
+ function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
14468
+ const normalizedX = x / radiusX;
14469
+ const normalizedY = y / radiusY;
14470
+ const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
14471
+ return Math.sqrt(remainingDepthRatio) * radiusZ;
14472
+ }
14473
+ /**
14474
+ * Draws one projected eye on the turned octopus mantle.
14475
+ *
14476
+ * @private helper of `octopus3dAvatarVisual`
14477
+ */
14478
+ function drawProjectedEye(context, localCenter, radiusX, radiusY, center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, phase, interaction, eyeStyle) {
14479
+ const centerScenePoint = transformScenePoint(localCenter, center, rotationX, rotationY);
14480
+ if (centerScenePoint.z <= center.z) {
14481
+ return;
14482
+ }
14483
+ const horizontalScenePoint = transformScenePoint({ x: localCenter.x + radiusX, y: localCenter.y, z: localCenter.z }, center, rotationX, rotationY);
14484
+ const verticalScenePoint = transformScenePoint({ x: localCenter.x, y: localCenter.y + radiusY, z: localCenter.z }, center, rotationX, rotationY);
14485
+ const projectedCenterPoint = projectScenePoint(centerScenePoint, size, sceneCenterX, sceneCenterY);
14486
+ const projectedHorizontalPoint = projectScenePoint(horizontalScenePoint, size, sceneCenterX, sceneCenterY);
14487
+ const projectedVerticalPoint = projectScenePoint(verticalScenePoint, size, sceneCenterX, sceneCenterY);
14488
+ const projectedRadiusX = Math.hypot(projectedHorizontalPoint.x - projectedCenterPoint.x, projectedHorizontalPoint.y - projectedCenterPoint.y);
14489
+ const projectedRadiusY = Math.hypot(projectedVerticalPoint.x - projectedCenterPoint.x, projectedVerticalPoint.y - projectedCenterPoint.y);
14490
+ if (projectedRadiusX < size * 0.008 || projectedRadiusY < size * 0.008) {
14491
+ return;
14492
+ }
14493
+ const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
14494
+ radiusX: projectedRadiusX,
14495
+ radiusY: projectedRadiusY,
14496
+ timeMs,
14497
+ phase,
14498
+ interaction,
14499
+ });
14500
+ const rotation = Math.atan2(projectedHorizontalPoint.y - projectedCenterPoint.y, projectedHorizontalPoint.x - projectedCenterPoint.x);
14501
+ context.save();
14502
+ context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
14503
+ context.rotate(rotation);
14504
+ context.beginPath();
14505
+ context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
14506
+ context.fillStyle = '#f8fbff';
14507
+ context.fill();
14508
+ context.clip();
14509
+ const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
14510
+ irisGradient.addColorStop(0, palette.highlight);
14511
+ irisGradient.addColorStop(0.56, palette.secondary);
14512
+ irisGradient.addColorStop(1, palette.shadow);
14513
+ context.beginPath();
14514
+ context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
14515
+ context.fillStyle = irisGradient;
14516
+ context.fill();
14517
+ context.beginPath();
14518
+ context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.15 * eyeStyle.pupilWidthScale, projectedRadiusY * 0.48 * eyeStyle.pupilHeightScale, 0, 0, Math.PI * 2);
14519
+ context.fillStyle = palette.ink;
14520
+ context.fill();
14521
+ context.beginPath();
14522
+ context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
14523
+ context.fillStyle = '#ffffff';
14524
+ context.fill();
14525
+ context.restore();
14526
+ context.save();
14527
+ context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
14528
+ context.rotate(rotation);
14529
+ context.beginPath();
14530
+ context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
14531
+ context.strokeStyle = `${palette.shadow}cc`;
14532
+ context.lineWidth = projectedRadiusX * 0.16;
14533
+ context.stroke();
14534
+ context.beginPath();
14535
+ context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
14536
+ context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
14537
+ context.strokeStyle = `${palette.shadow}73`;
14538
+ context.lineWidth = projectedRadiusX * 0.14;
14539
+ context.lineCap = 'round';
14540
+ context.stroke();
14541
+ if (eyeStyle.lowerLidOpacity > 0) {
14542
+ context.beginPath();
14543
+ context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
14544
+ context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
14545
+ context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
14546
+ context.lineWidth = projectedRadiusX * 0.08;
14547
+ context.lineCap = 'round';
14548
+ context.stroke();
14549
+ }
14550
+ context.restore();
14551
+ }
14552
+ /**
14553
+ * Draws a subtle projected mouth arc across the front of the mantle.
14554
+ *
14555
+ * @private helper of `octopus3dAvatarVisual`
14556
+ */
14557
+ function drawProjectedMouth(context, localPoints, center, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size) {
14558
+ const scenePoints = localPoints.map((localPoint) => transformScenePoint(localPoint, center, rotationX, rotationY));
14559
+ if (scenePoints.some((scenePoint) => scenePoint.z <= center.z)) {
14560
+ return;
14561
+ }
14562
+ const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
14563
+ context.beginPath();
14564
+ context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
14565
+ context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
14566
+ context.strokeStyle = `${palette.ink}b8`;
14567
+ context.lineWidth = Math.max(1.1, size * 0.009);
14568
+ context.lineCap = 'round';
14569
+ context.stroke();
14570
+ }
14571
+ /**
14572
+ * Draws one filled projected quad.
14573
+ *
14574
+ * @private helper of `octopus3dAvatarVisual`
14575
+ */
14576
+ function drawProjectedQuad(context, corners, fillStyle) {
14577
+ context.beginPath();
14578
+ context.moveTo(corners[0].x, corners[0].y);
14579
+ context.lineTo(corners[1].x, corners[1].y);
14580
+ context.lineTo(corners[2].x, corners[2].y);
14581
+ context.lineTo(corners[3].x, corners[3].y);
14582
+ context.closePath();
14583
+ context.fillStyle = fillStyle;
14584
+ context.fill();
14585
+ }
14586
+ /**
14587
+ * Converts an opacity ratio into a two-digit hexadecimal alpha suffix.
14588
+ *
14589
+ * @private helper of `octopus3dAvatarVisual`
14590
+ */
14591
+ function formatAlphaHex(opacity) {
14592
+ return Math.round(clampNumber$1(opacity, 0, 1) * 255)
14593
+ .toString(16)
14594
+ .padStart(2, '0');
14595
+ }
14596
+
14080
14597
  /* eslint-disable no-magic-numbers */
14081
14598
  /**
14082
14599
  * Octopus avatar visual.
@@ -14845,6 +15362,7 @@ const AVATAR_VISUALS = [
14845
15362
  octopusAvatarVisual,
14846
15363
  octopus2AvatarVisual,
14847
15364
  octopus3AvatarVisual,
15365
+ octopus3dAvatarVisual,
14848
15366
  asciiOctopusAvatarVisual,
14849
15367
  minecraftAvatarVisual,
14850
15368
  minecraft2AvatarVisual,
@@ -17038,16 +17556,22 @@ function resolveTeamTeammateLabels(teamContent, teammates) {
17038
17556
  * Each teammate is listed with its tool name, TEAM instructions, and optional profile hints.
17039
17557
  */
17040
17558
  function buildTeamSystemMessageBody(teamEntries) {
17041
- const lines = [
17042
- ...TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES,
17043
- '',
17044
- ...teamEntries.map((entry, index) => {
17045
- const toolLine = `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``;
17046
- const detailLines = collectTeamEntryDetails(entry).map(formatTeamEntryDetailLine);
17047
- return [toolLine, ...detailLines].join('\n');
17048
- }),
17049
- ];
17050
- return lines.join('\n');
17559
+ const teammateSections = teamEntries.map((entry, index) => {
17560
+ const toolLine = `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``;
17561
+ const detailLines = collectTeamEntryDetails(entry).map(formatTeamEntryDetailLine);
17562
+ if (detailLines.length === 0) {
17563
+ return toolLine;
17564
+ }
17565
+ return spaceTrim$1((block) => `
17566
+ ${toolLine}
17567
+ ${block(detailLines.join('\n'))}
17568
+ `);
17569
+ });
17570
+ return spaceTrim$1((block) => `
17571
+ ${block(TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES.join('\n'))}
17572
+
17573
+ ${block(teammateSections.join('\n\n'))}
17574
+ `);
17051
17575
  }
17052
17576
  /**
17053
17577
  * Builds the model-visible description for one teammate tool.
@@ -24555,7 +25079,11 @@ function createExampleInteractionsContent(parseResult, samples) {
24555
25079
  if (examples.length === 0) {
24556
25080
  return null;
24557
25081
  }
24558
- return `## Sample of communication with the agent:\n\n${examples.join('\n\n')}`;
25082
+ return spaceTrim$1((block) => `
25083
+ ## Sample of communication with the agent:
25084
+
25085
+ ${block(examples.join('\n\n'))}
25086
+ `);
24559
25087
  }
24560
25088
  /**
24561
25089
  * Collects the individual lines used in the example interaction section.
@@ -24592,7 +25120,11 @@ function collectExampleInteractionLines(parseResult, samples) {
24592
25120
  function appendSystemMessageSection(requirements, section) {
24593
25121
  return {
24594
25122
  ...requirements,
24595
- systemMessage: requirements.systemMessage + '\n\n' + section,
25123
+ systemMessage: spaceTrim$1((block) => `
25124
+ ${block(requirements.systemMessage)}
25125
+
25126
+ ${block(section)}
25127
+ `),
24596
25128
  };
24597
25129
  }
24598
25130
  /**
@@ -26814,8 +27346,7 @@ class Book {
26814
27346
  });
26815
27347
  }
26816
27348
  }
26817
- lineIndex =
26818
- nextBlockLineIndex === -1 ? -1 : findNextNonEmptyLineIndex(lines, nextBlockLineIndex);
27349
+ lineIndex = nextBlockLineIndex === -1 ? -1 : findNextNonEmptyLineIndex(lines, nextBlockLineIndex);
26819
27350
  }
26820
27351
  return new Book(agentName, commitments, messageBlocks);
26821
27352
  }
@@ -26842,18 +27373,12 @@ class Book {
26842
27373
  sections.push(this.agentName.trim());
26843
27374
  }
26844
27375
  for (const commitment of this.commitments) {
26845
- sections.push([
26846
- [commitment.type, commitment.subject].filter(Boolean).join(' ').trim(),
26847
- commitment.content.trim(),
26848
- ]
27376
+ sections.push([[commitment.type, commitment.subject].filter(Boolean).join(' ').trim(), commitment.content.trim()]
26849
27377
  .filter(Boolean)
26850
27378
  .join('\n'));
26851
27379
  }
26852
27380
  for (const messageBlock of this.messageBlocks) {
26853
- sections.push([
26854
- `${messageBlock.marker} @${messageBlock.sender}`,
26855
- messageBlock.content.trim(),
26856
- ]
27381
+ sections.push([`${messageBlock.marker} @${messageBlock.sender}`, messageBlock.content.trim()]
26857
27382
  .filter(Boolean)
26858
27383
  .join('\n'));
26859
27384
  }
@@ -31787,50 +32312,55 @@ function executionReportJsonToString(executionReportJson, options) {
31787
32312
  ? ''
31788
32313
  : ` *(Some cost is unknown)*`) +
31789
32314
  (taxRate !== 0 ? ` *(with tax ${taxRate * 100}%)*` : ''));
31790
- executionReportString += '\n\n' + headerList.map((header) => `- ${header}`).join('\n');
31791
- executionReportString +=
31792
- '\n\n' +
31793
- '## 🗃 Index' +
31794
- '\n\n' +
31795
- executionReportJson.promptExecutions
31796
- .map((promptExecution) => {
31797
- // TODO: [💩] Make some better system to convert headings to links
31798
- let hash = normalizeToKebabCase(promptExecution.prompt.title);
31799
- if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
31800
- hash = '-' + hash;
31801
- }
31802
- // TODO: Make working hash link for the task in md + pdf
31803
- return `- [${promptExecution.prompt.title}](#${hash})`;
31804
- })
31805
- .join('\n');
31806
- executionReportString +=
31807
- '\n\n' +
31808
- '## ⌚ Time chart' +
31809
- '\n\n' +
31810
- createMarkdownChart({
31811
- nameHeader: 'Task',
31812
- valueHeader: 'Timeline',
31813
- items: timingItems,
31814
- width: chartsWidth,
31815
- unitName: 'seconds',
31816
- });
31817
- executionReportString +=
31818
- '\n\n' +
31819
- '## 💸 Cost chart' +
31820
- '\n\n' +
31821
- createMarkdownChart({
31822
- nameHeader: 'Task',
31823
- valueHeader: 'Cost',
31824
- items: costItems,
31825
- width: chartsWidth,
31826
- unitName: 'USD',
31827
- });
32315
+ executionReportString = spaceTrim$1((block) => `
32316
+ ${block(executionReportString)}
32317
+
32318
+ ${block(headerList.map((header) => `- ${header}`).join('\n'))}
32319
+
32320
+ ## 🗃 Index
32321
+
32322
+ ${block(executionReportJson.promptExecutions
32323
+ .map((promptExecution) => {
32324
+ // TODO: [💩] Make some better system to convert headings to links
32325
+ let hash = normalizeToKebabCase(promptExecution.prompt.title);
32326
+ if (/^\s*\p{Extended_Pictographic}/u.test(promptExecution.prompt.title)) {
32327
+ hash = '-' + hash;
32328
+ }
32329
+ // TODO: Make working hash link for the task in md + pdf
32330
+ return `- [${promptExecution.prompt.title}](#${hash})`;
32331
+ })
32332
+ .join('\n'))}
32333
+
32334
+ ## ⌚ Time chart
32335
+
32336
+ ${block(createMarkdownChart({
32337
+ nameHeader: 'Task',
32338
+ valueHeader: 'Timeline',
32339
+ items: timingItems,
32340
+ width: chartsWidth,
32341
+ unitName: 'seconds',
32342
+ }))}
32343
+
32344
+ ## 💸 Cost chart
32345
+
32346
+ ${block(createMarkdownChart({
32347
+ nameHeader: 'Task',
32348
+ valueHeader: 'Cost',
32349
+ items: costItems,
32350
+ width: chartsWidth,
32351
+ unitName: 'USD',
32352
+ }))}
32353
+ `);
31828
32354
  }
31829
32355
  else {
31830
32356
  headerList.push(`TOTAL COST $0 *(Nothing executed)*`);
31831
32357
  }
31832
32358
  for (const promptExecution of executionReportJson.promptExecutions) {
31833
- executionReportString += '\n\n\n\n' + `## ${promptExecution.prompt.title}`;
32359
+ executionReportString = spaceTrim$1((block) => `
32360
+ ${block(executionReportString)}
32361
+
32362
+ ## ${promptExecution.prompt.title}
32363
+ `);
31834
32364
  const taskList = [];
31835
32365
  // TODO: What if startedAt OR/AND completedAt is not defined?
31836
32366
  const startedAt = moment((_b = (_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.timing) === null || _b === void 0 ? void 0 : _b.start);
@@ -31846,7 +32376,11 @@ function executionReportJsonToString(executionReportJson, options) {
31846
32376
  else {
31847
32377
  taskList.push(`COST UNKNOWN`);
31848
32378
  }
31849
- executionReportString += '\n\n' + taskList.map((header) => `- ${header}`).join('\n');
32379
+ executionReportString = spaceTrim$1((block) => `
32380
+ ${block(executionReportString)}
32381
+
32382
+ ${block(taskList.map((header) => `- ${header}`).join('\n'))}
32383
+ `);
31850
32384
  /*
31851
32385
  - MODEL VARIANT ${promptExecution.prompt.modelRequirements.modelVariant}
31852
32386
  - MODEL NAME \`${promptExecution.result?.model}\` (requested \`${
@@ -31854,49 +32388,60 @@ function executionReportJsonToString(executionReportJson, options) {
31854
32388
 
31855
32389
  */
31856
32390
  if (just(true)) {
31857
- executionReportString +=
31858
- '\n\n\n\n' +
31859
- spaceTrim$1((block) => {
31860
- var _a;
31861
- return `
32391
+ executionReportString = spaceTrim$1((block) => {
32392
+ var _a;
32393
+ return `
32394
+ ${block(executionReportString)}
31862
32395
 
31863
- ### Prompt
32396
+ ### Prompt
31864
32397
 
31865
- \`\`\`
31866
- ${block(escapeMarkdownBlock(((_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.rawPromptContent) || promptExecution.prompt.content))}
31867
- \`\`\`
31868
-
31869
- `;
31870
- });
32398
+ \`\`\`
32399
+ ${block(escapeMarkdownBlock(((_a = promptExecution.result) === null || _a === void 0 ? void 0 : _a.rawPromptContent) || promptExecution.prompt.content))}
32400
+ \`\`\`
32401
+ `;
32402
+ });
31871
32403
  }
31872
32404
  if (promptExecution.result && promptExecution.result.content) {
31873
- executionReportString += '\n\n\n\n' + '### Result' + '\n\n';
32405
+ const resultContent = promptExecution.result.content;
32406
+ executionReportString = spaceTrim$1((block) => `
32407
+ ${block(executionReportString)}
32408
+
32409
+ ### Result
32410
+ `);
31874
32411
  if (promptExecution.result === undefined) {
31875
- executionReportString += '*No result*';
32412
+ executionReportString = spaceTrim$1((block) => `
32413
+ ${block(executionReportString)}
32414
+
32415
+ *No result*
32416
+ `);
31876
32417
  }
31877
- else if (typeof promptExecution.result.content === 'string') {
31878
- executionReportString += spaceTrim$1((block) => `
31879
- \`\`\`
31880
- ${block(escapeMarkdownBlock(promptExecution.result.content))}
31881
- \`\`\`
31882
- `);
32418
+ else if (typeof resultContent === 'string') {
32419
+ executionReportString = spaceTrim$1((block) => `
32420
+ ${block(executionReportString)}
32421
+
32422
+ \`\`\`
32423
+ ${block(escapeMarkdownBlock(resultContent))}
32424
+ \`\`\`
32425
+ `);
31883
32426
  }
31884
32427
  else {
31885
- executionReportString += embeddingVectorToString(promptExecution.result.content);
32428
+ executionReportString = spaceTrim$1((block) => `
32429
+ ${block(executionReportString)}
32430
+
32431
+ ${block(embeddingVectorToString(resultContent))}
32432
+ `);
31886
32433
  }
31887
32434
  }
31888
32435
  if (promptExecution.error && promptExecution.error.message) {
31889
- executionReportString +=
31890
- '\n\n\n\n' +
31891
- spaceTrim$1((block) => `
32436
+ executionReportString = spaceTrim$1((block) => `
32437
+ ${block(executionReportString)}
31892
32438
 
31893
- ### Error
32439
+ ### Error
31894
32440
 
31895
- \`\`\`
31896
- ${block(escapeMarkdownBlock(promptExecution.error.message))}
31897
- \`\`\`
31898
-
31899
- `);
32441
+ \`\`\`
32442
+ ${block(escapeMarkdownBlock(promptExecution.error.message))}
32443
+ \`\`\`
32444
+ `);
31900
32445
  }
31901
32446
  }
31902
32447
  executionReportString = prettifyMarkdown(executionReportString);
@@ -45884,7 +46429,7 @@ const FormattedBookInMarkdownTranspiler = {
45884
46429
  lines = lines.map((line) => `${line}<br/>`);
45885
46430
  return lines.join('\n');
45886
46431
  },
45887
- } /* <- Note: [🤛] */;
46432
+ }; /* <- Note: [🤛] */
45888
46433
 
45889
46434
  /**
45890
46435
  * Transpiler to JavaScript code using the OpenAI Agents SDK.