@burdenoff/fe-libs 2026.1004.5 → 2026.1004.7

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 (82) hide show
  1. package/dist/chrome/ContextSwitcher.d.ts.map +1 -1
  2. package/dist/chrome/ContextSwitcher.js +73 -50
  3. package/dist/chrome/GlobalSearch.d.ts.map +1 -1
  4. package/dist/chrome/GlobalSearch.js +76 -72
  5. package/dist/chrome/LanguageSwitcher.d.ts.map +1 -1
  6. package/dist/chrome/LanguageSwitcher.js +61 -40
  7. package/dist/chrome/NotificationCenter.d.ts.map +1 -1
  8. package/dist/chrome/NotificationCenter.js +71 -68
  9. package/dist/chrome/ProfileSwitcher.d.ts.map +1 -1
  10. package/dist/chrome/ProfileSwitcher.js +87 -81
  11. package/dist/chrome/SideNavigation.d.ts.map +1 -1
  12. package/dist/chrome/SideNavigation.js +120 -76
  13. package/dist/shared/assistant/appControls/copy.d.ts +12 -0
  14. package/dist/shared/assistant/appControls/copy.d.ts.map +1 -0
  15. package/dist/shared/assistant/appControls/copy.js +98 -0
  16. package/dist/shared/assistant/appControls/grammar.d.ts +102 -0
  17. package/dist/shared/assistant/appControls/grammar.d.ts.map +1 -0
  18. package/dist/shared/assistant/appControls/grammar.js +236 -0
  19. package/dist/shared/assistant/appControls/languages.d.ts +6 -0
  20. package/dist/shared/assistant/appControls/languages.d.ts.map +1 -0
  21. package/dist/shared/assistant/appControls/languages.js +52 -0
  22. package/dist/shared/assistant/appControls/names.d.ts +22 -0
  23. package/dist/shared/assistant/appControls/names.d.ts.map +1 -0
  24. package/dist/shared/assistant/appControls/names.js +29 -0
  25. package/dist/shared/assistant/appControls/pageAdapters.d.ts +59 -0
  26. package/dist/shared/assistant/appControls/pageAdapters.d.ts.map +1 -0
  27. package/dist/shared/assistant/appControls/pageAdapters.js +87 -0
  28. package/dist/shared/assistant/appControls/plan.d.ts +148 -0
  29. package/dist/shared/assistant/appControls/plan.d.ts.map +1 -0
  30. package/dist/shared/assistant/appControls/plan.js +511 -0
  31. package/dist/shared/assistant/appControls/registry.d.ts +9 -0
  32. package/dist/shared/assistant/appControls/registry.d.ts.map +1 -0
  33. package/dist/shared/assistant/appControls/registry.js +38 -0
  34. package/dist/shared/assistant/appControls/snapshot.d.ts +42 -0
  35. package/dist/shared/assistant/appControls/snapshot.d.ts.map +1 -0
  36. package/dist/shared/assistant/appControls/snapshot.js +40 -0
  37. package/dist/shared/assistant/appControls/text.d.ts +7 -0
  38. package/dist/shared/assistant/appControls/text.d.ts.map +1 -0
  39. package/dist/shared/assistant/appControls/text.js +6 -0
  40. package/dist/shared/assistant/appControls/types.d.ts +183 -0
  41. package/dist/shared/assistant/appControls/types.d.ts.map +1 -0
  42. package/dist/shared/assistant/appControls/types.js +25 -0
  43. package/dist/shared/assistant/appControls/useAssistantControl.d.ts +24 -0
  44. package/dist/shared/assistant/appControls/useAssistantControl.d.ts.map +1 -0
  45. package/dist/shared/assistant/appControls/useAssistantControl.js +13 -0
  46. package/dist/shared/assistant/conversation.d.ts +12 -1
  47. package/dist/shared/assistant/conversation.d.ts.map +1 -1
  48. package/dist/shared/assistant/history/historyMapping.d.ts.map +1 -1
  49. package/dist/shared/assistant/history/historyMapping.js +130 -114
  50. package/dist/shared/assistant/i18nManifest.d.ts +64 -0
  51. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  52. package/dist/shared/assistant/i18nManifest.js +64 -0
  53. package/dist/shared/assistant/index.d.ts +13 -0
  54. package/dist/shared/assistant/index.d.ts.map +1 -1
  55. package/dist/shared/assistant/localUiCommandCopy.d.ts +7 -0
  56. package/dist/shared/assistant/localUiCommandCopy.d.ts.map +1 -1
  57. package/dist/shared/assistant/localUiCommandCopy.js +1 -1
  58. package/dist/shared/assistant/localUiCommands.d.ts +16 -0
  59. package/dist/shared/assistant/localUiCommands.d.ts.map +1 -1
  60. package/dist/shared/assistant/localUiCommands.js +97 -84
  61. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  62. package/dist/shared/assistant/ui/AIAssistantPanel.js +57 -49
  63. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  64. package/dist/shared/assistant/ui/AssistantChatArea.js +1176 -1123
  65. package/dist/shared/assistant/ui/AssistantControlConfirmDialog.d.ts +38 -0
  66. package/dist/shared/assistant/ui/AssistantControlConfirmDialog.d.ts.map +1 -0
  67. package/dist/shared/assistant/ui/AssistantControlConfirmDialog.js +65 -0
  68. package/dist/shared/assistant/ui/controlConfirmDialog.d.ts +30 -0
  69. package/dist/shared/assistant/ui/controlConfirmDialog.d.ts.map +1 -0
  70. package/dist/shared/assistant/ui/controlConfirmDialog.js +46 -0
  71. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  72. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +174 -171
  73. package/dist/shared/assistant/uiActions/recordNames.d.ts +33 -0
  74. package/dist/shared/assistant/uiActions/recordNames.d.ts.map +1 -1
  75. package/dist/shared/assistant/uiActions/recordNames.js +51 -1
  76. package/dist/shared/components/KeyboardHelpDialogWrapper.d.ts.map +1 -1
  77. package/dist/shared/components/KeyboardHelpDialogWrapper.js +11 -9
  78. package/dist/shared/providers/shell/GlobalUiProvider.d.ts +2 -0
  79. package/dist/shared/providers/shell/GlobalUiProvider.d.ts.map +1 -1
  80. package/dist/shared/providers/shell/GlobalUiProvider.js +4 -1
  81. package/dist/shared-assistant.js +219 -206
  82. package/package.json +1 -1
