workday-daemon 0.18.0 → 0.20.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.
@@ -0,0 +1,21 @@
1
+ import type { JiraIssue, PushLogEntry, PushPlanEntry, PushTombstone, TaskDayReport, TempoWorklog } from '../core/types.js';
2
+ export declare function formatHours(seconds: number): string;
3
+ export interface PushPlanOptions {
4
+ readonly tombstones?: readonly PushTombstone[];
5
+ readonly from?: string;
6
+ readonly to?: string;
7
+ readonly datesWithData?: ReadonlySet<string>;
8
+ }
9
+ /**
10
+ * Build the push plan: desired report vs Tempo snapshot, ownership from
11
+ * push-log. Orphaned desired entries re-adopt unowned worklogs on the same
12
+ * (date, issue) — by exact content for manual entries, by being the only
13
+ * candidate for session aggregates — instead of blindly creating duplicates.
14
+ */
15
+ export declare function buildPushPlan(report: readonly TaskDayReport[], jiraMap: Map<string, JiraIssue>, pushLog: Record<string, PushLogEntry>, tempoWorklogs: readonly TempoWorklog[], options?: PushPlanOptions): PushPlanEntry[];
16
+ /**
17
+ * Offline drift check for one day — the status side of the same diff. Works
18
+ * without Jira (ownership keys carry date|task), against a month snapshot.
19
+ * Returns human-readable drift lines; empty array = verified parity.
20
+ */
21
+ export declare function computeDayDrift(date: string, entries: readonly TaskDayReport[], pushLog: Record<string, PushLogEntry>, snapById: ReadonlyMap<number, TempoWorklog>, tombstones?: readonly PushTombstone[]): string[];
@@ -0,0 +1,300 @@
1
+ // Mirror-sync diff engine. Desired state (the local report) is compared
2
+ // against the ACTUAL Tempo state (worklog snapshot); push-log serves only as
3
+ // the ownership map localKey → tempoWorklogId, never as a source of truth
4
+ // about worklog content. Matching is identity-based (tempoWorklogId): field
5
+ // edits — time, text, activity, even a day move — keep the id on the Tempo
6
+ // side (verified live 2026-07-07); only a ticket move recreates the worklog.
7
+ import { TEMPO_TOLERANCE_SECONDS } from '../core/constants.js';
8
+ import { pushLogKey } from './push-log.js';
9
+ export function formatHours(seconds) {
10
+ const hours = seconds / 3600;
11
+ const rounded1 = parseFloat(hours.toFixed(1));
12
+ if (Math.abs(hours - rounded1) < 0.01)
13
+ return `${hours.toFixed(1)}h`;
14
+ return `${hours.toFixed(2)}h`;
15
+ }
16
+ function timeDrifts(a, b) {
17
+ return Math.abs(a - b) > TEMPO_TOLERANCE_SECONDS;
18
+ }
19
+ // Tempo fills "Working on work item <KEY>" into worklogs saved with an empty
20
+ // description — the placeholder and an empty description are the same thing.
21
+ // Without this a pushed empty-description entry drifts forever: our PUT sends
22
+ // '' and Tempo immediately re-inserts the placeholder.
23
+ function normalizeDescription(description, task) {
24
+ const desc = description ?? '';
25
+ return desc === `Working on work item ${task}` ? '' : desc;
26
+ }
27
+ function manualTextDrifts(entry, wl) {
28
+ return normalizeDescription(wl.description, entry.task) !== normalizeDescription(entry.description, entry.task)
29
+ || (wl.activity ?? '') !== (entry.activity ?? '');
30
+ }
31
+ /** The worklog no longer matches what we sent — someone edited it in Tempo. */
32
+ function remoteChanged(own, wl, entryDate, kind, task) {
33
+ if (own.timeSpentSeconds !== wl.timeSpentSeconds)
34
+ return true;
35
+ if (wl.startDate !== entryDate)
36
+ return true;
37
+ if (kind === 'manual') {
38
+ return normalizeDescription(own.description, task) !== normalizeDescription(wl.description, task)
39
+ || (own.activity ?? '') !== (wl.activity ?? '');
40
+ }
41
+ return false;
42
+ }
43
+ /** Worklog content equals a manual entry (adoption criterion). */
44
+ function contentMatches(entry, wl) {
45
+ return !timeDrifts(wl.timeSpentSeconds, entry.totalSeconds) && !manualTextDrifts(entry, wl);
46
+ }
47
+ /**
48
+ * Build the push plan: desired report vs Tempo snapshot, ownership from
49
+ * push-log. Orphaned desired entries re-adopt unowned worklogs on the same
50
+ * (date, issue) — by exact content for manual entries, by being the only
51
+ * candidate for session aggregates — instead of blindly creating duplicates.
52
+ */
53
+ export function buildPushPlan(report, jiraMap, pushLog, tempoWorklogs, options = {}) {
54
+ const plan = [];
55
+ const tombstones = options.tombstones ?? [];
56
+ const snapById = new Map();
57
+ const byDateIssue = new Map();
58
+ for (const wl of tempoWorklogs) {
59
+ snapById.set(wl.tempoWorklogId, wl);
60
+ const key = `${wl.startDate}|${wl.issueId}`;
61
+ const list = byDateIssue.get(key) ?? [];
62
+ list.push(wl);
63
+ byDateIssue.set(key, list);
64
+ }
65
+ // Every worklog id claimed by ANY ownership key — never an adoption candidate.
66
+ const ownedIds = new Set();
67
+ for (const logEntry of Object.values(pushLog))
68
+ ownedIds.add(logEntry.tempoWorklogId);
69
+ const accounted = new Set();
70
+ const pending = new Map();
71
+ // ── Pass 1: desired entries with a live owned worklog → field diff ──
72
+ for (const entry of report) {
73
+ const jira = jiraMap.get(entry.task);
74
+ if (!jira) {
75
+ plan.push({
76
+ date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
77
+ action: 'error', detail: 'Unresolved in Jira',
78
+ kind: entry.kind, entryId: entry.entryId, description: entry.description, activity: entry.activity,
79
+ });
80
+ continue;
81
+ }
82
+ const base = {
83
+ date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
84
+ issueId: jira.issueId, kind: entry.kind, entryId: entry.entryId,
85
+ };
86
+ const key = pushLogKey(entry.date, entry.task, entry.kind === 'manual' ? entry.entryId : undefined);
87
+ const own = pushLog[key];
88
+ const wl = own ? snapById.get(own.tempoWorklogId) : undefined;
89
+ if (own && wl) {
90
+ accounted.add(wl.tempoWorklogId);
91
+ if (wl.issueId !== jira.issueId) {
92
+ // Same id on a different issue — identity is confused; never guess.
93
+ plan.push({ ...base, action: 'error', existingWorklogId: wl.tempoWorklogId, detail: `Worklog #${wl.tempoWorklogId} sits on another issue in Tempo — resolve manually` });
94
+ continue;
95
+ }
96
+ const moved = wl.startDate !== entry.date;
97
+ const time = timeDrifts(wl.timeSpentSeconds, entry.totalSeconds);
98
+ const text = entry.kind === 'manual' && manualTextDrifts(entry, wl);
99
+ if (!moved && !time && !text) {
100
+ plan.push({ ...base, action: 'skip', detail: `In sync (${formatHours(wl.timeSpentSeconds)})`, existingWorklogId: wl.tempoWorklogId, description: entry.description, activity: entry.activity });
101
+ continue;
102
+ }
103
+ const parts = [];
104
+ if (time)
105
+ parts.push(`${formatHours(wl.timeSpentSeconds)} → ${formatHours(entry.totalSeconds)}`);
106
+ if (text)
107
+ parts.push('text/activity changed');
108
+ if (moved)
109
+ parts.push(`moved to ${wl.startDate} in Tempo → restoring ${entry.date}`);
110
+ plan.push({
111
+ ...base,
112
+ action: 'update',
113
+ detail: parts.join('; '),
114
+ existingWorklogId: wl.tempoWorklogId,
115
+ // Session worklogs: text/activity are Tempo-side cosmetics we do not
116
+ // manage — carry the current remote values through the PUT untouched.
117
+ description: entry.kind === 'manual' ? entry.description : wl.description,
118
+ activity: entry.kind === 'manual' ? entry.activity : wl.activity,
119
+ ...(remoteChanged(own, wl, entry.date, entry.kind, entry.task) ? { conflict: true } : {}),
120
+ });
121
+ continue;
122
+ }
123
+ // Ownerless (never pushed) or orphaned (worklog vanished remotely).
124
+ const group = pending.get(`${entry.date}|${jira.issueId}`) ?? { manuals: [], sessions: [] };
125
+ const item = { entry, issueId: jira.issueId, hadOwnership: !!own };
126
+ (entry.kind === 'manual' ? group.manuals : group.sessions).push(item);
127
+ pending.set(`${entry.date}|${jira.issueId}`, group);
128
+ }
129
+ // ── Pass 2: adoption / creation per (date, issue) ──
130
+ for (const [dateIssueKey, group] of pending) {
131
+ const pool = (byDateIssue.get(dateIssueKey) ?? [])
132
+ .filter(w => !accounted.has(w.tempoWorklogId) && !ownedIds.has(w.tempoWorklogId))
133
+ .sort((a, b) => a.tempoWorklogId - b.tempoWorklogId);
134
+ // Manual entries adopt by exact content — an identical unowned worklog
135
+ // IS this entry (either our lost push or the user logging the same thing
136
+ // directly in Tempo); any assignment among equals is semantically equal.
137
+ for (const { entry, issueId, hadOwnership } of [...group.manuals].sort((a, b) => (a.entry.entryId ?? '').localeCompare(b.entry.entryId ?? ''))) {
138
+ const base = {
139
+ date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
140
+ issueId, kind: entry.kind, entryId: entry.entryId,
141
+ description: entry.description, activity: entry.activity,
142
+ };
143
+ const idx = pool.findIndex(w => contentMatches(entry, w));
144
+ if (idx !== -1) {
145
+ const wl = pool.splice(idx, 1)[0];
146
+ accounted.add(wl.tempoWorklogId);
147
+ plan.push({ ...base, action: 'update', existingWorklogId: wl.tempoWorklogId, detail: `Re-adopted worklog #${wl.tempoWorklogId}` });
148
+ }
149
+ else {
150
+ plan.push({ ...base, action: 'create', detail: `New (${formatHours(entry.totalSeconds)})`, ...(hadOwnership ? { conflict: true } : {}) });
151
+ }
152
+ }
153
+ // Session aggregate: adopt the single remaining candidate; a multi-way
154
+ // ambiguity is only accepted when the candidates sum to the desired time
155
+ // (a split done in Tempo) — otherwise refuse to guess.
156
+ for (const { entry, issueId, hadOwnership } of group.sessions) {
157
+ const base = {
158
+ date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
159
+ issueId, kind: entry.kind,
160
+ };
161
+ if (pool.length === 1) {
162
+ const wl = pool.pop();
163
+ accounted.add(wl.tempoWorklogId);
164
+ const detail = timeDrifts(wl.timeSpentSeconds, entry.totalSeconds)
165
+ ? `Re-adopted worklog #${wl.tempoWorklogId}: ${formatHours(wl.timeSpentSeconds)} → ${formatHours(entry.totalSeconds)}`
166
+ : `Re-adopted worklog #${wl.tempoWorklogId}`;
167
+ plan.push({ ...base, action: 'update', existingWorklogId: wl.tempoWorklogId, detail, description: wl.description, activity: wl.activity });
168
+ }
169
+ else if (pool.length > 1) {
170
+ const sum = pool.reduce((s, w) => s + w.timeSpentSeconds, 0);
171
+ const ids = pool.map(w => w.tempoWorklogId);
172
+ for (const w of pool)
173
+ accounted.add(w.tempoWorklogId);
174
+ pool.length = 0;
175
+ if (!timeDrifts(sum, entry.totalSeconds)) {
176
+ plan.push({ ...base, action: 'skip', detail: `Exists in Tempo (${ids.length} worklogs, ${formatHours(sum)})`, extraWorklogIds: ids });
177
+ }
178
+ else {
179
+ plan.push({ ...base, action: 'error', detail: `Ambiguous: ${ids.length} unowned worklogs (${formatHours(sum)}) vs local ${formatHours(entry.totalSeconds)} — resolve in Tempo`, extraWorklogIds: ids });
180
+ }
181
+ }
182
+ else {
183
+ plan.push({ ...base, action: 'create', detail: `New (${formatHours(entry.totalSeconds)})`, ...(hadOwnership ? { conflict: true } : {}) });
184
+ }
185
+ }
186
+ }
187
+ // ── Pass 3: delete propagation ──
188
+ // Strays: ownership keys inside the range whose local line vanished (the
189
+ // user deleted a session / re-tasked a day after pushing) while the worklog
190
+ // still lives in Tempo. Local state is the source of truth — delete, unless
191
+ // the day file itself is missing (that is data loss, not intent).
192
+ if (options.from && options.to) {
193
+ for (const [key, own] of Object.entries(pushLog)) {
194
+ const [kDate, kTask, kManual] = key.split('|');
195
+ if (kDate < options.from || kDate > options.to)
196
+ continue;
197
+ const wl = snapById.get(own.tempoWorklogId);
198
+ if (!wl || accounted.has(wl.tempoWorklogId))
199
+ continue;
200
+ accounted.add(wl.tempoWorklogId);
201
+ const base = {
202
+ date: kDate, task: kTask, targetSeconds: wl.timeSpentSeconds,
203
+ issueId: wl.issueId, existingWorklogId: wl.tempoWorklogId,
204
+ kind: (kManual ? 'manual' : 'session'),
205
+ ...(kManual ? { entryId: kManual.slice(2) } : {}),
206
+ };
207
+ if (options.datesWithData?.has(kDate)) {
208
+ plan.push({ ...base, action: 'delete', detail: `Deleted locally → removing from Tempo (${formatHours(wl.timeSpentSeconds)})` });
209
+ }
210
+ else {
211
+ plan.push({ ...base, action: 'skip', detail: `Owned worklog kept — no local data for ${kDate}` });
212
+ }
213
+ }
214
+ }
215
+ // Tombstones: explicit local deletions of pushed manual entries.
216
+ for (const t of tombstones) {
217
+ const wl = snapById.get(t.tempoWorklogId);
218
+ if (!wl || accounted.has(wl.tempoWorklogId))
219
+ continue;
220
+ accounted.add(wl.tempoWorklogId);
221
+ plan.push({
222
+ date: t.date, task: t.task, targetSeconds: wl.timeSpentSeconds,
223
+ issueId: wl.issueId, existingWorklogId: wl.tempoWorklogId,
224
+ kind: 'manual', entryId: t.entryId,
225
+ action: 'delete', detail: `Deleted locally → removing from Tempo (${formatHours(wl.timeSpentSeconds)})`,
226
+ });
227
+ }
228
+ // ── Pass 4: unmatched Tempo worklogs — show, never mutate ──
229
+ for (const wl of tempoWorklogs) {
230
+ if (accounted.has(wl.tempoWorklogId))
231
+ continue;
232
+ let taskKey = `issue:${wl.issueId}`;
233
+ for (const [key, jira] of jiraMap) {
234
+ if (jira.issueId === wl.issueId) {
235
+ taskKey = key;
236
+ break;
237
+ }
238
+ }
239
+ plan.push({
240
+ date: wl.startDate, task: taskKey, targetSeconds: wl.timeSpentSeconds,
241
+ action: 'skip', detail: `Tempo only (${formatHours(wl.timeSpentSeconds)})`,
242
+ existingWorklogId: wl.tempoWorklogId, kind: 'session',
243
+ });
244
+ }
245
+ plan.sort((a, b) => a.date.localeCompare(b.date) || a.task.localeCompare(b.task));
246
+ return plan;
247
+ }
248
+ /**
249
+ * Offline drift check for one day — the status side of the same diff. Works
250
+ * without Jira (ownership keys carry date|task), against a month snapshot.
251
+ * Returns human-readable drift lines; empty array = verified parity.
252
+ */
253
+ export function computeDayDrift(date, entries, pushLog, snapById, tombstones = []) {
254
+ const drift = [];
255
+ const claimed = new Set();
256
+ for (const entry of entries) {
257
+ const key = pushLogKey(date, entry.task, entry.kind === 'manual' ? entry.entryId : undefined);
258
+ const label = entry.kind === 'manual' ? `${entry.task} (manual)` : entry.task;
259
+ const own = pushLog[key];
260
+ const wl = own ? snapById.get(own.tempoWorklogId) : undefined;
261
+ if (!own || !wl) {
262
+ drift.push(`${label}: not pushed (${formatHours(entry.totalSeconds)})`);
263
+ continue;
264
+ }
265
+ claimed.add(wl.tempoWorklogId);
266
+ // Field-drift lines only — an entry whose remote copy matches the local
267
+ // desired state stays parity even when the push-log baseline is stale.
268
+ const suffix = remoteChanged(own, wl, date, entry.kind, entry.task) ? ' — edited in Tempo' : '';
269
+ if (wl.startDate !== date) {
270
+ drift.push(`${label}: moved to ${wl.startDate} in Tempo`);
271
+ }
272
+ if (timeDrifts(wl.timeSpentSeconds, entry.totalSeconds)) {
273
+ drift.push(`${label}: ${formatHours(wl.timeSpentSeconds)} in Tempo vs ${formatHours(entry.totalSeconds)} local${suffix}`);
274
+ }
275
+ if (entry.kind === 'manual' && manualTextDrifts(entry, wl)) {
276
+ drift.push(`${label}: description/activity differ${suffix}`);
277
+ }
278
+ }
279
+ // Strays: ownership keys of this date whose local line is gone while the
280
+ // worklog still lives in Tempo — the next push deletes it.
281
+ for (const [key, own] of Object.entries(pushLog)) {
282
+ if (!key.startsWith(`${date}|`))
283
+ continue;
284
+ const wl = snapById.get(own.tempoWorklogId);
285
+ if (!wl || claimed.has(own.tempoWorklogId))
286
+ continue;
287
+ drift.push(`${key.split('|')[1]}: deleted locally, still in Tempo (${formatHours(wl.timeSpentSeconds)})`);
288
+ }
289
+ // Tombstoned manual entries awaiting the delete pass.
290
+ for (const t of tombstones) {
291
+ if (t.date !== date)
292
+ continue;
293
+ const wl = snapById.get(t.tempoWorklogId);
294
+ if (!wl || claimed.has(t.tempoWorklogId))
295
+ continue;
296
+ drift.push(`${t.task}: pending delete in Tempo (${formatHours(wl.timeSpentSeconds)})`);
297
+ }
298
+ return drift;
299
+ }
300
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/push/reconcile.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,26 @@ export interface TempoWorkAttribute {
14
14
  readonly values?: readonly string[];
15
15
  readonly names?: Readonly<Record<string, string>>;
16
16
  }
