@promptbook/browser 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.
- package/esm/index.es.js +765 -233
- package/esm/index.es.js.map +1 -1
- package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/esm/src/avatars/visuals/avatar3dProjectionShared.d.ts +141 -0
- package/esm/src/avatars/visuals/octopus3dAvatarVisual.d.ts +7 -0
- package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +2 -2
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +22 -0
- package/esm/src/cli/cli-commands/agent/runMultiple.d.ts +10 -0
- package/esm/src/cli/cli-commands/agent.d.ts +3 -2
- package/esm/src/cli/other/install.test.d.ts +1 -0
- package/esm/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +1 -1
- package/esm/src/commitments/WALLET/WALLET.d.ts +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +765 -233
- package/umd/index.umd.js.map +1 -1
- package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/umd/src/avatars/visuals/avatar3dProjectionShared.d.ts +141 -0
- package/umd/src/avatars/visuals/octopus3dAvatarVisual.d.ts +7 -0
- package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +2 -2
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +22 -0
- package/umd/src/cli/cli-commands/agent/runMultiple.d.ts +10 -0
- package/umd/src/cli/cli-commands/agent.d.ts +3 -2
- package/umd/src/cli/other/install.test.d.ts +1 -0
- package/umd/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +1 -1
- package/umd/src/commitments/WALLET/WALLET.d.ts +1 -1
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -29,7 +29,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
29
29
|
* @generated
|
|
30
30
|
* @see https://github.com/webgptorg/promptbook
|
|
31
31
|
*/
|
|
32
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
32
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-70';
|
|
33
33
|
/**
|
|
34
34
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
35
35
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -6239,6 +6239,184 @@ function drawFractalCore(context, size, palette, timeMs, corePhase) {
|
|
|
6239
6239
|
context.restore();
|
|
6240
6240
|
}
|
|
6241
6241
|
|
|
6242
|
+
/* eslint-disable no-magic-numbers */
|
|
6243
|
+
/**
|
|
6244
|
+
* Default camera distance ratio shared by the proper-3D avatar visuals.
|
|
6245
|
+
*
|
|
6246
|
+
* @private helper of the 3D avatar visuals
|
|
6247
|
+
*/
|
|
6248
|
+
const DEFAULT_3D_CAMERA_DISTANCE_RATIO = 1.4;
|
|
6249
|
+
/**
|
|
6250
|
+
* Clamps one number into the provided range.
|
|
6251
|
+
*
|
|
6252
|
+
* @param value Input value.
|
|
6253
|
+
* @param minimumValue Inclusive lower bound.
|
|
6254
|
+
* @param maximumValue Inclusive upper bound.
|
|
6255
|
+
* @returns Clamped value.
|
|
6256
|
+
*
|
|
6257
|
+
* @private helper of the 3D avatar visuals
|
|
6258
|
+
*/
|
|
6259
|
+
function clampNumber$1(value, minimumValue, maximumValue) {
|
|
6260
|
+
return Math.min(maximumValue, Math.max(minimumValue, value));
|
|
6261
|
+
}
|
|
6262
|
+
/**
|
|
6263
|
+
* Rotates one point around the local Y axis.
|
|
6264
|
+
*
|
|
6265
|
+
* @param point Source point.
|
|
6266
|
+
* @param angle Rotation angle in radians.
|
|
6267
|
+
* @returns Rotated point.
|
|
6268
|
+
*
|
|
6269
|
+
* @private helper of the 3D avatar visuals
|
|
6270
|
+
*/
|
|
6271
|
+
function rotatePointAroundY(point, angle) {
|
|
6272
|
+
const cosine = Math.cos(angle);
|
|
6273
|
+
const sine = Math.sin(angle);
|
|
6274
|
+
return {
|
|
6275
|
+
x: point.x * cosine + point.z * sine,
|
|
6276
|
+
y: point.y,
|
|
6277
|
+
z: -point.x * sine + point.z * cosine,
|
|
6278
|
+
};
|
|
6279
|
+
}
|
|
6280
|
+
/**
|
|
6281
|
+
* Rotates one point around the local X axis.
|
|
6282
|
+
*
|
|
6283
|
+
* @param point Source point.
|
|
6284
|
+
* @param angle Rotation angle in radians.
|
|
6285
|
+
* @returns Rotated point.
|
|
6286
|
+
*
|
|
6287
|
+
* @private helper of the 3D avatar visuals
|
|
6288
|
+
*/
|
|
6289
|
+
function rotatePointAroundX(point, angle) {
|
|
6290
|
+
const cosine = Math.cos(angle);
|
|
6291
|
+
const sine = Math.sin(angle);
|
|
6292
|
+
return {
|
|
6293
|
+
x: point.x,
|
|
6294
|
+
y: point.y * cosine - point.z * sine,
|
|
6295
|
+
z: point.y * sine + point.z * cosine,
|
|
6296
|
+
};
|
|
6297
|
+
}
|
|
6298
|
+
/**
|
|
6299
|
+
* Applies the local rotations and translation to one scene point.
|
|
6300
|
+
*
|
|
6301
|
+
* @param localPoint Point in local object space.
|
|
6302
|
+
* @param center Object center in scene space.
|
|
6303
|
+
* @param rotationX Object pitch in radians.
|
|
6304
|
+
* @param rotationY Object yaw in radians.
|
|
6305
|
+
* @returns Transformed scene-space point.
|
|
6306
|
+
*
|
|
6307
|
+
* @private helper of the 3D avatar visuals
|
|
6308
|
+
*/
|
|
6309
|
+
function transformScenePoint(localPoint, center, rotationX, rotationY) {
|
|
6310
|
+
const yawedPoint = rotatePointAroundY(localPoint, rotationY);
|
|
6311
|
+
const pitchedPoint = rotatePointAroundX(yawedPoint, rotationX);
|
|
6312
|
+
return {
|
|
6313
|
+
x: center.x + pitchedPoint.x,
|
|
6314
|
+
y: center.y + pitchedPoint.y,
|
|
6315
|
+
z: center.z + pitchedPoint.z,
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
/**
|
|
6319
|
+
* Projects one scene point into canvas coordinates.
|
|
6320
|
+
*
|
|
6321
|
+
* @param point Scene-space point.
|
|
6322
|
+
* @param size Canvas size in CSS pixels.
|
|
6323
|
+
* @param sceneCenterX Horizontal scene center.
|
|
6324
|
+
* @param sceneCenterY Vertical scene center.
|
|
6325
|
+
* @param cameraDistanceRatio Optional camera distance ratio.
|
|
6326
|
+
* @returns Projected point.
|
|
6327
|
+
*
|
|
6328
|
+
* @private helper of the 3D avatar visuals
|
|
6329
|
+
*/
|
|
6330
|
+
function projectScenePoint(point, size, sceneCenterX, sceneCenterY, cameraDistanceRatio = DEFAULT_3D_CAMERA_DISTANCE_RATIO) {
|
|
6331
|
+
const cameraDistance = size * cameraDistanceRatio;
|
|
6332
|
+
const perspectiveScale = cameraDistance / Math.max(cameraDistance - point.z, cameraDistance * 0.35);
|
|
6333
|
+
return {
|
|
6334
|
+
x: sceneCenterX + point.x * perspectiveScale,
|
|
6335
|
+
y: sceneCenterY + point.y * perspectiveScale,
|
|
6336
|
+
z: point.z,
|
|
6337
|
+
};
|
|
6338
|
+
}
|
|
6339
|
+
/**
|
|
6340
|
+
* Subtracts one 3D point from another.
|
|
6341
|
+
*
|
|
6342
|
+
* @param leftPoint Left point.
|
|
6343
|
+
* @param rightPoint Right point.
|
|
6344
|
+
* @returns Difference vector.
|
|
6345
|
+
*
|
|
6346
|
+
* @private helper of the 3D avatar visuals
|
|
6347
|
+
*/
|
|
6348
|
+
function subtractPoint3D(leftPoint, rightPoint) {
|
|
6349
|
+
return {
|
|
6350
|
+
x: leftPoint.x - rightPoint.x,
|
|
6351
|
+
y: leftPoint.y - rightPoint.y,
|
|
6352
|
+
z: leftPoint.z - rightPoint.z,
|
|
6353
|
+
};
|
|
6354
|
+
}
|
|
6355
|
+
/**
|
|
6356
|
+
* Computes the 3D cross product of two vectors.
|
|
6357
|
+
*
|
|
6358
|
+
* @param leftVector Left vector.
|
|
6359
|
+
* @param rightVector Right vector.
|
|
6360
|
+
* @returns Cross product.
|
|
6361
|
+
*
|
|
6362
|
+
* @private helper of the 3D avatar visuals
|
|
6363
|
+
*/
|
|
6364
|
+
function crossProduct3D(leftVector, rightVector) {
|
|
6365
|
+
return {
|
|
6366
|
+
x: leftVector.y * rightVector.z - leftVector.z * rightVector.y,
|
|
6367
|
+
y: leftVector.z * rightVector.x - leftVector.x * rightVector.z,
|
|
6368
|
+
z: leftVector.x * rightVector.y - leftVector.y * rightVector.x,
|
|
6369
|
+
};
|
|
6370
|
+
}
|
|
6371
|
+
/**
|
|
6372
|
+
* Computes the 3D dot product of two vectors.
|
|
6373
|
+
*
|
|
6374
|
+
* @param leftVector Left vector.
|
|
6375
|
+
* @param rightVector Right vector.
|
|
6376
|
+
* @returns Dot product.
|
|
6377
|
+
*
|
|
6378
|
+
* @private helper of the 3D avatar visuals
|
|
6379
|
+
*/
|
|
6380
|
+
function dotProduct3D(leftVector, rightVector) {
|
|
6381
|
+
return leftVector.x * rightVector.x + leftVector.y * rightVector.y + leftVector.z * rightVector.z;
|
|
6382
|
+
}
|
|
6383
|
+
/**
|
|
6384
|
+
* Normalizes one 3D vector while keeping zero vectors stable.
|
|
6385
|
+
*
|
|
6386
|
+
* @param vector Source vector.
|
|
6387
|
+
* @returns Normalized vector.
|
|
6388
|
+
*
|
|
6389
|
+
* @private helper of the 3D avatar visuals
|
|
6390
|
+
*/
|
|
6391
|
+
function normalizeVector3(vector) {
|
|
6392
|
+
const length = Math.hypot(vector.x, vector.y, vector.z);
|
|
6393
|
+
if (length === 0) {
|
|
6394
|
+
return vector;
|
|
6395
|
+
}
|
|
6396
|
+
return {
|
|
6397
|
+
x: vector.x / length,
|
|
6398
|
+
y: vector.y / length,
|
|
6399
|
+
z: vector.z / length,
|
|
6400
|
+
};
|
|
6401
|
+
}
|
|
6402
|
+
/**
|
|
6403
|
+
* Measures the perimeter of one projected quad.
|
|
6404
|
+
*
|
|
6405
|
+
* @param corners Quad corners.
|
|
6406
|
+
* @returns Perimeter length.
|
|
6407
|
+
*
|
|
6408
|
+
* @private helper of the 3D avatar visuals
|
|
6409
|
+
*/
|
|
6410
|
+
function getProjectedQuadPerimeter(corners) {
|
|
6411
|
+
let perimeter = 0;
|
|
6412
|
+
for (let cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
|
|
6413
|
+
const currentCorner = corners[cornerIndex];
|
|
6414
|
+
const nextCorner = corners[(cornerIndex + 1) % corners.length];
|
|
6415
|
+
perimeter += Math.hypot(nextCorner.x - currentCorner.x, nextCorner.y - currentCorner.y);
|
|
6416
|
+
}
|
|
6417
|
+
return perimeter;
|
|
6418
|
+
}
|
|
6419
|
+
|
|
6242
6420
|
/* eslint-disable no-magic-numbers */
|
|
6243
6421
|
/**
|
|
6244
6422
|
* Builds the seeded six-face texture pack used by the Minecraft-style head cuboid.
|
|
@@ -6411,18 +6589,12 @@ function fillTextureRect(texture, x, y, width, height, color) {
|
|
|
6411
6589
|
}
|
|
6412
6590
|
|
|
6413
6591
|
/* eslint-disable no-magic-numbers */
|
|
6414
|
-
/**
|
|
6415
|
-
* Fixed scene camera distance used for the proper-3D projection.
|
|
6416
|
-
*
|
|
6417
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6418
|
-
*/
|
|
6419
|
-
const CAMERA_DISTANCE_RATIO = 1.4;
|
|
6420
6592
|
/**
|
|
6421
6593
|
* Shared light direction used to shade projected cuboid faces.
|
|
6422
6594
|
*
|
|
6423
6595
|
* @private helper of `minecraft2AvatarVisual`
|
|
6424
6596
|
*/
|
|
6425
|
-
const LIGHT_DIRECTION = normalizeVector3({
|
|
6597
|
+
const LIGHT_DIRECTION$1 = normalizeVector3({
|
|
6426
6598
|
x: 0.4,
|
|
6427
6599
|
y: -0.65,
|
|
6428
6600
|
z: 0.92,
|
|
@@ -6634,7 +6806,7 @@ function resolveVisibleCuboidFaces(cuboid, size, sceneCenterX, sceneCenterY) {
|
|
|
6634
6806
|
corners: projectedCorners,
|
|
6635
6807
|
texture: faceDefinition.texture,
|
|
6636
6808
|
averageDepth: transformedCorners.reduce((depthSum, corner) => depthSum + corner.z, 0) / transformedCorners.length,
|
|
6637
|
-
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION), -1, 1),
|
|
6809
|
+
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$1), -1, 1),
|
|
6638
6810
|
outlineColor: cuboid.outlineColor,
|
|
6639
6811
|
};
|
|
6640
6812
|
});
|
|
@@ -6661,7 +6833,7 @@ function drawTexturedProjectedFace(context, face) {
|
|
|
6661
6833
|
const endX = (columnIndex + 1) / columns;
|
|
6662
6834
|
const startY = rowIndex / rows;
|
|
6663
6835
|
const endY = (rowIndex + 1) / rows;
|
|
6664
|
-
drawProjectedQuad(context, [
|
|
6836
|
+
drawProjectedQuad$1(context, [
|
|
6665
6837
|
interpolateProjectedQuad(face.corners, startX, startY),
|
|
6666
6838
|
interpolateProjectedQuad(face.corners, endX, startY),
|
|
6667
6839
|
interpolateProjectedQuad(face.corners, endX, endY),
|
|
@@ -6670,10 +6842,10 @@ function drawTexturedProjectedFace(context, face) {
|
|
|
6670
6842
|
}
|
|
6671
6843
|
}
|
|
6672
6844
|
if (face.lightIntensity > 0) {
|
|
6673
|
-
drawProjectedQuad(context, face.corners, `rgba(255, 255, 255, ${0.15 * face.lightIntensity})`);
|
|
6845
|
+
drawProjectedQuad$1(context, face.corners, `rgba(255, 255, 255, ${0.15 * face.lightIntensity})`);
|
|
6674
6846
|
}
|
|
6675
6847
|
else if (face.lightIntensity < 0) {
|
|
6676
|
-
drawProjectedQuad(context, face.corners, `rgba(0, 0, 0, ${0.22 * Math.abs(face.lightIntensity)})`);
|
|
6848
|
+
drawProjectedQuad$1(context, face.corners, `rgba(0, 0, 0, ${0.22 * Math.abs(face.lightIntensity)})`);
|
|
6677
6849
|
}
|
|
6678
6850
|
context.save();
|
|
6679
6851
|
context.beginPath();
|
|
@@ -6697,7 +6869,7 @@ function drawTexturedProjectedFace(context, face) {
|
|
|
6697
6869
|
*
|
|
6698
6870
|
* @private helper of `minecraft2AvatarVisual`
|
|
6699
6871
|
*/
|
|
6700
|
-
function drawProjectedQuad(context, corners, fillStyle) {
|
|
6872
|
+
function drawProjectedQuad$1(context, corners, fillStyle) {
|
|
6701
6873
|
context.beginPath();
|
|
6702
6874
|
context.moveTo(corners[0].x, corners[0].y);
|
|
6703
6875
|
context.lineTo(corners[1].x, corners[1].y);
|
|
@@ -6720,193 +6892,24 @@ function drawProjectedQuad(context, corners, fillStyle) {
|
|
|
6720
6892
|
function interpolateProjectedQuad(corners, horizontalRatio, verticalRatio) {
|
|
6721
6893
|
const topPoint = interpolateProjectedPoint(corners[0], corners[1], horizontalRatio);
|
|
6722
6894
|
const bottomPoint = interpolateProjectedPoint(corners[3], corners[2], horizontalRatio);
|
|
6723
|
-
return interpolateProjectedPoint(topPoint, bottomPoint, verticalRatio);
|
|
6724
|
-
}
|
|
6725
|
-
/**
|
|
6726
|
-
* Interpolates between two projected points.
|
|
6727
|
-
*
|
|
6728
|
-
* @param startPoint Start point.
|
|
6729
|
-
* @param endPoint End point.
|
|
6730
|
-
* @param ratio Interpolation ratio in the range `[0, 1]`.
|
|
6731
|
-
* @returns Interpolated projected point.
|
|
6732
|
-
*
|
|
6733
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6734
|
-
*/
|
|
6735
|
-
function interpolateProjectedPoint(startPoint, endPoint, ratio) {
|
|
6736
|
-
return {
|
|
6737
|
-
x: startPoint.x + (endPoint.x - startPoint.x) * ratio,
|
|
6738
|
-
y: startPoint.y + (endPoint.y - startPoint.y) * ratio,
|
|
6739
|
-
z: startPoint.z + (endPoint.z - startPoint.z) * ratio,
|
|
6740
|
-
};
|
|
6741
|
-
}
|
|
6742
|
-
/**
|
|
6743
|
-
* Projects one rotated scene point into canvas coordinates.
|
|
6744
|
-
*
|
|
6745
|
-
* @param point Scene point.
|
|
6746
|
-
* @param size Canvas size in CSS pixels.
|
|
6747
|
-
* @param sceneCenterX Horizontal scene center.
|
|
6748
|
-
* @param sceneCenterY Vertical scene center.
|
|
6749
|
-
* @returns Projected point.
|
|
6750
|
-
*
|
|
6751
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6752
|
-
*/
|
|
6753
|
-
function projectScenePoint(point, size, sceneCenterX, sceneCenterY) {
|
|
6754
|
-
const cameraDistance = size * CAMERA_DISTANCE_RATIO;
|
|
6755
|
-
const perspectiveScale = cameraDistance / Math.max(cameraDistance - point.z, cameraDistance * 0.35);
|
|
6756
|
-
return {
|
|
6757
|
-
x: sceneCenterX + point.x * perspectiveScale,
|
|
6758
|
-
y: sceneCenterY + point.y * perspectiveScale,
|
|
6759
|
-
z: point.z,
|
|
6760
|
-
};
|
|
6761
|
-
}
|
|
6762
|
-
/**
|
|
6763
|
-
* Applies the local cuboid rotations and translation to one scene point.
|
|
6764
|
-
*
|
|
6765
|
-
* @param localPoint Point in cuboid-local space.
|
|
6766
|
-
* @param center Cuboid center in scene space.
|
|
6767
|
-
* @param rotationX Cuboid pitch in radians.
|
|
6768
|
-
* @param rotationY Cuboid yaw in radians.
|
|
6769
|
-
* @returns Transformed scene-space point.
|
|
6770
|
-
*
|
|
6771
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6772
|
-
*/
|
|
6773
|
-
function transformScenePoint(localPoint, center, rotationX, rotationY) {
|
|
6774
|
-
const yawedPoint = rotatePointAroundY(localPoint, rotationY);
|
|
6775
|
-
const pitchedPoint = rotatePointAroundX(yawedPoint, rotationX);
|
|
6776
|
-
return {
|
|
6777
|
-
x: center.x + pitchedPoint.x,
|
|
6778
|
-
y: center.y + pitchedPoint.y,
|
|
6779
|
-
z: center.z + pitchedPoint.z,
|
|
6780
|
-
};
|
|
6781
|
-
}
|
|
6782
|
-
/**
|
|
6783
|
-
* Rotates one point around the local Y axis.
|
|
6784
|
-
*
|
|
6785
|
-
* @param point Source point.
|
|
6786
|
-
* @param angle Rotation angle in radians.
|
|
6787
|
-
* @returns Rotated point.
|
|
6788
|
-
*
|
|
6789
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6790
|
-
*/
|
|
6791
|
-
function rotatePointAroundY(point, angle) {
|
|
6792
|
-
const cosine = Math.cos(angle);
|
|
6793
|
-
const sine = Math.sin(angle);
|
|
6794
|
-
return {
|
|
6795
|
-
x: point.x * cosine + point.z * sine,
|
|
6796
|
-
y: point.y,
|
|
6797
|
-
z: -point.x * sine + point.z * cosine,
|
|
6798
|
-
};
|
|
6799
|
-
}
|
|
6800
|
-
/**
|
|
6801
|
-
* Rotates one point around the local X axis.
|
|
6802
|
-
*
|
|
6803
|
-
* @param point Source point.
|
|
6804
|
-
* @param angle Rotation angle in radians.
|
|
6805
|
-
* @returns Rotated point.
|
|
6806
|
-
*
|
|
6807
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6808
|
-
*/
|
|
6809
|
-
function rotatePointAroundX(point, angle) {
|
|
6810
|
-
const cosine = Math.cos(angle);
|
|
6811
|
-
const sine = Math.sin(angle);
|
|
6812
|
-
return {
|
|
6813
|
-
x: point.x,
|
|
6814
|
-
y: point.y * cosine - point.z * sine,
|
|
6815
|
-
z: point.y * sine + point.z * cosine,
|
|
6816
|
-
};
|
|
6817
|
-
}
|
|
6818
|
-
/**
|
|
6819
|
-
* Subtracts one 3D point from another.
|
|
6820
|
-
*
|
|
6821
|
-
* @param leftPoint Left point.
|
|
6822
|
-
* @param rightPoint Right point.
|
|
6823
|
-
* @returns Difference vector.
|
|
6824
|
-
*
|
|
6825
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6826
|
-
*/
|
|
6827
|
-
function subtractPoint3D(leftPoint, rightPoint) {
|
|
6828
|
-
return {
|
|
6829
|
-
x: leftPoint.x - rightPoint.x,
|
|
6830
|
-
y: leftPoint.y - rightPoint.y,
|
|
6831
|
-
z: leftPoint.z - rightPoint.z,
|
|
6832
|
-
};
|
|
6833
|
-
}
|
|
6834
|
-
/**
|
|
6835
|
-
* Computes the 3D cross product of two vectors.
|
|
6836
|
-
*
|
|
6837
|
-
* @param leftVector Left vector.
|
|
6838
|
-
* @param rightVector Right vector.
|
|
6839
|
-
* @returns Cross product.
|
|
6840
|
-
*
|
|
6841
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6842
|
-
*/
|
|
6843
|
-
function crossProduct3D(leftVector, rightVector) {
|
|
6844
|
-
return {
|
|
6845
|
-
x: leftVector.y * rightVector.z - leftVector.z * rightVector.y,
|
|
6846
|
-
y: leftVector.z * rightVector.x - leftVector.x * rightVector.z,
|
|
6847
|
-
z: leftVector.x * rightVector.y - leftVector.y * rightVector.x,
|
|
6848
|
-
};
|
|
6849
|
-
}
|
|
6850
|
-
/**
|
|
6851
|
-
* Computes the 3D dot product of two vectors.
|
|
6852
|
-
*
|
|
6853
|
-
* @param leftVector Left vector.
|
|
6854
|
-
* @param rightVector Right vector.
|
|
6855
|
-
* @returns Dot product.
|
|
6856
|
-
*
|
|
6857
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6858
|
-
*/
|
|
6859
|
-
function dotProduct3D(leftVector, rightVector) {
|
|
6860
|
-
return leftVector.x * rightVector.x + leftVector.y * rightVector.y + leftVector.z * rightVector.z;
|
|
6861
|
-
}
|
|
6862
|
-
/**
|
|
6863
|
-
* Normalizes one 3D vector while keeping zero vectors stable.
|
|
6864
|
-
*
|
|
6865
|
-
* @param vector Source vector.
|
|
6866
|
-
* @returns Normalized vector.
|
|
6867
|
-
*
|
|
6868
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6869
|
-
*/
|
|
6870
|
-
function normalizeVector3(vector) {
|
|
6871
|
-
const length = Math.hypot(vector.x, vector.y, vector.z);
|
|
6872
|
-
if (length === 0) {
|
|
6873
|
-
return vector;
|
|
6874
|
-
}
|
|
6875
|
-
return {
|
|
6876
|
-
x: vector.x / length,
|
|
6877
|
-
y: vector.y / length,
|
|
6878
|
-
z: vector.z / length,
|
|
6879
|
-
};
|
|
6880
|
-
}
|
|
6881
|
-
/**
|
|
6882
|
-
* Clamps one number into the provided range.
|
|
6883
|
-
*
|
|
6884
|
-
* @param value Input value.
|
|
6885
|
-
* @param minimumValue Inclusive lower bound.
|
|
6886
|
-
* @param maximumValue Inclusive upper bound.
|
|
6887
|
-
* @returns Clamped value.
|
|
6888
|
-
*
|
|
6889
|
-
* @private helper of `minecraft2AvatarVisual`
|
|
6890
|
-
*/
|
|
6891
|
-
function clampNumber$1(value, minimumValue, maximumValue) {
|
|
6892
|
-
return Math.min(maximumValue, Math.max(minimumValue, value));
|
|
6895
|
+
return interpolateProjectedPoint(topPoint, bottomPoint, verticalRatio);
|
|
6893
6896
|
}
|
|
6894
6897
|
/**
|
|
6895
|
-
*
|
|
6898
|
+
* Interpolates between two projected points.
|
|
6896
6899
|
*
|
|
6897
|
-
* @param
|
|
6898
|
-
* @
|
|
6900
|
+
* @param startPoint Start point.
|
|
6901
|
+
* @param endPoint End point.
|
|
6902
|
+
* @param ratio Interpolation ratio in the range `[0, 1]`.
|
|
6903
|
+
* @returns Interpolated projected point.
|
|
6899
6904
|
*
|
|
6900
6905
|
* @private helper of `minecraft2AvatarVisual`
|
|
6901
6906
|
*/
|
|
6902
|
-
function
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
}
|
|
6909
|
-
return perimeter;
|
|
6907
|
+
function interpolateProjectedPoint(startPoint, endPoint, ratio) {
|
|
6908
|
+
return {
|
|
6909
|
+
x: startPoint.x + (endPoint.x - startPoint.x) * ratio,
|
|
6910
|
+
y: startPoint.y + (endPoint.y - startPoint.y) * ratio,
|
|
6911
|
+
z: startPoint.z + (endPoint.z - startPoint.z) * ratio,
|
|
6912
|
+
};
|
|
6910
6913
|
}
|
|
6911
6914
|
|
|
6912
6915
|
/* eslint-disable no-magic-numbers */
|
|
@@ -7476,7 +7479,7 @@ function resolveSeededIntegerRange(random, minimumValue, maximumValue) {
|
|
|
7476
7479
|
*
|
|
7477
7480
|
* @private helper of `octopus3AvatarVisual`
|
|
7478
7481
|
*/
|
|
7479
|
-
function formatAlphaHex(opacity) {
|
|
7482
|
+
function formatAlphaHex$1(opacity) {
|
|
7480
7483
|
return Math.round(Math.min(1, Math.max(0, opacity)) * 255)
|
|
7481
7484
|
.toString(16)
|
|
7482
7485
|
.padStart(2, '0');
|
|
@@ -7855,7 +7858,7 @@ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, pa
|
|
|
7855
7858
|
context.beginPath();
|
|
7856
7859
|
context.moveTo(-radiusX * 0.74, radiusY * 0.2);
|
|
7857
7860
|
context.quadraticCurveTo(0, radiusY * 0.38, radiusX * 0.74, radiusY * 0.2);
|
|
7858
|
-
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
7861
|
+
context.strokeStyle = `${palette.highlight}${formatAlphaHex$1(eyeStyle.lowerLidOpacity)}`;
|
|
7859
7862
|
context.lineWidth = radiusX * 0.08;
|
|
7860
7863
|
context.lineCap = 'round';
|
|
7861
7864
|
context.stroke();
|
|
@@ -7863,6 +7866,518 @@ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, pa
|
|
|
7863
7866
|
context.restore();
|
|
7864
7867
|
}
|
|
7865
7868
|
|
|
7869
|
+
/* eslint-disable no-magic-numbers */
|
|
7870
|
+
/**
|
|
7871
|
+
* Light direction used by the organic 3D octopus shading.
|
|
7872
|
+
*
|
|
7873
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
7874
|
+
*/
|
|
7875
|
+
const LIGHT_DIRECTION = normalizeVector3({
|
|
7876
|
+
x: 0.48,
|
|
7877
|
+
y: -0.62,
|
|
7878
|
+
z: 0.94,
|
|
7879
|
+
});
|
|
7880
|
+
/**
|
|
7881
|
+
* Proper 3D Octopus visual built from projected organic meshes and tentacles.
|
|
7882
|
+
*
|
|
7883
|
+
* @private built-in avatar visual
|
|
7884
|
+
*/
|
|
7885
|
+
const octopus3dAvatarVisual = {
|
|
7886
|
+
id: 'octopus3d',
|
|
7887
|
+
title: 'Octopus 3D',
|
|
7888
|
+
description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
|
|
7889
|
+
isAnimated: true,
|
|
7890
|
+
supportsPointerTracking: true,
|
|
7891
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
7892
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
7893
|
+
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
7894
|
+
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
7895
|
+
const animationPhase = animationRandom() * Math.PI * 2;
|
|
7896
|
+
const sceneCenterX = size * 0.5;
|
|
7897
|
+
const sceneCenterY = size * 0.56;
|
|
7898
|
+
const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
|
|
7899
|
+
const mantleCenter = {
|
|
7900
|
+
x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
|
|
7901
|
+
y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
|
|
7902
|
+
z: interaction.intensity * size * 0.012,
|
|
7903
|
+
};
|
|
7904
|
+
const underbodyCenter = {
|
|
7905
|
+
x: mantleCenter.x * 0.86,
|
|
7906
|
+
y: mantleCenter.y + size * 0.168,
|
|
7907
|
+
z: mantleCenter.z - size * 0.018,
|
|
7908
|
+
};
|
|
7909
|
+
const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
|
|
7910
|
+
const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
|
|
7911
|
+
const mantleRadiusZ = size * morphologyProfile.body.bodyRadiusRatio * (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
|
|
7912
|
+
const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
|
|
7913
|
+
const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
|
|
7914
|
+
const underbodyRadiusZ = mantleRadiusZ * 0.78;
|
|
7915
|
+
const bodyYaw = -0.18 +
|
|
7916
|
+
Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
|
|
7917
|
+
interaction.bodyOffsetX * 0.18 +
|
|
7918
|
+
interaction.gazeX * 0.22;
|
|
7919
|
+
const bodyPitch = -0.08 +
|
|
7920
|
+
Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
|
|
7921
|
+
interaction.bodyOffsetY * 0.08 -
|
|
7922
|
+
interaction.gazeY * 0.08;
|
|
7923
|
+
const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
|
|
7924
|
+
const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
|
|
7925
|
+
const mantlePatches = resolveVisibleEllipsoidPatches({
|
|
7926
|
+
center: mantleCenter,
|
|
7927
|
+
radiusX: mantleRadiusX,
|
|
7928
|
+
radiusY: mantleRadiusY,
|
|
7929
|
+
radiusZ: mantleRadiusZ,
|
|
7930
|
+
rotationX: headPitch,
|
|
7931
|
+
rotationY: headYaw,
|
|
7932
|
+
sceneCenterX,
|
|
7933
|
+
sceneCenterY,
|
|
7934
|
+
size,
|
|
7935
|
+
palette,
|
|
7936
|
+
verticalColorBias: 0,
|
|
7937
|
+
outlineColor: `${palette.highlight}7a`,
|
|
7938
|
+
});
|
|
7939
|
+
const underbodyPatches = resolveVisibleEllipsoidPatches({
|
|
7940
|
+
center: underbodyCenter,
|
|
7941
|
+
radiusX: underbodyRadiusX,
|
|
7942
|
+
radiusY: underbodyRadiusY,
|
|
7943
|
+
radiusZ: underbodyRadiusZ,
|
|
7944
|
+
rotationX: bodyPitch,
|
|
7945
|
+
rotationY: bodyYaw,
|
|
7946
|
+
sceneCenterX,
|
|
7947
|
+
sceneCenterY,
|
|
7948
|
+
size,
|
|
7949
|
+
palette,
|
|
7950
|
+
verticalColorBias: 0.18,
|
|
7951
|
+
outlineColor: `${palette.shadow}8f`,
|
|
7952
|
+
});
|
|
7953
|
+
const tentacleStrokes = createOctopusTentacleStrokes({
|
|
7954
|
+
createRandom,
|
|
7955
|
+
morphologyProfile,
|
|
7956
|
+
timeMs,
|
|
7957
|
+
size,
|
|
7958
|
+
center: underbodyCenter,
|
|
7959
|
+
radiusX: underbodyRadiusX,
|
|
7960
|
+
radiusY: underbodyRadiusY,
|
|
7961
|
+
radiusZ: underbodyRadiusZ,
|
|
7962
|
+
rotationX: bodyPitch,
|
|
7963
|
+
rotationY: bodyYaw,
|
|
7964
|
+
sceneCenterX,
|
|
7965
|
+
sceneCenterY,
|
|
7966
|
+
animationPhase,
|
|
7967
|
+
});
|
|
7968
|
+
const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
|
|
7969
|
+
const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
|
|
7970
|
+
const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
|
|
7971
|
+
const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
|
|
7972
|
+
const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
|
|
7973
|
+
const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
|
|
7974
|
+
drawAvatarFrame(context, size, palette);
|
|
7975
|
+
drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
|
|
7976
|
+
drawOctopus3dShadow(context, size, palette, interaction, timeMs);
|
|
7977
|
+
for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
|
|
7978
|
+
drawTentacleStroke(context, tentacleStroke, palette);
|
|
7979
|
+
}
|
|
7980
|
+
for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
|
|
7981
|
+
drawSurfacePatch(context, surfacePatch);
|
|
7982
|
+
}
|
|
7983
|
+
for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
|
|
7984
|
+
drawTentacleStroke(context, tentacleStroke, palette);
|
|
7985
|
+
}
|
|
7986
|
+
drawProjectedEye(context, {
|
|
7987
|
+
x: -faceEyeSpacing,
|
|
7988
|
+
y: faceEyeYOffset,
|
|
7989
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
7990
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
7991
|
+
drawProjectedEye(context, {
|
|
7992
|
+
x: faceEyeSpacing,
|
|
7993
|
+
y: faceEyeYOffset,
|
|
7994
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
7995
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
7996
|
+
drawProjectedMouth(context, [
|
|
7997
|
+
{ x: -mouthHalfWidth, y: mouthY, z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY) },
|
|
7998
|
+
{
|
|
7999
|
+
x: size * morphologyProfile.face.mouthCenterOffsetRatio,
|
|
8000
|
+
y: mouthY +
|
|
8001
|
+
size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
|
|
8002
|
+
Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
|
|
8003
|
+
interaction.gazeY * size * 0.01,
|
|
8004
|
+
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
|
|
8005
|
+
},
|
|
8006
|
+
{ x: mouthHalfWidth, y: mouthY, z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY) },
|
|
8007
|
+
], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
|
|
8008
|
+
},
|
|
8009
|
+
};
|
|
8010
|
+
/**
|
|
8011
|
+
* Draws the atmospheric underwater glow behind the octopus mesh.
|
|
8012
|
+
*
|
|
8013
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8014
|
+
*/
|
|
8015
|
+
function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
|
|
8016
|
+
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);
|
|
8017
|
+
glowGradient.addColorStop(0, `${palette.highlight}5c`);
|
|
8018
|
+
glowGradient.addColorStop(0.36, `${palette.accent}24`);
|
|
8019
|
+
glowGradient.addColorStop(1, `${palette.highlight}00`);
|
|
8020
|
+
context.fillStyle = glowGradient;
|
|
8021
|
+
context.fillRect(0, 0, size, size);
|
|
8022
|
+
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);
|
|
8023
|
+
lowerGradient.addColorStop(0, `${palette.secondary}1d`);
|
|
8024
|
+
lowerGradient.addColorStop(1, `${palette.secondary}00`);
|
|
8025
|
+
context.fillStyle = lowerGradient;
|
|
8026
|
+
context.fillRect(0, 0, size, size);
|
|
8027
|
+
}
|
|
8028
|
+
/**
|
|
8029
|
+
* Draws the soft ground shadow below the octopus.
|
|
8030
|
+
*
|
|
8031
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8032
|
+
*/
|
|
8033
|
+
function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
|
|
8034
|
+
context.save();
|
|
8035
|
+
context.fillStyle = `${palette.shadow}66`;
|
|
8036
|
+
context.filter = `blur(${size * 0.022}px)`;
|
|
8037
|
+
context.beginPath();
|
|
8038
|
+
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);
|
|
8039
|
+
context.fill();
|
|
8040
|
+
context.restore();
|
|
8041
|
+
}
|
|
8042
|
+
/**
|
|
8043
|
+
* Resolves visible projected patches for one rotated ellipsoid mesh.
|
|
8044
|
+
*
|
|
8045
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8046
|
+
*/
|
|
8047
|
+
function resolveVisibleEllipsoidPatches(options) {
|
|
8048
|
+
const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
|
|
8049
|
+
const latitudePatchCount = 10;
|
|
8050
|
+
const longitudePatchCount = 18;
|
|
8051
|
+
const surfacePatches = [];
|
|
8052
|
+
for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
|
|
8053
|
+
const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
|
|
8054
|
+
const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
|
|
8055
|
+
const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
|
|
8056
|
+
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
8057
|
+
const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
|
|
8058
|
+
const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
|
|
8059
|
+
const localCorners = [
|
|
8060
|
+
sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
|
|
8061
|
+
sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
|
|
8062
|
+
sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
|
|
8063
|
+
sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
|
|
8064
|
+
];
|
|
8065
|
+
const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
|
|
8066
|
+
const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
|
|
8067
|
+
if (surfaceNormal.z <= 0.01) {
|
|
8068
|
+
continue;
|
|
8069
|
+
}
|
|
8070
|
+
const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
|
|
8071
|
+
surfacePatches.push({
|
|
8072
|
+
corners: projectedCorners,
|
|
8073
|
+
averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
|
|
8074
|
+
transformedCorners.length,
|
|
8075
|
+
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
8076
|
+
fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
|
|
8077
|
+
outlineColor,
|
|
8078
|
+
});
|
|
8079
|
+
}
|
|
8080
|
+
}
|
|
8081
|
+
return surfacePatches;
|
|
8082
|
+
}
|
|
8083
|
+
/**
|
|
8084
|
+
* Samples one point on an ellipsoid aligned to the local axes.
|
|
8085
|
+
*
|
|
8086
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8087
|
+
*/
|
|
8088
|
+
function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
|
|
8089
|
+
const cosineLatitude = Math.cos(latitude);
|
|
8090
|
+
return {
|
|
8091
|
+
x: Math.sin(longitude) * cosineLatitude * radiusX,
|
|
8092
|
+
y: Math.sin(latitude) * radiusY,
|
|
8093
|
+
z: Math.cos(longitude) * cosineLatitude * radiusZ,
|
|
8094
|
+
};
|
|
8095
|
+
}
|
|
8096
|
+
/**
|
|
8097
|
+
* Resolves one base fill tone for a surface patch across the octopus body.
|
|
8098
|
+
*
|
|
8099
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8100
|
+
*/
|
|
8101
|
+
function resolveSurfacePatchFillStyle(palette, verticalProgress) {
|
|
8102
|
+
const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
|
|
8103
|
+
if (clampedVerticalProgress < 0.2) {
|
|
8104
|
+
return palette.highlight;
|
|
8105
|
+
}
|
|
8106
|
+
if (clampedVerticalProgress < 0.45) {
|
|
8107
|
+
return palette.secondary;
|
|
8108
|
+
}
|
|
8109
|
+
if (clampedVerticalProgress < 0.8) {
|
|
8110
|
+
return palette.primary;
|
|
8111
|
+
}
|
|
8112
|
+
return `${palette.shadow}f2`;
|
|
8113
|
+
}
|
|
8114
|
+
/**
|
|
8115
|
+
* Draws one projected mesh patch with organic shading.
|
|
8116
|
+
*
|
|
8117
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8118
|
+
*/
|
|
8119
|
+
function drawSurfacePatch(context, surfacePatch) {
|
|
8120
|
+
drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
|
|
8121
|
+
if (surfacePatch.lightIntensity > 0) {
|
|
8122
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
|
|
8123
|
+
}
|
|
8124
|
+
else if (surfacePatch.lightIntensity < 0) {
|
|
8125
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
|
|
8126
|
+
}
|
|
8127
|
+
context.save();
|
|
8128
|
+
context.beginPath();
|
|
8129
|
+
context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
|
|
8130
|
+
for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
|
|
8131
|
+
context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
|
|
8132
|
+
}
|
|
8133
|
+
context.closePath();
|
|
8134
|
+
context.strokeStyle = surfacePatch.outlineColor;
|
|
8135
|
+
context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
|
|
8136
|
+
context.lineJoin = 'round';
|
|
8137
|
+
context.stroke();
|
|
8138
|
+
context.restore();
|
|
8139
|
+
}
|
|
8140
|
+
/**
|
|
8141
|
+
* Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
|
|
8142
|
+
*
|
|
8143
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8144
|
+
*/
|
|
8145
|
+
function createOctopusTentacleStrokes(options) {
|
|
8146
|
+
const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
|
|
8147
|
+
return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
|
|
8148
|
+
const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
|
|
8149
|
+
const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
|
|
8150
|
+
const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
|
|
8151
|
+
const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
|
|
8152
|
+
const lateralReach = size *
|
|
8153
|
+
(0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
|
|
8154
|
+
const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
|
|
8155
|
+
const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
|
|
8156
|
+
const anchorPoint = {
|
|
8157
|
+
x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
|
|
8158
|
+
y: radiusY * (0.22 + tentacleRandom() * 0.18),
|
|
8159
|
+
z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
|
|
8160
|
+
};
|
|
8161
|
+
const controlPointOne = {
|
|
8162
|
+
x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
|
|
8163
|
+
y: anchorPoint.y + flowLength * 0.26,
|
|
8164
|
+
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
|
|
8165
|
+
};
|
|
8166
|
+
const controlPointTwo = {
|
|
8167
|
+
x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
|
|
8168
|
+
y: anchorPoint.y + flowLength * 0.66,
|
|
8169
|
+
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
|
|
8170
|
+
};
|
|
8171
|
+
const endPoint = {
|
|
8172
|
+
x: anchorPoint.x +
|
|
8173
|
+
Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
|
|
8174
|
+
sway * size * 0.028,
|
|
8175
|
+
y: anchorPoint.y + flowLength,
|
|
8176
|
+
z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
|
|
8177
|
+
};
|
|
8178
|
+
const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
|
|
8179
|
+
const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
|
|
8180
|
+
const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
|
|
8181
|
+
return {
|
|
8182
|
+
projectedPoints,
|
|
8183
|
+
averageDepth,
|
|
8184
|
+
isFrontFacing: averageDepth >= center.z - size * 0.006,
|
|
8185
|
+
baseWidth: size *
|
|
8186
|
+
(0.019 +
|
|
8187
|
+
morphologyProfile.tentacles.baseWidthScale * 0.007 +
|
|
8188
|
+
tentacleRandom() * 0.003 +
|
|
8189
|
+
Math.abs(Math.sin(orbitAngle)) * 0.002),
|
|
8190
|
+
tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
|
|
8191
|
+
colorBias: tentacleRandom(),
|
|
8192
|
+
};
|
|
8193
|
+
});
|
|
8194
|
+
}
|
|
8195
|
+
/**
|
|
8196
|
+
* Samples one point on a cubic Bezier curve in 3D.
|
|
8197
|
+
*
|
|
8198
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8199
|
+
*/
|
|
8200
|
+
function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
|
|
8201
|
+
const inverseProgress = 1 - progress;
|
|
8202
|
+
return {
|
|
8203
|
+
x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
|
|
8204
|
+
3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
|
|
8205
|
+
3 * inverseProgress * progress * progress * controlPointTwo.x +
|
|
8206
|
+
progress * progress * progress * endPoint.x,
|
|
8207
|
+
y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
|
|
8208
|
+
3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
|
|
8209
|
+
3 * inverseProgress * progress * progress * controlPointTwo.y +
|
|
8210
|
+
progress * progress * progress * endPoint.y,
|
|
8211
|
+
z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
|
|
8212
|
+
3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
|
|
8213
|
+
3 * inverseProgress * progress * progress * controlPointTwo.z +
|
|
8214
|
+
progress * progress * progress * endPoint.z,
|
|
8215
|
+
};
|
|
8216
|
+
}
|
|
8217
|
+
/**
|
|
8218
|
+
* Draws one projected tentacle stroke with a slim highlight ridge.
|
|
8219
|
+
*
|
|
8220
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8221
|
+
*/
|
|
8222
|
+
function drawTentacleStroke(context, tentacleStroke, palette) {
|
|
8223
|
+
const projectedSegments = tentacleStroke.projectedPoints.length - 1;
|
|
8224
|
+
for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
|
|
8225
|
+
const startPoint = tentacleStroke.projectedPoints[segmentIndex];
|
|
8226
|
+
const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
|
|
8227
|
+
const progress = segmentIndex / projectedSegments;
|
|
8228
|
+
const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
|
|
8229
|
+
context.beginPath();
|
|
8230
|
+
context.moveTo(startPoint.x, startPoint.y);
|
|
8231
|
+
context.lineTo(endPoint.x, endPoint.y);
|
|
8232
|
+
context.strokeStyle =
|
|
8233
|
+
tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
|
|
8234
|
+
context.lineWidth = width;
|
|
8235
|
+
context.lineCap = 'round';
|
|
8236
|
+
context.stroke();
|
|
8237
|
+
context.beginPath();
|
|
8238
|
+
context.moveTo(startPoint.x, startPoint.y);
|
|
8239
|
+
context.lineTo(endPoint.x, endPoint.y);
|
|
8240
|
+
context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
|
|
8241
|
+
context.lineWidth = Math.max(1, width * 0.34);
|
|
8242
|
+
context.lineCap = 'round';
|
|
8243
|
+
context.stroke();
|
|
8244
|
+
}
|
|
8245
|
+
}
|
|
8246
|
+
/**
|
|
8247
|
+
* Resolves the front surface depth on an ellipsoid for one local face point.
|
|
8248
|
+
*
|
|
8249
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8250
|
+
*/
|
|
8251
|
+
function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
|
|
8252
|
+
const normalizedX = x / radiusX;
|
|
8253
|
+
const normalizedY = y / radiusY;
|
|
8254
|
+
const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
|
|
8255
|
+
return Math.sqrt(remainingDepthRatio) * radiusZ;
|
|
8256
|
+
}
|
|
8257
|
+
/**
|
|
8258
|
+
* Draws one projected eye on the turned octopus mantle.
|
|
8259
|
+
*
|
|
8260
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8261
|
+
*/
|
|
8262
|
+
function drawProjectedEye(context, localCenter, radiusX, radiusY, center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, phase, interaction, eyeStyle) {
|
|
8263
|
+
const centerScenePoint = transformScenePoint(localCenter, center, rotationX, rotationY);
|
|
8264
|
+
if (centerScenePoint.z <= center.z) {
|
|
8265
|
+
return;
|
|
8266
|
+
}
|
|
8267
|
+
const horizontalScenePoint = transformScenePoint({ x: localCenter.x + radiusX, y: localCenter.y, z: localCenter.z }, center, rotationX, rotationY);
|
|
8268
|
+
const verticalScenePoint = transformScenePoint({ x: localCenter.x, y: localCenter.y + radiusY, z: localCenter.z }, center, rotationX, rotationY);
|
|
8269
|
+
const projectedCenterPoint = projectScenePoint(centerScenePoint, size, sceneCenterX, sceneCenterY);
|
|
8270
|
+
const projectedHorizontalPoint = projectScenePoint(horizontalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
8271
|
+
const projectedVerticalPoint = projectScenePoint(verticalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
8272
|
+
const projectedRadiusX = Math.hypot(projectedHorizontalPoint.x - projectedCenterPoint.x, projectedHorizontalPoint.y - projectedCenterPoint.y);
|
|
8273
|
+
const projectedRadiusY = Math.hypot(projectedVerticalPoint.x - projectedCenterPoint.x, projectedVerticalPoint.y - projectedCenterPoint.y);
|
|
8274
|
+
if (projectedRadiusX < size * 0.008 || projectedRadiusY < size * 0.008) {
|
|
8275
|
+
return;
|
|
8276
|
+
}
|
|
8277
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
8278
|
+
radiusX: projectedRadiusX,
|
|
8279
|
+
radiusY: projectedRadiusY,
|
|
8280
|
+
timeMs,
|
|
8281
|
+
phase,
|
|
8282
|
+
interaction,
|
|
8283
|
+
});
|
|
8284
|
+
const rotation = Math.atan2(projectedHorizontalPoint.y - projectedCenterPoint.y, projectedHorizontalPoint.x - projectedCenterPoint.x);
|
|
8285
|
+
context.save();
|
|
8286
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
8287
|
+
context.rotate(rotation);
|
|
8288
|
+
context.beginPath();
|
|
8289
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
8290
|
+
context.fillStyle = '#f8fbff';
|
|
8291
|
+
context.fill();
|
|
8292
|
+
context.clip();
|
|
8293
|
+
const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
|
|
8294
|
+
irisGradient.addColorStop(0, palette.highlight);
|
|
8295
|
+
irisGradient.addColorStop(0.56, palette.secondary);
|
|
8296
|
+
irisGradient.addColorStop(1, palette.shadow);
|
|
8297
|
+
context.beginPath();
|
|
8298
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
|
|
8299
|
+
context.fillStyle = irisGradient;
|
|
8300
|
+
context.fill();
|
|
8301
|
+
context.beginPath();
|
|
8302
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.15 * eyeStyle.pupilWidthScale, projectedRadiusY * 0.48 * eyeStyle.pupilHeightScale, 0, 0, Math.PI * 2);
|
|
8303
|
+
context.fillStyle = palette.ink;
|
|
8304
|
+
context.fill();
|
|
8305
|
+
context.beginPath();
|
|
8306
|
+
context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
|
|
8307
|
+
context.fillStyle = '#ffffff';
|
|
8308
|
+
context.fill();
|
|
8309
|
+
context.restore();
|
|
8310
|
+
context.save();
|
|
8311
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
8312
|
+
context.rotate(rotation);
|
|
8313
|
+
context.beginPath();
|
|
8314
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
8315
|
+
context.strokeStyle = `${palette.shadow}cc`;
|
|
8316
|
+
context.lineWidth = projectedRadiusX * 0.16;
|
|
8317
|
+
context.stroke();
|
|
8318
|
+
context.beginPath();
|
|
8319
|
+
context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
8320
|
+
context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
8321
|
+
context.strokeStyle = `${palette.shadow}73`;
|
|
8322
|
+
context.lineWidth = projectedRadiusX * 0.14;
|
|
8323
|
+
context.lineCap = 'round';
|
|
8324
|
+
context.stroke();
|
|
8325
|
+
if (eyeStyle.lowerLidOpacity > 0) {
|
|
8326
|
+
context.beginPath();
|
|
8327
|
+
context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
8328
|
+
context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
8329
|
+
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
8330
|
+
context.lineWidth = projectedRadiusX * 0.08;
|
|
8331
|
+
context.lineCap = 'round';
|
|
8332
|
+
context.stroke();
|
|
8333
|
+
}
|
|
8334
|
+
context.restore();
|
|
8335
|
+
}
|
|
8336
|
+
/**
|
|
8337
|
+
* Draws a subtle projected mouth arc across the front of the mantle.
|
|
8338
|
+
*
|
|
8339
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8340
|
+
*/
|
|
8341
|
+
function drawProjectedMouth(context, localPoints, center, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size) {
|
|
8342
|
+
const scenePoints = localPoints.map((localPoint) => transformScenePoint(localPoint, center, rotationX, rotationY));
|
|
8343
|
+
if (scenePoints.some((scenePoint) => scenePoint.z <= center.z)) {
|
|
8344
|
+
return;
|
|
8345
|
+
}
|
|
8346
|
+
const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
|
|
8347
|
+
context.beginPath();
|
|
8348
|
+
context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
|
|
8349
|
+
context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
|
|
8350
|
+
context.strokeStyle = `${palette.ink}b8`;
|
|
8351
|
+
context.lineWidth = Math.max(1.1, size * 0.009);
|
|
8352
|
+
context.lineCap = 'round';
|
|
8353
|
+
context.stroke();
|
|
8354
|
+
}
|
|
8355
|
+
/**
|
|
8356
|
+
* Draws one filled projected quad.
|
|
8357
|
+
*
|
|
8358
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8359
|
+
*/
|
|
8360
|
+
function drawProjectedQuad(context, corners, fillStyle) {
|
|
8361
|
+
context.beginPath();
|
|
8362
|
+
context.moveTo(corners[0].x, corners[0].y);
|
|
8363
|
+
context.lineTo(corners[1].x, corners[1].y);
|
|
8364
|
+
context.lineTo(corners[2].x, corners[2].y);
|
|
8365
|
+
context.lineTo(corners[3].x, corners[3].y);
|
|
8366
|
+
context.closePath();
|
|
8367
|
+
context.fillStyle = fillStyle;
|
|
8368
|
+
context.fill();
|
|
8369
|
+
}
|
|
8370
|
+
/**
|
|
8371
|
+
* Converts an opacity ratio into a two-digit hexadecimal alpha suffix.
|
|
8372
|
+
*
|
|
8373
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8374
|
+
*/
|
|
8375
|
+
function formatAlphaHex(opacity) {
|
|
8376
|
+
return Math.round(clampNumber$1(opacity, 0, 1) * 255)
|
|
8377
|
+
.toString(16)
|
|
8378
|
+
.padStart(2, '0');
|
|
8379
|
+
}
|
|
8380
|
+
|
|
7866
8381
|
/* eslint-disable no-magic-numbers */
|
|
7867
8382
|
/**
|
|
7868
8383
|
* Octopus avatar visual.
|
|
@@ -8631,6 +9146,7 @@ const AVATAR_VISUALS = [
|
|
|
8631
9146
|
octopusAvatarVisual,
|
|
8632
9147
|
octopus2AvatarVisual,
|
|
8633
9148
|
octopus3AvatarVisual,
|
|
9149
|
+
octopus3dAvatarVisual,
|
|
8634
9150
|
asciiOctopusAvatarVisual,
|
|
8635
9151
|
minecraftAvatarVisual,
|
|
8636
9152
|
minecraft2AvatarVisual,
|
|
@@ -10898,16 +11414,22 @@ function resolveTeamTeammateLabels(teamContent, teammates) {
|
|
|
10898
11414
|
* Each teammate is listed with its tool name, TEAM instructions, and optional profile hints.
|
|
10899
11415
|
*/
|
|
10900
11416
|
function buildTeamSystemMessageBody(teamEntries) {
|
|
10901
|
-
const
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
11417
|
+
const teammateSections = teamEntries.map((entry, index) => {
|
|
11418
|
+
const toolLine = `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``;
|
|
11419
|
+
const detailLines = collectTeamEntryDetails(entry).map(formatTeamEntryDetailLine);
|
|
11420
|
+
if (detailLines.length === 0) {
|
|
11421
|
+
return toolLine;
|
|
11422
|
+
}
|
|
11423
|
+
return spaceTrim$1((block) => `
|
|
11424
|
+
${toolLine}
|
|
11425
|
+
${block(detailLines.join('\n'))}
|
|
11426
|
+
`);
|
|
11427
|
+
});
|
|
11428
|
+
return spaceTrim$1((block) => `
|
|
11429
|
+
${block(TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES.join('\n'))}
|
|
11430
|
+
|
|
11431
|
+
${block(teammateSections.join('\n\n'))}
|
|
11432
|
+
`);
|
|
10911
11433
|
}
|
|
10912
11434
|
/**
|
|
10913
11435
|
* Builds the model-visible description for one teammate tool.
|
|
@@ -21560,11 +22082,11 @@ function capitalize(word) {
|
|
|
21560
22082
|
*/
|
|
21561
22083
|
function pipelineJsonToString(pipelineJson) {
|
|
21562
22084
|
const { title, pipelineUrl, bookVersion, description, parameters, tasks } = pipelineJson;
|
|
21563
|
-
let pipelineString =
|
|
21564
|
-
|
|
21565
|
-
|
|
21566
|
-
|
|
21567
|
-
|
|
22085
|
+
let pipelineString = spaceTrim$1((block) => `
|
|
22086
|
+
# ${title}
|
|
22087
|
+
|
|
22088
|
+
${block(description || '')}
|
|
22089
|
+
`);
|
|
21568
22090
|
const commands = [];
|
|
21569
22091
|
if (pipelineUrl) {
|
|
21570
22092
|
commands.push(`PIPELINE URL ${pipelineUrl}`);
|
|
@@ -21580,20 +22102,17 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
21580
22102
|
for (const parameter of parameters.filter(({ isOutput }) => isOutput)) {
|
|
21581
22103
|
commands.push(`OUTPUT PARAMETER ${taskParameterJsonToString(parameter)}`);
|
|
21582
22104
|
}
|
|
21583
|
-
pipelineString
|
|
21584
|
-
|
|
22105
|
+
pipelineString = spaceTrim$1((block) => `
|
|
22106
|
+
${block(pipelineString)}
|
|
22107
|
+
|
|
22108
|
+
${block(commands.map((command) => `- ${command}`).join('\n'))}
|
|
22109
|
+
`);
|
|
21585
22110
|
for (const task of tasks) {
|
|
21586
22111
|
const {
|
|
21587
22112
|
/* Note: Not using:> name, */
|
|
21588
22113
|
title, description,
|
|
21589
22114
|
/* Note: dependentParameterNames, */
|
|
21590
22115
|
jokerParameterNames: jokers, taskType, content, postprocessingFunctionNames: postprocessing, expectations, format, resultingParameterName, } = task;
|
|
21591
|
-
pipelineString += '\n\n';
|
|
21592
|
-
pipelineString += `## ${title}`;
|
|
21593
|
-
if (description) {
|
|
21594
|
-
pipelineString += '\n\n';
|
|
21595
|
-
pipelineString += description;
|
|
21596
|
-
}
|
|
21597
22116
|
const commands = [];
|
|
21598
22117
|
let contentLanguage = 'text';
|
|
21599
22118
|
if (taskType === 'PROMPT_TASK') {
|
|
@@ -21656,18 +22175,23 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
21656
22175
|
commands.push(`FORMAT JSON`);
|
|
21657
22176
|
}
|
|
21658
22177
|
} /* not else */
|
|
21659
|
-
pipelineString
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
22178
|
+
pipelineString = spaceTrim$1((block) => `
|
|
22179
|
+
${block(pipelineString)}
|
|
22180
|
+
|
|
22181
|
+
## ${title}
|
|
22182
|
+
|
|
22183
|
+
${block(description || '')}
|
|
22184
|
+
|
|
22185
|
+
${block(commands.map((command) => `- ${command}`).join('\n'))}
|
|
22186
|
+
|
|
22187
|
+
\`\`\`${contentLanguage}
|
|
22188
|
+
${block(spaceTrim$1(content))}
|
|
22189
|
+
\`\`\`
|
|
22190
|
+
|
|
22191
|
+
\`-> {${resultingParameterName}}\`
|
|
22192
|
+
`); // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
|
|
22193
|
+
// <- TODO: [main] !!3 Escape
|
|
22194
|
+
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
21671
22195
|
}
|
|
21672
22196
|
return validatePipelineString(pipelineString);
|
|
21673
22197
|
}
|
|
@@ -26637,7 +27161,11 @@ function createExampleInteractionsContent(parseResult, samples) {
|
|
|
26637
27161
|
if (examples.length === 0) {
|
|
26638
27162
|
return null;
|
|
26639
27163
|
}
|
|
26640
|
-
return
|
|
27164
|
+
return spaceTrim$1((block) => `
|
|
27165
|
+
## Sample of communication with the agent:
|
|
27166
|
+
|
|
27167
|
+
${block(examples.join('\n\n'))}
|
|
27168
|
+
`);
|
|
26641
27169
|
}
|
|
26642
27170
|
/**
|
|
26643
27171
|
* Collects the individual lines used in the example interaction section.
|
|
@@ -26674,7 +27202,11 @@ function collectExampleInteractionLines(parseResult, samples) {
|
|
|
26674
27202
|
function appendSystemMessageSection(requirements, section) {
|
|
26675
27203
|
return {
|
|
26676
27204
|
...requirements,
|
|
26677
|
-
systemMessage:
|
|
27205
|
+
systemMessage: spaceTrim$1((block) => `
|
|
27206
|
+
${block(requirements.systemMessage)}
|
|
27207
|
+
|
|
27208
|
+
${block(section)}
|
|
27209
|
+
`),
|
|
26678
27210
|
};
|
|
26679
27211
|
}
|
|
26680
27212
|
/**
|