@@ -12,98 +12,98 @@ var s = /^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$/, c = 131072, l = 98304, u = 16384,
12
12
  "summary",
13
13
  "data",
14
14
  "at"
15
- ]), y = [
15
+ ]), re = [
16
16
  "proposed",
17
17
  "applied",
18
18
  "failed",
19
19
  "expired",
20
20
  "cancelled"
21
- ], re = /^(?:pending[-_]?write|write[-_]?proposal[-_]?refs?)$/i, b = "\n\n[…truncated in saved history]";
22
- function x(e) {
21
+ ], ie = /^(?:pending[-_]?write|write[-_]?proposal[-_]?refs?)$/i, y = "\n\n[…truncated in saved history]";
22
+ function b(e) {
23
23
  return typeof e == "string" && s.test(e);
24
24
  }
25
- var ie = new TextEncoder();
25
+ var ae = new TextEncoder();
26
+ function x(e) {
27
+ return ae.encode(e).length;
28
+ }
26
29
  function S(e) {
27
- return ie.encode(e).length;
30
+ return x(JSON.stringify(e));
28
31
  }
29
32
  function C(e) {
30
- return S(JSON.stringify(e));
31
- }
32
- function w(e) {
33
33
  if (typeof e != "object" || !e || Array.isArray(e)) return !1;
34
34
  let t = Object.getPrototypeOf(e);
35
35
  return t === Object.prototype || t === null;
36
36
  }
