@allixsenos/asu 0.3.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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/dist/cache.d.ts +15 -0
  4. package/dist/cache.js +112 -0
  5. package/dist/cache.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.js +95 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/errors.d.ts +10 -0
  10. package/dist/errors.js +24 -0
  11. package/dist/errors.js.map +1 -0
  12. package/dist/index.d.ts +11 -0
  13. package/dist/index.js +8 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/local.d.ts +14 -0
  16. package/dist/local.js +121 -0
  17. package/dist/local.js.map +1 -0
  18. package/dist/models.d.ts +184 -0
  19. package/dist/models.js +57 -0
  20. package/dist/models.js.map +1 -0
  21. package/dist/output.d.ts +13 -0
  22. package/dist/output.js +187 -0
  23. package/dist/output.js.map +1 -0
  24. package/dist/providers/base.d.ts +25 -0
  25. package/dist/providers/base.js +2 -0
  26. package/dist/providers/base.js.map +1 -0
  27. package/dist/providers/claude.d.ts +4 -0
  28. package/dist/providers/claude.js +167 -0
  29. package/dist/providers/claude.js.map +1 -0
  30. package/dist/providers/codex.d.ts +4 -0
  31. package/dist/providers/codex.js +66 -0
  32. package/dist/providers/codex.js.map +1 -0
  33. package/dist/providers/copilot.d.ts +4 -0
  34. package/dist/providers/copilot.js +64 -0
  35. package/dist/providers/copilot.js.map +1 -0
  36. package/dist/providers/cursor.d.ts +6 -0
  37. package/dist/providers/cursor.js +69 -0
  38. package/dist/providers/cursor.js.map +1 -0
  39. package/dist/providers/grok.d.ts +4 -0
  40. package/dist/providers/grok.js +59 -0
  41. package/dist/providers/grok.js.map +1 -0
  42. package/dist/providers/kimi.d.ts +4 -0
  43. package/dist/providers/kimi.js +49 -0
  44. package/dist/providers/kimi.js.map +1 -0
  45. package/dist/providers/minimax.d.ts +4 -0
  46. package/dist/providers/minimax.js +73 -0
  47. package/dist/providers/minimax.js.map +1 -0
  48. package/dist/providers/parse.d.ts +16 -0
  49. package/dist/providers/parse.js +78 -0
  50. package/dist/providers/parse.js.map +1 -0
  51. package/dist/providers/zai.d.ts +5 -0
  52. package/dist/providers/zai.js +67 -0
  53. package/dist/providers/zai.js.map +1 -0
  54. package/dist/registry.d.ts +4 -0
  55. package/dist/registry.js +45 -0
  56. package/dist/registry.js.map +1 -0
  57. package/dist/service.d.ts +28 -0
  58. package/dist/service.js +117 -0
  59. package/dist/service.js.map +1 -0
  60. package/dist/transport.d.ts +8 -0
  61. package/dist/transport.js +63 -0
  62. package/dist/transport.js.map +1 -0
  63. package/dist/version.d.ts +2 -0
  64. package/dist/version.js +4 -0
  65. package/dist/version.js.map +1 -0
  66. package/docs/architecture.md +83 -0
  67. package/docs/provider-contracts.md +32 -0
  68. package/docs/releasing.md +51 -0
  69. package/package.json +48 -0
