@nac3/forge-cli 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/yf.js CHANGED
File without changes
@@ -10,8 +10,18 @@
10
10
  * a stable slug. Returns '' only when the input is empty. */
11
11
  export declare function sanitizeProjectSlug(raw: string): string;
12
12
  export declare function resolveProjectSlug(projectRoot: string): Promise<string>;
13
- /** Sync variant for cases the caller already has the file
14
- * contents (e.g. CLI commands that prefer no IO). Returns ''
15
- * when nothing fits. */
13
+ /** Sync variant for callers that cannot await (el scope del cerebro en
14
+ * `yf chat`, `yf graph`, el anuncio mDNS). Mismo orden de resolucion que
15
+ * la async: yujin.forge.json -> package.json -> basename.
16
+ *
17
+ * 2026-10-02 -- esto leia los archivos con un require de node:fs. El CLI es
18
+ * ESM puro ("type": "module"), asi que ahi `require` no existe: tiraba
19
+ * ReferenceError, el catch exterior se lo tragaba y SIEMPRE devolvia el
20
+ * basename. En C:\adip\kikan daba "kikan" en vez de "yujin-kikan" (el name
21
+ * del package.json), asi que `yf chat` ataba el cerebro al slug equivocado
22
+ * y arrancaba con el cerebro COMPARTIDO en vez del del proyecto -- habia que
23
+ * tocar Plan en el panel para enderezarlo. Con el import estatico de
24
+ * readFileSync las dos variantes dan siempre lo mismo. Returns '' cuando no
25
+ * hay nada que sirva. */
16
26
  export declare function resolveProjectSlugSync(projectRoot: string): string;
17
27
  //# sourceMappingURL=project_slug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project_slug.d.ts","sourceRoot":"","sources":["../../src/chat/project_slug.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;8DAS8D;AAC9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB7E;AAED;;yBAEyB;AACzB,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAwBlE"}
1
+ {"version":3,"file":"project_slug.d.ts","sourceRoot":"","sources":["../../src/chat/project_slug.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;8DAS8D;AAC9D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB7E;AAED;;;;;;;;;;;;0BAY0B;AAC1B,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAsBlE"}
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * ASCII-only.
19
19
  */
20
- import { promises as fs } from 'node:fs';
20
+ import { promises as fs, readFileSync } from 'node:fs';
21
21
  import path from 'node:path';
22
22
  /** Make a raw slug filesystem-safe + stable (PND/dogfood
23
23
  * 2026-06-10). The graph/pending/wiring stores reject slugs with
@@ -69,35 +69,42 @@ export async function resolveProjectSlug(projectRoot) {
69
69
  /* 3. basename */
70
70
  return sanitizeProjectSlug(path.basename(projectRoot));
71
71
  }
