@oharness/server 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/analytics.d.ts +32 -29
  2. package/dist/analytics.js +225 -278
  3. package/dist/analytics.js.map +1 -1
  4. package/dist/i18n.js +152 -8
  5. package/dist/i18n.js.map +1 -1
  6. package/dist/icons.js +1 -0
  7. package/dist/icons.js.map +1 -1
  8. package/dist/model-order.js +1 -0
  9. package/dist/model-order.js.map +1 -1
  10. package/dist/page/client/account.js +140 -4
  11. package/dist/page/client/account.js.map +1 -1
  12. package/dist/page/client/base.js +40 -16
  13. package/dist/page/client/base.js.map +1 -1
  14. package/dist/page/client/browser.js +1 -1
  15. package/dist/page/client/composer.js +111 -7
  16. package/dist/page/client/composer.js.map +1 -1
  17. package/dist/page/client/dialogs.js +75 -0
  18. package/dist/page/client/dialogs.js.map +1 -1
  19. package/dist/page/client/events.js +25 -2
  20. package/dist/page/client/events.js.map +1 -1
  21. package/dist/page/client/index.js +4 -0
  22. package/dist/page/client/index.js.map +1 -1
  23. package/dist/page/client/panels.js +4 -4
  24. package/dist/page/client/ripple.d.ts +13 -0
  25. package/dist/page/client/ripple.js +247 -0
  26. package/dist/page/client/ripple.js.map +1 -0
  27. package/dist/page/client/routines.js +173 -41
  28. package/dist/page/client/routines.js.map +1 -1
  29. package/dist/page/client/shell.js +200 -54
  30. package/dist/page/client/shell.js.map +1 -1
  31. package/dist/page/client/state.js +7 -2
  32. package/dist/page/client/state.js.map +1 -1
  33. package/dist/page/client/terminal.js +34 -7
  34. package/dist/page/client/terminal.js.map +1 -1
  35. package/dist/page/client/theme.d.ts +17 -0
  36. package/dist/page/client/theme.js +365 -0
  37. package/dist/page/client/theme.js.map +1 -0
  38. package/dist/page/client/transcript.js +63 -7
  39. package/dist/page/client/transcript.js.map +1 -1
  40. package/dist/page/style.js +183 -22
  41. package/dist/page/style.js.map +1 -1
  42. package/dist/page.js +4 -5
  43. package/dist/page.js.map +1 -1
  44. package/dist/prefs.d.ts +17 -0
  45. package/dist/prefs.js +5 -0
  46. package/dist/prefs.js.map +1 -1
  47. package/dist/server.js +465 -42
  48. package/dist/server.js.map +1 -1
  49. package/dist/suggest.d.ts +42 -0
  50. package/dist/suggest.js +215 -0
  51. package/dist/suggest.js.map +1 -0
  52. package/dist/terminal.d.ts +28 -2
  53. package/dist/terminal.js +45 -3
  54. package/dist/terminal.js.map +1 -1
  55. package/dist/theme-assets.d.ts +39 -0
  56. package/dist/theme-assets.js +109 -0
  57. package/dist/theme-assets.js.map +1 -0
  58. package/dist/theme-store.d.ts +50 -0
  59. package/dist/theme-store.js +124 -0
  60. package/dist/theme-store.js.map +1 -0
  61. package/dist/theme-tools.d.ts +25 -0
  62. package/dist/theme-tools.js +243 -0
  63. package/dist/theme-tools.js.map +1 -0
  64. package/dist/turn-shots.d.ts +18 -2
  65. package/dist/turn-shots.js +10 -1
  66. package/dist/turn-shots.js.map +1 -1
  67. package/dist/user-theme.d.ts +143 -0
  68. package/dist/user-theme.js +510 -0
  69. package/dist/user-theme.js.map +1 -0
  70. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"model-order.js","sourceRoot":"","sources":["../src/model-order.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-order.js","sourceRoot":"","sources":["../src/model-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,6FAA6F;AAC7F,MAAM,eAAe,GAAG;IACtB,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,UAAU;IACV,MAAM;IACN,YAAY;IACZ,MAAM;IACN,gBAAgB;IAChB,YAAY;IACZ,WAAW;CACZ,CAAC;AAEF,8EAA8E;AAC9E,MAAM,eAAe,GAA2B;IAC9C,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;IAChB,cAAc,EAAE,QAAQ;IACxB,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,MAAM;IACZ,kBAAkB,EAAE,MAAM;IAC1B,QAAQ,EAAE,YAAY;IACtB,aAAa,EAAE,YAAY;IAC3B,GAAG,EAAE,MAAM;IACX,YAAY,EAAE,MAAM;IACpB,QAAQ,EAAE,gBAAgB;IAC1B,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,YAAY;CACpB,CAAC;AAEF,iFAAiF;AACjF,MAAM,aAAa,GAAuB;IACxC,CAAC,SAAS,EAAE,WAAW,CAAC;IACxB,CAAC,0BAA0B,EAAE,QAAQ,CAAC;IACtC,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC7B,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,WAAW,EAAE,UAAU,CAAC;IACzB,CAAC,aAAa,EAAE,MAAM,CAAC;IACvB,CAAC,kBAAkB,EAAE,YAAY,CAAC;IAClC,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,qBAAqB,EAAE,gBAAgB,CAAC;IACzC,CAAC,QAAQ,EAAE,YAAY,CAAC;IACxB,CAAC,mDAAmD,EAAE,WAAW,CAAC;CACnE,CAAC;AAEF,6FAA6F;AAC7F,MAAM,YAAY,GAAG;IACnB,cAAc;IACd,aAAa;IACb,eAAe;IACf,cAAc;IACd,KAAK;IACL,QAAQ;IACR,OAAO;IACP,MAAM;IACN,UAAU;IACV,MAAM;IACN,MAAM;IACN,KAAK;CACN,CAAC;AAYF,MAAM,IAAI,GAAG,mCAAmC,CAAC;AAEjD,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,QAAgB;IACrD,IAAI,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9E,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,GAAG,IAAI,CAAC;YACb,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,sEAAsE;IACtE,6DAA6D;IAC7D,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACrD,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,IAAI,CAAC,MAAM;QAAE,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvG,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAC/E,CAAC;IACD,OAAO;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,OAAO,EAAE,SAAS,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;QAChD,MAAM,EAAE,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAC5C,QAAQ;QACR,OAAO;KACR,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACnC,oEAAoE;IACpE,IAAI,IAAwB,CAAC;IAC7B,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;IAChB,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC/B,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YACvG,IAAI,GAAG,CAAC,CAAC;YACT,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvG,+EAA+E;AAC/E,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,CAAC;IACrD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAW,EAAE,CAAW;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,CAAqB,EAAE,CAAqB;IAC7D,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,MAAc,EAAE,QAAgB;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAElC,MAAW;IACX,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CACpF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC3C,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;QACzB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;QACzB,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC;QACxD,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC;QACxD,OAAO,CACL,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE;YAC/D,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;YACnC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC;YACrC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC;YACrE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;YACnC,EAAE,GAAG,EAAE;YACP,mBAAmB,CACjB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,EAAE,CAAE,EACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,EAAE,CAAE,CACvD;YACD,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;YACrD,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;YAC3C,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC;YAClC,MAAM,CAAC,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC;YACvD,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC;YACtC,MAAM,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;YACrD,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC;YACpC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -215,6 +215,21 @@ async function showModels() {
215
215
  return go;
216
216
  };
217
217
 
218
+ // What this vendor has cost lately, from this machine's own records — the
219
+ // question a pasted key leaves open, answered where the key is.
220
+ if (provider.spend30d >= 0.01) {
221
+ const spent = el("div", "muted small");
222
+ spent.appendChild(document.createTextNode(t("models.spend30d", { amount: moneyOf(Math.round(provider.spend30d * 100), "usd") }) + " "));
223
+ const more = el("button", "cn-inline", t("models.spendDetail"));
224
+ more.type = "button";
225
+ more.addEventListener("click", (e) => {
226
+ e.stopPropagation();
227
+ document.getElementById("nav-usage").click();
228
+ });
229
+ spent.appendChild(more);
230
+ cardBody.appendChild(spent);
231
+ }
232
+
218
233
  if (provider.readiness === "no-account-system") {
219
234
  cardBody.appendChild(el("div", "muted small", t("models.noAccounts")));
220
235
  cardBody.appendChild(el("div", "muted small", t("models.noAccountsHow")));
@@ -229,6 +244,8 @@ async function showModels() {
229
244
  cardBody.appendChild(signInButton());
230
245
  } else if (provider.signIn && (!provider.configured || String(provider.source || "").startsWith("env:"))) {
231
246
  cardBody.appendChild(signInButton());
247
+ } else if (provider.vendorSignIn && !provider.configured) {
248
+ cardBody.appendChild(vendorSignIn(provider, null, null));
232
249
  }
233
250
 
234
251
  // The key field, for every vendor that takes one — the account plans
@@ -236,7 +253,7 @@ async function showModels() {
236
253
  // and spends the same balance, and CI needs one because it does not
237
254
  // expire. This is where it belongs, next to every other vendor's key
238
255
  // field, rather than inside the sign-in dialog.
239
- if (!provider.configured || String(provider.source || "").startsWith("env:")) {
256
+ if (!keyless(provider) && (!provider.configured || String(provider.source || "").startsWith("env:"))) {
240
257
  const row = el("div", "keyrow");
241
258
  const field = document.createElement("input");
242
259
  // type=password so the key is not left legible on a screen, and
@@ -467,6 +484,12 @@ function openConnect(providerId, thenModel) {
467
484
  document.getElementById("cn-title").textContent = provider.signIn && provider.readiness !== "no-account-system"
468
485
  ? t("models.signIn")
469
486
  : provider.label || provider.id;
487
+ // A vendor's own sign-in is that vendor's page the user is about to visit,
488
+ // so the dialog carries its mark: recognising the logo is most of what
489
+ // makes "sign in with" feel safe to click.
490
+ if (!provider.signIn && provider.vendorSignIn) {
491
+ document.getElementById("cn-title").prepend(providerMark(provider.id, provider.label || provider.id, "cn-title-mark"));
492
+ }
470
493
  // What this dialog is answering. A credential that ran out and one that was
471
494
  // never created both arrive here, and telling someone to "sign in" when what
472
495
  // happened is "your session ended" leaves them wondering whether the first
@@ -594,6 +617,54 @@ function openConnect(providerId, thenModel) {
594
617
  const siteButton = site.querySelector("button");
595
618
  const orCode = el("div", "cn-note", ts("models.orCode"));
596
619
 
620
+ // A vendor's own sign-in, above the key field it makes optional — or, for a
621
+ // vendor with no key at all, in place of it.
622
+ const vendor = mode === "key" && provider.vendorSignIn
623
+ ? vendorSignIn(
624
+ provider,
625
+ () => {
626
+ if (dialog.open) void done("signed in to " + provider.id + " — discovering its models…");
627
+ },
628
+ (reason) => {
629
+ hint.textContent = reason;
630
+ hint.hidden = false;
631
+ },
632
+ )
633
+ : null;
634
+ const noKey = keyless(provider);
635
+ const orKey = vendor && !noKey ? el("div", "cn-note", t("models.orPasteKey")) : null;
636
+ // What signing in hands over, said where the hesitation is: right under the
637
+ // button. Only when the sign-in is the whole dialog — beside a key field the
638
+ // key's own note says the same, and two padlocks in a row read as clutter.
639
+ let vendorLocal = null;
640
+ if (vendor && noKey) {
641
+ vendorLocal = el("div", "cn-note cn-local");
642
+ vendorLocal.appendChild(svgIcon("lock"));
643
+ const words = el("span");
644
+ words.appendChild(el("strong", null, t("models.vendorLocalLead", { provider: provider.label || provider.id })));
645
+ words.appendChild(document.createTextNode(t("models.vendorLocalRest")));
646
+ vendorLocal.appendChild(words);
647
+ }
648
+ // Someone with a Claude plan arrives here looking for a way to use it, and
649
+ // a key field alone says nothing to them. The plan works in Claude Code and
650
+ // not in other apps, so the honest answer is a door to Claude Code — their
651
+ // own install, in this project's terminal — rather than a login of ours.
652
+ let claudePlan = null;
653
+ if (provider.id === "anthropic" && currentCwd) {
654
+ claudePlan = el("div", "cn-note");
655
+ claudePlan.appendChild(document.createTextNode(t("models.claudePlan") + " "));
656
+ const open = el("button", "cn-inline", t("models.claudePlanOpen"));
657
+ open.type = "button";
658
+ open.onclick = () => {
659
+ dialog.close();
660
+ void openClaudeCode(currentCwd);
661
+ };
662
+ claudePlan.appendChild(open);
663
+ }
664
+ // The sign-in is the whole dialog then, and the × already closes it: a
665
+ // Cancel alone in the actions row only read as a button left behind.
666
+ dialog.classList.toggle("cn-keyless", noKey);
667
+
597
668
  /**
598
669
  * What the dialog opens focused.
599
670
  *
@@ -606,7 +677,13 @@ function openConnect(providerId, thenModel) {
606
677
  // no account system it is the one that fetches a key, which is the same
607
678
  // shape of thing and deserves the same treatment. The field is where the
608
679
  // cursor goes only when pasting is what is left.
609
- const opener = mode === "account" && !flow ? siteButton : noAccounts ? keyButton : undefined;
680
+ const opener = mode === "account" && !flow
681
+ ? siteButton
682
+ : noAccounts
683
+ ? keyButton
684
+ : vendor
685
+ ? vendor.querySelector("button")
686
+ : undefined;
610
687
  if (opener) opener.focus();
611
688
  else field.focus();
612
689
  };
@@ -665,7 +742,16 @@ function openConnect(providerId, thenModel) {
665
742
  // button above the field: whichever control is the way in carries the
666
743
  // colour, and the actions row holds the fallback. Two filled buttons make
667
744
  // the reader choose by position, and position would pick the wrong one.
668
- save.classList.toggle("approve", mode === "key" && !noAccounts);
745
+ save.classList.toggle("approve", mode === "key" && !noAccounts && !vendor);
746
+ // Nothing to paste for a vendor that takes no key: the sign-in above is
747
+ // the whole dialog, and a field beside it could only ever be refused.
748
+ field.hidden = noKey;
749
+ save.hidden = noKey;
750
+ if (noKey) {
751
+ why.hidden = true;
752
+ keptLocal.hidden = true;
753
+ docs.hidden = true;
754
+ }
669
755
  field.value = "";
670
756
  focusPrimary();
671
757
  };
@@ -818,10 +904,14 @@ function openConnect(providerId, thenModel) {
818
904
  // somebody expecting a sign-in would ask — and they are exactly who opens
819
905
  // the mark.
820
906
  ...(noAccounts ? [keyLink(), el("div", "cn-note", t("models.orPasteKey"))] : []),
907
+ ...(vendor ? [vendor] : []),
908
+ ...(vendorLocal ? [vendorLocal] : []),
909
+ ...(orKey ? [orKey] : []),
821
910
  site,
822
911
  orCode,
823
912
  field,
824
913
  keptLocal,
914
+ ...(claudePlan ? [claudePlan] : []),
825
915
  );
826
916
  // Re-attached on every open: the actions row is markup, so a link left from
827
917
  // the last vendor would otherwise point at their key page. The link is built
@@ -982,7 +1072,7 @@ async function loadAccount() {
982
1072
  const name = body.name || body.email || t("account.signedIn");
983
1073
  row.appendChild(avatarFor(name, body.avatar));
984
1074
  row.appendChild(el("span", "who-name", name));
985
- row.appendChild(svgIcon("chevronsVertical", "acct-caret"));
1075
+ row.appendChild(svgIcon("caret", "acct-caret"));
986
1076
 
987
1077
  // The balance, once it can be read. Running out mid-turn is the failure this
988
1078
  // prevents: a number that appears only in a paywall is a number nobody sees
@@ -1245,6 +1335,7 @@ async function loadAccount() {
1245
1335
  cls: "accent",
1246
1336
  }),
1247
1337
  themeRow(),
1338
+ ...customThemeRows(),
1248
1339
  menuItem(t("account.signOut"), {
1249
1340
  run: () => {
1250
1341
  closeRowMenu();
@@ -1314,6 +1405,51 @@ function websiteSignIn(provider, onSignedIn, onUnavailable) {
1314
1405
  return row;
1315
1406
  }
1316
1407
 
1408
+ /**
1409
+ * A vendor whose only way in is its browser sign-in — ChatGPT, whose plan has
1410
+ * no key to paste. Offering a key field for it would be a dead end.
1411
+ */
1412
+ function keyless(provider) {
1413
+ return Boolean(provider.vendorSignIn) && !(provider.envVars || []).length;
1414
+ }
1415
+
1416
+ /**
1417
+ * A vendor's own browser sign-in: Sign in with ChatGPT, OpenRouter.
1418
+ *
1419
+ * Like the website sign-in, the answer does not come back to the click. The
1420
+ * vendor redirects to a listener on this machine, the server finishes the
1421
+ * login there, and models_changed is what tells this page — so the waiter is
1422
+ * registered only once the tab has actually been opened.
1423
+ */
1424
+ function vendorSignIn(provider, onSignedIn, onError) {
1425
+ const row = el("div", "keyrow");
1426
+ const go = el("button", "signin-site", provider.vendorSignIn);
1427
+ go.type = "button";
1428
+ go.addEventListener("click", (e) => {
1429
+ e.preventDefault();
1430
+ e.stopPropagation();
1431
+ go.disabled = true;
1432
+ void api("/signin/vendor", { provider: provider.id })
1433
+ .then((result) => {
1434
+ if (!result || result.error) {
1435
+ const message = (result && result.error) || "could not start the sign-in";
1436
+ if (onError) return void onError(message);
1437
+ return void addNotice(message, "err");
1438
+ }
1439
+ signedInWaiters.set(provider.id, onSignedIn || (() => {
1440
+ if (document.getElementById("nav-models").classList.contains("active")) void showModels();
1441
+ }));
1442
+ window.open(result.url, "_blank", "noopener");
1443
+ addNotice(t("models.signInOpened", { site: provider.label || provider.id }));
1444
+ })
1445
+ .finally(() => {
1446
+ go.disabled = false;
1447
+ });
1448
+ });
1449
+ row.appendChild(go);
1450
+ return row;
1451
+ }
1452
+
1317
1453
  /**
1318
1454
  * The sign-in itself, without a button attached to it.
1319
1455
  *
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/page/client/account.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqvEhC,CAAC"}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/page/client/account.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA63EhC,CAAC"}
@@ -117,23 +117,35 @@ const ICON_PATHS = {
117
117
  themeDark: ["M13.2 9.6A5.6 5.6 0 0 1 6.4 2.8a5.6 5.6 0 1 0 6.8 6.8Z"],
118
118
  themeSystemRects: [[1.8, 2.6, 12.4, 8.6, 1.6]],
119
119
  themeLightCircles: [[8, 8, 3.1]],
120
+ // The add menu's marks all sit on one keyline, 2–14, the box the folder was
121
+ // redrawn onto: anything that runs out to 1.33 is the heaviest mark in the
122
+ // column, and anything drawn in 4.5–11.5 is the faintest.
123
+ //
120
124
  // A page with its corner turned back, which is the one mark that reads as
121
125
  // "file" at thirteen pixels without any lines of text inside it.
122
126
  file: [
123
- "M9.33 1.33H4a1.33 1.33 0 0 0-1.33 1.34v10.66A1.33 1.33 0 0 0 4 14.67h8" +
124
- "a1.33 1.33 0 0 0 1.33-1.34V5.33Z",
125
- "M9.33 1.33v4h4",
127
+ "M9.5 2H4.33A1.33 1.33 0 0 0 3 3.33v9.34A1.33 1.33 0 0 0 4.33 14h7.34" +
128
+ "A1.33 1.33 0 0 0 13 12.67V5.5Z",
129
+ "M9.5 2v3.5H13",
130
+ ],
131
+ // A paperclip, for the menu row that attaches files or photos: the mark that
132
+ // row carries everywhere else, and one that covers a photo as well as a
133
+ // document. The chip an attachment becomes keeps the page above, since by
134
+ // then it is a file rather than the act of attaching one.
135
+ attach: [
136
+ "M10.4 4.4 5.35 9.55a1.2 1.2 0 0 0 1.7 1.7l5.05-5.15a2.4 2.4 0 1 0-3.4-3.4" +
137
+ "L3.67 7.83a3.6 3.6 0 1 0 5.1 5.1l5.03-5.13",
126
138
  ],
127
139
  // Two pins and a body: a connector is the thing something else plugs into.
128
- plug: ["M6 1.33v3.34", "M10 1.33v3.34", "M4 4.67h8v3.33a4 4 0 0 1-8 0Z", "M8 12v2.67"],
140
+ plug: ["M6 2v3", "M10 2v3", "M3.5 5h9v2.5a4.5 4.5 0 0 1-9 0Z", "M8 12v2"],
129
141
  // Stacked plates, because a plugin arrives as a bundle of contributions
130
142
  // rather than as one thing.
131
- plugin: ["M8 1.33 1.33 4.67 8 8l6.67-3.33Z", "M1.33 11.33 8 14.67l6.67-3.34", "M1.33 8 8 11.33 14.67 8"],
143
+ plugin: ["M8 2 2 5l6 3 6-3Z", "M2 11l6 3 6-3", "M2 8l6 3 6-3"],
132
144
  /* A bookmark: one path, and the only shape in this menu that is neither a
133
145
  sheet nor a folder. The open book it replaced was two mirrored paths
134
146
  meeting at a spine, which at the 13px these rows use closed into a blob —
135
147
  two strokes a pixel apart read as one thick one. */
136
- skill: ["M4.5 2.5h7v11l-3.5-2.6-3.5 2.6Z"],
148
+ skill: ["M5.33 2h5.34A1.33 1.33 0 0 1 12 3.33V14l-4-3-4 3V3.33A1.33 1.33 0 0 1 5.33 2Z"],
137
149
  /* A prompt caret: what a command line looks like anywhere else. */
138
150
  command: ["M4 5.5 6.5 8 4 10.5", "M8.5 10.5H12"],
139
151
  /* A bare chevron. The other back arrow has a shaft, which is right on a
@@ -144,6 +156,7 @@ const ICON_PATHS = {
144
156
  close: ["M4.5 4.5l7 7", "M11.5 4.5l-7 7"],
145
157
  /* Its counterpart, for adding one. */
146
158
  plus: ["M8 3.5v9", "M3.5 8h9"],
159
+ check: ["M3.5 8.5l3 3 6-7"],
147
160
  /* A picture: a frame, a hill and a sun — what "attach an image" looks like
148
161
  everywhere else. */
149
162
  image: ["M2.5 11.5 6 8l3 3 1.5-1.5 3 3"],
@@ -161,8 +174,11 @@ const ICON_PATHS = {
161
174
  // transcript: the arc lands on the new node rather than crossing it.
162
175
  fork: ["M5 2.6v7.7", "M11 6a5.7 5.7 0 0 1-4.3 6"],
163
176
  forkCircles: [[11, 4.3], [5, 12]],
164
- // A trunk and the branch that leaves it for a tree of its own.
165
- worktree: ["M4.5 2v12", "M4.5 10.5c0-3.5 7-2.5 7-6", "M11.5 2.5a1 1 0 1 1 0 2 1 1 0 1 1 0-2"],
177
+ // A trunk and the branch that leaves it for a tree of its own. Three nodes
178
+ // where the fork has two: the trunk carries on past the point the branch
179
+ // left it, because a worktree is a second checkout, not a turn that moved.
180
+ worktree: ["M4.5 5.1v5.8", "M11.5 6.1a6.4 6.4 0 0 1-5.4 6.4"],
181
+ worktreeCircles: [[4.5, 3.5, 1.6], [4.5, 12.5, 1.6], [11.5, 4.5, 1.6]],
166
182
  copy: [
167
183
  "M6.67 5.33h6.66a1.33 1.33 0 0 1 1.34 1.34v6.66a1.33 1.33 0 0 1-1.34 1.34" +
168
184
  "H6.67a1.33 1.33 0 0 1-1.34-1.34V6.67a1.33 1.33 0 0 1 1.34-1.34Z",
@@ -204,8 +220,8 @@ const ICON_PATHS = {
204
220
  // Accept edits lets the pencil through.
205
221
  modeEdits: ["M11.3 2.7 13.3 4.7 5.3 12.7H3.3v-2Z", "M9.8 4.2l2 2"],
206
222
  // Plan is read-only: an eye, which looks and does not touch.
207
- modePlan: ["M1.6 8s2.4-4.4 6.4-4.4S14.4 8 14.4 8s-2.4 4.4-6.4 4.4S1.6 8 1.6 8Z"],
208
- modePlanCircles: [[8, 8, 2.1]],
223
+ modePlan: ["M2 8s2.3-4.8 6-4.8S14 8 14 8s-2.3 4.8-6 4.8S2 8 2 8Z"],
224
+ modePlanCircles: [[8, 8, 2.2]],
209
225
  // Auto waves the routine through: a bolt.
210
226
  modeAuto: ["M8.8 1.6 3.6 9h4l-.7 5.4L12.4 7h-4Z"],
211
227
  // Bypass leaves the gate open: a padlock with its shackle swung clear.
@@ -218,9 +234,16 @@ const ICON_PATHS = {
218
234
  // Goal mode: a target, rings closing on the point being aimed at.
219
235
  goal: ["M8 8h.01"],
220
236
  goalCircles: [[8, 8, 6], [8, 8, 3]],
221
- // Computer use: a screen on its stand, with the pointer that drives it.
222
- computer: ["M5.5 14h5M8 11.5V14", "M7.2 4.6l3.6 1.5-1.6.5-.5 1.6Z"],
223
- computerRects: [[1.5, 2, 13, 9.5, 1.6]],
237
+ // Computer use: a screen on its stand, and the pointer that drives it. The
238
+ // pointer used to sit inside the screen at three and a half units, where it
239
+ // closed into a triangle and the whole mark read as a video's play button.
240
+ // Now it is full size and breaks out over the screen's corner, and the frame
241
+ // stops short of it so the two outlines never cross.
242
+ computer: [
243
+ "M8.5 10.5h-5A1.5 1.5 0 0 1 2 9V4A1.5 1.5 0 0 1 3.5 2.5h7A1.5 1.5 0 0 1 12 4v3",
244
+ "M7 10.5V13M5 13h4",
245
+ "M9.5 8.5l4.5 1.9-2 .6-.6 2Z",
246
+ ],
224
247
  chevronLeft: ["M10 3.5 5.5 8l4.5 4.5"],
225
248
  chevronRight: ["M6 3.5 10.5 8 6 12.5"],
226
249
  };
@@ -387,9 +410,10 @@ const api = (path, body, timeoutMs) =>
387
410
  /**
388
411
  * Record that a feature was used. Does nothing unless analytics are on.
389
412
  *
390
- * window.__TRACK exists only when the server was started with a PostHog key —
391
- * see analytics.ts — so the calls below read the same either way and nobody
392
- * has to remember which branch they are writing in.
413
+ * window.__TRACK forwards to this server's /track once it has said analytics
414
+ * are on, and drops everything otherwise — see analytics.ts — so the calls
415
+ * below read the same either way and nobody has to remember which branch they
416
+ * are writing in. The server checks what arrives before anything leaves.
393
417
  *
394
418
  * There is deliberately no way to send text through here: every caller passes
395
419
  * an event name and a handful of enumerable properties — which panel, whether
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/page/client/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8Z7B,CAAC"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/page/client/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsb7B,CAAC"}
@@ -578,7 +578,7 @@ async function browserReload() {
578
578
 
579
579
  async function browserStop() {
580
580
  if (!activeId || !browserView(activeId).running) return;
581
- if (!confirm(t("browser.stopConfirm"))) return;
581
+ if (!(await askConfirm({ body: t("browser.stopConfirm"), ok: t("dialog.stop"), danger: true }))) return;
582
582
  browserStopBtn.disabled = true;
583
583
  const result = await api("/browser/close", { session: activeId });
584
584
  if (result.error) {
@@ -50,13 +50,11 @@ const inputPlaceholder = () =>
50
50
 
51
51
  function setGoalMode(on) {
52
52
  goalMode = on;
53
- input.placeholder = inputPlaceholder();
54
53
  renderAttachments();
55
54
  }
56
55
 
57
56
  function setWorktreeMode(on) {
58
57
  worktreeMode = on;
59
- input.placeholder = inputPlaceholder();
60
58
  renderAttachments();
61
59
  }
62
60
 
@@ -251,6 +249,9 @@ function renderQueued() {
251
249
 
252
250
  function renderAttachments() {
253
251
  attachEl.replaceChildren();
252
+ // What is staged decides whether the guess still fits, and the goal and
253
+ // worktree modes repaint through here with their own placeholder.
254
+ paintSuggestion();
254
255
 
255
256
  if (goalMode) {
256
257
  const chip = el("div", "att goal");
@@ -553,7 +554,7 @@ let fileList = { entries: [] };
553
554
  /** Whether the context endpoint has answered once, for the mention list. */
554
555
  let offerLoaded = false;
555
556
  /** Connectors and plugins, refreshed each time the menu opens. */
556
- let offer = { connectors: [], plugins: [], skills: [] };
557
+ let offer = { connectors: [], plugins: [], skills: [], agents: [] };
557
558
  /** The connectors on offer rather than the ones already here. */
558
559
  let market = [];
559
560
  /** The connector whose sign-in is open in a browser tab, if any. */
@@ -730,6 +731,25 @@ function attachRows() {
730
731
  note: plugin.description || "",
731
732
  ref: { kind: "plugin", value: plugin.name, label: plugin.name },
732
733
  }));
734
+ /**
735
+ * External agents first: naming one at the start of a message hands the
736
+ * whole message to it — Claude Code on the user's own account — so it is
737
+ * the one mention that changes who answers, and worth seeing before the
738
+ * rest. Offered only while the @ opens the message, the one place it
739
+ * routes; mid-sentence it would only be a word.
740
+ */
741
+ const atStart = mentionAt >= 0 && !input.value.slice(0, mentionAt).trim();
742
+ const agents = atStart
743
+ ? (offer.agents || [])
744
+ .filter((agent) => !query || agent.name.toLowerCase().includes(query))
745
+ .map((agent) => ({
746
+ type: "agent",
747
+ icon: "command",
748
+ label: "@" + agent.name,
749
+ note: t("mention.agentNote"),
750
+ ref: { kind: "agent", value: agent.name, label: agent.name },
751
+ }))
752
+ : [];
733
753
  const files = (fileList.entries || []).map((entry) => ({
734
754
  type: entry.dir ? "folder" : "file",
735
755
  icon: entry.dir ? "folder" : "file",
@@ -746,6 +766,7 @@ function attachRows() {
746
766
  * label on a list of one kind, which is noise.
747
767
  */
748
768
  const sections = [
769
+ [t("mention.agents"), agents],
749
770
  [t("add.skills"), skills],
750
771
  [t("add.plugins"), plugins],
751
772
  [t("mention.files"), files],
@@ -767,7 +788,7 @@ function attachRows() {
767
788
  // which one opens before it opens is also how someone reaching for a
768
789
  // screenshot stops reading at the first row.
769
790
  { type: "group", label: t("add.sectionAttach") },
770
- { type: "pick", kind: "files", icon: "file", label: t("add.attachFiles") },
791
+ { type: "pick", kind: "files", icon: "attach", label: t("add.attachFiles") },
771
792
  { type: "pick", kind: "folder", icon: "folder", label: t("add.attachFolders") },
772
793
  { type: "group", label: t("add.sectionMode") },
773
794
  // The permission mode of the same name, from the place people look for a
@@ -1326,7 +1347,7 @@ async function installConnector(id, remove) {
1326
1347
  addNotice(body.error, "err");
1327
1348
  return void paintMarket();
1328
1349
  }
1329
- if (body.connectors) offer = { connectors: body.connectors, plugins: body.plugins || [], skills: body.skills || [] };
1350
+ if (body.connectors) offer = { connectors: body.connectors, plugins: body.plugins || [], skills: body.skills || [], agents: body.agents || [] };
1330
1351
  for (const entry of market) if (entry.id === id) entry.installed = remove !== true;
1331
1352
  paintMarket();
1332
1353
  }
@@ -1549,7 +1570,10 @@ function paintMarks() {
1549
1570
  ensureOffer();
1550
1571
  const names = mentionNames();
1551
1572
  inputMirror.replaceChildren();
1552
- if (!names.size) return void (inputMirror.textContent = input.value);
1573
+ if (!names.size) {
1574
+ inputMirror.textContent = input.value;
1575
+ return void paintGhost();
1576
+ }
1553
1577
 
1554
1578
  const text = input.value;
1555
1579
  let at = 0;
@@ -1570,6 +1594,7 @@ function paintMarks() {
1570
1594
  }
1571
1595
  inputMirror.appendChild(document.createTextNode(text.slice(at)));
1572
1596
  if (inputMirror.querySelector("mark")) inputMirror.style.setProperty("--at-w", atWidth() + "px");
1597
+ paintGhost();
1573
1598
  }
1574
1599
 
1575
1600
  // --- the caret ------------------------------------------------------------
@@ -1632,7 +1657,10 @@ for (const event of ["input", "focus", "blur", "scroll"]) {
1632
1657
  input.addEventListener(event, placeCaret);
1633
1658
  }
1634
1659
  document.addEventListener("selectionchange", () => {
1635
- if (document.activeElement === input) placeCaret();
1660
+ if (document.activeElement !== input) return;
1661
+ placeCaret();
1662
+ // The rest of a guess is only offered from the end of the text.
1663
+ paintGhost();
1636
1664
  });
1637
1665
  window.addEventListener("resize", placeCaret);
1638
1666
 
@@ -2029,6 +2057,82 @@ input.addEventListener("keydown", (e) => {
2029
2057
  input.addEventListener("input", () => {
2030
2058
  autosize();
2031
2059
  paintMirror();
2060
+ paintSuggestion();
2061
+ });
2062
+
2063
+ // --- the next-message guess -----------------------------------------------
2064
+
2065
+ /**
2066
+ * The server's guess at what this conversation's user types next, drawn as
2067
+ * the empty box's placeholder and taken whole with Tab.
2068
+ *
2069
+ * Held per pane, so a guess written for a background tab waits there rather
2070
+ * than showing on the one on screen. Shown only where it can be acted on: an
2071
+ * idle conversation, nothing typed, and no goal or worktree mode, whose own
2072
+ * placeholder says what the next message will be sent as.
2073
+ */
2074
+ function suggestionNow() {
2075
+ const here = panes.get(activeId);
2076
+ if (!here || here.busy || staged.length || refs.length || goalMode || worktreeMode) return "";
2077
+ return here.suggestion || "";
2078
+ }
2079
+
2080
+ /** The whole guess, while the box is empty. */
2081
+ function suggestionHere() {
2082
+ return input.value ? "" : suggestionNow();
2083
+ }
2084
+
2085
+ /**
2086
+ * What is left of the guess once some of it has been typed: the text so far
2087
+ * has to be its start, letter for letter, and the caret at the end with
2088
+ * nothing selected — anywhere else, Tab finishing a sentence the caret is not
2089
+ * at would put words somewhere the user is not looking.
2090
+ */
2091
+ function ghostTail() {
2092
+ const typed = input.value;
2093
+ const guess = suggestionNow();
2094
+ if (!typed || !guess || guess.length <= typed.length || !guess.startsWith(typed)) return "";
2095
+ if (input.selectionStart !== typed.length || input.selectionEnd !== typed.length) return "";
2096
+ return guess.slice(typed.length);
2097
+ }
2098
+
2099
+ /**
2100
+ * Draw the rest of the guess after the text, on the mirror under the field.
2101
+ * The mirror lays out exactly as the field does, so the tail starts where the
2102
+ * last typed glyph ends.
2103
+ */
2104
+ function paintGhost() {
2105
+ if (!inputMirror) return;
2106
+ const old = inputMirror.querySelector(".ghost");
2107
+ if (old) old.remove();
2108
+ const tail = ghostTail();
2109
+ if (tail) inputMirror.appendChild(el("span", "ghost", tail));
2110
+ }
2111
+
2112
+ function paintSuggestion() {
2113
+ const guess = suggestionHere();
2114
+ input.placeholder = guess || inputPlaceholder();
2115
+ input.classList.toggle("suggesting", !!guess);
2116
+ paintGhost();
2117
+ }
2118
+
2119
+ input.addEventListener("keydown", (e) => {
2120
+ if ((e.key !== "Tab" && e.key !== "Escape") || e.shiftKey || e.altKey || e.metaKey || e.ctrlKey || e.isComposing) return;
2121
+ const tail = ghostTail();
2122
+ const guess = tail ? input.value + tail : suggestionHere();
2123
+ if (!guess) return;
2124
+ e.preventDefault();
2125
+ e.stopImmediatePropagation();
2126
+ if (e.key === "Escape") {
2127
+ panes.get(activeId).suggestion = null;
2128
+ paintGhost();
2129
+ return void paintSuggestion();
2130
+ }
2131
+ input.value = guess;
2132
+ input.setSelectionRange(guess.length, guess.length);
2133
+ autosize();
2134
+ paintMirror();
2135
+ paintSuggestion();
2032
2136
  });
2033
2137
 
2034
2138
  // --- the field's height ---------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"composer.js","sourceRoot":"","sources":["../../../src/page/client/composer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAozEjC,CAAC"}
1
+ {"version":3,"file":"composer.js","sourceRoot":"","sources":["../../../src/page/client/composer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA45EjC,CAAC"}