17
+ /** Worklog as the /4/worklogs list endpoints return it. */
18
+ export interface RawTempoWorklog {
19
+ readonly tempoWorklogId: number;
20
+ readonly issue?: {
21
+ readonly id: number;
22
+ };
23
+ readonly issueId?: number;
24
+ readonly startDate: string;
25
+ readonly timeSpentSeconds: number;
26
+ readonly description?: string;
27
+ readonly updatedAt?: string;
28
+ readonly attributes?: {
29
+ readonly values?: ReadonlyArray<{
30
+ readonly key: string;
31
+ readonly value: string;
32
+ }>;
33
+ };
34
+ }
35
+ /** Map a raw API worklog to our full snapshot shape (description/activity/updatedAt kept). */
36
+ export declare function mapTempoWorklog(raw: RawTempoWorklog): TempoWorklog;
17
37
  /** Tempo HTTP failure with the status preserved — 403 means "scope missing". */
18
38
  export declare class TempoApiError extends Error {
19
39
  readonly status: number;
@@ -1,4 +1,17 @@
1
1
  import { TEMPO_BASE_URL, TEMPO_RATE_LIMIT_MS, ACTIVITY_ATTRIBUTE_KEY, DEFAULT_ACTIVITY } from '../core/constants.js';
2
+ /** Map a raw API worklog to our full snapshot shape (description/activity/updatedAt kept). */
3
+ export function mapTempoWorklog(raw) {
4
+ const activity = raw.attributes?.values?.find(v => v.key === ACTIVITY_ATTRIBUTE_KEY)?.value;
5
+ return {
6
+ tempoWorklogId: raw.tempoWorklogId,
7
+ issueId: raw.issue?.id ?? raw.issueId ?? 0,
8
+ startDate: raw.startDate,
9
+ timeSpentSeconds: raw.timeSpentSeconds,
10
+ ...(raw.description !== undefined ? { description: raw.description } : {}),
11
+ ...(activity !== undefined ? { activity } : {}),
12
+ ...(raw.updatedAt !== undefined ? { updatedAt: raw.updatedAt } : {}),
13
+ };
14
+ }
2
15
  /** Tempo HTTP failure with the status preserved — 403 means "scope missing". */
3
16
  export class TempoApiError extends Error {
4
17
  status;
@@ -53,16 +66,13 @@ export class TempoClient {
53
66
  const path = `/4/worklogs/user/${encodeURIComponent(accountId)}`
54
67
  + `?from=${from}&to=${to}&offset=${offset}&limit=${limit}`;
55
68
  const response = await this.request('GET', path);
56
- for (const wl of response.results ?? []) {
57
- allWorklogs.push({
58
- tempoWorklogId: wl.tempoWorklogId,
59
- issueId: wl.issue?.id ?? wl.issueId ?? 0,
60
- startDate: wl.startDate,
61
- timeSpentSeconds: wl.timeSpentSeconds,
62
- });
69
+ const items = response.results ?? [];
70
+ for (const wl of items) {
71
+ allWorklogs.push(mapTempoWorklog(wl));
63
72
  }
64
- const meta = response.metadata;
65
- if (!meta || offset + limit >= meta.count)
73
+ // metadata.count is the PAGE size, not the total — the only reliable
74
+ // "more pages" signal is metadata.next (verified live 2026-07-07).
75
+ if (!response.metadata?.next || items.length === 0)
66
76
  break;
67
77
  offset += limit;
68
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tempo-client.js","sourceRoot":"","sources":["../../src/push/tempo-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tempo-client.js","sourceRoot":"","sources":["../../src/push/tempo-client.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { type AppConfig, type Secrets, type TaskDayReport, type TempoWorklog, type JiraIssue, type PushPlanEntry, type PushLogEntry, type PushResult, type PushResponse } from '../core/types.js';
1
+ import { type AppConfig, type Secrets, type PushPlanEntry, type PushResult, type PushResponse } from '../core/types.js';
2
2
  import { TempoClient } from './tempo-client.js';
3
- /** Build a plan by comparing report entries with push log and existing Tempo worklogs */
4
- export declare function buildPushPlan(report: readonly TaskDayReport[], jiraMap: Map<string, JiraIssue>, pushLog: Record<string, PushLogEntry>, tempoWorklogs: readonly TempoWorklog[]): PushPlanEntry[];
3
+ import { buildPushPlan } from './reconcile.js';
4
+ export { buildPushPlan };
5
5
  /** Execute mutations from the plan, update push log */
6
6
  export declare function executePlan(plan: readonly PushPlanEntry[], tempoClient: TempoClient, accountId: string): Promise<PushResult>;
7
7
  interface RunPushOptions {
@@ -11,7 +11,7 @@ interface RunPushOptions {
11
11
  readonly config: AppConfig;
12
12
  readonly secrets: Secrets;
13
13
  readonly filePath?: string;
14
+ readonly force?: boolean;
14
15
  }
15
16
  /** Full push pipeline: build report → resolve Jira → fetch Tempo → plan → execute */
16
17
  export declare function runPush(options: RunPushOptions): Promise<PushResponse>;
17
- export {};