72
- /** Sync variant for cases the caller already has the file
73
- * contents (e.g. CLI commands that prefer no IO). Returns ''
74
- * when nothing fits. */
72
+ /** Sync variant for callers that cannot await (el scope del cerebro en
73
+ * `yf chat`, `yf graph`, el anuncio mDNS). Mismo orden de resolucion que
74
+ * la async: yujin.forge.json -> package.json -> basename.
75
+ *
76
+ * 2026-10-02 -- esto leia los archivos con un require de node:fs. El CLI es
77
+ * ESM puro ("type": "module"), asi que ahi `require` no existe: tiraba
78
+ * ReferenceError, el catch exterior se lo tragaba y SIEMPRE devolvia el
79
+ * basename. En C:\adip\kikan daba "kikan" en vez de "yujin-kikan" (el name
80
+ * del package.json), asi que `yf chat` ataba el cerebro al slug equivocado
81
+ * y arrancaba con el cerebro COMPARTIDO en vez del del proyecto -- habia que
82
+ * tocar Plan en el panel para enderezarlo. Con el import estatico de
83
+ * readFileSync las dos variantes dan siempre lo mismo. Returns '' cuando no
84
+ * hay nada que sirva. */
75
85
  export function resolveProjectSlugSync(projectRoot) {
76
- /* Best effort only -- callers should prefer the async version. */
86
+ /* 1. yujin.forge.json -> project_slug / project_name */
77
87
  try {
78
- /* eslint-disable @typescript-eslint/no-require-imports */
79
- const fsSync = require('node:fs');
80
- try {
81
- const raw = fsSync.readFileSync(path.join(projectRoot, 'yujin.forge.json'), 'utf-8');
82
- const parsed = JSON.parse(raw);
83
- if (parsed && typeof parsed.project_slug === 'string' && parsed.project_slug.trim() !== '') {
84
- return sanitizeProjectSlug(parsed.project_slug);
85
- }
86
- if (parsed && typeof parsed.project_name === 'string' && parsed.project_name.trim() !== '') {
87
- return sanitizeProjectSlug(parsed.project_name);
88
- }
88
+ const raw = readFileSync(path.join(projectRoot, 'yujin.forge.json'), 'utf-8');
89
+ const parsed = JSON.parse(raw);
90
+ if (parsed && typeof parsed.project_slug === 'string' && parsed.project_slug.trim() !== '') {
91
+ return sanitizeProjectSlug(parsed.project_slug);
89
92
  }
90
- catch { /* */ }
91
- try {
92
- const raw = fsSync.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8');
93
- const parsed = JSON.parse(raw);
94
- if (parsed && typeof parsed.name === 'string' && parsed.name.trim() !== '') {
95
- return sanitizeProjectSlug(parsed.name);
96
- }
93
+ if (parsed && typeof parsed.project_name === 'string' && parsed.project_name.trim() !== '') {
94
+ return sanitizeProjectSlug(parsed.project_name);
97
95
  }
98
- catch { /* */ }
99
96
  }
100
- catch { /* */ }
97
+ catch { /* fall through */ }
98
+ /* 2. package.json -> name */
99
+ try {
100
+ const raw = readFileSync(path.join(projectRoot, 'package.json'), 'utf-8');
101
+ const parsed = JSON.parse(raw);
102
+ if (parsed && typeof parsed.name === 'string' && parsed.name.trim() !== '') {
103
+ return sanitizeProjectSlug(parsed.name);
104
+ }
105
+ }
106
+ catch { /* fall through */ }
107
+ /* 3. basename */
101
108
  return sanitizeProjectSlug(path.basename(projectRoot));
102
109
  }
103
110
  //# sourceMappingURL=project_slug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project_slug.js","sourceRoot":"","sources":["../../src/chat/project_slug.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project_slug.js","sourceRoot":"","sources":["../../src/chat/project_slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;8DAS8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACxB,8CAA8C;IAC9C,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACzC,IAAI,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC;QAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;SAChB,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAG,yBAAyB;SAC1D,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAW,6BAA6B;SAC9D,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAI,+BAA+B;SAChE,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAU,8BAA8B;IAClE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB;IAC1D,sCAAsC;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QACnF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3F,OAAO,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3F,OAAO,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC9B,0BAA0B;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,OAAO,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC9B,iBAAiB;IACjB,OAAO,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;0BAY0B;AAC1B,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,wDAAwD;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3F,OAAO,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3F,OAAO,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC9B,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,OAAO,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC9B,iBAAiB;IACjB,OAAO,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -71,6 +71,16 @@ export interface StartedServer {
71
71
  * publish its result on the typed 'session_reply' lane back to the
72
72
  * parent (yujin.session.*). */
73
73
  bridge?: import('./bridge.js').BridgeHandle | null;
74
+ /** Hot re-anchor: re-apunta ESTA instancia viva a otro proyecto (lo que
75
+ * hace yujin.project.set-root). Expuesto porque es un cambio de estado de
76
+ * sesion -- scope del cerebro, modalidad Plan/Console, grafo, watcher --
77
+ * y hasta ahora solo se alcanzaba por un verbo con token, asi que los
78
+ * tests tenian que mockearlo. */
79
+ reanchor: (newRoot: string) => Promise<{
80
+ projectRoot: string;
81
+ projectName: string;
82
+ projectSlug: string;
83
+ }>;
74
84
  }
75
85
  export declare function startChatServer(opts: StartOptions): Promise<StartedServer>;
76
86
  interface Ctx {
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/chat/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/chat/server.ts"],"names":[],"mappings":"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"}
@@ -131,6 +131,20 @@ export async function startChatServer(opts) {
131
131
  * CLI + panel converge. */
132
132
  const { resolveProjectSlug } = await import('./project_slug.js');
133
133
  const projectSlug = await resolveProjectSlug(opts.projectRoot);
134
+ /* Cerebro por instancia (Pablo, 2026-09-30). Habia una sola config para
135
+ * todas: cambiar el cerebro en un `yf chat` lo cambiaba en todos. Este
136
+ * proceso queda atado al cerebro de SU proyecto -- lee el del proyecto si
137
+ * existe y cae al global si no, asi que nada cambia hasta que alguien
138
+ * elige uno aca, y ahi el cambio se queda aca.
139
+ *
140
+ * 2026-10-03 -- esto estaba DESPUES de construir el brain client, asi que
141
+ * la modalidad (Plan/Console) se decidia con el scope todavia sin atar.
142
+ * Va antes de cualquier lectura de brain_config. */
143
+ try {
144
+ const { setBrainConfigScope } = await import('../core/brain_config.js');
145
+ setBrainConfigScope(projectSlug);
146
+ }
147
+ catch { /* sin scope se sigue usando el global, como antes */ }
134
148
  /* Director sprint slice 9 -- hydrate ingest sessions from disk
135
149
  * for this project so spec extract+plan survive restarts. */
136
150
  try {
@@ -234,9 +248,42 @@ export async function startChatServer(opts) {
234
248
  }
235
249
  return new ClaudeClient();
236
250
  }
251
+ /* De donde sale la modalidad cuando el llamador no la fija: la config del
252
+ * cerebro de ESTE proyecto (ya scopeada arriba) y, si no dice nada, el
253
+ * camino que eligio el wizard. Prioridad: --provider > brain_config >
254
+ * wizard_state > anthropic-api.
255
+ *
256
+ * 2026-10-03 -- esto se derivaba en `yf chat` ANTES de arrancar el server,
257
+ * con un scope resuelto por otro camino (resolveProjectSlugSync). Cuando
258
+ * los dos slugs no coincidian, el boot leia la config del proyecto
259
+ * equivocado: el panel mostraba la modalidad correcta (lee la config ya
260
+ * scopeada) y el cerebro vivo era el de arrastre. Ahora la cadena vive
261
+ * aca, que es donde se resuelve el slug autoritativo. */
262
+ async function providerFromBrainConfig() {
263
+ try {
264
+ const { readBrainConfig } = await import('../core/brain_config.js');
265
+ const bc = await readBrainConfig();
266
+ if (bc.anthropic_mode === 'plan')
267
+ return 'claude-code-cli';
268
+ if (bc.anthropic_mode === 'console')
269
+ return 'anthropic-api';
270
+ }
271
+ catch { /* sin config -> probamos el wizard */ }
272
+ try {
273
+ const { readWizardState } = await import('../core/wizard_state.js');
274
+ if ((await readWizardState()).path_chosen === 'claude_plan')
275
+ return 'claude-code-cli';
276
+ }
277
+ catch { /* swallow */ }
278
+ return null;
279
+ }
280
+ /* `--provider` -- y el anthropic-api forzado de una sub-sesion agentMode,
281
+ * que es lo que hace que el scope de verbos aplique -- pisan la config y
282
+ * NO se re-derivan: ni al boot ni al cambiar de proyecto. */
283
+ const providerPinned = !!opts.chatProvider;
237
284
  /* MUTABLE per-session provider state, so flipping Plan/Console in the
238
285
  * panel applies LIVE (mirrors the reanchor pattern). */
239
- let activeChatProvider = opts.chatProvider ?? 'anthropic-api';
286
+ let activeChatProvider = opts.chatProvider ?? (await providerFromBrainConfig()) ?? 'anthropic-api';
240
287
  let claude = opts.claude ?? await buildClaudeClient(activeChatProvider);
241
288
  /** Hot-swap the brain provider when the user flips the mode in the
242
289
  * panel. 'plan' -> claude-code-cli (subscription); 'console' ->
@@ -256,6 +303,25 @@ export async function startChatServer(opts) {
256
303
  catch { /* */ }
257
304
  return true;
258
305
  }
306
+ /** El cerebro sigue al proyecto activo: despues de un reanchor hay que
307
+ * re-derivar la modalidad del proyecto NUEVO. Sin esto el provider
308
+ * quedaba de arrastre (el del proyecto anterior) mientras el selector del
309
+ * panel -- que lee la config ya re-scopeada -- mostraba la del nuevo, y
310
+ * solo se enderezaba al tocar Plan/Console a mano. */
311
+ async function applyProviderFromBrainConfig() {
312
+ if (providerPinned || opts.claude)
313
+ return false;
314
+ const target = (await providerFromBrainConfig()) ?? 'anthropic-api';
315
+ if (target === activeChatProvider)
316
+ return false;
317
+ claude = await buildClaudeClient(target);
318
+ activeChatProvider = target;
319
+ try {
320
+ console.error('[brain] provider del proyecto activo -> ' + target);
321
+ }
322
+ catch { /* */ }
323
+ return true;
324
+ }
259
325
  const voice = opts.voice ?? new VoiceRouter({
260
326
  configDir: configDir(),
261
327
  registry: buildDefaultRegistry(),
@@ -289,16 +355,6 @@ export async function startChatServer(opts) {
289
355
  * handlers (que leen de `session`) pasan a apuntar al nuevo root
290
356
  * sin reiniciar el panel. */
291
357
  const session = { projectRoot: opts.projectRoot, projectName, projectSlug };
292
- /* Cerebro por instancia (Pablo, 2026-09-30). Habia una sola config para
293
- * todas: cambiar el cerebro en un `yf chat` lo cambiaba en todos. Este
294
- * proceso queda atado al cerebro de SU proyecto -- lee el del proyecto si
295
- * existe y cae al global si no, asi que nada cambia hasta que alguien
296
- * elige uno aca, y ahi el cambio se queda aca. */
297
- try {
298
- const { setBrainConfigScope } = await import('../core/brain_config.js');
299
- setBrainConfigScope(projectSlug);
300
- }
301
- catch { /* sin scope se sigue usando el global, como antes */ }
302
358
  /* Project registry (task #33) -- record the project we just opened in
303
359
  * ~/.yujin-forge/projects.json + mark it active, so the project
304
360
  * selector (panel + mobile) always lists at least the current one.
@@ -344,6 +400,15 @@ export async function startChatServer(opts) {
344
400
  setBrainConfigScope(session.projectSlug);
345
401
  }
346
402
  catch { /* best-effort */ }
403
+ /* ...y con el scope nuevo, la modalidad (Plan/Console) del proyecto
404
+ * nuevo. Antes se quedaba la del anterior hasta tocarla a mano. */
405
+ try {
406
+ if (await applyProviderFromBrainConfig()) {
407
+ chatLog('Cerebro de este proyecto: '
408
+ + (activeChatProvider === 'claude-code-cli' ? 'Plan (suscripcion)' : 'Console (API)') + '.');
409
+ }
410
+ }
411
+ catch { /* best-effort */ }
347
412
  /* keep the registry in sync after a hot switch (task #33) */
348
413
  try {
349
414
  await upsertProject({ slug: session.projectSlug, path: abs });
@@ -492,6 +557,16 @@ export async function startChatServer(opts) {
492
557
  };
493
558
  tryListen(opts.port);
494
559
  });
560
+ /* El puerto REAL, no el pedido (2026-10-03). El retry de EADDRINUSE ya
561
+ * reescribia opts.port, pero un port:0 (liga uno efimero) no pasa por ahi:
562
+ * opts.port se quedaba en 0 y entonces la url, el lock de instancia y el
563
+ * panelBridge del subproceso apuntaban a un puerto que no existe. */
564
+ {
565
+ const addr = server.address();
566
+ if (addr && typeof addr === 'object' && typeof addr.port === 'number' && addr.port > 0) {
567
+ opts.port = addr.port;
568
+ }
569
+ }
495
570
  /* Port-race fix (2026-09-01). The eager `claude` client above was built
496
571
  * BEFORE the EADDRINUSE retry could finalize opts.port. The CLI client
497
572
  * FREEZES panelBridge.port at construction, so when two instances race for
@@ -605,6 +680,7 @@ export async function startChatServer(opts) {
605
680
  port: opts.port,
606
681
  store,
607
682
  bridge: bridgeHandle,
683
+ reanchor,
608
684
  close: () => new Promise((resolve) => {
609
685
  /* alpha.59w -- stop the component watcher on shutdown so
610
686
  * vitest does not hang on lingering fs watchers. */