mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 17:09:13 -10:00
feat(pet): web and iOS pet dot-glyph bodies, pixel whale, shared page (committed as-is; not yet built or tested by the committer)
Pet-model work in progress under pet/: dot field and glyph builds, pixel whale body, shared.html and pet-native bundles. pet/ build and conformance checks still to be run. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
dc8884455d
commit
3360a6d38d
12 files changed
+7938
-1479
No files matched your search
+10
-1
@@ -36,13 +36,22 @@ In the running application:
|
||||
| --- | --- |
|
||||
| `/pet` | Toggle pet mode for this terminal: the habitat takes the whole content viewport now and on every accepted turn |
|
||||
| `/pet on` / `/pet off` | Enable or disable explicitly; `off` closes the view and stops automatic entry while the companion keeps the pet alive |
|
||||
| `/pet appearance` | Configure the shared palette in the authenticated local browser studio |
|
||||
| `/pet appearance` | Configure the shared palette, whale style and large-text language in the authenticated local browser studio |
|
||||
| `/pet style smooth\|pixel` | Choose the smooth aurora or pixel whale |
|
||||
| `/pet language auto\|en\|zh-Hans\|zh-Hant\|ja` | Choose large activity phrases independently of the interface language |
|
||||
| `/pet window` | Open the independently closable native macOS window |
|
||||
| `/pet source` | Explicitly select this terminal session as the source |
|
||||
| `/pet sound on\|off` | Request/release the companion's audio device |
|
||||
| `/pet export` | Save a replay to this saved session's artifacts |
|
||||
| `/pet status` | Mode, view, identity and measured terminal output counters |
|
||||
|
||||
Large text follows the interface language by default. English, Simplified
|
||||
Chinese, Traditional Chinese and Japanese phrases are available; other
|
||||
interface languages currently use English large text. A fixed choice lets an
|
||||
English reader learn Chinese or Japanese phrases beside the normal English
|
||||
status. Both whale styles turn their 980 drones into these same activity words.
|
||||
The saved presentation settings leave the pet’s identity and recording intact.
|
||||
|
||||
The pet has no workbar panel; the habitat is its only terminal view. Escape
|
||||
leaves it without cancelling the turn or touching the composer draft. F6
|
||||
toggles sound, F8 opens the appearance studio, and F9 opens the native window;
|
||||
|
||||
@@ -20,15 +20,17 @@ The generator verifies the source font SHA-256 before rasterization.
|
||||
|
||||
Each mask is 48 rows of 48 ASCII characters. '#' means ink; '.' means empty.
|
||||
Coordinates are row-major, with x increasing right and y increasing down.
|
||||
Glyphs use one shared font size, are individually centered without stretching,
|
||||
Phrases use the largest fitting font size, are centered without stretching,
|
||||
have at least two empty pixels of padding, and use a coverage threshold of 128.
|
||||
|
||||
reading=读, editing=写, searching=搜, testing=试, executing=行,
|
||||
browsing=览, computer=控, memory=记, tool=用, thinking=思,
|
||||
responding=答, delegating=协, waiting=待, done=成.
|
||||
|
||||
These are visual activity mnemonics; surrounding status text retains the
|
||||
full action meaning. 成 is for observed successful completion.
|
||||
The generator reads the English, Simplified Chinese, Traditional Chinese and
|
||||
Japanese status and tool labels from crates/localization/locales/. The same
|
||||
typed activity mapping is used by the terminal caption. Chinese labels of up
|
||||
to three characters occupy one line; longer phrases occupy two centered
|
||||
lines. English wraps at spaces and Japanese at phrase boundaries. No phrase
|
||||
is abbreviated to a single character. Captions retain the full meaning in
|
||||
the interface language independently of particle density, motion and color.
|
||||
完成 is only for observed successful completion.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License,
|
||||
Version 1.1.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" shape-rendering="crispEdges"><rect x="213.333" y="40.000" width="24.030" height="2.697" fill="#00D7E8"/><rect x="189.333" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="192.000" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="194.667" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="197.333" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="200.000" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="202.667" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="205.333" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="208.000" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="210.667" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="213.333" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="216.000" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="218.667" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="221.333" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="224.000" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="226.667" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="229.333" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="232.000" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="234.667" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="237.333" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="240.000" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="242.667" y="42.667" width="2.697" height="2.697" fill="#00D7E8"/><rect x="245.333" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="248.000" y="42.667" width="8.030" height="2.697" fill="#00D7E8"/><rect x="256.000" y="42.667" width="2.697" height="2.697" fill="#03A7FF"/><rect x="178.667" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="181.333" y="45.333" width="2.697" height="2.697" fill="#00D7E8"/><rect x="184.000" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="186.667" y="45.333" width="2.697" height="2.697" fill="#00D7E8"/><rect x="189.333" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="192.000" y="45.333" width="2.697" height="2.697" fill="#00D7E8"/><rect x="194.667" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="197.333" y="45.333" width="2.697" height="2.697" fill="#00D7E8"/><rect x="200.000" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="202.667" y="45.333" width="2.697" height="2.697" fill="#00D7E8"/><rect x="205.333" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="208.000" y="45.333" width="8.030" height="2.697" fill="#00D7E8"/><rect x="216.000" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="218.667" y="45.333" width="8.030" height="2.697" fill="#00D7E8"/><rect x="226.667" y="45.333" width="2.697" height="2.697" fill="#03A7FF"/><rect x="229.333" y="45.333" width="42.697" height="2.697" fill="#00D7E8"/><rect x="168.000" y="48.000" width="5.363" height="2.697" fill="#03A7FF"/><rect x="173.333" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="176.000" y="48.000" width="8.030" height="2.697" fill="#03A7FF"/><rect x="184.000" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="186.667" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="189.333" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="192.000" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="194.667" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="197.333" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="200.000" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="202.667" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="205.333" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="208.000" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="210.667" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="213.333" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="216.000" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="218.667" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="221.333" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="224.000" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="226.667" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="229.333" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="232.000" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="234.667" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="237.333" y="48.000" width="2.697" height="2.697" fill="#00D7E8"/><rect x="240.000" y="48.000" width="2.697" height="2.697" fill="#03A7FF"/><rect x="242.667" y="4Line truncated
|
||||
|
After Width: | Height: | Size: 482 KiB |
+3906
-714
File diff suppressed because it is too large.
Load diff
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
+19
-15
@@ -5,18 +5,18 @@
|
||||
<style>
|
||||
:root{color-scheme:dark;font:14px system-ui,sans-serif;background:#101619;color:#dae2e2;--line:#344044;--muted:#a4b3b5;--accent:#a3dcd4}*{box-sizing:border-box}[hidden]{display:none!important}body{margin:0}button,input,select{font:inherit}button{color:inherit;background:transparent;border:1px solid var(--line);border-radius:5px;padding:9px 13px;cursor:pointer}button:hover{background:#273338}button:disabled{opacity:.5;cursor:wait}button[aria-pressed=true]{border-color:var(--accent);background:#263b3a}button:focus-visible,input:focus-visible,select:focus-visible,canvas:focus-visible{outline:2px solid var(--accent);outline-offset:3px}::selection{background:#98d7cf;color:#142522}a{color:var(--accent);text-underline-offset:4px}header{height:74px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;padding:0 30px;gap:16px}header strong{font-size:18px;font-weight:550;letter-spacing:-.025em}header span{font-size:12px;color:var(--muted);margin-left:15px}nav{display:flex;gap:8px}main{display:grid;grid-template-columns:minmax(0,1fr) 290px;min-height:calc(100vh - 74px)}.stage{padding:28px;min-width:0}h1{font-size:30px;letter-spacing:-.03em;font-weight:500;margin:0 0 8px}p{color:var(--muted);line-height:1.6;margin:0 0 22px;max-width:68ch}.habitat{position:relative;height:calc(100vh - 282px);min-height:350px;background:#080f15;border:1px solid #374347;border-radius:5px;overflow:hidden}canvas{display:block;width:100%;height:100%;outline:none}.caption{position:absolute;left:25px;bottom:22px;right:25px;display:flex;justify-content:space-between;gap:12px;font:11px ui-monospace,monospace;color:#d1e1e2;pointer-events:none;font-variant-numeric:tabular-nums}.caption small{font:inherit}.controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:16px}.controls label{margin:0 8px}.identity{font:10px ui-monospace,monospace;color:var(--muted);margin-top:15px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.settings{border-left:1px solid var(--line);padding:28px 24px;overflow-y:auto;max-height:calc(100vh - 74px);scrollbar-color:#55686a #101619}.settings h2{font-size:16px;font-weight:550;margin:0 0 8px}.settings p{font-size:12px;line-height:1.55;margin-bottom:22px}.presets{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-bottom:24px}.presets button{padding:9px;text-align:left;font-size:12px;display:flex;align-items:center;gap:8px}.swatch{width:18px;height:18px;display:inline-grid;place-items:center;border-radius:50%;border:1px solid #788887}.swatch i{width:7px;height:7px;border-radius:50%}.field{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:17px 0;font-size:12px}.field input[type=color]{width:40px;height:26px;padding:0;border:1px solid var(--line);background:none;border-radius:3px;cursor:pointer}.range{display:block}.range span{display:flex;justify-content:space-between;margin-bottom:8px}.range input{width:100%;accent-color:var(--accent)}input[type=checkbox]{accent-color:var(--accent)}input[type=file]{max-width:100%;font-size:11px}output{font-variant-numeric:tabular-nums;color:var(--muted)}.divider{border-top:1px solid var(--line);margin-top:22px;padding-top:8px}.config-actions{display:flex;gap:8px;margin-top:20px}.config-actions button{font-size:11px;padding:8px}.status{min-height:32px;font-size:11px!important;margin-top:16px!important}.result{position:absolute;left:clamp(24px,9vw,160px);right:clamp(24px,9vw,160px);top:50%;max-height:44%;overflow:auto;padding:24px 30px;background:#111b20f2;color:#e4eeec;border-radius:6px;opacity:0;transform:translateY(18px);pointer-events:none;transition:opacity .65s cubic-bezier(.16,1,.3,1),transform .65s cubic-bezier(.16,1,.3,1);scrollbar-color:#65817f #111b20}.result.visible{opacity:1;transform:translateY(0);pointer-events:auto}.result h2{font-size:21px;font-weight:500;letter-spacing:-.02em;margin:0 0 12px}.result p{color:#b9cecc;font-size:14px;line-height:1.7;margin:0 0 14px}.result .label{font:11px ui-monospace,monospace;color:#94beb8;margin:0 0 12px}.result button{font-size:12px}.immersive header,.immersive .settings,.immersive .intro,.immersive .identity{display:none}.immersive main{display:block}.immersive .stage{padding:0}.immersive .habitat{height:calc(100dvh - 64px);min-height:200px;border:0;border-radius:0}.immersive .controls{height:64px;margin:0;padding:10px 22px}.gallery{display:none;grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;margin:24px 0}.gallery figure{margin:0;height:205px;position:relative;border-radius:5px;overflow:hidden}.gallery figcaption{position:absolute;left:16px;bottom:14px;font-size:12px}.gallery-mode .gallery{display:grid}.gallery-mode .habitat{display:none}.gallery-mode .stage> .controls{display:none}.gallery-mode .settings{position:sticky;top:0}.connection{margin-top:12px;font-size:11px}.connection a{display:inline-block;margin-top:8px}.work-label{font:11px ui-monospace,monospace;color:var(--muted);margin-left:auto}#finish{display:none}.preview-runLine truncated
|
||||
|
||||
.activity{position:absolute;top:48px;left:30px;right:30px;color:#d4e5e5;pointer-events:none}.activity .eyebrow{font:12px ui-monospace,monospace;opacity:.75;margin-bottom:8px}.activity h2{font-size:clamp(22px,2.8vw,34px);font-weight:500;letter-spacing:-.035em;margin:0 0 8px}.activity .detail{font:12px ui-monospace,monospace;line-height:1.6;overflow-wrap:anywhere}.activity .parallel{display:block;margin-top:7px;font:12px system-ui,sans-serif}.result.visible~.activity{opacity:1}.action-field{display:block;font-size:12px;margin:18px 0 10px}.action-field select{display:block;width:100%;margin-top:8px;color:inherit;background:#182226;border:1px solid var(--line);padding:9px;border-radius:4px}.settings .behavior-note{font-size:12px;margin-bottom:24px}.caption{font-size:12px}.identity{font-size:11px}.status,.config-actions button,.connection{font-size:12px!important}.gallery figcaption{font-size:13px}@media(max-width:480px){.activity{top:38px;left:22px;right:22px}.activity h2{font-size:23px}.activity .detail{font-size:12px}.caption{font-size:12px}.result.visible~.activity{display:none}.immersive .habitat{height:calc(100dvh - 112px)}}
|
||||
.activity{position:absolute;top:48px;left:30px;right:30px;color:#d4e5e5;pointer-events:none}.activity .phrase{font-size:16px;line-height:1.5;margin-bottom:7px}.activity .eyebrow{font:12px ui-monospace,monospace;opacity:.75;margin-bottom:8px}.activity h2{font-size:clamp(22px,2.8vw,34px);font-weight:500;letter-spacing:-.035em;margin:0 0 8px}.activity .detail{font:12px ui-monospace,monospace;line-height:1.6;overflow-wrap:anywhere}.activity .parallel{display:block;margin-top:7px;font:12px system-ui,sans-serif}.result.visible~.activity{opacity:1}.action-field{display:block;font-size:12px;margin:18px 0 10px}.action-field select{display:block;width:100%;margin-top:8px;color:inherit;background:#182226;border:1px solid var(--line);padding:9px;border-radius:4px}.settings .behavior-note{font-size:12px;margin-bottom:24px}.caption{font-size:12px}.identity{font-size:11px}.status,.config-actions button,.connection{font-size:12px!important}.gallery figcaption{font-size:13px}@media(max-width:480px){.activity{top:38px;left:22px;right:22px}.activity h2{font-size:23px}.activity .detail{font-size:12px}.caption{font-size:12px}.result.visible~.activity{display:none}.immersive .habitat{height:calc(100dvh - 112px)}}
|
||||
|
||||
/* A reliable backing protects labels even when the two user colors have
|
||||
opposite luminance. Particle colors remain entirely configurable. */
|
||||
.activity{width:max-content;max-width:calc(100% - 60px);padding:12px 15px;background:#10191df2;border-radius:5px;color:#eaf2f0}.activity .eyebrow{margin:0 0 8px;opacity:1;color:#b9ceca}.caption{padding:8px 10px;background:#10191df2;border-radius:4px;color:#eaf2f0}.result:focus{outline:2px solid #a3dcd4;outline-offset:3px}@media(max-width:480px){.activity{max-width:calc(100% - 44px);padding:12px}.activity h2{font-size:22px}}
|
||||
.activity{width:max-content;max-width:calc(100% - 60px);padding:12px 15px;background:#10191df2;border-radius:5px;color:#eaf2f0}.activity .phrase{font-size:16px;line-height:1.5;margin-bottom:7px}.activity .eyebrow{margin:0 0 8px;opacity:1;color:#b9ceca}.caption{padding:8px 10px;background:#10191df2;border-radius:4px;color:#eaf2f0}.result:focus{outline:2px solid #a3dcd4;outline-offset:3px}@media(max-width:480px){.activity{max-width:calc(100% - 44px);padding:12px}.activity h2{font-size:22px}}
|
||||
</style>
|
||||
<header><div><strong>Codewhale pet</strong><span id="connection-label">Shared habitat</span></div><nav aria-label="View options"><button id="compare" aria-pressed="false">Compare looks</button><button id="configure" aria-pressed="true">Appearance</button></nav></header>
|
||||
<main><section class="stage"><div class="intro"><h1>The whale speaks in light.</h1><p>The whole whale flows into a living character: reading scans 读, writing traces 写, and searching sweeps light through 搜. Then every dot gathers back into the whale.</p></div>
|
||||
<div class="habitat"><canvas id="tank" tabindex="0" role="img" aria-label="Codewhale habitat"></canvas><article class="result" id="result" tabindex="-1" aria-live="polite" aria-hidden="true" inert><h2>The work is ready.</h2><div class="label">Preview result · no task was run</div><p>The whale held the space while the task was running. Now the answer comes forward, with the habitat still present behind it.</p><p>In Codewhale, this space will show the completed assistant response from your existing conversation. Your draft, history, and selection stay intact.</p><button id="replay">Replay transition</button></article><div class="activity" id="activity" aria-live="polite" aria-atomic="true"><h2 id="activity-title">A moment between tasks.</h2><div class="eyebrow" id="activity-evidence">Local companion</div><div class="detail" id="activity-detail">Activity unobserved</div><span class="parallel" id="activity-parallel"></span></div><div class="caption"><strong id="caption">Connecting…</strong><small id="clock"></small></div></div>
|
||||
<main><section class="stage"><div class="intro"><h1>The whale speaks in light.</h1><p>Choose a whale style and a language for its large activity words. Its pixels and drones form the same phrases Codewhale uses, then return to the whale.</p></div>
|
||||
<div class="habitat"><canvas id="tank" tabindex="0" role="img" aria-label="Codewhale habitat"></canvas><article class="result" id="result" tabindex="-1" aria-live="polite" aria-hidden="true" inert><h2>The work is ready.</h2><div class="label">Preview result · no task was run</div><p>The whale held the space while the task was running. Now the answer comes forward, with the habitat still present behind it.</p><p>In Codewhale, this space will show the completed assistant response from your existing conversation. Your draft, history, and selection stay intact.</p><button id="replay">Replay transition</button></article><div class="activity" id="activity" aria-live="polite" aria-atomic="true"><h2 id="activity-title">A moment between tasks.</h2><div class="phrase" id="activity-phrase" hidden></div><div class="eyebrow" id="activity-evidence">Local companion</div><div class="detail" id="activity-detail">Activity unobserved</div><span class="parallel" id="activity-parallel"></span></div><div class="caption"><strong id="caption">Connecting…</strong><small id="clock"></small></div></div>
|
||||
<div class="gallery" id="gallery" aria-label="The same whale across eight appearances"></div>
|
||||
<div class="controls"><button id="focus">Focus</button><button id="pulse">Pulse</button><button id="sound" aria-pressed="false">Sound off</button><label><input id="still" type="checkbox"> Still</label><button id="expand">Full habitat</button><button id="work">Preview work → result</button><button id="finish">Finish preview now</button><button id="return-live" hidden>Return to live pet</button><span class="work-label" id="work-label">Escape returns</span></div><div class="identity" id="identity"></div></section>
|
||||
<aside class="settings" aria-label="Appearance settings"><h2>Behavior</h2><label class="action-field">Try a preview action<select id="action-preview"><option value="thinking">Thinking</option><option value="reading">Reading files</option><option value="searching">Searching</option><option value="editing">Editing files</option><option value="executing">Running a command</option><option value="testing">Running tests</option><option value="browsing">Using the browser</option><option value="computer">Controlling the desktop</option><option value="memory">Retrieving context</option><option value="tool">Using a tool</option><option value="delegating">Three parallel agents</option><option value="waiting">Waiting for you</option><option value="responding">Writing a response</option><option value="error">An operation failed</option><option value="unknown">No telemetry</option></select></label><p class="behavior-note">Preview actions are simulated. All 980 dots become one large character, alive with light and motion, before returning to the filled whale. Live activity comes from the session owner.</p><h2>Appearance</h2><p>Presets are starting points. Every color is yours to change.</p><div class="presets" id="presets"></div>
|
||||
<aside class="settings" aria-label="Appearance settings"><h2>Behavior</h2><label class="action-field">Try a preview action<select id="action-preview"><option value="thinking">Thinking</option><option value="reading">Reading files</option><option value="searching">Searching</option><option value="editing">Editing files</option><option value="executing">Running a command</option><option value="testing">Running tests</option><option value="browsing">Using the browser</option><option value="computer">Controlling the desktop</option><option value="memory">Retrieving context</option><option value="tool">Using a tool</option><option value="delegating">Three parallel agents</option><option value="waiting">Waiting for you</option><option value="responding">Writing a response</option><option value="error">An operation failed</option><option value="unknown">No telemetry</option></select></label><p class="behavior-note">Preview actions are simulated. All 980 dots form complete activity phrases, alive with light and motion, before returning to the filled whale. Live activity comes from the session owner.</p><h2>Whale</h2><label class="action-field">Whale style<select id="bodyStyle"><option value="smooth">Smooth aurora</option><option value="pixel">Pixel whale</option></select></label><label class="action-field">Large-text language<select id="textLanguage"><option value="auto">Follow Codewhale interface</option><option value="en">English</option><option value="zh-Hans">简体中文 · Simplified Chinese</option><option value="zh-Hant">繁體中文 · Traditional Chinese</option><option value="ja">日本語 · Japanese</option></select></label><p class="behavior-note">Try another language to learn its activity phrases. Regular status text stays in the interface language. Other interface languages currently use English for the large text.</p><h2>Appearance</h2><p>Presets are starting points. Every color is yours to change.</p><div class="presets" id="presets"></div>
|
||||
<label class="field">Background <input type="color" id="background" value="#080f15"></label><label class="field">Upper light <input type="color" id="backgroundTop" value="#182d38"></label><label class="field">Particle color <input type="color" id="particle" value="#87dddb"></label><label class="field"><span>Colors follow activity</span><input type="checkbox" id="eventColors" checked></label>
|
||||
<label class="field range"><span>Brightness <output id="brightness-value"></output></span><input type="range" id="brightness" min="0.25" max="2" step="0.05" value="1.25"></label><label class="field range"><span>Dot size <output id="dotScale-value"></output></span><input type="range" id="dotScale" min="0.65" max="1.8" step="0.05" value="1"></label><label class="field range"><span>Glow <output id="glow-value"></output></span><input type="range" id="glow" min="0" max="1" step="0.05" value="0.5"></label><label class="field"><span>Water and horizon</span><input type="checkbox" id="environment" checked></label>
|
||||
<div class="config-actions"><button id="export-config">Save appearance</button><button id="import-config">Load appearance</button><input id="config-file" type="file" accept="application/json,.json" hidden></div><p class="status" id="message" role="status">Opening the habitat…</p><div class="connection"><button id="save">Save pet replay</button><br><a href="pet.html" id="join">Join a live pet from the standalone viewer</a></div></aside></main>
|
||||
@@ -25,20 +25,23 @@
|
||||
'use strict';
|
||||
const $=id=>document.getElementById(id), canvas=$('tank');
|
||||
const rgb=h=>h.match(/[a-f\d]{2}/gi).map(n=>parseInt(n,16)),hex=c=>'#'+c.map(n=>n.toString(16).padStart(2,'0')).join('');
|
||||
const base={background:[8,15,21],backgroundTop:[24,45,56],particle:[135,221,219],eventColors:true,brightness:1.25,dotScale:1,glow:.5,environment:true};
|
||||
const base={background:[8,15,21],backgroundTop:[24,45,56],particle:[135,221,219],eventColors:true,brightness:1.25,dotScale:1,glow:.5,environment:true,bodyStyle:'smooth',textLanguage:'auto'};
|
||||
const presets=[['Ocean','#080f15','#182d38','#87dddb'],['Chalk','#e8edee','#fbfdfb','#285967'],['Graphite','#141518','#28292e','#d9e0e3'],['Linen','#e9e1d2','#f8f2e7','#79573a'],['Forest','#0c1916','#20382d','#c5db9b'],['Plum','#201a29','#3b2e4b','#e7b8d0'],['Ember','#211610','#49291b','#edb177'],['Cobalt','#101934','#263b60','#b2d7f2']].map(([name,b,t,p])=>({name,...base,background:rgb(b),backgroundTop:rgb(t),particle:rgb(p),eventColors:false,brightness:name==='Chalk'||name==='Linen'?1.8:1.35}));
|
||||
let appearance={...base}, selected='Ocean', current, previous, lastTickAt=0, received=0, client=crypto.randomUUID(), seq=0, pending=null, nextAppearance=null, busy=false, sound=false;
|
||||
let preview=new URLSearchParams(location.search).has('preview'), pet, points, demoTick=0, demoRunning=false, demoDone=false, actionChoice='thinking', actionTick=0, lastDraw=0, accumulator=0, galleryTick=0, previewSaved=false;
|
||||
const pixelWhale=new Image();pixelWhale.src='pixel-whale.webp';
|
||||
const pixelTints=new Map();
|
||||
function pixelSource(a){if(a.eventColors)return pixelWhale;const key=hex(a.particle);if(pixelTints.has(key))return pixelTints.get(key);const c=document.createElement('canvas');c.width=c.height=512;const ctx=c.getContext('2d');ctx.imageSmoothingEnabled=false;ctx.drawImage(pixelWhale,0,0,512,512);ctx.globalCompositeOperation='source-in';ctx.fillStyle=key;ctx.fillRect(0,0,512,512);if(pixelTints.size>=16)pixelTints.clear();pixelTints.set(key,c);return c}
|
||||
const media=matchMedia('(prefers-reduced-motion: reduce)');$('still').checked=media.matches;media.onchange=()=>{$('still').checked=media.matches};
|
||||
function valid(a){return a&&Object.keys(base).every(k=>k in a)&&['background','backgroundTop','particle'].every(k=>Array.isArray(a[k])&&a[k].length===3&&a[k].every(n=>Number.isInteger(n)&&n>=0&&n<=255))&&typeof a.eventColors==='boolean'&&typeof a.environment==='boolean'&&[['brightness',.25,2],['dotScale',.65,1.8],['glow',0,1]].every(([k,lo,hi])=>Number.isFinite(a[k])&&a[k]>=lo&&a[k]<=hi)}
|
||||
function clean(a){if(!valid(a))throw Error('This appearance has invalid colors or control ranges.');return Object.fromEntries(Object.keys(base).map(k=>[k,a[k]]))}
|
||||
function valid(a){return a&&Object.keys(base).filter(k=>!['bodyStyle','textLanguage'].includes(k)).every(k=>k in a)&&['background','backgroundTop','particle'].every(k=>Array.isArray(a[k])&&a[k].length===3&&a[k].every(n=>Number.isInteger(n)&&n>=0&&n<=255))&&typeof a.eventColors==='boolean'&&typeof a.environment==='boolean'&&['smooth','pixel'].includes(a.bodyStyle??'smooth')&&['auto','en','zh-Hans','zh-Hant','ja'].includes(a.textLanguage??'auto')&&[['brightness',.25,2],['dotScale',.65,1.8],['glow',0,1]].every(([k,lo,hi])=>Number.isFinite(a[k])&&a[k]>=lo&&a[k]<=hi)}
|
||||
function clean(a){if(!valid(a))throw Error('This appearance has invalid colors or control ranges.');return Object.fromEntries(Object.keys(base).map(k=>[k,a[k]??base[k]]))}
|
||||
try{const saved=JSON.parse(localStorage.getItem('codewhale-pet-appearance-v1'));if(valid(saved))appearance=clean(saved)}catch{}
|
||||
function presetName(a){return presets.find(p=>JSON.stringify(clean(p))===JSON.stringify(clean(a)))?.name||'Custom'}
|
||||
function presetName(a){const palette=v=>Object.fromEntries(Object.entries(clean(v)).filter(([k])=>!['bodyStyle','textLanguage'].includes(k)));return presets.find(p=>JSON.stringify(palette(p))===JSON.stringify(palette(a)))?.name||'Custom'}
|
||||
selected=presetName(appearance);
|
||||
function syncControls(){for(const k of ['background','backgroundTop','particle'])$(k).value=hex(appearance[k]);for(const k of ['eventColors','environment'])$(k).checked=appearance[k];for(const k of ['brightness','dotScale','glow']){$(k).value=appearance[k];$(k+'-value').value=k==='glow'?Math.round(appearance[k]*100)+'%':appearance[k].toFixed(2)+'×'}for(const b of $('presets').children)b.setAttribute('aria-pressed',String(b.textContent===selected));}
|
||||
function syncControls(){for(const k of ['bodyStyle','textLanguage'])$(k).value=appearance[k];for(const k of ['background','backgroundTop','particle'])$(k).value=hex(appearance[k]);for(const k of ['eventColors','environment'])$(k).checked=appearance[k];for(const k of ['brightness','dotScale','glow']){$(k).value=appearance[k];$(k+'-value').value=k==='glow'?Math.round(appearance[k]*100)+'%':appearance[k].toFixed(2)+'×'}for(const b of $('presets').children)b.setAttribute('aria-pressed',String(b.textContent===selected));}
|
||||
function saveAppearance(){try{localStorage.setItem('codewhale-pet-appearance-v1',JSON.stringify(appearance))}catch{}if(preview){$('message').textContent='Appearance saved in this preview. Export it to keep a portable copy.'}else{nextAppearance=clean(appearance);$('message').textContent='Saving appearance to the companion…';void flushAction()}}
|
||||
for(const a of presets){const b=document.createElement('button');b.type='button';b.setAttribute('aria-pressed','false');const sw=document.createElement('span');sw.className='swatch';sw.style.background=hex(a.background);const dot=document.createElement('i');dot.style.background=hex(a.particle);sw.append(dot);b.append(sw,document.createTextNode(a.name));b.onclick=()=>{appearance=clean(a);selected=a.name;syncControls();saveAppearance()};$('presets').append(b);const f=document.createElement('figure'),c=document.createElement('canvas'),label=document.createElement('figcaption');c.setAttribute('role','img');c.setAttribute('aria-label',a.name+' appearance');label.textContent=a.name;label.style.color=readable(a.background);f.append(c,label);$('gallery').append(f)}
|
||||
for(const key of Object.keys(base))$(key).oninput=()=>{appearance[key]=['background','backgroundTop','particle'].includes(key)?rgb($(key).value):['eventColors','environment'].includes(key)?$(key).checked:Number($(key).value);if(key==='particle')appearance.eventColors=false;selected='Custom';syncControls();saveAppearance()};
|
||||
for(const a of presets){const b=document.createElement('button');b.type='button';b.setAttribute('aria-pressed','false');const sw=document.createElement('span');sw.className='swatch';sw.style.background=hex(a.background);const dot=document.createElement('i');dot.style.background=hex(a.particle);sw.append(dot);b.append(sw,document.createTextNode(a.name));b.onclick=()=>{appearance=clean({...a,bodyStyle:appearance.bodyStyle,textLanguage:appearance.textLanguage});selected=a.name;syncControls();saveAppearance()};$('presets').append(b);const f=document.createElement('figure'),c=document.createElement('canvas'),label=document.createElement('figcaption');c.setAttribute('role','img');c.setAttribute('aria-label',a.name+' appearance');label.textContent=a.name;label.style.color=readable(a.background);f.append(c,label);$('gallery').append(f)}
|
||||
for(const key of Object.keys(base))$(key).oninput=()=>{appearance[key]=['bodyStyle','textLanguage'].includes(key)?$(key).value:['background','backgroundTop','particle'].includes(key)?rgb($(key).value):['eventColors','environment'].includes(key)?$(key).checked:Number($(key).value);if(key==='particle')appearance.eventColors=false;if(!['bodyStyle','textLanguage'].includes(key))selected='Custom';syncControls();saveAppearance()};
|
||||
syncControls();
|
||||
async function request(path,body,headers={}){const r=await fetch(path,{method:body===undefined?'GET':'POST',headers:{'Content-Type':'application/json',...headers},body:body===undefined?undefined:JSON.stringify(body),signal:AbortSignal.timeout(2500)});if(!r.ok){let e;try{e=await r.json()}catch{}const error=Error(e?.error||'Local pet unavailable. Reopen from Codewhale or use the preview.');error.rejected=r.status===409&&!error.message.includes('storage');throw error}return r.json()}
|
||||
async function flushAction(){if(busy||!current||preview)return;if(!pending&&nextAppearance){pending={identity:current.identity,client,seq:seq+1,source_revision:current.sourceRevision,action:{kind:'appearance',appearance:nextAppearance}};nextAppearance=null}if(!pending)return;busy=true;try{await request('/v1/action',pending);seq=pending.seq;pending=null;$('message').textContent='Appearance and interactions saved by the shared companion.'}catch(e){if(e.rejected)pending=null;$('message').textContent=e.message}finally{busy=false}}
|
||||
@@ -69,7 +72,7 @@ const previewActions={reading:'read_file',searching:'grep_files',editing:'apply_
|
||||
const workPhases=['thinking','reading','searching','browsing','computer','memory','tool','delegating','editing','executing','testing','waiting','responding'];
|
||||
function beginAction(kind,at){const emit=e=>pet.observeEngine(JSON.stringify(e),at);emit({event:'turn_started',turn_id:'preview-turn-'+(++previewTurn)});if(operationKinds.includes(kind))emit({event:'operation_activity_started',span_id:'preview-op-'+(++previewSpan),activity_kind:kind,action_id:previewActions[kind]});else if(kind==='waiting')emit({event:'user_input_required',id:'preview-question'});else if(kind==='delegating'){for(let i=0;i<3;i++)emit({event:'agent_spawned',id:'preview-worker-'+i})}else if(kind==='thinking'||kind==='responding')emit({event:kind==='thinking'?'thinking_started':'message_started',index:0});else if(kind==='error'){const span='preview-op-'+(++previewSpan);emit({event:'operation_activity_started',span_id:span,activity_kind:'executing',action_id:'exec_shell'});emit({event:'operation_activity_completed',span_id:span,activity_kind:'executing',action_id:'exec_shell',outcome:'failed'})}actionTick=0}
|
||||
$('action-preview').onchange=async()=>{try{if(!preview)await makePreview();demoRunning=false;demoDone=false;actionChoice=$('action-preview').value;beginAction(actionChoice,demoTick*1000/30);showResult(false);document.body.classList.remove('preview-running')}catch(e){$('message').textContent=e.message}};
|
||||
function advancePreview(){const at=demoTick*1000/30;if(!demoDone){if(demoRunning){const phase=Math.min(workPhases.length-1,Math.floor(demoTick/180));if(demoTick%180===0){actionChoice=workPhases[phase];$('action-preview').value=actionChoice;beginAction(actionChoice,at)}}else if(demoTick===0)beginAction(actionChoice,at);if(actionTick%6===0){const emit=e=>pet.observeEngine(JSON.stringify(e),at);if(operationKinds.includes(actionChoice))emit({event:'tool_call_heartbeat'});else if(actionChoice==='delegating'){for(let i=0;i<3;i++)emit({event:'agent_progress',id:'preview-worker-'+i,worker_status:'running'})}else if(actionChoice==='thinking'||actionChoice==='responding')emit({event:'response_delta',index:0,channel:actionChoice==='thinking'?'reasoning':'text'});}}actionTick++;pet.advanceEngine(++demoTick*1000/30,true,!demoDone&&actionChoice==='waiting');if(demoRunning&&demoTick>=180*workPhases.length)finishWork();previous=current;current=JSON.parse(pet.presentation());lastTickAt=received=performance.now();current.producerConnected=!demoDone&&actionChoice!=='unknown';current.epoch='preview';}
|
||||
function advancePreview(){const at=demoTick*1000/30;if(!demoDone){if(demoRunning){const phase=Math.min(workPhases.length-1,Math.floor(demoTick/180));if(demoTick%180===0){actionChoice=workPhases[phase];$('action-preview').value=actionChoice;beginAction(actionChoice,at)}}else if(demoTick===0)beginAction(actionChoice,at);if(actionTick%6===0){const emit=e=>pet.observeEngine(JSON.stringify(e),at);if(operationKinds.includes(actionChoice))emit({event:'tool_call_heartbeat'});else if(actionChoice==='delegating'){for(let i=0;i<3;i++)emit({event:'agent_progress',id:'preview-worker-'+i,worker_status:'running'})}else if(actionChoice==='thinking'||actionChoice==='responding')emit({event:'response_delta',index:0,channel:actionChoice==='thinking'?'reasoning':'text'});}}actionTick++;pet.advanceEngine(++demoTick*1000/30,true,!demoDone&&actionChoice==='waiting');if(demoRunning&&demoTick>=180*workPhases.length)finishWork();previous=current;current=JSON.parse(pet.presentation(appearance,navigator.language));lastTickAt=received=performance.now();current.producerConnected=!demoDone&&actionChoice!=='unknown';current.epoch='preview';}
|
||||
function readable(c){return c[0]*.2126+c[1]*.7152+c[2]*.0722>145?'#28383d':'#d4e5e5'}
|
||||
function paint(c,f,a,now,small=false){const w=c.clientWidth,h=c.clientHeight,d=small?1:Math.min(devicePixelRatio||1,2);if(!w||!h)return;if(c.width!==Math.round(w*d)||c.height!==Math.round(h*d)){c.width=Math.round(w*d);c.height=Math.round(h*d)}const ctx=c.getContext('2d');ctx.setTransform(d,0,0,d,0,0);const gradient=ctx.createRadialGradient(w*.5,0,0,w*.5,h*.18,w*.9);gradient.addColorStop(0,hex(a.backgroundTop));gradient.addColorStop(1,hex(a.background));ctx.fillStyle=gradient;ctx.fillRect(0,0,w,h);if(!f)return;const still=$('still').checked,pose=still?f.still:f,state=pose.state,style=pose.style,stale=!preview&&(now-lastTickAt>800||now-received>800),t=still?0:f.timeMs/1000;
|
||||
if(a.environment){ctx.strokeStyle=readable(a.background);ctx.globalAlpha=.12;ctx.lineWidth=.7;ctx.beginPath();ctx.moveTo(20,26);ctx.lineTo(w-20,26);ctx.stroke();for(let lane=0;lane<6;lane++){ctx.globalAlpha=.025;ctx.beginPath();for(let x=0;x<=w;x+=8){const y=h*.85+Math.sin(x/110+lane+t*.18)*7+lane*5;x?ctx.lineTo(x,y):ctx.moveTo(x,y)}ctx.stroke()}}ctx.globalAlpha=1;
|
||||
@@ -77,10 +80,11 @@ const complete=demoDone&&!small,scale=Math.min(w*.44,h*(complete?.18:.34)),ox=w*
|
||||
const light=a.background[0]*.2126+a.background[1]*.7152+a.background[2]*.0722>145;
|
||||
const radius=Math.max(.6,Math.min(w,h)*.0022)*a.dotScale,hollow=stale||!f.producerConnected||state.observed<.92;
|
||||
const fallback=[style.r,style.g,style.b,style.alpha],local=preview||small;
|
||||
const pixel=pose.bodyStyle==='pixel',morph=pose.morph??1;if(pixel&&pixelWhale.complete&&pixelWhale.naturalWidth){ctx.globalAlpha=(1-morph)*Math.min(1,a.brightness)*(hollow?.45:1)*(stale?.55:1);ctx.imageSmoothingEnabled=false;ctx.filter=hollow?'grayscale(1)':'none';ctx.drawImage(pixelSource(a),ox-scale*.8341,oy-scale*.8341,scale*1.6682,scale*1.6682);ctx.filter='none';ctx.globalAlpha=1;}
|
||||
for(let i=0;i<pose.points.length;i++){const q=pose.points[i],p=previous?.points[i],x=ox+(p&&!still?p[0]+(q[0]-p[0])*mix:q[0])*scale,y=oy+(p&&!still?p[1]+(q[1]-p[1])*mix:q[1])*scale,m=pose.materials?.[i]||fallback;
|
||||
let color=m.slice(0,3),alpha=m[3];if(local){if(!a.eventColors)color=a.particle;else if(light){const peak=Math.max(...color,1);color=color.map(v=>Math.round(v*Math.min(1,115/peak)))}alpha=Math.min(1,alpha*a.brightness/(preview?1:f.appearance?.brightness||1))}if(hollow)alpha=Math.min(alpha,.48);if(stale)alpha*=.55;
|
||||
let color=m.slice(0,3),alpha=m[3];if(local){if(!a.eventColors)color=a.particle;else if(light){const peak=Math.max(...color,1);color=color.map(v=>Math.round(v*Math.min(1,115/peak)))}alpha=Math.min(1,alpha*a.brightness/(preview?1:f.appearance?.brightness||1))}if(pixel&&pixelWhale.complete&&pixelWhale.naturalWidth)alpha*=morph;if(hollow)alpha=Math.min(alpha,.48);if(stale)alpha*=.55;
|
||||
const material='rgb('+color.map(Math.round).join(',')+')',depth=.8+.2*Math.min(1,alpha);ctx.fillStyle=ctx.strokeStyle=material;ctx.globalAlpha=alpha;ctx.lineWidth=Math.max(.7,radius*.6);ctx.beginPath();ctx.arc(x,y,radius*depth,0,Math.PI*2);hollow?ctx.stroke():ctx.fill();if(!hollow&&!light&&a.glow>0&&i%5===0){ctx.globalAlpha=alpha*.035*a.glow;ctx.beginPath();ctx.arc(x,y,radius*(1+a.glow*4),0,Math.PI*2);ctx.fill()}}ctx.globalAlpha=1;}
|
||||
function draw(now){requestAnimationFrame(draw);if(document.hidden)return;const dt=lastDraw?Math.min(.1,(now-lastDraw)/1000):0;lastDraw=now;if(preview&&pet){accumulator+=dt;let count=0;while(accumulator>=1/30&&count++<3){advancePreview();accumulator-=1/30}}if(document.body.classList.contains('gallery-mode')){if(++galleryTick%3===0)Array.from($('gallery').querySelectorAll('canvas')).forEach((c,i)=>paint(c,current,presets[i],now,true))}else paint(canvas,current,appearance,now);if(current){const p=$('still').checked?current.still:current,activity=current.activity,c=cue(activity),known=c&&(preview||now-lastTickAt<800),title=demoDone?'Settling back into the habitat.':known?c.label:'A moment between tasks.',detail=demoDone?'Preview complete':known?((preview?'Simulated action':'Observed action')+(c.actionId?' · '+c.actionId:'')):'Activity unobserved',evidence=preview?'Simulated preview':known?'Observed in Codewhale':'Local companion';for(const [id,text] of [['activity-title',title],['activity-detail',detail],['activity-evidence',evidence]])if($(id).textContent!==text)$(id).textContent=text;$('activity-parallel').textContent=known&&activity.parallelAgentCount?activity.parallelAgentCount+' parallel agent'+(activity.parallelAgentCount===1?'':'s')+' active':'';$('caption').textContent=(preview?'Preview · ':'')+'Codewhale'+(current.state.observed<.92?' · unobserved':'')+(demoDone?' · complete':'');$('clock').textContent=Math.floor(current.timeMs/60000)+':'+String(Math.floor(current.timeMs/1000)%60).padStart(2,'0');canvas.setAttribute('aria-label',title+'; '+detail+'; '+$('caption').textContent+'; '+(selected==='Custom'?'custom':selected)+' appearance')}}
|
||||
function draw(now){requestAnimationFrame(draw);if(document.hidden)return;const dt=lastDraw?Math.min(.1,(now-lastDraw)/1000):0;lastDraw=now;if(preview&&pet){accumulator+=dt;let count=0;while(accumulator>=1/30&&count++<3){advancePreview();accumulator-=1/30}}if(document.body.classList.contains('gallery-mode')){if(++galleryTick%3===0)Array.from($('gallery').querySelectorAll('canvas')).forEach((c,i)=>paint(c,current,presets[i],now,true))}else paint(canvas,current,appearance,now);if(current){const p=$('still').checked?current.still:current,activity=current.activity,c=cue(activity),known=c&&(preview||now-lastTickAt<800),title=demoDone?'Settling back into the habitat.':known?c.label:'A moment between tasks.',detail=demoDone?'Preview complete':known?((preview?'Simulated action':'Observed action')+(c.actionId?' · '+c.actionId:'')):'Activity unobserved',evidence=preview?'Simulated preview':known?'Observed in Codewhale':'Local companion';for(const [id,text] of [['activity-title',title],['activity-detail',detail],['activity-evidence',evidence]])if($(id).textContent!==text)$(id).textContent=text;const phrase=$('activity-phrase');phrase.hidden=!known||!current.displayPhrase;phrase.lang=current.displayLanguage||'en';if(phrase.textContent!==(current.displayPhrase||''))phrase.textContent=current.displayPhrase||'';$('activity-parallel').textContent=known&&activity.parallelAgentCount?activity.parallelAgentCount+' parallel agent'+(activity.parallelAgentCount===1?'':'s')+' active':'';$('caption').textContent=(preview?'Preview · ':'')+'Codewhale'+(current.state.observed<.92?' · unobserved':'')+(demoDone?' · complete':'');$('clock').textContent=Math.floor(current.timeMs/60000)+':'+String(Math.floor(current.timeMs/1000)%60).padStart(2,'0');canvas.setAttribute('aria-label',title+'; '+detail+'; '+$('caption').textContent+'; '+(current.displayPhrase?current.displayPhrase+'; '+current.displayLanguage+'; ':'')+(selected==='Custom'?'custom':selected)+' appearance')}}
|
||||
async function connect(){if(preview){await makePreview();return}const token=location.hash.slice(1);history.replaceState(null,'',location.pathname);if(token){if(!/^[a-f0-9]{64}$/i.test(token))throw Error('Invalid local connection');await request('/v1/attach',{}, {Authorization:'Bearer '+token})}$('join').hidden=true;$('message').textContent='One live pet. Appearance changes are shared; preview work stays isolated.';await poll()}
|
||||
requestAnimationFrame(draw);connect().catch(e=>{$('message').textContent=e.message});
|
||||
</script></html>
|
||||
@@ -1,5 +1,7 @@
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
@@ -8,8 +10,37 @@ parser = argparse.ArgumentParser()
|
||||
parser.add_argument("font", type=Path, nargs="?")
|
||||
parser.add_argument("--output", type=Path)
|
||||
parser.add_argument("--whale-body", action="store_true")
|
||||
parser.add_argument("--pixel-body", action="store_true")
|
||||
args = parser.parse_args()
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
if args.pixel_body:
|
||||
source = root / "assets/pixel-whale.svg"
|
||||
if hashlib.sha256(source.read_bytes()).hexdigest() != "9d3742fbf325aedc18435d7b15e89178b8684ccbb40cd55a32e60bed156de700":
|
||||
raise ValueError("Expected the approved 192-cell Codewhale pixel whale")
|
||||
step = 512 / 192
|
||||
candidates = []
|
||||
for rect in ET.fromstring(source.read_text()):
|
||||
color = rect.attrib["fill"].lstrip("#")
|
||||
rgb = tuple(int(color[i:i + 2], 16) for i in (0, 2, 4))
|
||||
for col in range(max(1, round(float(rect.attrib["width"]) / step))):
|
||||
candidates.append((float(rect.attrib["x"]) + (col + .5) * step,
|
||||
float(rect.attrib["y"]) + step / 2, *rgb))
|
||||
distances = [float("inf")] * len(candidates)
|
||||
selected = []
|
||||
at = 0
|
||||
for _ in range(980):
|
||||
x, y, *color = candidates[at]
|
||||
selected.append((x, y, *color))
|
||||
distances = [min(d, (x - p[0]) ** 2 + (y - p[1]) ** 2)
|
||||
for d, p in zip(distances, candidates, strict=True)]
|
||||
at = max(range(len(distances)), key=distances.__getitem__)
|
||||
output = args.output or root / "src/core/dot-pixel-body.ts"
|
||||
lines = ["export const DOT_PIXEL_BODY: readonly (readonly [number, number, number, number, number])[] = ["]
|
||||
lines.extend(f" [{(x - 256) / 512 * .878:.6f}, {(y - 256) / 512 * .878:.6f}, {r}, {g}, {b}]," for x, y, r, g, b in selected)
|
||||
lines.append("];")
|
||||
output.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
print(f"Generated 980 drones from the approved 192-cell pixel whale: {output}")
|
||||
raise SystemExit(0)
|
||||
if args.whale_body:
|
||||
source = root / "public/whale.png"
|
||||
if hashlib.sha256(source.read_bytes()).hexdigest() != "dc180fe5bde033f55bed5c7c7c1ab81182f31dd5913df237fb23e2a2da5098df":
|
||||
@@ -38,32 +69,60 @@ if args.whale_body:
|
||||
print(f"Generated 980 interior dots from the filled pet mark: {output}")
|
||||
raise SystemExit(0)
|
||||
if args.font is None:
|
||||
parser.error("font is required unless --whale-body is selected")
|
||||
parser.error("font is required unless --whale-body or --pixel-body is selected")
|
||||
args.output = args.output or root / "src/core/dot-glyphs.ts"
|
||||
font_hash = hashlib.sha256(args.font.read_bytes()).hexdigest()
|
||||
if font_hash != "ca094f6b0001fb048ca39ddd797a0cdb0179e1e55c6561e111c49c3e6a61d7b7":
|
||||
raise ValueError("Expected the pinned Noto Sans CJK SC Medium font in dot-glyphs-LICENSE.txt")
|
||||
characters = dict(zip(
|
||||
("reading", "editing", "searching", "testing", "executing", "browsing", "computer", "memory", "tool", "thinking", "responding", "delegating", "waiting", "done"),
|
||||
("读", "写", "搜", "试", "行", "览", "控", "记", "工具", "思", "答", "协", "待", "成"),
|
||||
strict=True,
|
||||
))
|
||||
lines = ["import type { OwnerActivityKind } from './pet-engine.js';", "", "export const DOT_GLYPHS: Record<OwnerActivityKind | 'waiting' | 'done', string[]> = {"]
|
||||
messages = {
|
||||
"reading": "ToolFamilyRead", "editing": "ToolFamilyPatch",
|
||||
"searching": "ToolFamilyFind", "testing": "ToolFamilyVerify",
|
||||
"executing": "ToolFamilyRun", "browsing": "PetActivityBrowsing",
|
||||
"computer": "PetActivityComputer", "memory": "PetActivityMemory",
|
||||
"tool": "ToolFamilyGeneric", "thinking": "ToolFamilyThink",
|
||||
"responding": "PetModeReplyTitle", "delegating": "PhaseSubagents",
|
||||
"waiting": "PhaseWaitingOnYou", "done": "PhaseDone",
|
||||
}
|
||||
languages = ["en", "zh-Hans", "zh-Hant", "ja"]
|
||||
labels = {language: {key: json.loads((root.parent / f"crates/localization/locales/{language}.json").read_text(encoding="utf-8"))[message]
|
||||
for key, message in messages.items()} for language in languages}
|
||||
lines = ["import type { OwnerActivityKind } from './pet-engine.js';", "",
|
||||
"export type GlyphLanguage = 'en' | 'zh-Hans' | 'zh-Hant' | 'ja';", "",
|
||||
"export const DOT_LABELS = " + json.dumps(labels, ensure_ascii=False, indent=2) + " as const;", "",
|
||||
"export const DOT_GLYPHS: Record<GlyphLanguage, Record<OwnerActivityKind | 'waiting' | 'done', string[]>> = {"]
|
||||
sizes = set()
|
||||
for key, char in characters.items():
|
||||
for size in range(48, 0, -1):
|
||||
font = ImageFont.truetype(str(args.font), size)
|
||||
left, top, right, bottom = font.getbbox(char)
|
||||
if right - left <= 44 and bottom - top <= 44:
|
||||
break
|
||||
sizes.add(size)
|
||||
image = Image.new("L", (48, 48), 0)
|
||||
ImageDraw.Draw(image).text(((48 - right + left) // 2 - left, (48 - bottom + top) // 2 - top), char, font=font, fill=255)
|
||||
rows = ["".join("#" if image.getpixel((x, y)) >= 128 else "." for x in range(48)) for y in range(48)]
|
||||
lines.append(f" {key}: [")
|
||||
lines.extend(f" '{row}'," for row in rows)
|
||||
lines.append(" ],")
|
||||
for language, characters in labels.items():
|
||||
lines.append(f" '{language}': {{")
|
||||
for key, char in characters.items():
|
||||
split = len(char) // 2
|
||||
words = char.split() if language == "en" else [char] if len(char) <= 3 else [char[:split], char[split:]]
|
||||
if language == "ja" and "を" in char:
|
||||
at = char.index("を")
|
||||
words = [char[:at], char[at:]]
|
||||
elif language == "ja" and "エージェント" in char:
|
||||
at = char.index("エージェント")
|
||||
end = at + len("エージェント")
|
||||
words = [word for word in [char[:at], char[at:end], char[end:]] if word]
|
||||
for size in range(48, 0, -1):
|
||||
font = ImageFont.truetype(str(args.font), size)
|
||||
boxes = [font.getbbox(word) for word in words]
|
||||
line_height = max(bottom - top for left, top, right, bottom in boxes)
|
||||
height = line_height * len(words) + 2 * (len(words) - 1)
|
||||
if max(right - left for left, top, right, bottom in boxes) <= 44 and height <= 44:
|
||||
break
|
||||
sizes.add(size)
|
||||
image = Image.new("L", (48, 48), 0)
|
||||
draw = ImageDraw.Draw(image)
|
||||
y = (48 - height) // 2
|
||||
for word, (left, top, right, bottom) in zip(words, boxes, strict=True):
|
||||
draw.text(((48 - right + left) // 2 - left, y - top), word, font=font, fill=255)
|
||||
y += line_height + 2
|
||||
rows = ["".join("#" if image.getpixel((x, y)) >= 128 else "." for x in range(48)) for y in range(48)]
|
||||
lines.append(f" {key}: [")
|
||||
lines.extend(f" '{row}'," for row in rows)
|
||||
lines.append(" ],")
|
||||
lines.append(" },")
|
||||
lines.append("};")
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
print(f"Generated {len(characters)} masks at 48 × 48, font sizes {sorted(sizes)}, threshold 128: {args.output}")
|
||||
print(f"Generated {len(languages) * len(messages)} masks at 48 × 48, font sizes {sorted(sizes)}, threshold 128: {args.output}")
|
||||
@@ -8,7 +8,7 @@ import ts from 'typescript';
|
||||
const root = fileURLToPath(new URL('../', import.meta.url));
|
||||
const result = spawnSync(process.execPath, [root + 'node_modules/typescript/bin/tsc', '-p', root + 'tsconfig.json'], { stdio: 'inherit' });
|
||||
if (result.status !== 0) process.exit(result.status || 1);
|
||||
for (const name of ['pet.html', 'shared.html', 'pet.css', 'whale-points.tsv']) await cp(root + 'public/' + name, root + 'dist/' + name);
|
||||
for (const name of ['pet.html', 'shared.html', 'pet.css', 'whale-points.tsv', 'pixel-whale.webp']) await cp(root + 'public/' + name, root + 'dist/' + name);
|
||||
const modules = new Map();
|
||||
async function moduleFor(name) {
|
||||
if (modules.has(name)) return;
|
||||
@@ -32,12 +32,13 @@ const generated = [];
|
||||
if (check || process.argv.includes('--tui')) {
|
||||
const destination = root + '../crates/tui/src/tui/pet_watch/';
|
||||
generated.push([destination + 'pet-native.js', Buffer.from(bundle)],
|
||||
[destination + 'shared.html', await readFile(root + 'public/shared.html')]);
|
||||
[destination + 'shared.html', await readFile(root + 'public/shared.html')],
|
||||
[destination + 'pixel-whale.webp', await readFile(root + 'public/pixel-whale.webp')]);
|
||||
}
|
||||
if (process.argv.includes('--study')) {
|
||||
const study = root + 'world/';
|
||||
await mkdir(study, { recursive: true });
|
||||
for (const name of ['pet.html', 'pet.css', 'whale-points.tsv', 'core', 'ui/pet.js', 'ui/storage.js']) {
|
||||
for (const name of ['pet.html', 'pet.css', 'whale-points.tsv', 'pixel-whale.webp', 'core', 'ui/pet.js', 'ui/storage.js']) {
|
||||
await mkdir(study + name.split('/').slice(0, -1).join('/'), { recursive: true });
|
||||
await cp(root + 'dist/' + name, study + name, { recursive: true });
|
||||
}
|
||||
|
||||
+30
-12
@@ -1,16 +1,22 @@
|
||||
import { stableHash } from './model.js';
|
||||
import { DOT_GLYPHS } from './dot-glyphs.js';
|
||||
import { DOT_GLYPHS, type GlyphLanguage } from './dot-glyphs.js';
|
||||
import { DOT_BODY } from './dot-body.js';
|
||||
import { DOT_PIXEL_BODY } from './dot-pixel-body.js';
|
||||
import type { EngineOwnerProjection, OwnerActivityKind } from './pet-engine.js';
|
||||
|
||||
export interface DotField { points: number[][]; materials: number[][] }
|
||||
export type BodyStyle = 'smooth' | 'pixel';
|
||||
export type TextLanguage = GlyphLanguage | 'auto';
|
||||
export interface DotOptions { bodyStyle?: BodyStyle; textLanguage?: TextLanguage }
|
||||
export interface DotField { points: number[][]; materials: number[][]; morph: number; bodyStyle: BodyStyle }
|
||||
type Verb = OwnerActivityKind | 'waiting' | 'done';
|
||||
const TAU = Math.PI * 2;
|
||||
const clamp = (n: number, lo = 0, hi = 1) => Math.max(lo, Math.min(hi, n));
|
||||
const ease = (n: number) => { const u = clamp(n); return u * u * (3 - 2 * u); };
|
||||
const GLYPH_POINTS = Object.fromEntries(Object.entries(DOT_GLYPHS).map(([key, rows]) => [key,
|
||||
rows.flatMap((row, y) => [...row].flatMap((pixel, x) => pixel === '#' ? [[(x - 23.5) / 24, (y - 23.5) / 24]] : [])),
|
||||
])) as Record<Verb, number[][]>;
|
||||
const GLYPH_POINTS = Object.fromEntries(Object.entries(DOT_GLYPHS).map(([language, glyphs]) => [language,
|
||||
Object.fromEntries(Object.entries(glyphs).map(([key, rows]) => [key,
|
||||
rows.flatMap((row, y) => [...row].flatMap((pixel, x) => pixel === '#' ? [[(x - 23.5) / 24, (y - 23.5) / 24]] : [])),
|
||||
])),
|
||||
])) as Record<GlyphLanguage, Record<Verb, number[][]>>;
|
||||
const HUES: Record<Verb, number> = {
|
||||
reading: 185, editing: 190, searching: 194, testing: 201, executing: 198,
|
||||
browsing: 195, computer: 198, memory: 180, tool: 195, thinking: 185,
|
||||
@@ -38,13 +44,21 @@ function pigment(hue: number, light: number): number[] {
|
||||
return rgb.map(v => Math.round((v + m) * 255));
|
||||
}
|
||||
|
||||
export function textLanguage(value = 'auto', interfaceLanguage = 'en'): GlyphLanguage {
|
||||
const tag = (value === 'auto' ? interfaceLanguage : value).toLowerCase();
|
||||
return tag.startsWith('ja') ? 'ja' : /^(zh-hant|zh-tw|zh-hk|zh-mo)/.test(tag) ? 'zh-Hant'
|
||||
: tag.startsWith('zh') ? 'zh-Hans' : 'en';
|
||||
}
|
||||
|
||||
export function projectDotField(activity: EngineOwnerProjection,
|
||||
timeMs: number, still = false, expressionAtMs = 0): DotField {
|
||||
timeMs: number, still = false, expressionAtMs = 0, options: DotOptions = {}): DotField {
|
||||
const kind = verb(activity, timeMs), identity = activity.actionId || activity.activityKind || 'whale';
|
||||
const seed = stableHash(identity), variant = (seed % 997) / 997;
|
||||
const t = still ? 0 : timeMs / 1000, cycle = still ? .43 : (t / (2.8 + variant * .6)) % 1;
|
||||
const sweep = -.86 + cycle * 1.72, scanRow = Math.floor(cycle * 5) % 5;
|
||||
const glyph = kind ? GLYPH_POINTS[kind] : null;
|
||||
const bodyStyle = options.bodyStyle ?? 'smooth', language = textLanguage(options.textLanguage);
|
||||
const body = bodyStyle === 'pixel' ? DOT_PIXEL_BODY : DOT_BODY;
|
||||
const glyph = kind ? GLYPH_POINTS[language][kind] : null;
|
||||
const fresh = activity.freshness === 'fresh' && activity.observed;
|
||||
const failed = fresh && !activity.activeSpans.length && !!activity.failedToolAge;
|
||||
const phase = ((Math.max(0, timeMs - expressionAtMs) / 1000 + 1.7) % 8.4);
|
||||
@@ -53,8 +67,8 @@ export function projectDotField(activity: EngineOwnerProjection,
|
||||
: ease(phase / 1.7) * (1 - ease((phase - 5.4) / .9));
|
||||
const points: number[][] = [], materials: number[][] = [];
|
||||
const lens = [Math.sin(cycle * TAU) * .62, -.62 + scanRow * .31];
|
||||
for (let i = 0; i < DOT_BODY.length; i++) {
|
||||
const [hx, hy] = DOT_BODY[i];
|
||||
for (let i = 0; i < body.length; i++) {
|
||||
const [hx, hy] = body[i];
|
||||
const tail = clamp((-hx - hy + .1) / .65);
|
||||
const homeX = hx * 1.9 + (still ? 0 : .008 * Math.sin(t * .75 + hy * 5));
|
||||
const homeY = hy * 1.9 + (still ? 0 : .009 * Math.sin(t * 1.1 + hx * 4)
|
||||
@@ -62,7 +76,7 @@ export function projectDotField(activity: EngineOwnerProjection,
|
||||
const bodyLight = .61 + .14 * clamp((hx + .45) / .9) + .035 * Math.cos(hy * 7);
|
||||
let x = homeX, y = homeY, light = bodyLight, alpha = fresh ? .88 : .42;
|
||||
if (glyph && kind) {
|
||||
[x, y] = glyph[Math.floor(i * glyph.length / DOT_BODY.length)];
|
||||
[x, y] = glyph[Math.floor(i * glyph.length / body.length)];
|
||||
x += ((i * 17) % 7 - 3) * .0016;
|
||||
y += ((i * 11) % 7 - 3) * .0016;
|
||||
let beam = Math.exp(-Math.pow((y - sweep) * 10, 2));
|
||||
@@ -101,17 +115,21 @@ export function projectDotField(activity: EngineOwnerProjection,
|
||||
if (!still) light = clamp(light + .025 * Math.sin(hx * 10 - hy * 5 - t * 1.1), .5, .9);
|
||||
points.push([clamp(x, -.94, .94), clamp(y, -.94, .94)]);
|
||||
const hue = morph > 0 ? (failed ? 16 : kind ? HUES[kind] : 188) : 188;
|
||||
const base = pigment(188 + variant * 6 - 3, light), accent = pigment(hue + variant * 6 - 3, light);
|
||||
const base = bodyStyle === 'pixel' ? DOT_PIXEL_BODY[i].slice(2)
|
||||
: pigment(185 + clamp((hy - hx + .45) / .9) * 70, light);
|
||||
const accent = pigment(hue + variant * 6 - 3, light);
|
||||
const color = !fresh ? [145, 166, 178] : base.map((v, k) => Math.round(v + (accent[k] - v) * morph));
|
||||
materials.push([...color, alpha]);
|
||||
}
|
||||
return { points, materials };
|
||||
return { points, materials, morph, bodyStyle };
|
||||
}
|
||||
|
||||
export function blendDotFields(from: DotField, to: DotField, progress: number): DotField {
|
||||
const mix = ease(progress);
|
||||
if (mix >= 1) return to;
|
||||
return {
|
||||
morph: from.morph + (to.morph - from.morph) * mix,
|
||||
bodyStyle: to.bodyStyle,
|
||||
points: to.points.map((p, i) => p.map((v, k) => from.points[i][k] + (v - from.points[i][k]) * mix)),
|
||||
materials: to.materials.map((p, i) => p.map((v, k) => from.materials[i][k] + (v - from.materials[i][k]) * mix)),
|
||||
};
|
||||
|
||||
+2878
-701
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,982 @@
|
||||
export const DOT_PIXEL_BODY: readonly (readonly [number, number, number, number, number])[] = [
|
||||
[-0.070881, -0.368120, 0, 215, 232],
|
||||
[0.057161, 0.363547, 11, 111, 255],
|
||||
[-0.404703, 0.066307, 56, 65, 255],
|
||||
[0.395557, -0.052589, 0, 215, 232],
|
||||
[0.034297, -0.002287, 11, 111, 255],
|
||||
[-0.331536, -0.221787, 11, 111, 255],
|
||||
[0.308672, 0.221786, 3, 167, 255],
|
||||
[-0.221787, 0.285807, 56, 65, 255],
|
||||
[0.185204, -0.240078, 41, 247, 187],
|
||||
[-0.180631, 0.066307, 56, 65, 255],
|
||||
[0.116610, 0.176057, 11, 111, 255],
|
||||
[0.221786, 0.020579, 3, 167, 255],
|
||||
[-0.061735, 0.203494, 56, 65, 255],
|
||||
[0.006860, -0.208068, 0, 215, 232],
|
||||
[-0.294953, -0.057162, 56, 65, 255],
|
||||
[-0.166911, -0.230932, 3, 167, 255],
|
||||
[-0.093745, 0.363547, 76, 25, 214],
|
||||
[0.390985, 0.098318, 3, 167, 255],
|
||||
[-0.345256, 0.203494, 76, 25, 214],
|
||||
[0.194348, 0.313244, 11, 111, 255],
|
||||
[0.057161, -0.336109, 0, 215, 232],
|
||||
[-0.057161, 0.080025, 11, 111, 255],
|
||||
[-0.390984, -0.121182, 11, 111, 255],
|
||||
[-0.230932, 0.171485, 56, 65, 255],
|
||||
[-0.253796, -0.304100, 3, 167, 255],
|
||||
[-0.294953, 0.080025, 56, 65, 255],
|
||||
[0.038869, 0.253797, 11, 111, 255],
|
||||
[0.121182, 0.066307, 11, 111, 255],
|
||||
[0.290380, -0.061734, 0, 215, 232],
|
||||
[0.249224, 0.134900, 3, 167, 255],
|
||||
[-0.249224, -0.162339, 11, 111, 255],
|
||||
[0.134902, -0.034296, 3, 167, 255],
|
||||
[0.020578, 0.144047, 11, 111, 255],
|
||||
[0.102890, -0.185203, 0, 215, 232],
|
||||
[-0.075453, -0.267515, 3, 167, 255],
|
||||
[0.322391, 0.029724, 3, 167, 255],
|
||||
[-0.162339, -0.336109, 3, 167, 255],
|
||||
[-0.125756, 0.272088, 56, 65, 255],
|
||||
[-0.409276, -0.029725, 56, 65, 255],
|
||||
[-0.139475, 0.153193, 56, 65, 255],
|
||||
[-0.038870, 0.294954, 56, 65, 255],
|
||||
[0.221786, 0.230932, 11, 111, 255],
|
||||
[0.112037, 0.299525, 11, 111, 255],
|
||||
[0.102891, -0.267515, 0, 215, 232],
|
||||
[-0.336110, 0.011432, 56, 65, 255],
|
||||
[-0.166912, 0.340682, 56, 65, 255],
|
||||
[0.413850, 0.025150, 0, 215, 232],
|
||||
[-0.363546, 0.130329, 76, 25, 214],
|
||||
[-0.002287, -0.290381, 0, 215, 232],
|
||||
[-0.294953, 0.258369, 76, 25, 214],
|
||||
[0.176057, 0.116610, 3, 167, 255],
|
||||
[0.340682, 0.153193, 0, 215, 232],
|
||||
[0.208068, -0.052589, 0, 215, 232],
|
||||
[-0.317818, -0.134901, 56, 65, 255],
|
||||
[0.043443, 0.070880, 11, 111, 255],
|
||||
[-0.016006, 0.368119, 76, 25, 214],
|
||||
[-0.171485, 0.217213, 56, 65, 255],
|
||||
[-0.240078, -0.235506, 3, 167, 255],
|
||||
[-0.294953, 0.148619, 56, 65, 255],
|
||||
[0.148619, 0.235505, 3, 167, 255],
|
||||
[-0.002286, -0.363546, 0, 215, 232],
|
||||
[-0.235506, 0.107463, 11, 111, 255],
|
||||
[-0.025151, 0.020579, 11, 111, 255],
|
||||
[-0.121183, 0.089172, 11, 111, 255],
|
||||
[0.084599, 0.121182, 11, 111, 255],
|
||||
[-0.075453, 0.139474, 11, 111, 255],
|
||||
[0.057161, 0.194349, 11, 111, 255],
|
||||
[-0.358975, -0.066307, 56, 65, 255],
|
||||
[0.093745, 0.011432, 3, 167, 255],
|
||||
[-0.002286, 0.208068, 11, 111, 255],
|
||||
[-0.134900, -0.281234, 3, 167, 255],
|
||||
[-0.194348, -0.285807, 3, 167, 255],
|
||||
[0.340682, -0.029725, 0, 215, 232],
|
||||
[0.162338, 0.020579, 3, 167, 255],
|
||||
[0.226359, 0.080025, 3, 167, 255],
|
||||
[0.267516, 0.267516, 11, 111, 255],
|
||||
[0.043443, -0.253796, 0, 215, 232],
|
||||
[0.016005, 0.313244, 56, 65, 255],
|
||||
[-0.276662, 0.025150, 56, 65, 255],
|
||||
[-0.240078, 0.230932, 56, 65, 255],
|
||||
[0.272088, -0.006859, 0, 215, 232],
|
||||
[-0.363546, -0.171484, 56, 65, 255],
|
||||
[0.262943, 0.189775, 3, 167, 255],
|
||||
[-0.116609, 0.212641, 56, 65, 255],
|
||||
[-0.294953, -0.267515, 11, 111, 255],
|
||||
[-0.349828, 0.070880, 56, 65, 255],
|
||||
[-0.290381, 0.203494, 76, 25, 214],
|
||||
[-0.093745, -0.317818, 3, 167, 255],
|
||||
[0.272089, 0.048016, 3, 167, 255],
|
||||
[0.322391, 0.102891, 3, 167, 255],
|
||||
[-0.189776, 0.134900, 11, 111, 255],
|
||||
[-0.006860, 0.098318, 11, 111, 255],
|
||||
[0.134901, -0.226359, 0, 215, 232],
|
||||
[-0.281234, -0.203495, 3, 167, 255],
|
||||
[-0.089172, 0.308672, 56, 65, 255],
|
||||
[-0.038870, -0.326964, 0, 215, 232],
|
||||
[0.148620, 0.336110, 11, 111, 255],
|
||||
[0.212641, 0.180630, 3, 167, 255],
|
||||
[-0.029724, 0.162338, 11, 111, 255],
|
||||
[-0.029725, -0.244651, 0, 215, 232],
|
||||
[-0.386411, 0.016005, 56, 65, 255],
|
||||
[0.052588, -0.185203, 3, 167, 255],
|
||||
[0.084600, 0.235505, 11, 111, 255],
|
||||
[-0.080026, 0.249224, 56, 65, 255],
|
||||
[-0.176057, 0.267516, 56, 65, 255],
|
||||
[-0.240078, 0.057161, 56, 65, 255],
|
||||
[-0.093745, 0.048016, 11, 111, 255],
|
||||
[0.180630, 0.066307, 3, 167, 255],
|
||||
[0.368120, 0.011432, 0, 215, 232],
|
||||
[0.102890, 0.349829, 56, 65, 255],
|
||||
[-0.121182, -0.358975, 3, 167, 255],
|
||||
[-0.025151, 0.249224, 56, 65, 255],
|
||||
[0.130329, 0.130329, 11, 111, 255],
|
||||
[0.157766, 0.281235, 11, 111, 255],
|
||||
[-0.208068, -0.331537, 3, 167, 255],
|
||||
[0.294954, 0.148619, 3, 167, 255],
|
||||
[-0.281234, -0.107464, 56, 65, 255],
|
||||
[-0.052589, 0.340682, 56, 65, 255],
|
||||
[0.080025, -0.226359, 0, 215, 232],
|
||||
[0.221786, 0.276661, 11, 111, 255],
|
||||
[-0.208068, -0.203495, 3, 167, 255],
|
||||
[0.176057, -0.020578, 0, 215, 232],
|
||||
[-0.317817, -0.180631, 11, 111, 255],
|
||||
[-0.299526, -0.011432, 11, 111, 255],
|
||||
[-0.326964, 0.107463, 56, 65, 255],
|
||||
[0.016005, 0.038869, 3, 167, 255],
|
||||
[0.180630, 0.208068, 11, 111, 255],
|
||||
[-0.400131, -0.080026, 56, 65, 255],
|
||||
[-0.130328, 0.317818, 56, 65, 255],
|
||||
[-0.326964, -0.093745, 11, 111, 255],
|
||||
[0.249224, -0.043443, 3, 167, 255],
|
||||
[-0.180631, 0.176057, 56, 65, 255],
|
||||
[-0.336109, 0.162338, 56, 65, 255],
|
||||
[-0.363546, -0.020578, 11, 111, 255],
|
||||
[0.386411, 0.057161, 3, 167, 255],
|
||||
[-0.162338, 0.102891, 56, 65, 255],
|
||||
[-0.102890, 0.171485, 56, 65, 255],
|
||||
[0.080027, 0.052588, 3, 167, 255],
|
||||
[0.016005, -0.326964, 0, 215, 232],
|
||||
[0.413848, -0.016006, 0, 215, 232],
|
||||
[-0.313244, 0.043443, 56, 65, 255],
|
||||
[0.043443, 0.112036, 11, 111, 255],
|
||||
[0.189775, 0.253797, 11, 111, 255],
|
||||
[-0.038870, 0.121182, 11, 111, 255],
|
||||
[-0.112036, -0.249225, 3, 167, 255],
|
||||
[0.080025, 0.162338, 11, 111, 255],
|
||||
[-0.258370, 0.272088, 76, 25, 214],
|
||||
[-0.020578, 0.061735, 11, 111, 255],
|
||||
[-0.390984, 0.102891, 76, 25, 214],
|
||||
[0.336110, 0.194349, 3, 167, 255],
|
||||
[-0.208068, 0.203494, 76, 25, 214],
|
||||
[0.002286, 0.276661, 56, 65, 255],
|
||||
[0.020578, 0.354400, 56, 65, 255],
|
||||
[-0.203495, -0.249225, 3, 167, 255],
|
||||
[-0.112037, 0.125755, 56, 65, 255],
|
||||
[-0.258370, 0.139474, 56, 65, 255],
|
||||
[-0.038870, -0.281234, 0, 215, 232],
|
||||
[-0.285807, -0.153193, 11, 111, 255],
|
||||
[-0.203495, 0.240079, 56, 65, 255],
|
||||
[0.217213, -0.016006, 0, 215, 232],
|
||||
[0.372692, 0.130329, 3, 167, 255],
|
||||
[-0.326964, -0.038870, 11, 111, 255],
|
||||
[-0.198921, 0.098318, 11, 111, 255],
|
||||
[0.308672, -0.011432, 0, 215, 232],
|
||||
[0.125755, 0.029724, 3, 167, 255],
|
||||
[-0.354401, -0.125756, 56, 65, 255],
|
||||
[0.006860, -0.249225, 3, 167, 255],
|
||||
[-0.235506, -0.272089, 11, 111, 255],
|
||||
[0.358974, -0.061734, 0, 215, 232],
|
||||
[-0.057161, 0.038869, 11, 111, 255],
|
||||
[-0.244650, -0.198921, 11, 111, 255],
|
||||
[-0.130329, -0.317818, 3, 167, 255],
|
||||
[-0.016005, 0.331536, 56, 65, 255],
|
||||
[-0.130328, 0.354400, 76, 25, 214],
|
||||
[-0.144046, 0.240079, 76, 25, 214],
|
||||
[0.148620, 0.089172, 3, 167, 255],
|
||||
[-0.144047, 0.189775, 56, 65, 255],
|
||||
[-0.267515, 0.176057, 56, 65, 255],
|
||||
[-0.317818, 0.226360, 56, 65, 255],
|
||||
[0.052588, 0.029724, 3, 167, 255],
|
||||
[0.070880, -0.016006, 3, 167, 255],
|
||||
[0.020579, 0.180630, 11, 111, 255],
|
||||
[-0.084600, 0.102891, 11, 111, 255],
|
||||
[-0.144047, 0.061735, 11, 111, 255],
|
||||
[-0.272089, 0.107463, 56, 65, 255],
|
||||
[0.116610, 0.249224, 11, 111, 255],
|
||||
[-0.368120, 0.171485, 76, 25, 214],
|
||||
[-0.358975, 0.038869, 56, 65, 255],
|
||||
[0.089172, 0.084599, 3, 167, 255],
|
||||
[0.043443, -0.217214, 0, 215, 232],
|
||||
[0.029724, 0.221786, 56, 65, 255],
|
||||
[0.276661, 0.230932, 11, 111, 255],
|
||||
[0.070881, -0.276662, 0, 215, 232],
|
||||
[0.093744, 0.203494, 11, 111, 255],
|
||||
[0.102891, -0.025151, 3, 167, 255],
|
||||
[0.377266, -0.020578, 0, 215, 232],
|
||||
[-0.162339, -0.299526, 3, 167, 255],
|
||||
[-0.299526, -0.230932, 3, 167, 255],
|
||||
[-0.066307, -0.299526, 0, 215, 232],
|
||||
[-0.070880, 0.281235, 56, 65, 255],
|
||||
[0.290380, 0.020579, 0, 215, 232],
|
||||
[-0.034297, -0.368120, 0, 215, 232],
|
||||
[-0.166912, -0.267515, 3, 167, 255],
|
||||
[0.322391, -0.057162, 0, 215, 232],
|
||||
[-0.221786, 0.139474, 56, 65, 255],
|
||||
[0.006860, 0.244650, 56, 65, 255],
|
||||
[0.038869, 0.290380, 11, 111, 255],
|
||||
[-0.272089, 0.235505, 56, 65, 255],
|
||||
[0.130328, -0.002287, 3, 167, 255],
|
||||
[-0.102891, -0.285807, 3, 167, 255],
|
||||
[-0.066307, 0.171485, 56, 65, 255],
|
||||
[0.139473, -0.194350, 0, 215, 232],
|
||||
[0.253797, 0.020579, 0, 215, 232],
|
||||
[0.011432, 0.070880, 3, 167, 255],
|
||||
[-0.272088, 0.057161, 56, 65, 255],
|
||||
[0.048016, 0.162338, 11, 111, 255],
|
||||
[-0.034296, 0.217213, 11, 111, 255],
|
||||
[0.235506, 0.048016, 3, 167, 255],
|
||||
[-0.272088, -0.244651, 11, 111, 255],
|
||||
[-0.011432, 0.134900, 11, 111, 255],
|
||||
[0.198921, 0.093744, 3, 167, 255],
|
||||
[-0.368120, -0.098318, 56, 65, 255],
|
||||
[-0.112036, 0.244650, 56, 65, 255],
|
||||
[0.194349, 0.038869, 3, 167, 255],
|
||||
[0.189776, 0.006860, 3, 167, 255],
|
||||
[-0.221787, -0.299526, 3, 167, 255],
|
||||
[0.336110, 0.002286, 0, 215, 232],
|
||||
[0.148619, 0.052588, 3, 167, 255],
|
||||
[-0.212640, 0.070880, 56, 65, 255],
|
||||
[0.116610, 0.098318, 11, 111, 255],
|
||||
[0.144047, 0.157766, 3, 167, 255],
|
||||
[-0.253796, 0.203494, 76, 25, 214],
|
||||
[-0.194350, 0.326963, 76, 25, 214],
|
||||
[0.070880, 0.336110, 56, 65, 255],
|
||||
[-0.308671, 0.176057, 76, 25, 214],
|
||||
[0.029723, -0.354401, 0, 215, 232],
|
||||
[-0.386411, -0.052589, 56, 65, 255],
|
||||
[-0.349828, -0.198921, 11, 111, 255],
|
||||
[0.025152, -0.276662, 0, 215, 232],
|
||||
[0.153192, -0.249225, 0, 215, 232],
|
||||
[-0.409276, 0.034297, 56, 65, 255],
|
||||
[0.102891, 0.144047, 3, 167, 255],
|
||||
[0.162339, -0.212640, 0, 215, 232],
|
||||
[-0.144047, -0.249225, 3, 167, 255],
|
||||
[-0.107463, 0.336110, 56, 65, 255],
|
||||
[-0.070881, -0.336109, 3, 167, 255],
|
||||
[-0.253797, 0.084599, 56, 65, 255],
|
||||
[-0.336109, -0.157765, 11, 111, 255],
|
||||
[0.230932, 0.157766, 11, 111, 255],
|
||||
[0.244650, 0.212641, 3, 167, 255],
|
||||
[-0.153193, 0.285807, 76, 25, 214],
|
||||
[-0.267515, -0.276662, 11, 111, 255],
|
||||
[0.107463, -0.235506, 0, 215, 232],
|
||||
[0.006860, 0.006860, 11, 111, 255],
|
||||
[-0.358975, 0.098318, 76, 25, 214],
|
||||
[0.281235, -0.034296, 0, 215, 232],
|
||||
[0.121182, 0.326963, 11, 111, 255],
|
||||
[-0.230932, 0.258369, 56, 65, 255],
|
||||
[-0.089171, 0.221786, 56, 65, 255],
|
||||
[-0.011432, -0.317818, 0, 215, 232],
|
||||
[-0.061734, 0.368119, 76, 25, 214],
|
||||
[-0.299525, 0.116610, 56, 65, 255],
|
||||
[-0.052588, 0.258369, 56, 65, 255],
|
||||
[-0.194348, 0.290380, 56, 65, 255],
|
||||
[0.057161, 0.230932, 56, 65, 255],
|
||||
[-0.322390, 0.134900, 76, 25, 214],
|
||||
[-0.299526, -0.084600, 11, 111, 255],
|
||||
[-0.322390, -0.066307, 56, 65, 255],
|
||||
[0.244650, -0.011432, 3, 167, 255],
|
||||
[-0.139475, 0.121182, 11, 111, 255],
|
||||
[-0.304100, 0.016005, 56, 65, 255],
|
||||
[-0.025151, 0.189775, 11, 111, 255],
|
||||
[0.162339, 0.308672, 11, 111, 255],
|
||||
[0.016005, 0.116610, 11, 111, 255],
|
||||
[-0.011432, 0.304099, 56, 65, 255],
|
||||
[0.066307, 0.258369, 56, 65, 255],
|
||||
[-0.061734, 0.313244, 56, 65, 255],
|
||||
[-0.377265, 0.061735, 56, 65, 255],
|
||||
[-0.089171, 0.075454, 56, 65, 255],
|
||||
[-0.322390, 0.075454, 56, 65, 255],
|
||||
[-0.409276, -0.002287, 56, 65, 255],
|
||||
[-0.002286, 0.162338, 11, 111, 255],
|
||||
[0.308672, 0.194349, 3, 167, 255],
|
||||
[-0.080025, 0.336110, 56, 65, 255],
|
||||
[0.075454, -0.198921, 3, 167, 255],
|
||||
[-0.116609, 0.061735, 11, 111, 255],
|
||||
[-0.034296, 0.093744, 56, 65, 255],
|
||||
[-0.203495, 0.162338, 56, 65, 255],
|
||||
[-0.057161, 0.230932, 56, 65, 255],
|
||||
[-0.098318, -0.345256, 3, 167, 255],
|
||||
[-0.166911, 0.148619, 56, 65, 255],
|
||||
[0.043443, 0.340682, 11, 111, 255],
|
||||
[-0.185204, -0.317818, 3, 167, 255],
|
||||
[0.038869, -0.313245, 0, 215, 232],
|
||||
[0.066307, 0.098318, 3, 167, 255],
|
||||
[-0.377265, -0.144046, 11, 111, 255],
|
||||
[-0.016006, -0.267515, 0, 215, 232],
|
||||
[-0.272088, -0.176057, 11, 111, 255],
|
||||
[-0.089172, 0.194349, 56, 65, 255],
|
||||
[0.125756, -0.253796, 0, 215, 232],
|
||||
[0.395557, 0.002286, 0, 215, 232],
|
||||
[0.208067, 0.061735, 3, 167, 255],
|
||||
[0.281235, 0.171485, 3, 167, 255],
|
||||
[-0.267516, -0.134901, 11, 111, 255],
|
||||
[0.116610, -0.208068, 0, 215, 232],
|
||||
[-0.020578, -0.345256, 0, 215, 232],
|
||||
[0.157766, 0.134900, 3, 167, 255],
|
||||
[-0.057162, -0.249225, 3, 167, 255],
|
||||
[-0.317818, 0.198922, 56, 65, 255],
|
||||
[0.244650, 0.258369, 11, 111, 255],
|
||||
[-0.048016, 0.144047, 11, 111, 255],
|
||||
[-0.194350, -0.226359, 3, 167, 255],
|
||||
[0.070880, -0.249225, 0, 215, 232],
|
||||
[0.166911, -0.043443, 3, 167, 255],
|
||||
[0.025150, 0.093744, 11, 111, 255],
|
||||
[0.029724, -0.194350, 0, 215, 232],
|
||||
[-0.157765, 0.317818, 76, 25, 214],
|
||||
[0.061735, 0.006860, 11, 111, 255],
|
||||
[0.313244, 0.125755, 0, 215, 232],
|
||||
[-0.112036, 0.299525, 56, 65, 255],
|
||||
[-0.363547, 0.006860, 56, 65, 255],
|
||||
[-0.386411, -0.011432, 56, 65, 255],
|
||||
[0.102891, 0.043443, 3, 167, 255],
|
||||
[-0.203495, 0.267516, 56, 65, 255],
|
||||
[-0.308672, -0.208068, 11, 111, 255],
|
||||
[-0.308672, -0.112037, 11, 111, 255],
|
||||
[-0.326964, -0.011432, 56, 65, 255],
|
||||
[0.134901, 0.290380, 11, 111, 255],
|
||||
[-0.061734, 0.112036, 56, 65, 255],
|
||||
[-0.262943, -0.221787, 3, 167, 255],
|
||||
[0.153193, -0.011432, 3, 167, 255],
|
||||
[0.409276, 0.048016, 0, 215, 232],
|
||||
[0.368119, 0.102891, 3, 167, 255],
|
||||
[-0.171484, 0.244650, 56, 65, 255],
|
||||
[-0.098318, 0.148619, 56, 65, 255],
|
||||
[-0.148619, 0.212641, 56, 65, 255],
|
||||
[-0.102890, 0.267516, 56, 65, 255],
|
||||
[-0.308672, -0.157765, 11, 111, 255],
|
||||
[0.390985, 0.029724, 0, 215, 232],
|
||||
[0.089172, 0.304099, 11, 111, 255],
|
||||
[-0.144047, -0.354401, 3, 167, 255],
|
||||
[-0.290381, -0.130328, 11, 111, 255],
|
||||
[-0.336109, 0.048016, 56, 65, 255],
|
||||
[-0.294953, 0.230932, 76, 25, 214],
|
||||
[0.171485, 0.093744, 3, 167, 255],
|
||||
[-0.354400, -0.043443, 56, 65, 255],
|
||||
[0.043442, 0.139474, 11, 111, 255],
|
||||
[-0.148620, 0.262943, 56, 65, 255],
|
||||
[-0.029725, 0.272088, 56, 65, 255],
|
||||
[0.171485, 0.043443, 3, 167, 255],
|
||||
[0.198922, 0.290380, 11, 111, 255],
|
||||
[0.080025, 0.358974, 11, 111, 255],
|
||||
[-0.043443, -0.304100, 0, 215, 232],
|
||||
[-0.230932, 0.208068, 56, 65, 255],
|
||||
[0.153193, 0.112036, 3, 167, 255],
|
||||
[0.313244, -0.034296, 3, 167, 255],
|
||||
[-0.304098, -0.034296, 56, 65, 255],
|
||||
[-0.386412, 0.125755, 76, 25, 214],
|
||||
[-0.038869, 0.363547, 56, 65, 255],
|
||||
[-0.294954, -0.185203, 11, 111, 255],
|
||||
[-0.212641, 0.116610, 56, 65, 255],
|
||||
[-0.070881, 0.057161, 56, 65, 255],
|
||||
[0.075454, 0.029724, 11, 111, 255],
|
||||
[0.363547, 0.153193, 3, 167, 255],
|
||||
[0.244650, 0.281235, 11, 111, 255],
|
||||
[-0.121183, 0.185204, 56, 65, 255],
|
||||
[-0.034297, 0.043443, 11, 111, 255],
|
||||
[0.363546, -0.038870, 0, 215, 232],
|
||||
[-0.166911, 0.194349, 56, 65, 255],
|
||||
[-0.052589, -0.349828, 0, 215, 232],
|
||||
[-0.313245, -0.249225, 11, 111, 255],
|
||||
[-0.011432, -0.230932, 3, 167, 255],
|
||||
[0.020579, -0.230932, 0, 215, 232],
|
||||
[-0.006859, 0.034297, 3, 167, 255],
|
||||
[-0.162339, 0.080025, 11, 111, 255],
|
||||
[-0.034297, 0.317818, 56, 65, 255],
|
||||
[-0.331537, -0.116609, 11, 111, 255],
|
||||
[0.230932, -0.057162, 0, 215, 232],
|
||||
[0.267516, -0.057162, 0, 215, 232],
|
||||
[0.189775, -0.038870, 3, 167, 255],
|
||||
[0.038869, 0.048016, 11, 111, 255],
|
||||
[0.400130, 0.075454, 0, 215, 232],
|
||||
[0.377266, 0.080025, 0, 215, 232],
|
||||
[0.326963, 0.171485, 3, 167, 255],
|
||||
[-0.253796, 0.249224, 76, 25, 214],
|
||||
[-0.011432, 0.230932, 11, 111, 255],
|
||||
[-0.217214, -0.230932, 3, 167, 255],
|
||||
[-0.230932, 0.084599, 56, 65, 255],
|
||||
[-0.212640, -0.272089, 3, 167, 255],
|
||||
[0.048016, -0.276662, 0, 215, 232],
|
||||
[0.253797, 0.061735, 3, 167, 255],
|
||||
[-0.048015, 0.185204, 11, 111, 255],
|
||||
[0.349828, 0.176057, 3, 167, 255],
|
||||
[-0.290380, 0.043443, 56, 65, 255],
|
||||
[0.034296, 0.198922, 11, 111, 255],
|
||||
[0.354401, -0.011432, 0, 215, 232],
|
||||
[-0.157766, 0.171485, 56, 65, 255],
|
||||
[-0.002287, 0.185204, 11, 111, 255],
|
||||
[-0.089172, -0.249225, 3, 167, 255],
|
||||
[-0.185203, -0.340682, 3, 167, 255],
|
||||
[-0.386412, 0.038869, 56, 65, 255],
|
||||
[0.066307, 0.075454, 11, 111, 255],
|
||||
[-0.166912, 0.125755, 56, 65, 255],
|
||||
[0.016005, -0.304100, 0, 215, 232],
|
||||
[0.107463, 0.121182, 3, 167, 255],
|
||||
[0.093744, 0.180630, 3, 167, 255],
|
||||
[0.221786, 0.299525, 11, 111, 255],
|
||||
[0.029724, 0.020579, 11, 111, 255],
|
||||
[-0.281234, 0.130329, 76, 25, 214],
|
||||
[-0.377265, 0.148619, 76, 25, 214],
|
||||
[0.070880, 0.212641, 11, 111, 255],
|
||||
[0.025150, 0.272088, 56, 65, 255],
|
||||
[-0.144046, 0.336110, 56, 65, 255],
|
||||
[-0.002287, 0.349829, 56, 65, 255],
|
||||
[-0.253796, -0.258370, 3, 167, 255],
|
||||
[-0.377265, 0.084599, 56, 65, 255],
|
||||
[-0.180630, -0.249225, 3, 167, 255],
|
||||
[-0.349828, -0.089171, 11, 111, 255],
|
||||
[-0.249225, 0.162338, 56, 65, 255],
|
||||
[-0.226359, -0.253796, 11, 111, 255],
|
||||
[-0.390984, -0.098318, 56, 65, 255],
|
||||
[0.230932, -0.034296, 3, 167, 255],
|
||||
[-0.144046, 0.089172, 11, 111, 255],
|
||||
[-0.345256, 0.180630, 56, 65, 255],
|
||||
[-0.272089, 0.212641, 76, 25, 214],
|
||||
[0.308672, 0.011432, 0, 215, 232],
|
||||
[0.294954, 0.240079, 11, 111, 255],
|
||||
[-0.340683, 0.125755, 56, 65, 255],
|
||||
[-0.121182, -0.299526, 3, 167, 255],
|
||||
[-0.340682, 0.089172, 56, 65, 255],
|
||||
[0.349829, 0.020579, 3, 167, 255],
|
||||
[0.176058, 0.272088, 11, 111, 255],
|
||||
[0.093744, 0.331536, 56, 65, 255],
|
||||
[-0.043443, 0.061735, 11, 111, 255],
|
||||
[0.061735, 0.121182, 11, 111, 255],
|
||||
[-0.308672, 0.098318, 56, 65, 255],
|
||||
[-0.354401, 0.153193, 56, 65, 255],
|
||||
[-0.121182, 0.162338, 56, 65, 255],
|
||||
[-0.230932, -0.317818, 3, 167, 255],
|
||||
[0.098318, 0.066307, 3, 167, 255],
|
||||
[0.157766, 0.070880, 3, 167, 255],
|
||||
[0.198922, 0.198922, 11, 111, 255],
|
||||
[0.212641, 0.249224, 11, 111, 255],
|
||||
[0.098318, -0.217214, 0, 215, 232],
|
||||
[0.262943, -0.025151, 0, 215, 232],
|
||||
[-0.285807, 0.166911, 56, 65, 255],
|
||||
[-0.189776, 0.194349, 56, 65, 255],
|
||||
[-0.194350, 0.221786, 56, 65, 255],
|
||||
[0.395557, -0.029725, 41, 247, 187],
|
||||
[-0.377265, -0.080026, 11, 111, 255],
|
||||
[-0.116609, -0.336109, 3, 167, 255],
|
||||
[-0.226359, -0.189776, 11, 111, 255],
|
||||
[-0.203494, -0.308671, 3, 167, 255],
|
||||
[-0.253796, 0.116610, 56, 65, 255],
|
||||
[-0.326964, -0.198921, 56, 65, 255],
|
||||
[0.006860, -0.345256, 0, 215, 232],
|
||||
[-0.212641, 0.180630, 56, 65, 255],
|
||||
[0.139473, 0.317818, 11, 111, 255],
|
||||
[-0.354400, -0.148620, 11, 111, 255],
|
||||
[0.048015, 0.272088, 11, 111, 255],
|
||||
[-0.340682, -0.180631, 11, 111, 255],
|
||||
[-0.153193, -0.317818, 3, 167, 255],
|
||||
[0.121182, 0.153193, 3, 167, 255],
|
||||
[0.171484, 0.326963, 11, 111, 255],
|
||||
[-0.285807, 0.006860, 56, 65, 255],
|
||||
[-0.304098, 0.061735, 56, 65, 255],
|
||||
[-0.093745, 0.285807, 56, 65, 255],
|
||||
[0.052588, -0.235506, 0, 215, 232],
|
||||
[-0.226359, -0.212640, 3, 167, 255],
|
||||
[-0.180631, 0.089172, 11, 111, 255],
|
||||
[-0.020578, -0.299526, 0, 215, 232],
|
||||
[0.070881, 0.180630, 11, 111, 255],
|
||||
[0.048016, 0.212641, 56, 65, 255],
|
||||
[-0.006860, 0.258369, 56, 65, 255],
|
||||
[-0.107464, 0.102891, 56, 65, 255],
|
||||
[-0.029724, 0.345255, 56, 65, 255],
|
||||
[-0.377266, -0.034296, 56, 65, 255],
|
||||
[-0.322391, 0.025150, 56, 65, 255],
|
||||
[-0.244651, 0.185204, 76, 25, 214],
|
||||
[-0.125756, -0.262943, 3, 167, 255],
|
||||
[-0.125756, 0.230932, 56, 65, 255],
|
||||
[0.235505, 0.006860, 3, 167, 255],
|
||||
[0.166911, 0.221786, 11, 111, 255],
|
||||
[-0.217214, 0.221786, 76, 25, 214],
|
||||
[-0.057162, -0.317818, 0, 215, 232],
|
||||
[0.093744, -0.249225, 0, 215, 232],
|
||||
[0.116609, 0.011432, 3, 167, 255],
|
||||
[0.144046, 0.011432, 3, 167, 255],
|
||||
[0.002286, 0.052588, 3, 167, 255],
|
||||
[0.057161, 0.057161, 11, 111, 255],
|
||||
[-0.372693, 0.112036, 76, 25, 214],
|
||||
[-0.185203, 0.112036, 56, 65, 255],
|
||||
[-0.020579, 0.112036, 11, 111, 255],
|
||||
[-0.089171, 0.125755, 11, 111, 255],
|
||||
[-0.272089, 0.153193, 56, 65, 255],
|
||||
[0.258369, 0.244650, 3, 167, 255],
|
||||
[0.016005, 0.290380, 56, 65, 255],
|
||||
[0.180630, 0.299525, 11, 111, 255],
|
||||
[0.006859, 0.368119, 56, 65, 255],
|
||||
[-0.349828, -0.006859, 56, 65, 255],
|
||||
[0.281234, 0.253797, 3, 167, 255],
|
||||
[-0.125755, 0.139474, 56, 65, 255],
|
||||
[-0.084600, 0.162338, 56, 65, 255],
|
||||
[-0.189775, 0.253797, 56, 65, 255],
|
||||
[-0.340682, -0.057162, 56, 65, 255],
|
||||
[-0.340682, -0.025151, 56, 65, 255],
|
||||
[-0.308671, 0.244650, 56, 65, 255],
|
||||
[-0.272088, 0.258369, 76, 25, 214],
|
||||
[0.322390, 0.208068, 3, 167, 255],
|
||||
[-0.240079, 0.130329, 56, 65, 255],
|
||||
[-0.313245, 0.153193, 56, 65, 255],
|
||||
[0.217213, 0.043443, 3, 167, 255],
|
||||
[-0.262943, -0.194350, 3, 167, 255],
|
||||
[0.166911, -0.235506, 0, 215, 232],
|
||||
[0.166912, 0.002286, 3, 167, 255],
|
||||
[0.112036, 0.194349, 11, 111, 255],
|
||||
[0.034297, -0.336109, 0, 215, 232],
|
||||
[-0.089172, -0.299526, 3, 167, 255],
|
||||
[-0.061734, -0.281234, 3, 167, 255],
|
||||
[-0.240078, 0.276661, 56, 65, 255],
|
||||
[0.002286, -0.272089, 3, 167, 255],
|
||||
[0.061735, -0.212640, 3, 167, 255],
|
||||
[0.089172, -0.011432, 3, 167, 255],
|
||||
[0.208068, 0.002286, 3, 167, 255],
|
||||
[0.304099, 0.034297, 0, 215, 232],
|
||||
[0.048016, 0.089172, 3, 167, 255],
|
||||
[0.098318, 0.102891, 3, 167, 255],
|
||||
[0.290380, 0.217213, 3, 167, 255],
|
||||
[-0.098318, -0.267515, 0, 215, 232],
|
||||
[-0.016005, 0.285807, 56, 65, 255],
|
||||
[0.125755, 0.345255, 56, 65, 255],
|
||||
[0.194349, -0.011432, 0, 215, 232],
|
||||
[-0.139475, -0.336109, 3, 167, 255],
|
||||
[0.043443, 0.180630, 11, 111, 255],
|
||||
[-0.176057, 0.322391, 56, 65, 255],
|
||||
[-0.240078, -0.290381, 3, 167, 255],
|
||||
[-0.189777, -0.267515, 3, 167, 255],
|
||||
[-0.404703, -0.061734, 56, 65, 255],
|
||||
[0.180630, 0.025150, 3, 167, 255],
|
||||
[0.290380, -0.002287, 3, 167, 255],
|
||||
[-0.011432, 0.080025, 11, 111, 255],
|
||||
[-0.400131, 0.084599, 76, 25, 214],
|
||||
[0.121183, -0.020578, 3, 167, 255],
|
||||
[0.107464, -0.006859, 3, 167, 255],
|
||||
[0.130329, 0.084599, 11, 111, 255],
|
||||
[-0.029725, 0.139474, 11, 111, 255],
|
||||
[-0.048016, 0.276661, 56, 65, 255],
|
||||
[-0.340682, 0.029724, 56, 65, 255],
|
||||
[-0.272089, 0.080025, 56, 65, 255],
|
||||
[0.121182, -0.189776, 3, 167, 255],
|
||||
[0.038870, 0.358974, 56, 65, 255],
|
||||
[0.354400, 0.134900, 3, 167, 255],
|
||||
[0.377266, -0.057162, 41, 247, 187],
|
||||
[0.340682, -0.052589, 0, 215, 232],
|
||||
[0.326963, -0.016006, 0, 215, 232],
|
||||
[0.134902, 0.107463, 3, 167, 255],
|
||||
[-0.038870, 0.235505, 56, 65, 255],
|
||||
[-0.281235, -0.226359, 11, 111, 255],
|
||||
[-0.185203, 0.153193, 56, 65, 255],
|
||||
[0.084599, -0.180631, 3, 167, 255],
|
||||
[0.130328, 0.048016, 3, 167, 255],
|
||||
[0.016005, 0.203494, 11, 111, 255],
|
||||
[-0.267516, -0.157765, 11, 111, 255],
|
||||
[0.025151, 0.162338, 11, 111, 255],
|
||||
[0.272088, 0.016005, 3, 167, 255],
|
||||
[-0.089171, -0.363546, 3, 167, 255],
|
||||
[-0.043443, -0.262943, 3, 167, 255],
|
||||
[-0.112037, 0.358974, 56, 65, 255],
|
||||
[-0.125756, 0.107463, 11, 111, 255],
|
||||
[-0.372693, -0.116609, 56, 65, 255],
|
||||
[-0.075453, 0.354400, 56, 65, 255],
|
||||
[0.144047, 0.034297, 3, 167, 255],
|
||||
[0.011432, 0.226360, 11, 111, 255],
|
||||
[0.025150, 0.240079, 11, 111, 255],
|
||||
[0.025150, -0.212640, 3, 167, 255],
|
||||
[-0.130328, 0.253797, 56, 65, 255],
|
||||
[-0.290381, -0.249225, 3, 167, 255],
|
||||
[-0.217214, 0.098318, 56, 65, 255],
|
||||
[-0.244651, -0.217214, 11, 111, 255],
|
||||
[-0.249225, -0.180631, 11, 111, 255],
|
||||
[0.208067, -0.034296, 3, 167, 255],
|
||||
[-0.107464, 0.317818, 56, 65, 255],
|
||||
[-0.221787, 0.240079, 56, 65, 255],
|
||||
[0.025152, -0.258370, 0, 215, 232],
|
||||
[-0.349828, -0.107464, 11, 111, 255],
|
||||
[0.153193, -0.029725, 3, 167, 255],
|
||||
[-0.139474, 0.171485, 56, 65, 255],
|
||||
[-0.326964, 0.180630, 56, 65, 255],
|
||||
[-0.409276, 0.016005, 56, 65, 255],
|
||||
[0.253797, 0.043443, 3, 167, 255],
|
||||
[0.098318, 0.162338, 11, 111, 255],
|
||||
[-0.048015, 0.166911, 11, 111, 255],
|
||||
[-0.285807, 0.185204, 56, 65, 255],
|
||||
[-0.011432, -0.249225, 3, 167, 255],
|
||||
[-0.180630, -0.299526, 3, 167, 255],
|
||||
[0.203494, 0.020579, 3, 167, 255],
|
||||
[-0.052589, -0.368120, 0, 215, 232],
|
||||
[-0.112037, -0.317818, 3, 167, 255],
|
||||
[-0.144047, -0.299526, 3, 167, 255],
|
||||
[-0.153192, -0.281234, 3, 167, 255],
|
||||
[-0.162339, -0.249225, 3, 167, 255],
|
||||
[-0.075453, 0.038869, 11, 111, 255],
|
||||
[-0.290380, 0.098318, 56, 65, 255],
|
||||
[-0.002286, 0.116610, 11, 111, 255],
|
||||
[-0.057162, 0.294954, 56, 65, 255],
|
||||
[0.413849, 0.002286, 0, 215, 232],
|
||||
[-0.125755, 0.336110, 56, 65, 255],
|
||||
[-0.336109, -0.139475, 11, 111, 255],
|
||||
[-0.176057, 0.285807, 56, 65, 255],
|
||||
[-0.075453, -0.317818, 0, 215, 232],
|
||||
[-0.157766, 0.230932, 56, 65, 255],
|
||||
[-0.336110, 0.144047, 56, 65, 255],
|
||||
[-0.107463, 0.080025, 11, 111, 255],
|
||||
[-0.070881, 0.089172, 11, 111, 255],
|
||||
[-0.130328, 0.203494, 56, 65, 255],
|
||||
[-0.075453, 0.299525, 56, 65, 255],
|
||||
[-0.331536, 0.212641, 76, 25, 214],
|
||||
[-0.253797, 0.066307, 56, 65, 255],
|
||||
[0.006860, 0.089172, 11, 111, 255],
|
||||
[0.084600, -0.267515, 0, 215, 232],
|
||||
[-0.276662, -0.262943, 3, 167, 255],
|
||||
[-0.304100, 0.134900, 76, 25, 214],
|
||||
[-0.317817, 0.002286, 56, 65, 255],
|
||||
[0.093744, 0.029724, 11, 111, 255],
|
||||
[0.226359, 0.061735, 3, 167, 255],
|
||||
[0.194348, 0.075454, 3, 167, 255],
|
||||
[-0.194350, 0.080025, 56, 65, 255],
|
||||
[0.107463, 0.084599, 3, 167, 255],
|
||||
[-0.016005, 0.171485, 11, 111, 255],
|
||||
[-0.304100, 0.212641, 56, 65, 255],
|
||||
[-0.006859, -0.336109, 3, 167, 255],
|
||||
[0.080025, 0.002286, 3, 167, 255],
|
||||
[0.253797, 0.002286, 0, 215, 232],
|
||||
[0.052588, -0.006859, 3, 167, 255],
|
||||
[-0.034296, 0.075454, 11, 111, 255],
|
||||
[-0.043443, 0.203494, 56, 65, 255],
|
||||
[-0.294953, -0.166912, 11, 111, 255],
|
||||
[-0.267516, 0.038869, 56, 65, 255],
|
||||
[-0.358975, 0.057161, 56, 65, 255],
|
||||
[0.299527, -0.048015, 0, 215, 232],
|
||||
[0.020578, 0.057161, 11, 111, 255],
|
||||
[0.144047, -0.212640, 0, 215, 232],
|
||||
[0.285807, 0.038869, 3, 167, 255],
|
||||
[0.185203, 0.102891, 3, 167, 255],
|
||||
[-0.203494, 0.144047, 56, 65, 255],
|
||||
[0.002287, 0.322391, 56, 65, 255],
|
||||
[-0.235506, 0.148619, 76, 25, 214],
|
||||
[-0.107464, 0.194349, 56, 65, 255],
|
||||
[-0.093745, 0.240079, 56, 65, 255],
|
||||
[0.235505, 0.029724, 3, 167, 255],
|
||||
[0.093744, -0.198921, 3, 167, 255],
|
||||
[-0.029723, -0.313245, 0, 215, 232],
|
||||
[-0.080026, -0.285807, 0, 215, 232],
|
||||
[-0.148620, 0.139474, 56, 65, 255],
|
||||
[-0.221786, 0.157766, 56, 65, 255],
|
||||
[-0.212641, 0.253797, 56, 65, 255],
|
||||
[0.048016, -0.349828, 0, 215, 232],
|
||||
[0.377266, -0.002287, 0, 215, 232],
|
||||
[0.381838, 0.116610, 3, 167, 255],
|
||||
[-0.057162, 0.130329, 11, 111, 255],
|
||||
[-0.070881, 0.189775, 11, 111, 255],
|
||||
[-0.070881, 0.217213, 11, 111, 255],
|
||||
[0.034296, 0.125755, 11, 111, 255],
|
||||
[0.006860, 0.134900, 11, 111, 255],
|
||||
[0.153193, -0.226359, 0, 215, 232],
|
||||
[0.057161, -0.262943, 3, 167, 255],
|
||||
[0.290380, -0.020578, 0, 215, 232],
|
||||
[0.043443, 0.011432, 3, 167, 255],
|
||||
[-0.372693, 0.025150, 56, 65, 255],
|
||||
[0.006860, 0.025150, 11, 111, 255],
|
||||
[0.066307, 0.043443, 3, 167, 255],
|
||||
[-0.253796, 0.048016, 56, 65, 255],
|
||||
[-0.322390, 0.057161, 56, 65, 255],
|
||||
[0.139474, 0.066307, 11, 111, 255],
|
||||
[0.240079, 0.070880, 0, 215, 232],
|
||||
[-0.345256, 0.107463, 56, 65, 255],
|
||||
[-0.226359, 0.189775, 56, 65, 255],
|
||||
[-0.272089, 0.194349, 76, 25, 214],
|
||||
[-0.098318, 0.208068, 11, 111, 255],
|
||||
[-0.020578, 0.208068, 56, 65, 255],
|
||||
[-0.258370, 0.221786, 56, 65, 255],
|
||||
[-0.185203, 0.235505, 56, 65, 255],
|
||||
[0.016005, 0.258369, 11, 111, 255],
|
||||
[-0.080026, -0.349828, 0, 215, 232],
|
||||
[-0.171484, -0.285807, 3, 167, 255],
|
||||
[0.034297, -0.240078, 3, 167, 255],
|
||||
[-0.322391, -0.235506, 11, 111, 255],
|
||||
[-0.299527, -0.144046, 11, 111, 255],
|
||||
[-0.340682, -0.075453, 56, 65, 255],
|
||||
[-0.313245, -0.052589, 11, 111, 255],
|
||||
[-0.400130, -0.043443, 56, 65, 255],
|
||||
[-0.317818, -0.025151, 56, 65, 255],
|
||||
[-0.354402, 0.020579, 56, 65, 255],
|
||||
[-0.043442, 0.029724, 11, 111, 255],
|
||||
[-0.400131, 0.048016, 76, 25, 214],
|
||||
[-0.285808, 0.066307, 56, 65, 255],
|
||||
[-0.134901, 0.075454, 56, 65, 255],
|
||||
[-0.066307, 0.153193, 56, 65, 255],
|
||||
[-0.285807, 0.244650, 76, 25, 214],
|
||||
[-0.006859, 0.016005, 3, 167, 255],
|
||||
[0.080025, 0.194349, 11, 111, 255],
|
||||
[0.093744, 0.221786, 56, 65, 255],
|
||||
[-0.368119, -0.052589, 56, 65, 255],
|
||||
[-0.144047, -0.267515, 3, 167, 255],
|
||||
[-0.052589, 0.098318, 11, 111, 255],
|
||||
[-0.107464, 0.226360, 56, 65, 255],
|
||||
[0.130328, 0.166911, 11, 111, 255],
|
||||
[-0.016006, 0.153193, 11, 111, 255],
|
||||
[-0.093745, 0.345255, 56, 65, 255],
|
||||
[-0.093745, 0.326963, 56, 65, 255],
|
||||
[-0.116609, -0.276662, 3, 167, 255],
|
||||
[0.381839, -0.038870, 0, 215, 232],
|
||||
[-0.020578, -0.363546, 0, 215, 232],
|
||||
[-0.171484, -0.313245, 3, 167, 255],
|
||||
[0.025152, 0.075454, 11, 111, 255],
|
||||
[-0.208068, -0.290381, 11, 111, 255],
|
||||
[-0.070881, 0.235505, 11, 111, 255],
|
||||
[0.038870, 0.235505, 11, 111, 255],
|
||||
[-0.139473, 0.281235, 56, 65, 255],
|
||||
[-0.294953, -0.212640, 11, 111, 255],
|
||||
[0.409277, -0.034296, 0, 215, 232],
|
||||
[0.212641, 0.089172, 3, 167, 255],
|
||||
[0.139474, -0.016006, 3, 167, 255],
|
||||
[-0.372692, -0.006859, 56, 65, 255],
|
||||
[0.107464, 0.025150, 3, 167, 255],
|
||||
[-0.075453, 0.116610, 11, 111, 255],
|
||||
[0.070880, 0.240079, 11, 111, 255],
|
||||
[0.002286, 0.294954, 56, 65, 255],
|
||||
[-0.400131, -0.016006, 76, 25, 214],
|
||||
[-0.294953, -0.102890, 11, 111, 255],
|
||||
[-0.336109, 0.066307, 76, 25, 214],
|
||||
[0.002287, -0.226359, 3, 167, 255],
|
||||
[-0.066307, 0.262943, 56, 65, 255],
|
||||
[-0.093745, 0.089172, 11, 111, 255],
|
||||
[-0.368120, -0.157765, 11, 111, 255],
|
||||
[-0.089171, -0.331537, 0, 215, 232],
|
||||
[0.331536, 0.016005, 0, 215, 232],
|
||||
[0.386411, 0.016005, 0, 215, 232],
|
||||
[0.304098, 0.208068, 3, 167, 255],
|
||||
[-0.313245, 0.121182, 56, 65, 255],
|
||||
[-0.034297, -0.349828, 0, 215, 232],
|
||||
[0.208068, 0.308672, 11, 111, 255],
|
||||
[0.308672, -0.061734, 0, 215, 232],
|
||||
[-0.226359, 0.066307, 56, 65, 255],
|
||||
[0.016005, -0.358975, 0, 215, 232],
|
||||
[-0.066307, -0.354401, 0, 215, 232],
|
||||
[-0.217213, -0.313245, 3, 167, 255],
|
||||
[-0.107464, -0.304100, 0, 215, 232],
|
||||
[-0.272089, -0.290381, 11, 111, 255],
|
||||
[-0.253796, -0.285807, 3, 167, 255],
|
||||
[-0.025151, -0.285807, 0, 215, 232],
|
||||
[-0.130328, -0.244651, 3, 167, 255],
|
||||
[0.139473, -0.244651, 0, 215, 232],
|
||||
[-0.258370, -0.235506, 3, 167, 255],
|
||||
[0.066307, -0.230932, 0, 215, 232],
|
||||
[0.121182, -0.230932, 0, 215, 232],
|
||||
[0.084599, -0.212640, 0, 215, 232],
|
||||
[-0.354402, -0.185203, 11, 111, 255],
|
||||
[-0.322391, -0.166912, 11, 111, 255],
|
||||
[-0.313245, -0.080026, 11, 111, 255],
|
||||
[0.326963, -0.038870, 0, 215, 232],
|
||||
[-0.299526, 0.029724, 56, 65, 255],
|
||||
[-0.066308, 0.326963, 56, 65, 255],
|
||||
[-0.052589, -0.331537, 0, 215, 232],
|
||||
[0.048016, -0.203495, 0, 215, 232],
|
||||
[-0.395557, 0.002286, 56, 65, 255],
|
||||
[0.020579, 0.002286, 11, 111, 255],
|
||||
[0.189775, 0.052588, 3, 167, 255],
|
||||
[0.166911, 0.057161, 11, 111, 255],
|
||||
[0.084599, 0.070880, 3, 167, 255],
|
||||
[0.084599, 0.098318, 3, 167, 255],
|
||||
[0.029724, 0.107463, 3, 167, 255],
|
||||
[0.358974, 0.121182, 3, 167, 255],
|
||||
[0.144047, 0.125755, 11, 111, 255],
|
||||
[0.089172, 0.134900, 11, 111, 255],
|
||||
[0.139474, 0.144047, 3, 167, 255],
|
||||
[0.061734, 0.166911, 11, 111, 255],
|
||||
[-0.358975, 0.185204, 76, 25, 214],
|
||||
[-0.304100, 0.194349, 56, 65, 255],
|
||||
[0.258369, 0.203494, 11, 111, 255],
|
||||
[0.134900, 0.240079, 11, 111, 255],
|
||||
[0.052588, 0.249224, 11, 111, 255],
|
||||
[-0.162339, 0.258369, 76, 25, 214],
|
||||
[-0.244651, 0.262943, 56, 65, 255],
|
||||
[0.057161, 0.345255, 11, 111, 255],
|
||||
[0.084599, 0.345255, 11, 111, 255],
|
||||
[-0.322390, 0.166911, 56, 65, 255],
|
||||
[-0.025151, 0.299525, 11, 111, 255],
|
||||
[0.230932, -0.006859, 3, 167, 255],
|
||||
[-0.025150, -0.331537, 0, 215, 232],
|
||||
[0.112036, -0.249225, 0, 215, 232],
|
||||
[0.267516, 0.034297, 0, 215, 232],
|
||||
[-0.098318, 0.061735, 11, 111, 255],
|
||||
[-0.208068, 0.130329, 56, 65, 255],
|
||||
[-0.084600, 0.180630, 56, 65, 255],
|
||||
[-0.258370, -0.208068, 11, 111, 255],
|
||||
[-0.313245, -0.098318, 11, 111, 255],
|
||||
[-0.267516, 0.093744, 56, 65, 255],
|
||||
[-0.267516, 0.121182, 56, 65, 255],
|
||||
[-0.390984, -0.066307, 11, 111, 255],
|
||||
[-0.354401, 0.084599, 76, 25, 214],
|
||||
[-0.249224, 0.098318, 56, 65, 255],
|
||||
[-0.226359, 0.125755, 56, 65, 255],
|
||||
[0.002286, 0.148619, 56, 65, 255],
|
||||
[-0.171484, 0.162338, 56, 65, 255],
|
||||
[-0.185203, 0.208068, 56, 65, 255],
|
||||
[-0.244650, 0.217213, 56, 65, 255],
|
||||
[-0.048016, 0.326963, 56, 65, 255],
|
||||
[0.116609, 0.052588, 3, 167, 255],
|
||||
[0.153193, 0.322391, 11, 111, 255],
|
||||
[0.107463, 0.336110, 56, 65, 255],
|
||||
[0.390984, -0.011432, 0, 215, 232],
|
||||
[0.267515, -0.038870, 0, 215, 232],
|
||||
[0.404703, 0.061735, 0, 215, 232],
|
||||
[0.011432, 0.102891, 11, 111, 255],
|
||||
[0.358973, -0.025151, 0, 215, 232],
|
||||
[0.176057, 0.080025, 3, 167, 255],
|
||||
[0.322391, 0.185204, 3, 167, 255],
|
||||
[-0.052589, 0.217213, 11, 111, 255],
|
||||
[-0.189776, 0.276661, 76, 25, 214],
|
||||
[-0.125756, 0.304099, 76, 25, 214],
|
||||
[-0.345256, -0.212640, 11, 111, 255],
|
||||
[-0.016005, 0.048016, 11, 111, 255],
|
||||
[-0.034296, 0.176057, 56, 65, 255],
|
||||
[-0.011432, 0.272088, 56, 65, 255],
|
||||
[-0.057161, 0.354400, 56, 65, 255],
|
||||
[-0.208068, 0.281235, 56, 65, 255],
|
||||
[0.322391, -0.002287, 0, 215, 232],
|
||||
[0.354402, 0.006860, 0, 215, 232],
|
||||
[0.034297, 0.034297, 11, 111, 255],
|
||||
[-0.006859, 0.066307, 11, 111, 255],
|
||||
[0.121182, 0.112036, 11, 111, 255],
|
||||
[-0.153193, 0.116610, 11, 111, 255],
|
||||
[0.116610, 0.134900, 11, 111, 255],
|
||||
[0.276661, 0.185204, 11, 111, 255],
|
||||
[-0.285807, 0.217213, 76, 25, 214],
|
||||
[0.235505, 0.226360, 11, 111, 255],
|
||||
[-0.048016, 0.308672, 56, 65, 255],
|
||||
[0.176058, 0.313244, 11, 111, 255],
|
||||
[-0.180631, 0.336110, 56, 65, 255],
|
||||
[-0.313244, -0.221787, 11, 111, 255],
|
||||
[-0.372693, 0.048016, 76, 25, 214],
|
||||
[-0.107464, -0.363546, 3, 167, 255],
|
||||
[-0.006859, -0.304100, 0, 215, 232],
|
||||
[-0.226359, -0.285807, 3, 167, 255],
|
||||
[-0.057162, -0.267515, 3, 167, 255],
|
||||
[-0.070881, -0.253796, 3, 167, 255],
|
||||
[-0.180631, -0.221787, 3, 167, 255],
|
||||
[-0.212640, -0.217214, 3, 167, 255],
|
||||
[-0.313245, -0.194350, 11, 111, 255],
|
||||
[-0.276662, -0.189776, 11, 111, 255],
|
||||
[0.070880, -0.185203, 3, 167, 255],
|
||||
[-0.322390, -0.148620, 11, 111, 255],
|
||||
[-0.368120, -0.130328, 56, 65, 255],
|
||||
[-0.304100, -0.125756, 11, 111, 255],
|
||||
[-0.276662, -0.121182, 11, 111, 255],
|
||||
[-0.363546, -0.084600, 11, 111, 255],
|
||||
[-0.390984, -0.029725, 56, 65, 255],
|
||||
[0.244650, -0.029725, 3, 167, 255],
|
||||
[-0.075453, 0.070880, 11, 111, 255],
|
||||
[-0.208068, 0.084599, 56, 65, 255],
|
||||
[-0.139475, 0.102891, 11, 111, 255],
|
||||
[-0.358975, 0.116610, 76, 25, 214],
|
||||
[-0.025150, 0.125755, 11, 111, 255],
|
||||
[-0.349828, 0.166911, 56, 65, 255],
|
||||
[-0.235506, 0.244650, 56, 65, 255],
|
||||
[-0.098317, 0.253797, 56, 65, 255],
|
||||
[-0.226359, 0.272088, 56, 65, 255],
|
||||
[0.020578, -0.340682, 0, 215, 232],
|
||||
[0.130328, 0.016005, 3, 167, 255],
|
||||
[0.395558, 0.043443, 0, 215, 232],
|
||||
[0.011433, 0.166911, 11, 111, 255],
|
||||
[-0.112037, 0.144047, 56, 65, 255],
|
||||
[-0.194349, 0.180630, 56, 65, 255],
|
||||
[-0.349828, -0.162339, 11, 111, 255],
|
||||
[-0.322390, 0.093744, 56, 65, 255],
|
||||
[-0.285807, 0.112036, 56, 65, 255],
|
||||
[-0.258370, 0.189775, 56, 65, 255],
|
||||
[-0.157765, -0.349828, 3, 167, 255],
|
||||
[0.002287, -0.322390, 0, 215, 232],
|
||||
[-0.235505, -0.304100, 3, 167, 255],
|
||||
[0.093745, -0.230932, 0, 215, 232],
|
||||
[0.180631, -0.006859, 3, 167, 255],
|
||||
[-0.299525, 0.162338, 56, 65, 255],
|
||||
[-0.144046, 0.313244, 76, 25, 214],
|
||||
[0.134900, 0.331536, 11, 111, 255],
|
||||
[0.157766, 0.038869, 3, 167, 255],
|
||||
[-0.038870, 0.253797, 56, 65, 255],
|
||||
[-0.153193, -0.235506, 11, 111, 255],
|
||||
[-0.157765, 0.066307, 11, 111, 255],
|
||||
[-0.116609, 0.258369, 56, 65, 255],
|
||||
[-0.153192, 0.157766, 56, 65, 255],
|
||||
[-0.390985, 0.070880, 56, 65, 255],
|
||||
[-0.349828, 0.139474, 56, 65, 255],
|
||||
[-0.331536, 0.194349, 76, 25, 214],
|
||||
[-0.198922, 0.066307, 56, 65, 255],
|
||||
[-0.134902, 0.217213, 56, 65, 255],
|
||||
[0.244652, -0.057162, 0, 215, 232],
|
||||
[0.048016, 0.125755, 3, 167, 255],
|
||||
[-0.198922, 0.116610, 56, 65, 255],
|
||||
[-0.020578, 0.317818, 56, 65, 255],
|
||||
[-0.057161, 0.057161, 11, 111, 255],
|
||||
[0.340683, -0.016006, 0, 215, 232],
|
||||
[0.212640, 0.075454, 3, 167, 255],
|
||||
[0.020579, 0.130329, 11, 111, 255],
|
||||
[-0.075454, 0.313244, 56, 65, 255],
|
||||
[-0.006859, -0.349828, 0, 215, 232],
|
||||
[0.075453, 0.016005, 3, 167, 255],
|
||||
[-0.034297, 0.107463, 11, 111, 255],
|
||||
[-0.052589, 0.244650, 11, 111, 255],
|
||||
[-0.162339, 0.272088, 56, 65, 255],
|
||||
[0.002286, 0.308672, 11, 111, 255],
|
||||
[-0.034296, 0.331536, 56, 65, 255],
|
||||
[-0.016005, 0.354400, 56, 65, 255],
|
||||
[-0.299525, 0.002286, 56, 65, 255],
|
||||
[-0.102890, -0.331537, 3, 167, 255],
|
||||
[-0.281234, -0.276662, 3, 167, 255],
|
||||
[-0.253796, -0.272089, 11, 111, 255],
|
||||
[-0.029725, -0.267515, 3, 167, 255],
|
||||
[-0.112037, -0.262943, 3, 167, 255],
|
||||
[0.070880, -0.262943, 0, 215, 232],
|
||||
[-0.240078, -0.258370, 11, 111, 255],
|
||||
[-0.043443, -0.249225, 0, 215, 232],
|
||||
[0.020579, -0.244651, 3, 167, 255],
|
||||
[-0.180631, -0.235506, 11, 111, 255],
|
||||
[0.130329, -0.212640, 0, 215, 232],
|
||||
[-0.294953, -0.198921, 11, 111, 255],
|
||||
[0.061735, -0.198921, 0, 215, 232],
|
||||
[-0.326964, -0.080026, 56, 65, 255],
|
||||
[-0.299526, -0.070881, 56, 65, 255],
|
||||
[-0.372693, -0.066307, 11, 111, 255],
|
||||
[-0.326964, -0.052589, 56, 65, 255],
|
||||
[0.281235, -0.048015, 0, 215, 232],
|
||||
[0.294954, -0.034296, 3, 167, 255],
|
||||
[0.189775, -0.025151, 0, 215, 232],
|
||||
[0.230932, -0.020578, 0, 215, 232],
|
||||
[0.276661, -0.020578, 0, 215, 232],
|
||||
[-0.313245, -0.011432, 56, 65, 255],
|
||||
[0.258369, -0.011432, 0, 215, 232],
|
||||
[-0.349828, 0.006860, 56, 65, 255],
|
||||
[0.221786, 0.006860, 0, 215, 232],
|
||||
[0.400130, 0.016005, 0, 215, 232],
|
||||
[-0.020578, 0.034297, 11, 111, 255],
|
||||
[0.052588, 0.043443, 11, 111, 255],
|
||||
[-0.130328, 0.061735, 11, 111, 255],
|
||||
[-0.363547, 0.070880, 56, 65, 255],
|
||||
[-0.240078, 0.070880, 56, 65, 255],
|
||||
[-0.308671, 0.075454, 76, 25, 214],
|
||||
[-0.121182, 0.075454, 11, 111, 255],
|
||||
[-0.377265, 0.098318, 76, 25, 214],
|
||||
[-0.020579, 0.098318, 11, 111, 255],
|
||||
[-0.326964, 0.121182, 76, 25, 214],
|
||||
[-0.125756, 0.121182, 56, 65, 255],
|
||||
[0.089172, 0.148619, 11, 111, 255],
|
||||
[0.057162, 0.180630, 11, 111, 255],
|
||||
[-0.084600, 0.208068, 56, 65, 255],
|
||||
[0.070880, 0.226360, 11, 111, 255],
|
||||
[-0.025151, 0.230932, 56, 65, 255],
|
||||
[-0.258370, 0.235505, 76, 25, 214],
|
||||
[-0.157766, 0.244650, 56, 65, 255],
|
||||
[-0.011432, 0.244650, 56, 65, 255],
|
||||
[-0.272089, 0.272088, 56, 65, 255],
|
||||
[-0.144046, 0.349829, 76, 25, 214],
|
||||
[0.020578, 0.368119, 56, 65, 255],
|
||||
[-0.340682, -0.038870, 56, 65, 255],
|
||||
[-0.331537, 0.226360, 76, 25, 214],
|
||||
[-0.317818, 0.212641, 76, 25, 214],
|
||||
[0.057162, -0.249225, 0, 215, 232],
|
||||
[-0.066307, 0.340682, 56, 65, 255],
|
||||
[-0.171484, 0.230932, 76, 25, 214],
|
||||
[-0.194348, -0.240078, 3, 167, 255],
|
||||
[-0.281234, -0.139475, 11, 111, 255],
|
||||
[-0.294953, -0.116609, 11, 111, 255],
|
||||
[0.107463, -0.198921, 0, 215, 232],
|
||||
[-0.043442, 0.349829, 56, 65, 255],
|
||||
[-0.386412, 0.052588, 56, 65, 255],
|
||||
[0.377266, 0.093744, 3, 167, 255],
|
||||
[0.240079, 0.148619, 11, 111, 255],
|
||||
[0.267516, 0.253797, 3, 167, 255],
|
||||
[0.253797, 0.267516, 3, 167, 255],
|
||||
];
|
||||
@@ -3,7 +3,8 @@ import { compilePetTelemetry, decodePetJSONL, PetLiveTape } from './pet-telemetr
|
||||
import { ARCH_OF, digest, layout, PetSim } from './pet-sim.js';
|
||||
import { renderPetPCM, type PetVoice } from './pet-audio.js';
|
||||
import { PetEngineTelemetry, type EngineOwnerProjection } from './pet-engine.js';
|
||||
import { blendDotFields, dotFieldKey, projectDotField, type DotField } from './dot-field.js';
|
||||
import { blendDotFields, dotFieldKey, projectDotField, textLanguage, type DotField, type DotOptions } from './dot-field.js';
|
||||
import { DOT_LABELS, type GlyphLanguage } from './dot-glyphs.js';
|
||||
|
||||
/** Synchronous native boundary: JSON state and directly transferable PCM.
|
||||
* Native hosts share the actual world / score implementation, not a rewrite. */
|
||||
@@ -12,6 +13,7 @@ export class PetNative {
|
||||
private engine = new PetEngineTelemetry();
|
||||
private expressionActivity = this.engine.activity(0);
|
||||
private expressionTransition?: { at: number; from: DotField };
|
||||
private expressionOptions: Required<DotOptions> = { bodyStyle: 'smooth', textLanguage: 'en' };
|
||||
private engineTick = 0;
|
||||
private segment?: PetSegment;
|
||||
private liveTape = new PetLiveTape();
|
||||
@@ -26,7 +28,7 @@ export class PetNative {
|
||||
snapshot(): string { return JSON.stringify({ ...this.world.frame, voices: this.world.voices, digest: digest(this.world.sim) }); }
|
||||
private expression(): DotField {
|
||||
const { frame } = this.world;
|
||||
const target = projectDotField(this.expressionActivity, frame.timeMs, false, this.expressionTransition?.at ?? 0);
|
||||
const target = projectDotField(this.expressionActivity, frame.timeMs, false, this.expressionTransition?.at ?? 0, this.expressionOptions);
|
||||
return this.expressionTransition
|
||||
? blendDotFields(this.expressionTransition.from, target, (frame.timeMs - this.expressionTransition.at) / 560)
|
||||
: target;
|
||||
@@ -38,7 +40,15 @@ export class PetNative {
|
||||
}
|
||||
/** View-only projection. Display cadence and accessibility preferences never
|
||||
* advance the owner, consume randomness, or change its score/checkpoint. */
|
||||
presentation(): string {
|
||||
presentation(options: DotOptions = {}, interfaceLanguage = 'en'): string {
|
||||
if (!['smooth', 'pixel'].includes(options.bodyStyle ?? 'smooth')
|
||||
|| !['auto', 'en', 'zh-Hans', 'zh-Hant', 'ja'].includes(options.textLanguage ?? 'auto'))
|
||||
throw new Error('Invalid pet presentation preferences.');
|
||||
const next = { bodyStyle: options.bodyStyle ?? 'smooth', textLanguage: textLanguage(options.textLanguage, interfaceLanguage) };
|
||||
if (next.bodyStyle !== this.expressionOptions.bodyStyle || next.textLanguage !== this.expressionOptions.textLanguage) {
|
||||
const from = this.expression(); this.expressionOptions = next;
|
||||
this.expressionTransition = { at: this.world.frame.timeMs, from };
|
||||
}
|
||||
const { sim, frame } = this.world;
|
||||
const activity = this.engine.activity(frame.timeMs);
|
||||
const observed = activity.observed && activity.freshness === 'fresh';
|
||||
@@ -52,9 +62,13 @@ export class PetNative {
|
||||
podSlots: peers.length >= 3 ? peers.map(p => [[0, 2, 4, 1, 3, 5][p.slot], p.phase] as const) : undefined });
|
||||
this.stillProjection = { key, style: still.frame };
|
||||
}
|
||||
const still = projectDotField(activity, frame.timeMs, true);
|
||||
const still = projectDotField(activity, frame.timeMs, true, 0, this.expressionOptions);
|
||||
const language = this.expressionOptions.textLanguage as GlyphLanguage;
|
||||
const label = activity.authoritativePresence === 'needs_you' ? 'waiting'
|
||||
: activity.authoritativePresence === 'done' ? 'done' : activity.activityKind;
|
||||
return JSON.stringify({ ...frame, digest: digest(sim), state, style: { ...sim.frame, hollow: !observed }, activity,
|
||||
...this.expression(),
|
||||
...this.expression(), displayLanguage: language,
|
||||
displayPhrase: observed && label ? DOT_LABELS[language][label] : '',
|
||||
still: { ...still, style: { ...this.stillProjection.style, hollow: !observed }, state } });
|
||||
}
|
||||
/** Losing a producer invalidates outstanding coverage, never the creature. */
|
||||
|
||||
Reference in new issue
Block a user