@@ -0,0 +1,69 @@
1
+ import { join } from 'node:path';
2
+ import { UsageError } from '../errors.js';
3
+ import { detectCommands, homePath } from '../local.js';
4
+ import { emptyUsage } from '../models.js';
5
+ import { credentialObject, nonnegative, object, optionalObject, ratio, requireUsage, string, timestamp } from './parse.js';
6
+ export function cursorDatabasePaths(context) {
7
+ const suffix = ['Cursor', 'User', 'globalStorage', 'state.vscdb'];
8
+ if (context.platform === 'win32')
9
+ return context.env.APPDATA ? [join(context.env.APPDATA, ...suffix)] : [];
10
+ if (context.platform === 'darwin')
11
+ return [join(context.home, 'Library', 'Application Support', ...suffix)];
12
+ return [join(homePath(context, context.env.XDG_CONFIG_HOME, '.config'), ...suffix)];
13
+ }
14
+ export function normalizeCursor(payload) {
15
+ const raw = object(payload), data = emptyUsage(), plan = optionalObject(raw.planUsage);
16
+ const used = nonnegative(plan.totalSpend), limit = nonnegative(plan.limit), remaining = nonnegative(plan.remaining);
17
+ if (used !== undefined || remaining !== undefined || limit !== undefined) {
18
+ data.balances.push({ id: 'plan', label: 'Plan usage', unit: 'USD',
19
+ used: used === undefined ? undefined : used / 100,
20
+ remaining: remaining === undefined ? undefined : remaining / 100,
21
+ limit: limit === undefined ? undefined : limit / 100 });
22
+ data.windows.push({ id: 'billing-period', label: 'Billing period',
23
+ percentUsed: ratio(used, limit), resetsAt: timestamp(raw.billingCycleEnd) });
24
+ }
25
+ return requireUsage(data);
26
+ }
27
+ export const cursor = {
28
+ id: 'cursor', displayName: 'Cursor', version: 1, experimental: true,
29
+ detect: context => detectCommands(context, ['cursor', 'cursor-agent'], context.platform === 'darwin' ? ['/Applications/Cursor.app', join(context.home, 'Applications', 'Cursor.app')] : []),
30
+ async resolveCredentials(context) {
31
+ const token = string(context.env.CURSOR_ACCESS_TOKEN) ?? string(context.env.CURSOR_TOKEN);
32
+ if (token)
33
+ return { token };
34
+ let failure;
35
+ for (const path of cursorDatabasePaths(context)) {
36
+ try {
37
+ const modern = await context.sqliteToken(path, 'cursorAuth/accessToken');
38
+ if (modern)
39
+ return { token: modern };
40
+ const legacy = await context.sqliteToken(path, 'cursorAuthStatus');
41
+ if (legacy) {
42
+ const token = string(credentialObject(JSON.parse(legacy)).accessToken);
43
+ if (token)
44
+ return { token };
45
+ }
46
+ }
47
+ catch {
48
+ failure = new UsageError('credential_read_error');
49
+ }
50
+ }
51
+ const config = homePath(context, context.env.XDG_CONFIG_HOME, '.config');
52
+ const raw = await context.readJson(join(config, 'cursor', 'auth.json'));
53
+ if (raw != null) {
54
+ const token = string(credentialObject(raw).accessToken);
55
+ if (token)
56
+ return { token };
57
+ }
58
+ if (failure)
59
+ throw failure;
60
+ return null;
61
+ },
62
+ async fetchUsage(context, credentials) {
63
+ return normalizeCursor(await context.request('https://api2.cursor.sh/aiserver.v1.DashboardService/GetCurrentPeriodUsage', {
64
+ method: 'POST', body: {}, signal: context.signal,
65
+ headers: { Authorization: `Bearer ${credentials.token}`, 'Connect-Protocol-Version': '1' },
66
+ }));
67
+ },
68
+ };
69
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeGrok(payload: unknown): UsageData;
4
+ export declare const grok: Provider;
@@ -0,0 +1,59 @@
1
+ import { join } from 'node:path';
2
+ import { detectCommands } from '../local.js';
3
+ import { emptyUsage } from '../models.js';
4
+ import { credentialObject, nonnegative, object, optionalObject, percent, ratio, requireUsage, string, timestamp } from './parse.js';
5
+ function cents(raw) {
6
+ if (raw == null)
7
+ return undefined;
8
+ const amount = object(raw);
9
+ // Protobuf omits zero scalar values: an explicitly present {} Cent means zero.
10
+ return nonnegative(amount.val ?? 0);
11
+ }
12
+ export function normalizeGrok(payload) {
13
+ const raw = object(payload), config = optionalObject(raw.config), data = emptyUsage();
14
+ data.planLabel = string(raw.subscription_tier) ?? string(raw.subscriptionTier) ?? null;
15
+ const used = cents(config.used), limit = cents(config.monthlyLimit), prepaid = cents(config.prepaidBalance);
16
+ const current = optionalObject(config.currentPeriod);
17
+ const resetsAt = timestamp(current.end ?? config.billingPeriodEnd);
18
+ const percentUsed = config.creditUsagePercent == null ? ratio(used, limit) : percent(config.creditUsagePercent);
19
+ if (percentUsed !== null)
20
+ data.windows.push({ id: 'included', label: string(current.type)?.includes('WEEKLY') ? 'Weekly' : 'Billing period', percentUsed, resetsAt });
21
+ if (used !== undefined || limit !== undefined)
22
+ data.balances.push({ id: 'included', label: 'Included allowance', unit: 'USD',
23
+ used: used === undefined ? undefined : used / 100, limit: limit === undefined ? undefined : limit / 100,
24
+ remaining: used === undefined || limit === undefined ? undefined : Math.max(0, limit - used) / 100 });
25
+ if (prepaid !== undefined)
26
+ data.balances.push({ id: 'prepaid', label: 'Prepaid balance', unit: 'USD', remaining: prepaid / 100 });
27
+ if (config.isUnifiedBillingUser === true)
28
+ data.details.push({ label: 'Billing', value: 'Shared subscription usage' });
29
+ return requireUsage(data);
30
+ }
31
+ export const grok = {
32
+ id: 'grok', displayName: 'Grok', version: 1, experimental: true,
33
+ detect: context => detectCommands(context, ['grok']),
34
+ async resolveCredentials(context) {
35
+ const token = string(context.env.GROK_API_KEY) ?? string(context.env.GROK_TOKEN);
36
+ if (token)
37
+ return { token };
38
+ const raw = await context.readJson(join(context.home, '.grok', 'auth.json'));
39
+ if (raw == null)
40
+ return null;
41
+ const auth = credentialObject(raw), legacy = string(auth.access_token);
42
+ if (legacy)
43
+ return { token: legacy };
44
+ for (const [key, value] of Object.entries(auth)) {
45
+ if (!key.startsWith('https://auth.x.ai::'))
46
+ continue;
47
+ const token = string(credentialObject(value).key);
48
+ if (token)
49
+ return { token };
50
+ }
51
+ return null;
52
+ },
53
+ async fetchUsage(context, credentials) {
54
+ return normalizeGrok(await context.request('https://cli-chat-proxy.grok.com/v1/billing?format=credits', {
55
+ signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}`, 'X-XAI-Token-Auth': 'xai-grok-cli' },
56
+ }));
57
+ },
58
+ };
59
+ //# sourceMappingURL=grok.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grok.js","sourceRoot":"","sources":["../../src/providers/grok.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEpI,SAAS,KAAK,CAAC,GAAY;IACzB,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,+EAA+E;IAC/E,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AACD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,UAAU,EAAE,CAAC;IACtF,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC;IACvF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC5G,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,MAAM,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAChH,IAAI,WAAW,KAAK,IAAI;QAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtK,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,KAAK;YAC1H,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG;YACvG,SAAS,EAAE,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IACxG,IAAI,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;IAClI,IAAI,MAAM,CAAC,oBAAoB,KAAK,IAAI;QAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;IACtH,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AACD,MAAM,CAAC,MAAM,IAAI,GAAa;IAC5B,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI;IAC/D,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IACpD,KAAK,CAAC,kBAAkB,CAAC,OAAO;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACjF,IAAI,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAC7E,IAAI,GAAG,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvE,IAAI,MAAM;YAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACrC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,qBAAqB,CAAC;gBAAE,SAAS;YACrD,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK;gBAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW;QACnC,OAAO,aAAa,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,2DAA2D,EAAE;YACtG,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,CAAC,KAAK,EAAE,EAAE,kBAAkB,EAAE,cAAc,EAAE;SACtH,CAAC,CAAC,CAAC;IACN,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeKimi(payload: unknown): UsageData;
4
+ export declare const kimi: Provider;
@@ -0,0 +1,49 @@
1
+ import { join } from 'node:path';
2
+ import { detectCommands, homePath } from '../local.js';
3
+ import { emptyUsage } from '../models.js';
4
+ import { countWindow, credentialObject, list, nonnegative, object, optionalObject, requireUsage, string, timestamp } from './parse.js';
5
+ export function normalizeKimi(payload) {
6
+ const raw = object(payload), data = emptyUsage();
7
+ function add(id, label, value) {
8
+ const row = { ...object(value) }, remaining = nonnegative(row.remaining), limit = nonnegative(row.limit);
9
+ if (row.used == null && remaining !== undefined && limit !== undefined)
10
+ row.used = Math.max(0, limit - remaining);
11
+ data.windows.push(countWindow(id, label, row, row.resetTime ?? row.resetAt ?? row.reset_time ?? row.reset_at));
12
+ }
13
+ if (raw.usage != null)
14
+ add('weekly', 'Weekly', raw.usage);
15
+ for (const [index, value] of list(raw.limits).entries()) {
16
+ const row = object(value), window = optionalObject(row.window);
17
+ const duration = nonnegative(window.duration), unit = string(window.timeUnit)?.replace('TIME_UNIT_', '').toLowerCase();
18
+ const period = duration === 300 && unit === 'minute' ? '5 hours' : duration && unit ? `${duration} ${unit}` : `Limit ${index + 1}`;
19
+ add(`limit-${index}`, string(row.name) ?? period, row.detail ?? row);
20
+ }
21
+ return requireUsage(data);
22
+ }
23
+ export const kimi = {
24
+ id: 'kimi', displayName: 'Kimi', version: 1, experimental: true,
25
+ detect: context => detectCommands(context, ['kimi']),
26
+ async resolveCredentials(context) {
27
+ const token = string(context.env.KIMI_TOKEN) ?? string(context.env.KIMI_API_KEY);
28
+ if (token)
29
+ return { token };
30
+ const homes = [homePath(context, context.env.KIMI_CODE_HOME, '.kimi-code'), join(context.home, '.kimi')];
31
+ for (const home of homes) {
32
+ const raw = await context.readJson(join(home, 'credentials', 'kimi-code.json'));
33
+ if (raw == null)
34
+ continue;
35
+ const auth = credentialObject(raw), token = string(auth.access_token);
36
+ if (token) {
37
+ const expiry = timestamp(auth.expires_at);
38
+ return { token, expiresAt: expiry ? Date.parse(expiry) : undefined };
39
+ }
40
+ }
41
+ return null;
42
+ },
43
+ async fetchUsage(context, credentials) {
44
+ return normalizeKimi(await context.request('https://api.kimi.com/coding/v1/usages', {
45
+ signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}` },
46
+ }));
47
+ },
48
+ };
49
+ //# sourceMappingURL=kimi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi.js","sourceRoot":"","sources":["../../src/providers/kimi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeMiniMax(payload: unknown): UsageData;
4
+ export declare const minimax: Provider;
@@ -0,0 +1,73 @@
1
+ import { join } from 'node:path';
2
+ import { UsageError } from '../errors.js';
3
+ import { detectCommands } from '../local.js';
4
+ import { emptyUsage } from '../models.js';
5
+ import { credentialObject, list, nonnegative, object, optionalObject, percent, ratio, requireUsage, slug, string, timestamp } from './parse.js';
6
+ function baseUrl(value, region) {
7
+ if (!value)
8
+ return region === 'cn' ? 'https://api.minimaxi.com' : 'https://api.minimax.io';
9
+ try {
10
+ const url = new URL(value);
11
+ if (url.protocol !== 'https:' || url.username || url.password || url.port)
12
+ throw new Error();
13
+ if (['api.minimaxi.com', 'www.minimaxi.com'].includes(url.hostname))
14
+ return url.origin;
15
+ if (['api.minimax.io', 'www.minimax.io'].includes(url.hostname))
16
+ return url.origin;
17
+ }
18
+ catch { /* Never forward a subscription key to an arbitrary configured host. */ }
19
+ throw new UsageError('invalid_credentials');
20
+ }
21
+ function auth(token, url, region, expiry) {
22
+ const expiresAt = timestamp(expiry);
23
+ return { token, metadata: { baseUrl: baseUrl(url, region) }, expiresAt: expiresAt ? Date.parse(expiresAt) : undefined };
24
+ }
25
+ export function normalizeMiniMax(payload) {
26
+ const raw = object(payload), data = emptyUsage(), status = optionalObject(raw.base_resp);
27
+ if (status.status_code != null && status.status_code !== 0 && status.status_code !== '0')
28
+ throw new UsageError(status.status_code === 1004 ? 'unauthorized' : 'provider_error');
29
+ for (const [index, value] of list(raw.model_remains).entries()) {
30
+ const model = object(value), name = string(model.model_name) ?? 'Token plan';
31
+ for (const [prefix, label, reset] of [['current_interval', '5 hours', model.end_time], ['current_weekly', 'Weekly', model.weekly_end_time]]) {
32
+ const remaining = nonnegative(model[`${prefix}_remaining_percent`]);
33
+ if (remaining !== undefined && remaining > 100)
34
+ throw new UsageError('invalid_response');
35
+ const used = nonnegative(model[`${prefix}_usage_count`]), limit = nonnegative(model[`${prefix}_total_count`]);
36
+ const percentUsed = remaining === undefined ? ratio(used, limit) : percent(100 - remaining);
37
+ if (percentUsed === null)
38
+ continue;
39
+ data.windows.push({ id: `${slug(name).slice(0, 50)}-${index}-${prefix}`, label: `${name} · ${label}`,
40
+ percentUsed, resetsAt: timestamp(reset), scope: { model: name } });
41
+ }
42
+ }
43
+ return requireUsage(data);
44
+ }
45
+ export const minimax = {
46
+ id: 'minimax', displayName: 'MiniMax', version: 1, experimental: true,
47
+ detect: context => detectCommands(context, ['mmx', 'minimax']),
48
+ async resolveCredentials(context) {
49
+ const token = string(context.env.MINIMAX_API_KEY);
50
+ if (token)
51
+ return auth(token, string(context.env.MINIMAX_BASE_URL), string(context.env.MINIMAX_REGION));
52
+ const raw = await context.readJson(join(context.home, '.mmx', 'credentials.json'));
53
+ if (raw != null) {
54
+ const credentials = credentialObject(raw), token = string(credentials.access_token);
55
+ if (token)
56
+ return auth(token, string(credentials.resource_url), undefined, credentials.expires_at);
57
+ }
58
+ const configRaw = await context.readJson(join(context.home, '.mmx', 'config.json'));
59
+ if (configRaw == null)
60
+ return null;
61
+ const config = credentialObject(configRaw), apiKey = string(config.api_key);
62
+ if (apiKey)
63
+ return auth(apiKey, string(config.base_url), string(config.region));
64
+ const oauth = config.oauth == null ? {} : credentialObject(config.oauth), accessToken = string(oauth.access_token);
65
+ return accessToken ? auth(accessToken, string(oauth.resource_url) ?? string(config.base_url), string(config.region), oauth.expires_at) : null;
66
+ },
67
+ async fetchUsage(context, credentials) {
68
+ return normalizeMiniMax(await context.request(`${credentials.metadata?.baseUrl ?? 'https://api.minimax.io'}/v1/token_plan/remains`, {
69
+ signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}`, 'Content-Type': 'application/json' },
70
+ }));
71
+ },
72
+ };
73
+ //# sourceMappingURL=minimax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimax.js","sourceRoot":"","sources":["../../src/providers/minimax.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { UsageData, UsageWindow } from '../models.js';
2
+ export type Obj = Record<string, unknown>;
3
+ export declare function object(value: unknown): Obj;
4
+ export declare function optionalObject(value: unknown): Obj;
5
+ export declare function list(value: unknown): unknown[];
6
+ export declare function string(value: unknown): string | undefined;
7
+ export declare function number(value: unknown): number | undefined;
8
+ export declare function nonnegative(value: unknown): number | undefined;
9
+ export declare function percent(value: unknown): number;
10
+ export declare function timestamp(value: unknown): string | null;
11
+ export declare function slug(value: string): string;
12
+ export declare function title(value: string): string;
13
+ export declare function ratio(used: unknown, limit: unknown): number | null;
14
+ export declare function countWindow(id: string, label: string, raw: Obj, reset: unknown, unit?: string): UsageWindow;
15
+ export declare function requireUsage(data: UsageData): UsageData;
16
+ export declare function credentialObject(value: unknown): Obj;
@@ -0,0 +1,78 @@
1
+ import { UsageError } from '../errors.js';
2
+ export function object(value) {
3
+ if (!value || typeof value !== 'object' || Array.isArray(value))
4
+ throw new UsageError('invalid_response');
5
+ return value;
6
+ }
7
+ export function optionalObject(value) { return value == null ? {} : object(value); }
8
+ export function list(value) {
9
+ if (value == null)
10
+ return [];
11
+ if (!Array.isArray(value))
12
+ throw new UsageError('invalid_response');
13
+ return value;
14
+ }
15
+ export function string(value) {
16
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
17
+ }
18
+ export function number(value) {
19
+ if (typeof value !== 'number' && (typeof value !== 'string' || !/^-?\d+(\.\d+)?$/.test(value)))
20
+ return undefined;
21
+ const n = Number(value);
22
+ return Number.isFinite(n) ? n : undefined;
23
+ }
24
+ export function nonnegative(value) {
25
+ const n = number(value);
26
+ return n !== undefined && n >= 0 ? n : undefined;
27
+ }
28
+ export function percent(value) {
29
+ const n = nonnegative(value);
30
+ if (n === undefined)
31
+ throw new UsageError('invalid_response');
32
+ return n; // Providers may report overage above 100%; do not hide it.
33
+ }
34
+ export function timestamp(value) {
35
+ if (value == null || value === '')
36
+ return null;
37
+ const numeric = number(value);
38
+ const ms = numeric === undefined ? (typeof value === 'string' ? Date.parse(value) : NaN)
39
+ : numeric < 100_000_000_000 ? numeric * 1000 : numeric;
40
+ if (!Number.isFinite(ms))
41
+ throw new UsageError('invalid_response');
42
+ try {
43
+ return new Date(ms).toISOString();
44
+ }
45
+ catch {
46
+ throw new UsageError('invalid_response');
47
+ }
48
+ }
49
+ export function slug(value) {
50
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 100) || 'scope';
51
+ }
52
+ export function title(value) {
53
+ return value.replace(/[_-]+/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
54
+ }
55
+ export function ratio(used, limit) {
56
+ const u = nonnegative(used), l = nonnegative(limit);
57
+ return u !== undefined && l !== undefined && l > 0 ? u / l * 100 : null;
58
+ }
59
+ export function countWindow(id, label, raw, reset, unit = 'requests') {
60
+ const used = nonnegative(raw.used), limit = nonnegative(raw.limit);
61
+ if (used === undefined && limit === undefined)
62
+ throw new UsageError('invalid_response');
63
+ return { id, label, used, limit, unit, percentUsed: ratio(used, limit), resetsAt: timestamp(reset) };
64
+ }
65
+ export function requireUsage(data) {
66
+ if (!data.planLabel && !data.windows.length && !data.balances.length && !data.details.length)
67
+ throw new UsageError('invalid_response');
68
+ return data;
69
+ }
70
+ export function credentialObject(value) {
71
+ try {
72
+ return object(value);
73
+ }
74
+ catch {
75
+ throw new UsageError('invalid_credentials');
76
+ }
77
+ }
78
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/providers/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC1G,OAAO,KAAY,CAAC;AACtB,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAc,IAAS,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClG,MAAM,UAAU,IAAI,CAAC,KAAc;IACjC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACjH,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9D,OAAO,CAAC,CAAC,CAAC,2DAA2D;AACvE,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACtF,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACnE,IAAI,CAAC;QAAC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAAC,CAAC;AAChG,CAAC;AACD,MAAM,UAAU,IAAI,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC;AACxG,CAAC;AACD,MAAM,UAAU,KAAK,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACnF,CAAC;AACD,MAAM,UAAU,KAAK,CAAC,IAAa,EAAE,KAAc;IACjD,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,KAAa,EAAE,GAAQ,EAAE,KAAc,EAAE,IAAI,GAAG,UAAU;IAChG,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnE,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACxF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AACvG,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;QAC1F,MAAM,IAAI,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC;QAAC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { UsageData } from '../models.js';
2
+ import type { Provider } from './base.js';
3
+ export declare function normalizeZaiPlan(payload: unknown): UsageData;
4
+ export declare function normalizeZaiQuota(payload: unknown): UsageData;
5
+ export declare const zai: Provider;
@@ -0,0 +1,67 @@
1
+ import { UsageError } from '../errors.js';
2
+ import { emptyUsage } from '../models.js';
3
+ import { list, nonnegative, object, percent, requireUsage, slug, string, timestamp } from './parse.js';
4
+ function envelope(payload) {
5
+ const raw = object(payload);
6
+ if (raw.success === false || (raw.code !== undefined && ![0, 200, '0', '200'].includes(raw.code)))
7
+ throw new UsageError(raw.code === 401 || raw.code === 403 ? 'unauthorized' : 'provider_error');
8
+ return raw.data;
9
+ }
10
+ export function normalizeZaiPlan(payload) {
11
+ const data = emptyUsage();
12
+ const subscriptions = list(envelope(payload)).map(object);
13
+ const names = subscriptions.map(sub => string(sub.productName)).filter((name) => Boolean(name));
14
+ data.planLabel = [...new Set(names)].join(' / ') || null;
15
+ for (const sub of subscriptions) {
16
+ for (const field of ['status', 'valid', 'purchaseTime']) {
17
+ const value = string(sub[field]);
18
+ if (value)
19
+ data.details.push({ label: `${string(sub.productName) ?? 'Subscription'} ${field}`, value });
20
+ }
21
+ }
22
+ return requireUsage(data);
23
+ }
24
+ export function normalizeZaiQuota(payload) {
25
+ const raw = object(envelope(payload)), data = emptyUsage();
26
+ for (const [index, value] of list(raw.limits).entries()) {
27
+ const quota = object(value), type = string(quota.type) ?? 'Quota';
28
+ const label = type === 'TOKENS_LIMIT' ? '5 hours' : type === 'TIME_LIMIT' ? 'MCP monthly' : type;
29
+ if (quota.percentage == null)
30
+ continue;
31
+ data.windows.push({ id: `${slug(type)}-${index}`, label, percentUsed: percent(quota.percentage),
32
+ resetsAt: timestamp(quota.nextResetTime),
33
+ used: type === 'TIME_LIMIT' ? nonnegative(quota.currentValue) : undefined,
34
+ limit: type === 'TIME_LIMIT' ? nonnegative(quota.usage) : undefined });
35
+ }
36
+ return requireUsage(data);
37
+ }
38
+ export const zai = {
39
+ id: 'zai', displayName: 'Z.ai', version: 1, experimental: true,
40
+ // A subscription provider used through other CLIs; no distinct installation to prove.
41
+ detect: async () => null,
42
+ async resolveCredentials(context) {
43
+ const token = string(context.env.ZAI_API_KEY) ?? string(context.env.GLM_API_KEY);
44
+ return token ? { token } : null;
45
+ },
46
+ async fetchUsage(context, credentials) {
47
+ const [plan, quota] = await Promise.allSettled([
48
+ context.request('https://api.z.ai/api/biz/subscription/list', {
49
+ signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}` },
50
+ }).then(normalizeZaiPlan),
51
+ context.request('https://api.z.ai/api/monitor/usage/quota/limit', {
52
+ signal: context.signal, headers: { Authorization: credentials.token, 'Accept-Language': 'en-US,en' },
53
+ }).then(normalizeZaiQuota),
54
+ ]);
55
+ if (plan.status === 'rejected' && quota.status === 'rejected')
56
+ throw quota.reason;
57
+ const data = plan.status === 'fulfilled' ? plan.value : emptyUsage();
58
+ if (quota.status === 'fulfilled')
59
+ data.windows = quota.value.windows;
60
+ else
61
+ data.details.push({ label: 'Quota', value: 'Usage figures could not be retrieved' });
62
+ if (plan.status === 'rejected')
63
+ data.details.push({ label: 'Plan', value: 'Plan metadata could not be retrieved' });
64
+ return data;
65
+ },
66
+ };
67
+ //# sourceMappingURL=zai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zai.js","sourceRoot":"","sources":["../../src/providers/zai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Provider } from './providers/base.js';
2
+ export declare const builtInProviders: readonly Provider[];
3
+ export declare function validateProvider(value: unknown): Provider;
4
+ export declare function loadProviders(plugins?: string[], cwd?: string): Promise<Provider[]>;
@@ -0,0 +1,45 @@
1
+ import { createRequire } from 'node:module';
2
+ import { resolve } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { claude } from './providers/claude.js';
5
+ import { codex } from './providers/codex.js';
6
+ import { copilot } from './providers/copilot.js';
7
+ import { cursor } from './providers/cursor.js';
8
+ import { zai } from './providers/zai.js';
9
+ import { grok } from './providers/grok.js';
10
+ import { kimi } from './providers/kimi.js';
11
+ import { minimax } from './providers/minimax.js';
12
+ export const builtInProviders = [claude, codex, copilot, cursor, zai, grok, kimi, minimax];
13
+ export function validateProvider(value) {
14
+ if (!value || typeof value !== 'object')
15
+ throw new Error('Invalid provider plugin');
16
+ const p = value;
17
+ if (typeof p.id !== 'string' || !/^[a-z0-9][a-z0-9-]{0,47}$/.test(p.id)
18
+ || typeof p.displayName !== 'string' || !/^[\p{L}\p{N} ._-]{1,80}$/u.test(p.displayName)
19
+ || !Number.isSafeInteger(p.version) || (p.version ?? 0) < 1
20
+ || typeof p.detect !== 'function' || typeof p.resolveCredentials !== 'function' || typeof p.fetchUsage !== 'function'
21
+ || (p.experimental !== undefined && typeof p.experimental !== 'boolean'))
22
+ throw new Error('Invalid provider plugin');
23
+ return value;
24
+ }
25
+ export async function loadProviders(plugins = [], cwd = process.cwd()) {
26
+ const providers = [...builtInProviders], ids = new Set(providers.map(p => p.id));
27
+ const require = createRequire(resolve(cwd, '__asu_resolve__.cjs'));
28
+ for (const specifier of plugins) {
29
+ try {
30
+ // Explicit local/package imports only. No remote downloads or auto-scanning directories.
31
+ const file = specifier.startsWith('.') || specifier.startsWith('/') ? resolve(cwd, specifier) : require.resolve(specifier);
32
+ const module = await import(pathToFileURL(file).href);
33
+ const provider = validateProvider(module.default ?? module.provider);
34
+ if (ids.has(provider.id))
35
+ throw new Error('Duplicate provider ID');
36
+ providers.push(provider);
37
+ ids.add(provider.id);
38
+ }
39
+ catch {
40
+ throw new Error('Could not load a provider plugin. Check its path, exports, and unique provider ID.');
41
+ }
42
+ }
43
+ return providers;
44
+ }
45
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { UsageCache } from './cache.js';
2
+ import type { UsageReport } from './models.js';
3
+ import type { LocalContext } from './local.js';
4
+ import type { RequestJson } from './transport.js';
5
+ import type { Provider } from './providers/base.js';
6
+ export interface ServiceOptions {
7
+ local?: LocalContext;
8
+ request?: RequestJson;
9
+ cache?: UsageCache;
10
+ now?: () => number;
11
+ timeoutMs?: number;
12
+ }
13
+ export declare function deadline<T>(work: (signal: AbortSignal) => Promise<T>, timeoutMs: number): Promise<T>;
14
+ export declare class UsageService {
15
+ private readonly providers;
16
+ private readonly local;
17
+ private readonly request;
18
+ private readonly cache;
19
+ private readonly now;
20
+ private readonly timeoutMs;
21
+ constructor(providers: readonly Provider[], options?: ServiceOptions);
22
+ collect(options?: {
23
+ providerIds?: string[];
24
+ fresh?: boolean;
25
+ }): Promise<UsageReport>;
26
+ private result;
27
+ private collectProvider;
28
+ }