37
- function T(e, t) {
37
+ function w(e, t) {
38
38
  if (e === null || typeof e == "string" || typeof e == "boolean") return 0;
39
39
  if (typeof e == "number") return Number.isFinite(e) ? 0 : Infinity;
40
- let n = Array.isArray(e) ? e : w(e) ? Object.values(e) : null;
40
+ let n = Array.isArray(e) ? e : C(e) ? Object.values(e) : null;
41
41
  if (n === null || t <= 0) return Infinity;
42
42
  let r = 0;
43
- for (let e of n) if (r = Math.max(r, T(e, t - 1)), r === Infinity) return Infinity;
43
+ for (let e of n) if (r = Math.max(r, w(e, t - 1)), r === Infinity) return Infinity;
44
44
  return r + 1;
45
45
  }
46
- var E = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/, D = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, O = "\0";
46
+ var T = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/, E = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, D = "\0";
47
+ function O(e) {
48
+ return !e.includes(D) && !T.test(e);
49
+ }
47
50
  function k(e) {
48
- return !e.includes(O) && !E.test(e);
51
+ return O(e) ? e : e.replaceAll(D, "�").replace(E, "�");
49
52
  }
50
53
  function A(e) {
51
- return k(e) ? e : e.replaceAll(O, "�").replace(D, "�");
54
+ return typeof e == "string" ? O(e) : Array.isArray(e) ? e.every(A) : C(e) ? Object.entries(e).every(([e, t]) => O(e) && A(t)) : !0;
52
55
  }
53
56
  function j(e) {
54
- return typeof e == "string" ? k(e) : Array.isArray(e) ? e.every(j) : w(e) ? Object.entries(e).every(([e, t]) => k(e) && j(t)) : !0;
55
- }
56
- function M(e) {
57
- if (Array.isArray(e)) return e.map(M);
58
- if (!w(e)) return e;
57
+ if (Array.isArray(e)) return e.map(j);
58
+ if (!C(e)) return e;
59
59
  let t = {};
60
- for (let [n, r] of Object.entries(e)) re.test(n) || Object.defineProperty(t, n, {
61
- value: M(r),
60
+ for (let [n, r] of Object.entries(e)) ie.test(n) || Object.defineProperty(t, n, {
61
+ value: j(r),
62
62
  enumerable: !0,
63
63
  writable: !0,
64
64
  configurable: !0
65
65
  });
66
66
  return t;
67
67
  }
68
- var N = (e) => e === !0, P = (e) => (t) => typeof t == "string" && t.length <= e, F = (e) => (t) => w(t) && T(t, d) <= d && C(t) <= e, I = (e, t) => (n) => Array.isArray(n) && n.length <= e && n.every(F(t));
69
- function L(e) {
70
- return typeof e == "string" && e.length <= te && k(e) && Number.isFinite(Date.parse(e));
68
+ var M = (e) => e === !0, N = (e) => (t) => typeof t == "string" && t.length <= e, P = (e) => (t) => C(t) && w(t, d) <= d && S(t) <= e, F = (e, t) => (n) => Array.isArray(n) && n.length <= e && n.every(P(t));
69
+ function I(e) {
70
+ return typeof e == "string" && e.length <= te && O(e) && Number.isFinite(Date.parse(e));
71
71
  }
72
- function R(e) {
73
- if (!w(e) || !Object.keys(e).every((e) => ne.has(e))) return !1;
72
+ function L(e) {
73
+ if (!C(e) || !Object.keys(e).every((e) => ne.has(e))) return !1;
74
74
  let { kind: t, version: n, status: r, summary: i, data: a, at: o } = e;
75
- return typeof t == "string" && v.test(t) && typeof n == "number" && Number.isSafeInteger(n) && n >= 1 && (r === void 0 || P(16)(r)) && (i === void 0 || P(500)(i)) && (a === void 0 || F(m)(a)) && (o === void 0 || L(o));
75
+ return typeof t == "string" && v.test(t) && typeof n == "number" && Number.isSafeInteger(n) && n >= 1 && (r === void 0 || N(16)(r)) && (i === void 0 || N(500)(i)) && (a === void 0 || P(m)(a)) && (o === void 0 || I(o));
76
76
  }
77
- var z = new Map([
78
- ["voice", N],
79
- ["voiceSessionId", P(64)],
80
- ["lang", P(35)],
81
- ["mode", P(64)],
82
- ["sandboxId", P(128)],
83
- ["sessionId", P(128)],
84
- ["attachments", I(h, p)],
85
- ["artifacts", I(g, p)],
86
- ["localAction", F(p)],
77
+ var R = new Map([
78
+ ["voice", M],
79
+ ["voiceSessionId", N(64)],
80
+ ["lang", N(35)],
81
+ ["mode", N(64)],
82
+ ["sandboxId", N(128)],
83
+ ["sessionId", N(128)],
84
+ ["attachments", F(h, p)],
85
+ ["artifacts", F(g, p)],
86
+ ["localAction", P(p)],
87
87
  ["continuedVoiceTurns", (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0],
88
- ["approvalFollowUp", N],
89
- ["incomplete", N],
90
- ["truncated", N],
91
- ["records", (e) => Array.isArray(e) && e.length <= _ && e.every(R)]
92
- ]), ae = [...z.keys()];
93
- function B(e) {
88
+ ["approvalFollowUp", M],
89
+ ["incomplete", M],
90
+ ["truncated", M],
91
+ ["records", (e) => Array.isArray(e) && e.length <= _ && e.every(L)]
92
+ ]), oe = [...R.keys()];
93
+ function z(e) {
94
94
  let t = {}, n = [];
95
- if (!w(e)) return {
95
+ if (!C(e)) return {
96
96
  kept: t,
97
97
  dropped: n
98
98
  };
99
99
  for (let [r, i] of Object.entries(e)) {
100
- let e = z.get(r);
101
- if (!e || !e(i) || !j(i)) {
100
+ let e = R.get(r);
101
+ if (!e || !e(i) || !A(i)) {
102
102
  n.push(r);
103
103
  continue;
104
104
  }
105
- let a = M(i);
106
- if (T(a, f) > f) {
105
+ let a = j(i);
106
+ if (w(a, f) > f) {
107
107
  n.push(r);
108
108
  continue;
109
109
  }
@@ -114,37 +114,37 @@ function B(e) {
114
114
  dropped: n
115
115
  };
116
116
  }
117
- var V = [
117
+ var B = [
118
118
  "artifacts",
119
119
  "attachments",
120
120
  "records",
121
121
  "localAction"
122
- ], H = (e) => {
123
- let t = V.indexOf(e);
124
- return t === -1 ? V.length : t;
122
+ ], V = (e) => {
123
+ let t = B.indexOf(e);
124
+ return t === -1 ? B.length : t;
125
125
  };
126
- function U(e, t, n) {
126
+ function H(e, t, n) {
127
127
  let r = n;
128
128
  for (;;) {
129
- if (C({ assistant: {
129
+ if (S({ assistant: {
130
130
  v: 1,
131
131
  kind: e,
132
132
  clientCreatedAt: t,
133
133
  data: r
134
134
  } }) <= 16384) return r;
135
- let n = Object.entries(r).map(([e, t]) => [e, C({ [e]: t })]);
136
- n.sort(([e, t], [n, r]) => r - t || H(e) - H(n) || (e < n ? -1 : Number(e > n)));
135
+ let n = Object.entries(r).map(([e, t]) => [e, S({ [e]: t })]);
136
+ n.sort(([e, t], [n, r]) => r - t || V(e) - V(n) || (e < n ? -1 : Number(e > n)));
137
137
  let i = n[0]?.[0];
138
138
  if (i === void 0) return r;
139
139
  r = Object.fromEntries(Object.entries(r).filter(([e]) => e !== i));
140
140
  }
141
141
  }
142
- var W = {
142
+ var U = {
143
143
  user: "USER",
144
144
  assistant: "ASSISTANT",
145
145
  system: "NOTE"
146
146
  };
147
- function G(e) {
147
+ function W(e) {
148
148
  return {
149
149
  id: e.id,
150
150
  filename: e.filename,
@@ -154,7 +154,7 @@ function G(e) {
154
154
  ...e.fileId ? { fileId: e.fileId } : {}
155
155
  };
156
156
  }
157
- function K(e) {
157
+ function G(e) {
158
158
  return {
159
159
  name: e.name,
160
160
  path: e.path,
@@ -163,7 +163,7 @@ function K(e) {
163
163
  ...e.downloadPath ? { downloadPath: e.downloadPath } : {}
164
164
  };
165
165
  }
166
- function q(e) {
166
+ function K(e) {
167
167
  if (!e) return {};
168
168
  let t = {};
169
169
  e.voice === !0 && (t.voice = !0), e.voice === !0 && typeof e.voiceSessionId == "string" && (t.voiceSessionId = e.voiceSessionId);
@@ -176,46 +176,46 @@ function q(e) {
176
176
  let r = e[n];
177
177
  typeof r == "string" && r.length > 0 && (t[n] = r);
178
178
  }
179
- let n = F(p);
179
+ let n = P(p);
180
180
  if (Array.isArray(e.attachments)) {
181
- let r = e.attachments.map(G).filter(n).slice(0, h);
181
+ let r = e.attachments.map(W).filter(n).slice(0, h);
182
182
  r.length > 0 && (t.attachments = r);
183
183
  }
184
184
  if (Array.isArray(e.artifacts)) {
185
- let r = e.artifacts.map(K).filter(n).slice(0, g);
185
+ let r = e.artifacts.map(G).filter(n).slice(0, g);
186
186
  r.length > 0 && (t.artifacts = r);
187
187
  }
188
188
  if (e.localAction && (t.localAction = { ...e.localAction }), typeof e.continuedVoiceTurns == "number" && (t.continuedVoiceTurns = e.continuedVoiceTurns), e.approvalFollowUp === !0 && (t.approvalFollowUp = !0), e.incomplete === !0 && (t.incomplete = !0), e.truncated === !0 && (t.truncated = !0), Array.isArray(e.records)) {
189
- let n = e.records.filter(R).slice(0, _);
189
+ let n = e.records.filter(L).slice(0, _);
190
190
  n.length > 0 && (t.records = n);
191
191
  }
192
192
  return t;
193
193
  }
194
- function oe(e) {
194
+ function se(e) {
195
195
  let t = e.codePointAt(0) ?? 0;
196
196
  return e === "\"" || e === "\\" ? 2 : t < 32 ? "\b\f\n\r ".includes(e) ? 2 : 6 : t < 128 ? 1 : t < 2048 ? 2 : t < 65536 ? 3 : 4;
197
197
  }
198
- function se(e, t) {
198
+ function ce(e, t) {
199
199
  let n = 0, r = 0;
200
200
  for (let i of e) {
201
- let e = oe(i);
201
+ let e = se(i);
202
202
  if (n + e > t) break;
203
203
  n += e, r += i.length;
204
204
  }
205
205
  return e.slice(0, r);
206
206
  }
207
- function J(e, t) {
208
- if (S(e) <= t) return e;
207
+ function q(e, t) {
208
+ if (x(e) <= t) return e;
209
209
  let n = 0, r = 0;
210
210
  for (let i of e) {
211
- let e = S(i);
211
+ let e = x(i);
212
212
  if (n + e > t) break;
213
213
  n += e, r += i.length;
214
214
  }
215
215
  return e.slice(0, r);
216
216
  }
217
- var Y = (e) => C(e) - 2;
218
- function X(e, t, n) {
217
+ var J = (e) => S(e) - 2;
218
+ function Y(e, t, n) {
219
219
  if (!n) return {
220
220
  ...e,
221
221
  input: {
@@ -236,8 +236,8 @@ function X(e, t, n) {
236
236
  }
237
237
  };
238
238
  }
239
- function Z(e, t) {
240
- return C({
239
+ function X(e, t) {
240
+ return S({
241
241
  operationName: i,
242
242
  query: r,
243
243
  variables: a({
@@ -251,52 +251,52 @@ function Z(e, t) {
251
251
  })
252
252
  });
253
253
  }
254
- var Q = t - u;
255
- function $(e, t) {
254
+ var Z = t - u;
255
+ function le(e, t) {
256
256
  let r = e.map((e) => {
257
- let r = A(n(e.content)), i = L(e.timestamp) ? e.timestamp : null, a = U(t.kind, i, B(q(e.metadata)).kept), o = {
257
+ let r = k(n(e.content)), i = I(e.timestamp) ? e.timestamp : null, a = H(t.kind, i, z(K(e.metadata)).kept), o = {
258
258
  input: {
259
259
  clientMessageId: e.id,
260
- role: W[e.role],
260
+ role: U[e.role],
261
261
  content: r,
262
262
  ...i ? { clientCreatedAt: i } : {},
263
263
  ...Object.keys(a).length > 0 ? { metadata: a } : {}
264
264
  },
265
265
  source: r
266
266
  };
267
- return S(r) <= 98304 ? o : X(o, J(r, l - S(b)) + b, !0);
268
- }), i = Y(b);
267
+ return x(r) <= 98304 ? o : Y(o, q(r, l - x(y)) + y, !0);
268
+ }), i = J(y);
269
269
  for (let e = 0; e < 3; e += 1) {
270
- let e = Z(t, r.map((e) => e.input)) - Q;
270
+ let e = X(t, r.map((e) => e.input)) - Z;
271
271
  if (e <= 0) break;
272
272
  let n = -1, a = -1;
273
273
  r.forEach((e, t) => {
274
- let r = Y(e.input.content);
274
+ let r = J(e.input.content);
275
275
  r > a && (n = t, a = r);
276
276
  });
277
277
  let o = r[n];
278
278
  if (!o) break;
279
- let s = Math.max(0, a - e - i - 64), c = se(o.source, s) + b;
280
- r = r.map((e, t) => t === n ? X(e, c, !0) : e);
279
+ let s = Math.max(0, a - e - i - 64), c = ce(o.source, s) + y;
280
+ r = r.map((e, t) => t === n ? Y(e, c, !0) : e);
281
281
  }
282
282
  return r.map((e) => e.input);
283
283
  }
284
- function ce(e, t) {
284
+ function ue(e, t) {
285
285
  let n = e === "NOTE" ? ["NOTE"] : ["USER", "ASSISTANT"];
286
- return t.length === n.length ? new Set(t.map((e) => e.clientMessageId)).size === t.length && t.every((e, t) => e.role === n[t] && x(e.clientMessageId)) : !1;
286
+ return t.length === n.length ? new Set(t.map((e) => e.clientMessageId)).size === t.length && t.every((e, t) => e.role === n[t] && b(e.clientMessageId)) : !1;
287
287
  }
288
- var le = {
288
+ var de = {
289
289
  USER: "user",
290
290
  ASSISTANT: "assistant",
291
291
  NOTE: "system"
292
- }, ue = [
292
+ }, fe = [
293
293
  "image",
294
294
  "text",
295
295
  "document"
296
296
  ];
297
- function de(e) {
298
- if (!w(e)) return null;
299
- let { id: t, filename: n, mimeType: r, size: i, kind: a, fileId: o } = e, s = ue.find((e) => e === a);
297
+ function pe(e) {
298
+ if (!C(e)) return null;
299
+ let { id: t, filename: n, mimeType: r, size: i, kind: a, fileId: o } = e, s = fe.find((e) => e === a);
300
300
  return typeof t != "string" || typeof n != "string" || typeof r != "string" || typeof i != "number" || !s ? null : {
301
301
  id: t,
302
302
  filename: n,
@@ -306,8 +306,8 @@ function de(e) {
306
306
  ...typeof o == "string" ? { fileId: o } : {}
307
307
  };
308
308
  }
309
- function fe(e) {
310
- if (!w(e)) return null;
309
+ function me(e) {
310
+ if (!C(e)) return null;
311
311
  let { name: t, path: n, type: r, size: i, downloadPath: a } = e;
312
312
  return typeof t != "string" || typeof n != "string" || r !== "file" && r !== "directory" || typeof i != "number" ? null : {
313
313
  name: t,
@@ -317,28 +317,36 @@ function fe(e) {
317
317
  ...typeof a == "string" ? { downloadPath: a } : {}
318
318
  };
319
319
  }
320
- var pe = [
320
+ var he = [
321
321
  "named",
322
322
  "link",
323
323
  "choice",
324
324
  "back",
325
325
  "offer"
326
- ], me = [
326
+ ], Q = [
327
327
  "arrived",
328
328
  "redirected",
329
329
  "new-tab",
330
330
  "refused",
331
331
  "unconfirmed"
332
- ], he = 256;
333
- function ge(e) {
334
- if (!w(e)) return null;
332
+ ], $ = 256, ge = [
333
+ "done",
334
+ "already",
335
+ "failed",
336
+ "blocked",
337
+ "not-found",
338
+ "ambiguous",
339
+ "confirm"
340
+ ];
341
+ function _e(e) {
342
+ if (!C(e)) return null;
335
343
  if (e.kind === "theme" && typeof e.mode == "string" && typeof e.alreadyApplied == "boolean") return {
336
344
  kind: "theme",
337
345
  mode: e.mode,
338
346
  alreadyApplied: e.alreadyApplied
339
347
  };
340
348
  if (e.kind === "navigate" && typeof e.destinationId == "string" && typeof e.path == "string" && typeof e.alreadyHere == "boolean") {
341
- let t = pe.find((t) => t === e.via), n = me.find((t) => t === e.outcome), { landedPath: r } = e;
349
+ let t = he.find((t) => t === e.via), n = Q.find((t) => t === e.outcome), { landedPath: r } = e;
342
350
  return {
343
351
  kind: "navigate",
344
352
  destinationId: e.destinationId,
@@ -346,9 +354,17 @@ function ge(e) {
346
354
  alreadyHere: e.alreadyHere,
347
355
  ...t ? { via: t } : {},
348
356
  ...n ? { outcome: n } : {},
349
- ...typeof r == "string" && r.length <= he ? { landedPath: r } : {}
357
+ ...typeof r == "string" && r.length <= $ ? { landedPath: r } : {}
350
358
  };
351
359
  }
360
+ if (e.kind === "app-control" && typeof e.control == "string") {
361
+ let t = ge.find((t) => t === e.outcome);
362
+ return t && e.control.length <= $ ? {
363
+ kind: "app-control",
364
+ control: e.control,
365
+ outcome: t
366
+ } : null;
367
+ }
352
368
  if (e.kind === "write-reply" && typeof e.line == "string") return {
353
369
  kind: "write-reply",
354
370
  line: e.line
@@ -359,42 +375,42 @@ function ge(e) {
359
375
  candidateIds: [...t]
360
376
  } : null;
361
377
  }
362
- function _e(e) {
363
- if (!R(e) || !w(e)) return null;
378
+ function ve(e) {
379
+ if (!L(e) || !C(e)) return null;
364
380
  let { kind: t, version: n, status: r, summary: i, data: a, at: o } = e;
365
381
  if (typeof t != "string" || typeof n != "number") return null;
366
- let s = y.find((e) => e === r), c = s === "proposed" ? "expired" : s;
382
+ let s = re.find((e) => e === r), c = s === "proposed" ? "expired" : s;
367
383
  return {
368
384
  kind: t,
369
385
  version: n,
370
386
  ...c ? { status: c } : {},
371
387
  ...typeof i == "string" ? { summary: i } : {},
372
- ...w(a) ? { data: a } : {},
388
+ ...C(a) ? { data: a } : {},
373
389
  ...typeof o == "string" ? { at: o } : {}
374
390
  };
375
391
  }
376
- function ve(t) {
377
- let { kept: n } = B(t), r = {};
392
+ function ye(t) {
393
+ let { kept: n } = z(t), r = {};
378
394
  if (n.voice === !0 && (r.voice = !0, typeof n.voiceSessionId == "string" && n.voiceSessionId.length > 0 && (r.voiceSessionId = n.voiceSessionId)), typeof n.lang == "string" && n.lang.length > 0 && (r.lang = n.lang), e(n.mode) && (r.mode = n.mode), typeof n.sandboxId == "string" && (r.sandboxId = n.sandboxId), typeof n.sessionId == "string" && (r.sessionId = n.sessionId), Array.isArray(n.attachments)) {
379
- let e = n.attachments.map(de).filter((e) => e !== null);
395
+ let e = n.attachments.map(pe).filter((e) => e !== null);
380
396
  e.length > 0 && (r.attachments = e);
381
397
  }
382
398
  if (Array.isArray(n.artifacts)) {
383
- let e = n.artifacts.map(fe).filter((e) => e !== null);
399
+ let e = n.artifacts.map(me).filter((e) => e !== null);
384
400
  e.length > 0 && (r.artifacts = e);
385
401
  }
386
- let i = ge(n.localAction);
402
+ let i = _e(n.localAction);
387
403
  if (i && (r.localAction = i), typeof n.continuedVoiceTurns == "number" && (r.continuedVoiceTurns = n.continuedVoiceTurns), n.approvalFollowUp === !0 && (r.approvalFollowUp = !0), n.incomplete === !0 && (r.incomplete = !0), n.truncated === !0 && (r.truncated = !0), Array.isArray(n.records)) {
388
- let e = n.records.map(_e).filter((e) => e !== null);
404
+ let e = n.records.map(ve).filter((e) => e !== null);
389
405
  e.length > 0 && (r.records = e);
390
406
  }
391
407
  return r;
392
408
  }
393
- function ye(e) {
394
- let t = ve(e.metadata);
409
+ function be(e) {
410
+ let t = ye(e.metadata);
395
411
  return {
396
412
  id: e.clientMessageId ?? `legacy:${e.id}`,
397
- role: le[e.role],
413
+ role: de[e.role],
398
414
  content: n(e.content),
399
415
  timestamp: o(e.clientCreatedAt) ?? o(e.createdAt) ?? e.createdAt,
400
416
  ...Object.keys(t).length > 0 ? { metadata: t } : {},
@@ -403,4 +419,4 @@ function ye(e) {
403
419
  };
404
420
  }
405
421
  //#endregion
406
- export { s as HISTORY_CLIENT_ID_PATTERN, l as HISTORY_ENTRY_CONTENT_CAP_BYTES, c as HISTORY_MAX_CONTENT_BYTES, ee as HISTORY_METADATA_ENVELOPE_MAX_BYTES, ae as HISTORY_METADATA_KEYS, u as HISTORY_REQUEST_HEADROOM_BYTES, Q as HISTORY_SAVE_REQUEST_BUDGET_BYTES, b as HISTORY_TRUNCATION_MARKER, B as filterHistoryMetadata, U as fitHistoryMetadataEnvelope, ye as fromHistoryEntry, ce as historyEntriesMatchKind, x as isHistoryClientId, Z as measureHistorySaveRequest, $ as toHistoryEntries, A as toStorableHistoryText, J as truncateUtf8, S as utf8ByteLength };
422
+ export { s as HISTORY_CLIENT_ID_PATTERN, l as HISTORY_ENTRY_CONTENT_CAP_BYTES, c as HISTORY_MAX_CONTENT_BYTES, ee as HISTORY_METADATA_ENVELOPE_MAX_BYTES, oe as HISTORY_METADATA_KEYS, u as HISTORY_REQUEST_HEADROOM_BYTES, Z as HISTORY_SAVE_REQUEST_BUDGET_BYTES, y as HISTORY_TRUNCATION_MARKER, z as filterHistoryMetadata, H as fitHistoryMetadataEnvelope, be as fromHistoryEntry, ue as historyEntriesMatchKind, b as isHistoryClientId, X as measureHistorySaveRequest, le as toHistoryEntries, k as toStorableHistoryText, q as truncateUtf8, x as utf8ByteLength };
@@ -118,6 +118,70 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
118
118
  readonly "apiCalls.consentCancel": "Stay in Ask";
119
119
  readonly "apiCalls.consentConfirm": "Enable Take action";
120
120
  readonly "apiCalls.consentTitle": "Switch to Take action mode?";
121
+ readonly "appControl.ambiguous": "More than one {{what}} matches “{{name}}”: {{options}}. Say which one.";
122
+ readonly "appControl.blockedPermission": "That isn't available to you here.";
123
+ readonly "appControl.blockedVoice": "I can't open that while the voice screen is up. End the voice session, or use the button in the assistant's header.";
124
+ readonly "appControl.dialog.cancel": "Cancel";
125
+ readonly "appControl.dialog.logoutBody": "You'll be signed out of this account on this device.";
126
+ readonly "appControl.dialog.logoutConfirm": "Log out";
127
+ readonly "appControl.dialog.logoutTitle": "Log out?";
128
+ readonly "appControl.dialog.workspaceBody": "You'll switch to {{name}}. The page may reload.";
129
+ readonly "appControl.dialog.workspaceConfirm": "Switch";
130
+ readonly "appControl.dialog.workspaceTitle": "Switch workspace?";
131
+ readonly "appControl.directionAsc": "ascending";
132
+ readonly "appControl.directionDesc": "descending";
133
+ readonly "appControl.entryAlreadyCollapsed": "{{name}} is already collapsed.";
134
+ readonly "appControl.entryAlreadyExpanded": "{{name}} is already expanded.";
135
+ readonly "appControl.entryCollapsed": "Collapsed {{name}}.";
136
+ readonly "appControl.entryExpanded": "Expanded {{name}}.";
137
+ readonly "appControl.failed": "That didn't work. Nothing was changed.";
138
+ readonly "appControl.filterAlready": "{{filter}}: {{option}} is already on.";
139
+ readonly "appControl.filterChoose": "Which {{filter}}? Options: {{options}}.";
140
+ readonly "appControl.filterCleared": "Cleared the {{filter}} filter.";
141
+ readonly "appControl.filterSet": "Filtered by {{filter}}: {{option}}.";
142
+ readonly "appControl.filtersCleared": "Cleared the filters.";
143
+ readonly "appControl.formOpened": "Opened {{name}}. Nothing is saved until you submit it.";
144
+ readonly "appControl.languageAlready": "The app is already in {{language}}.";
145
+ readonly "appControl.languageNotOffered": "{{language}} isn't one of the languages this app offers.";
146
+ readonly "appControl.languageSet": "The app language is now {{language}}. Assistant replies and voice keep their own settings.";
147
+ readonly "appControl.logoutConfirm": "Log out of your account? Nothing changes until you choose Log out on screen.";
148
+ readonly "appControl.logoutDone": "Logging you out.";
149
+ readonly "appControl.notFound.filter": "{{page}} has no filter option called “{{name}}”. Filters: {{options}}.";
150
+ readonly "appControl.notFound.filterOption": "The {{filter}} filter has no option called “{{name}}”. Options: {{options}}.";
151
+ readonly "appControl.notFound.form": "There's no “{{name}}” form to open on {{page}}. Available: {{options}}.";
152
+ readonly "appControl.notFound.sort": "{{page}} can't be sorted by “{{name}}”. Columns: {{options}}.";
153
+ readonly "appControl.notFound.tab": "There's no tab called “{{name}}” on {{page}}. Tabs: {{options}}.";
154
+ readonly "appControl.notFound.workspace": "I couldn't find a workspace called “{{name}}”. You can switch to: {{options}}.";
155
+ readonly "appControl.opened.context": "Opened the workspace switcher.";
156
+ readonly "appControl.opened.conversation": "Started a new conversation.";
157
+ readonly "appControl.opened.help": "Opened help and keyboard shortcuts.";
158
+ readonly "appControl.opened.history": "Opened your conversation history.";
159
+ readonly "appControl.opened.notifications": "Opened your notifications.";
160
+ readonly "appControl.opened.preview": "Opened the AI preview.";
161
+ readonly "appControl.opened.transcript": "Opened the voice transcript.";
162
+ readonly "appControl.searchCleared": "Cleared the search.";
163
+ readonly "appControl.searchOpened": "Opened search.";
164
+ readonly "appControl.searchOpenedFor": "Opened search for “{{query}}”.";
165
+ readonly "appControl.searched": "Searched {{page}} for “{{query}}”.";
166
+ readonly "appControl.sidebarAlreadyCollapsed": "The sidebar is already collapsed.";
167
+ readonly "appControl.sidebarAlreadyExpanded": "The sidebar is already expanded.";
168
+ readonly "appControl.sidebarCollapsed": "Collapsed the sidebar.";
169
+ readonly "appControl.sidebarExpanded": "Expanded the sidebar.";
170
+ readonly "appControl.sortNeedsField": "Say which column to sort by.";
171
+ readonly "appControl.sorted": "Sorted {{page}} by {{field}}, {{direction}}.";
172
+ readonly "appControl.sortedAlready": "{{page}} is already sorted by {{field}}, {{direction}}.";
173
+ readonly "appControl.tabAlready": "You're already on the {{name}} tab.";
174
+ readonly "appControl.tabOpened": "Opened the {{name}} tab.";
175
+ readonly "appControl.what.column": "column";
176
+ readonly "appControl.what.filter": "filter option";
177
+ readonly "appControl.what.form": "form";
178
+ readonly "appControl.what.menu": "menu";
179
+ readonly "appControl.what.tab": "tab";
180
+ readonly "appControl.what.workspace": "workspace";
181
+ readonly "appControl.workspaceAlready": "You're already in {{name}}.";
182
+ readonly "appControl.workspaceConfirm": "Switch to {{name}}? Nothing changes until you choose Switch on screen.";
183
+ readonly "appControl.workspaceNone": "There is no other workspace to switch to.";
184
+ readonly "appControl.workspaceSwitched": "Switching to {{name}}.";
121
185
  readonly "attachments.blockedMany": "{{count}} attachments didn't upload. Retry or remove them before sending.";
122
186
  readonly "attachments.blockedOne": "{{name}} didn't upload. Retry or remove it before sending.";
123
187
  readonly "attachments.empty": "That file is empty.";
@@ -1 +1 @@
1
- {"version":3,"file":"i18nManifest.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18nManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAa1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoZG,CAAC;AAE5C,mDAAmD;AACnD,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAW/E;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCtE,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,+BAA+B;;EAGjC,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKjE,CAAC;AAEL,kEAAkE;AAClE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,mBAAmB,EACnB,IAAI,GAAG,OAAO,GAAG,mBAAmB,CACrC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,uBAAuB,EAAE,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiCzB"}
1
+ {"version":3,"file":"i18nManifest.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18nManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAa1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAodG,CAAC;AAE5C,mDAAmD;AACnD,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAW/E;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCtE,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,+BAA+B;;EAGjC,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKjE,CAAC;AAEL,kEAAkE;AAClE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,mBAAmB,EACnB,IAAI,GAAG,OAAO,GAAG,mBAAmB,CACrC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,uBAAuB,EAAE,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiCzB"}
@@ -16,6 +16,70 @@ var p = {
16
16
  "apiCalls.consentCancel": "Stay in Ask",
17
17
  "apiCalls.consentConfirm": "Enable Take action",
18
18
  "apiCalls.consentTitle": "Switch to Take action mode?",
19
+ "appControl.ambiguous": "More than one {{what}} matches “{{name}}”: {{options}}. Say which one.",
20
+ "appControl.blockedPermission": "That isn't available to you here.",
21
+ "appControl.blockedVoice": "I can't open that while the voice screen is up. End the voice session, or use the button in the assistant's header.",
22
+ "appControl.dialog.cancel": "Cancel",
23
+ "appControl.dialog.logoutBody": "You'll be signed out of this account on this device.",
24
+ "appControl.dialog.logoutConfirm": "Log out",
25
+ "appControl.dialog.logoutTitle": "Log out?",
26
+ "appControl.dialog.workspaceBody": "You'll switch to {{name}}. The page may reload.",
27
+ "appControl.dialog.workspaceConfirm": "Switch",
28
+ "appControl.dialog.workspaceTitle": "Switch workspace?",
29
+ "appControl.directionAsc": "ascending",
30
+ "appControl.directionDesc": "descending",
31
+ "appControl.entryAlreadyCollapsed": "{{name}} is already collapsed.",
32
+ "appControl.entryAlreadyExpanded": "{{name}} is already expanded.",
33
+ "appControl.entryCollapsed": "Collapsed {{name}}.",
34
+ "appControl.entryExpanded": "Expanded {{name}}.",
35
+ "appControl.failed": "That didn't work. Nothing was changed.",
36
+ "appControl.filterAlready": "{{filter}}: {{option}} is already on.",
37
+ "appControl.filterChoose": "Which {{filter}}? Options: {{options}}.",
38
+ "appControl.filterCleared": "Cleared the {{filter}} filter.",
39
+ "appControl.filterSet": "Filtered by {{filter}}: {{option}}.",
40
+ "appControl.filtersCleared": "Cleared the filters.",
41
+ "appControl.formOpened": "Opened {{name}}. Nothing is saved until you submit it.",
42
+ "appControl.languageAlready": "The app is already in {{language}}.",
43
+ "appControl.languageNotOffered": "{{language}} isn't one of the languages this app offers.",
44
+ "appControl.languageSet": "The app language is now {{language}}. Assistant replies and voice keep their own settings.",
45
+ "appControl.logoutConfirm": "Log out of your account? Nothing changes until you choose Log out on screen.",
46
+ "appControl.logoutDone": "Logging you out.",
47
+ "appControl.notFound.filter": "{{page}} has no filter option called “{{name}}”. Filters: {{options}}.",
48
+ "appControl.notFound.filterOption": "The {{filter}} filter has no option called “{{name}}”. Options: {{options}}.",
49
+ "appControl.notFound.form": "There's no “{{name}}” form to open on {{page}}. Available: {{options}}.",
50
+ "appControl.notFound.sort": "{{page}} can't be sorted by “{{name}}”. Columns: {{options}}.",
51
+ "appControl.notFound.tab": "There's no tab called “{{name}}” on {{page}}. Tabs: {{options}}.",
52
+ "appControl.notFound.workspace": "I couldn't find a workspace called “{{name}}”. You can switch to: {{options}}.",
53
+ "appControl.opened.context": "Opened the workspace switcher.",
54
+ "appControl.opened.conversation": "Started a new conversation.",
55
+ "appControl.opened.help": "Opened help and keyboard shortcuts.",
56
+ "appControl.opened.history": "Opened your conversation history.",
57
+ "appControl.opened.notifications": "Opened your notifications.",
58
+ "appControl.opened.preview": "Opened the AI preview.",
59
+ "appControl.opened.transcript": "Opened the voice transcript.",
60
+ "appControl.searchCleared": "Cleared the search.",
61
+ "appControl.searchOpened": "Opened search.",
62
+ "appControl.searchOpenedFor": "Opened search for “{{query}}”.",
63
+ "appControl.searched": "Searched {{page}} for “{{query}}”.",
64
+ "appControl.sidebarAlreadyCollapsed": "The sidebar is already collapsed.",
65
+ "appControl.sidebarAlreadyExpanded": "The sidebar is already expanded.",
66
+ "appControl.sidebarCollapsed": "Collapsed the sidebar.",
67
+ "appControl.sidebarExpanded": "Expanded the sidebar.",
68
+ "appControl.sortNeedsField": "Say which column to sort by.",
69
+ "appControl.sorted": "Sorted {{page}} by {{field}}, {{direction}}.",
70
+ "appControl.sortedAlready": "{{page}} is already sorted by {{field}}, {{direction}}.",
71
+ "appControl.tabAlready": "You're already on the {{name}} tab.",
72
+ "appControl.tabOpened": "Opened the {{name}} tab.",
73
+ "appControl.what.column": "column",
74
+ "appControl.what.filter": "filter option",
75
+ "appControl.what.form": "form",
76
+ "appControl.what.menu": "menu",
77
+ "appControl.what.tab": "tab",
78
+ "appControl.what.workspace": "workspace",
79
+ "appControl.workspaceAlready": "You're already in {{name}}.",
80
+ "appControl.workspaceConfirm": "Switch to {{name}}? Nothing changes until you choose Switch on screen.",
81
+ "appControl.workspaceNone": "There is no other workspace to switch to.",
82
+ "appControl.workspaceSwitched": "Switching to {{name}}.",
19
83
  "attachments.blockedMany": "{{count}} attachments didn't upload. Retry or remove them before sending.",
20
84
  "attachments.blockedOne": "{{name}} didn't upload. Retry or remove it before sending.",
21
85
  "attachments.empty": "That file is empty.",