@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1
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/LICENSE +57744 -0
- package/native-manifest.json +1414 -0
- package/package.json +254 -0
- package/plugins/abacus-ai/icon.svg +18 -0
- package/plugins/abacus-ai/plugin.js +121 -0
- package/plugins/abacus-ai/plugin.json +17 -0
- package/plugins/alibaba/icon-color.svg +1 -0
- package/plugins/alibaba/icon.svg +1 -0
- package/plugins/alibaba/plugin.js +322 -0
- package/plugins/alibaba/plugin.json +20 -0
- package/plugins/alibaba-token-plan/icon-color.svg +1 -0
- package/plugins/alibaba-token-plan/icon.svg +1 -0
- package/plugins/alibaba-token-plan/plugin.js +544 -0
- package/plugins/alibaba-token-plan/plugin.json +19 -0
- package/plugins/amp/icon-color.svg +1 -0
- package/plugins/amp/icon-conflict.svg +6 -0
- package/plugins/amp/icon.svg +1 -0
- package/plugins/amp/plugin.js +175 -0
- package/plugins/amp/plugin.json +16 -0
- package/plugins/antigravity/icon-color.svg +1 -0
- package/plugins/antigravity/icon-conflict.svg +3 -0
- package/plugins/antigravity/icon.svg +1 -0
- package/plugins/antigravity/plugin.js +739 -0
- package/plugins/antigravity/plugin.json +31 -0
- package/plugins/antigravity-cli/icon.svg +3 -0
- package/plugins/antigravity-cli/plugin.js +570 -0
- package/plugins/antigravity-cli/plugin.json +16 -0
- package/plugins/antigravity-ide/icon.svg +3 -0
- package/plugins/antigravity-ide/plugin.js +257 -0
- package/plugins/antigravity-ide/plugin.json +29 -0
- package/plugins/augment/icon.svg +14 -0
- package/plugins/augment/plugin.js +59 -0
- package/plugins/augment/plugin.json +18 -0
- package/plugins/aws-bedrock/icon-color.svg +1 -0
- package/plugins/aws-bedrock/icon.svg +1 -0
- package/plugins/aws-bedrock/plugin.js +206 -0
- package/plugins/aws-bedrock/plugin.json +18 -0
- package/plugins/azure-openai/icon-color.svg +1 -0
- package/plugins/azure-openai/icon.svg +1 -0
- package/plugins/azure-openai/plugin.js +145 -0
- package/plugins/azure-openai/plugin.json +17 -0
- package/plugins/chutes/icon.svg +7 -0
- package/plugins/chutes/plugin.js +236 -0
- package/plugins/chutes/plugin.json +19 -0
- package/plugins/claude/icon-color.svg +1 -0
- package/plugins/claude/icon.svg +1 -0
- package/plugins/claude/plugin.js +1723 -0
- package/plugins/claude/plugin.json +30 -0
- package/plugins/codebuff/icon.svg +92 -0
- package/plugins/codebuff/plugin.js +113 -0
- package/plugins/codebuff/plugin.json +17 -0
- package/plugins/codex/icon-color.svg +5 -0
- package/plugins/codex/icon.svg +1 -0
- package/plugins/codex/plugin.js +1009 -0
- package/plugins/codex/plugin.json +82 -0
- package/plugins/command-code/icon.svg +3 -0
- package/plugins/command-code/plugin.js +184 -0
- package/plugins/command-code/plugin.json +20 -0
- package/plugins/copilot/icon-color.svg +1 -0
- package/plugins/copilot/icon.svg +1 -0
- package/plugins/copilot/plugin.js +684 -0
- package/plugins/copilot/plugin.json +21 -0
- package/plugins/crof/icon.svg +3 -0
- package/plugins/crof/plugin.js +53 -0
- package/plugins/crof/plugin.json +17 -0
- package/plugins/crofai/icon.svg +16 -0
- package/plugins/crofai/plugin.js +81 -0
- package/plugins/crofai/plugin.json +18 -0
- package/plugins/cursor/icon-conflict.svg +3 -0
- package/plugins/cursor/icon.svg +1 -0
- package/plugins/cursor/plugin.js +1379 -0
- package/plugins/cursor/plugin.json +23 -0
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +1379 -0
- package/plugins/cursor-nightly/plugin.json +23 -0
- package/plugins/deepgram/icon.svg +1 -0
- package/plugins/deepgram/plugin.js +20 -0
- package/plugins/deepgram/plugin.json +17 -0
- package/plugins/deepseek/icon-color.svg +1 -0
- package/plugins/deepseek/icon.svg +1 -0
- package/plugins/deepseek/plugin.js +71 -0
- package/plugins/deepseek/plugin.json +17 -0
- package/plugins/devin/icon.svg +5 -0
- package/plugins/devin/plugin.js +341 -0
- package/plugins/devin/plugin.json +16 -0
- package/plugins/doubao/icon-color.svg +1 -0
- package/plugins/doubao/icon.svg +1 -0
- package/plugins/doubao/plugin.js +92 -0
- package/plugins/doubao/plugin.json +17 -0
- package/plugins/droid/icon.svg +1 -0
- package/plugins/droid/plugin.json +20 -0
- package/plugins/elevenlabs/icon.svg +4 -0
- package/plugins/elevenlabs/plugin.js +48 -0
- package/plugins/elevenlabs/plugin.json +18 -0
- package/plugins/factory/icon-conflict.svg +1 -0
- package/plugins/factory/icon.svg +1 -0
- package/plugins/factory/plugin.js +487 -0
- package/plugins/factory/plugin.json +15 -0
- package/plugins/fireworks-ai/icon.svg +6 -0
- package/plugins/fireworks-ai/plugin.js +370 -0
- package/plugins/fireworks-ai/plugin.json +19 -0
- package/plugins/gemini/icon-color.svg +1 -0
- package/plugins/gemini/icon.svg +1 -0
- package/plugins/gemini/plugin.js +460 -0
- package/plugins/gemini/plugin.json +16 -0
- package/plugins/grok/icon.svg +1 -0
- package/plugins/grok/plugin.js +297 -0
- package/plugins/grok/plugin.json +19 -0
- package/plugins/groqcloud/icon.svg +1 -0
- package/plugins/groqcloud/plugin.js +117 -0
- package/plugins/groqcloud/plugin.json +19 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +14 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +3 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +14 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +313 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +16 -0
- package/plugins/kilo/icon.svg +1 -0
- package/plugins/kilo/plugin.js +111 -0
- package/plugins/kilo/plugin.json +19 -0
- package/plugins/kimi/icon-color.svg +1 -0
- package/plugins/kimi/icon-conflict.svg +3 -0
- package/plugins/kimi/icon.svg +1 -0
- package/plugins/kimi/plugin.js +358 -0
- package/plugins/kimi/plugin.json +15 -0
- package/plugins/kimi-k2/icon-color.svg +1 -0
- package/plugins/kimi-k2/icon.svg +1 -0
- package/plugins/kimi-k2/plugin.js +58 -0
- package/plugins/kimi-k2/plugin.json +18 -0
- package/plugins/kiro/icon-color.svg +5 -0
- package/plugins/kiro/icon-conflict.svg +1 -0
- package/plugins/kiro/icon.svg +4 -0
- package/plugins/kiro/plugin.js +390 -0
- package/plugins/kiro/plugin.json +16 -0
- package/plugins/litellm/icon.svg +16 -0
- package/plugins/litellm/plugin.js +199 -0
- package/plugins/litellm/plugin.json +16 -0
- package/plugins/llm-proxy/icon.svg +1 -0
- package/plugins/llm-proxy/plugin.js +40 -0
- package/plugins/llm-proxy/plugin.json +17 -0
- package/plugins/manus/icon.svg +6 -0
- package/plugins/manus/plugin.js +50 -0
- package/plugins/manus/plugin.json +17 -0
- package/plugins/mimo/icon.svg +1 -0
- package/plugins/mimo/plugin.js +177 -0
- package/plugins/mimo/plugin.json +19 -0
- package/plugins/minimax/icon-color.svg +1 -0
- package/plugins/minimax/icon-conflict.svg +4 -0
- package/plugins/minimax/icon.svg +1 -0
- package/plugins/minimax/plugin.js +453 -0
- package/plugins/minimax/plugin.json +14 -0
- package/plugins/mistral/icon-color.svg +1 -0
- package/plugins/mistral/icon.svg +1 -0
- package/plugins/mistral/plugin.js +152 -0
- package/plugins/mistral/plugin.json +18 -0
- package/plugins/moonshot/icon.svg +1 -0
- package/plugins/moonshot/plugin.js +43 -0
- package/plugins/moonshot/plugin.json +16 -0
- package/plugins/nanogpt/icon-color.svg +17 -0
- package/plugins/nanogpt/icon.svg +10 -0
- package/plugins/nanogpt/plugin.js +80 -0
- package/plugins/nanogpt/plugin.json +17 -0
- package/plugins/neuralwatt/icon.svg +3 -0
- package/plugins/neuralwatt/plugin.js +152 -0
- package/plugins/neuralwatt/plugin.json +17 -0
- package/plugins/ollama/icon.svg +1 -0
- package/plugins/ollama/plugin.js +92 -0
- package/plugins/ollama/plugin.json +20 -0
- package/plugins/openai-api/icon.svg +1 -0
- package/plugins/openai-api/plugin.js +533 -0
- package/plugins/openai-api/plugin.json +26 -0
- package/plugins/opencode/icon.svg +1 -0
- package/plugins/opencode/plugin.js +342 -0
- package/plugins/opencode/plugin.json +19 -0
- package/plugins/opencode-go/icon-conflict.svg +1 -0
- package/plugins/opencode-go/icon.svg +1 -0
- package/plugins/opencode-go/plugin.js +617 -0
- package/plugins/opencode-go/plugin.json +50 -0
- package/plugins/openrouter/icon.svg +1 -0
- package/plugins/openrouter/plugin.js +156 -0
- package/plugins/openrouter/plugin.json +8 -0
- package/plugins/perplexity/icon-color.svg +1 -0
- package/plugins/perplexity/icon-conflict.svg +1 -0
- package/plugins/perplexity/icon.svg +1 -0
- package/plugins/perplexity/plugin.js +425 -0
- package/plugins/perplexity/plugin.json +19 -0
- package/plugins/poe/icon.svg +1 -0
- package/plugins/poe/plugin.js +190 -0
- package/plugins/poe/plugin.json +19 -0
- package/plugins/stepfun/icon-color.svg +1 -0
- package/plugins/stepfun/icon.svg +1 -0
- package/plugins/stepfun/plugin.js +155 -0
- package/plugins/stepfun/plugin.json +18 -0
- package/plugins/synthetic/icon-conflict.svg +12 -0
- package/plugins/synthetic/icon.svg +14 -0
- package/plugins/synthetic/plugin.js +331 -0
- package/plugins/synthetic/plugin.json +23 -0
- package/plugins/t3chat/icon-color.svg +28 -0
- package/plugins/t3chat/icon.svg +4 -0
- package/plugins/t3chat/plugin.js +243 -0
- package/plugins/t3chat/plugin.json +20 -0
- package/plugins/venice/icon-color.svg +1 -0
- package/plugins/venice/icon.svg +1 -0
- package/plugins/venice/plugin.js +69 -0
- package/plugins/venice/plugin.json +16 -0
- package/plugins/vertex-ai/icon-color.svg +1 -0
- package/plugins/vertex-ai/icon.svg +1 -0
- package/plugins/vertex-ai/plugin.js +172 -0
- package/plugins/vertex-ai/plugin.json +18 -0
- package/plugins/warp/icon-color.svg +10 -0
- package/plugins/warp/icon.svg +6 -0
- package/plugins/warp/plugin.js +108 -0
- package/plugins/warp/plugin.json +18 -0
- package/plugins/windsurf/icon-conflict.svg +3 -0
- package/plugins/windsurf/icon.svg +1 -0
- package/plugins/windsurf/plugin.js +208 -0
- package/plugins/windsurf/plugin.json +16 -0
- package/plugins/zai/icon-conflict.svg +5 -0
- package/plugins/zai/icon.svg +1 -0
- package/plugins/zai/plugin.js +188 -0
- package/plugins/zai/plugin.json +16 -0
- package/plugins/zed/icon.svg +4 -0
- package/plugins/zed/plugin.js +270 -0
- package/plugins/zed/plugin.json +19 -0
- package/usagestat +0 -0
- package/usagestatd +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
var GATEWAY_BASE_URL = "https://bailian.console.aliyun.com";
|
|
3
|
+
var DASHBOARD_URL = "https://bailian.console.aliyun.com/cn-beijing?tab=plan#/efm/subscription/token-plan";
|
|
4
|
+
var TOKEN_PLAN_PRODUCT_CODE = "sfm_tokenplanteams_dp_cn";
|
|
5
|
+
var CURRENT_REGION_ID = "cn-beijing";
|
|
6
|
+
var BSS_SERVICE_CODE = "BssOpenAPI-V3";
|
|
7
|
+
var ACTION = "GetSubscriptionSummary";
|
|
8
|
+
var USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36";
|
|
9
|
+
|
|
10
|
+
var PLAN_NAME_KEYS = [
|
|
11
|
+
"planName", "plan_name", "packageName", "package_name", "commodityName", "commodity_name",
|
|
12
|
+
"instanceName", "instance_name", "displayName", "display_name", "name", "title",
|
|
13
|
+
"planType", "plan_type", "ProductName", "productName",
|
|
14
|
+
];
|
|
15
|
+
var USED_QUOTA_KEYS = [
|
|
16
|
+
"usedQuota", "used_quota", "usedCredits", "usedCredit", "consumedCredits", "usage", "used",
|
|
17
|
+
"usedAmount", "consumeAmount", "usedValue", "UsedValue", "consumedValue", "ConsumedValue",
|
|
18
|
+
];
|
|
19
|
+
var TOTAL_QUOTA_KEYS = [
|
|
20
|
+
"totalQuota", "total_quota", "totalCredits", "totalCredit", "quota", "creditLimit",
|
|
21
|
+
"creditsTotal", "monthlyTotalQuota", "amount", "totalValue", "TotalValue", "totalCount",
|
|
22
|
+
"TotalCount", "subscriptionTotalNumber", "SubscriptionTotalNumber",
|
|
23
|
+
];
|
|
24
|
+
var REMAINING_QUOTA_KEYS = [
|
|
25
|
+
"remainingQuota", "remainQuota", "remainingCredits", "remainingCredit", "availableCredits",
|
|
26
|
+
"balance", "remaining", "availableAmount", "remainAmount", "totalSurplusValue",
|
|
27
|
+
"TotalSurplusValue", "surplusValue", "SurplusValue",
|
|
28
|
+
];
|
|
29
|
+
var RESET_DATE_KEYS = [
|
|
30
|
+
"nextRefreshTime", "resetTime", "periodEndTime", "billingCycleEnd", "billCycleEndTime",
|
|
31
|
+
"expireTime", "expirationTime", "endTime", "validEndTime", "instanceEndTime",
|
|
32
|
+
"nearestExpireDate", "NearestExpireDate",
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
function trim(value) {
|
|
36
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function cleaned(value) {
|
|
40
|
+
var text = trim(value);
|
|
41
|
+
if (!text) return null;
|
|
42
|
+
if ((text[0] === "\"" && text[text.length - 1] === "\"") || (text[0] === "'" && text[text.length - 1] === "'")) {
|
|
43
|
+
text = text.slice(1, -1).trim();
|
|
44
|
+
}
|
|
45
|
+
return text || null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function env(ctx, name) {
|
|
49
|
+
try {
|
|
50
|
+
return cleaned(ctx.host.env.get(name));
|
|
51
|
+
} catch (_) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function settings(ctx) {
|
|
57
|
+
return ctx.provider && ctx.provider.settings ? ctx.provider.settings : {};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function normalizeCookie(raw) {
|
|
61
|
+
var text = cleaned(raw);
|
|
62
|
+
if (!text) return null;
|
|
63
|
+
if (text.slice(0, 7).toLowerCase() === "cookie:") text = text.slice(7).trim();
|
|
64
|
+
return text && text.indexOf("=") >= 0 ? text : null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function cookieHeader(ctx) {
|
|
68
|
+
var s = settings(ctx);
|
|
69
|
+
var value = normalizeCookie(ctx.provider && ctx.provider.cookieHeader) ||
|
|
70
|
+
normalizeCookie(s.cookieHeader) ||
|
|
71
|
+
normalizeCookie(s.cookie) ||
|
|
72
|
+
normalizeCookie(env(ctx, "ALIBABA_TOKEN_PLAN_COOKIE")) ||
|
|
73
|
+
normalizeCookie(env(ctx, "ALIBABA_TOKEN_PLAN_COOKIE_HEADER")) ||
|
|
74
|
+
normalizeCookie(env(ctx, "BAILIAN_TOKEN_PLAN_COOKIE")) ||
|
|
75
|
+
normalizeCookie(env(ctx, "ALIBABA_COOKIE"));
|
|
76
|
+
if (!value) throw "Alibaba Token Plan session not configured. Set ALIBABA_TOKEN_PLAN_COOKIE.";
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function cookieValue(name, cookie) {
|
|
81
|
+
var parts = String(cookie || "").split(";");
|
|
82
|
+
for (var i = 0; i < parts.length; i++) {
|
|
83
|
+
var idx = parts[i].indexOf("=");
|
|
84
|
+
if (idx < 0) continue;
|
|
85
|
+
var key = parts[i].slice(0, idx).trim();
|
|
86
|
+
var value = parts[i].slice(idx + 1).trim();
|
|
87
|
+
if (key === name && value) return value;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function hostBase(ctx) {
|
|
93
|
+
var raw = cleaned(settings(ctx).host) || env(ctx, "ALIBABA_TOKEN_PLAN_HOST") || GATEWAY_BASE_URL;
|
|
94
|
+
if (!/^https:\/\//i.test(raw)) raw = "https://" + raw;
|
|
95
|
+
return raw.replace(/\/+$/, "");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function quotaUrl(ctx) {
|
|
99
|
+
var raw = cleaned(settings(ctx).quotaUrl) || env(ctx, "ALIBABA_TOKEN_PLAN_QUOTA_URL");
|
|
100
|
+
if (raw) {
|
|
101
|
+
if (!/^https:\/\//i.test(raw)) raw = "https://" + raw;
|
|
102
|
+
return raw;
|
|
103
|
+
}
|
|
104
|
+
return hostBase(ctx) + "/data/api.json?action=" + encodeURIComponent(ACTION) +
|
|
105
|
+
"&product=" + encodeURIComponent(BSS_SERVICE_CODE) + "&_tag=";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function dashboardUrl(ctx) {
|
|
109
|
+
var base = hostBase(ctx);
|
|
110
|
+
return base + "/cn-beijing?tab=plan#/efm/subscription/token-plan";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function extractSecToken(html) {
|
|
114
|
+
var patterns = [
|
|
115
|
+
/"secToken"\s*:\s*"([^"]+)"/,
|
|
116
|
+
/"sec_token"\s*:\s*"([^"]+)"/,
|
|
117
|
+
/secToken['"]?\s*[:=]\s*['"]([^'"]+)['"]/,
|
|
118
|
+
/sec_token['"]?\s*[:=]\s*['"]([^'"]+)['"]/,
|
|
119
|
+
];
|
|
120
|
+
for (var i = 0; i < patterns.length; i++) {
|
|
121
|
+
var match = patterns[i].exec(String(html || ""));
|
|
122
|
+
if (match && match[1] && match[1].trim()) return match[1].trim();
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function resolveSecToken(ctx, cookie) {
|
|
128
|
+
try {
|
|
129
|
+
var resp = ctx.util.request({
|
|
130
|
+
method: "GET",
|
|
131
|
+
url: dashboardUrl(ctx),
|
|
132
|
+
headers: {
|
|
133
|
+
Cookie: cookie,
|
|
134
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
135
|
+
"User-Agent": USER_AGENT,
|
|
136
|
+
},
|
|
137
|
+
timeoutMs: 10000,
|
|
138
|
+
});
|
|
139
|
+
if (resp.status >= 200 && resp.status < 300) {
|
|
140
|
+
var token = extractSecToken(resp.bodyText);
|
|
141
|
+
if (token) return token;
|
|
142
|
+
}
|
|
143
|
+
} catch (_) {}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
var base = hostBase(ctx);
|
|
147
|
+
var userInfo = ctx.util.request({
|
|
148
|
+
method: "GET",
|
|
149
|
+
url: base + "/tool/user/info.json",
|
|
150
|
+
headers: {
|
|
151
|
+
Cookie: cookie,
|
|
152
|
+
Accept: "application/json, text/plain, */*",
|
|
153
|
+
Referer: base + "/",
|
|
154
|
+
"User-Agent": USER_AGENT,
|
|
155
|
+
},
|
|
156
|
+
timeoutMs: 10000,
|
|
157
|
+
});
|
|
158
|
+
if (userInfo.status >= 200 && userInfo.status < 300) {
|
|
159
|
+
var expanded = expandJsonStrings(ctx.util.tryParseJson(userInfo.bodyText));
|
|
160
|
+
var fromInfo = findFirstString(expanded, ["secToken", "sec_token"]);
|
|
161
|
+
if (fromInfo) return fromInfo;
|
|
162
|
+
}
|
|
163
|
+
} catch (_) {}
|
|
164
|
+
|
|
165
|
+
return cookieValue("sec_token", cookie);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function formBody(secToken) {
|
|
169
|
+
var parts = [
|
|
170
|
+
["product", BSS_SERVICE_CODE],
|
|
171
|
+
["action", ACTION],
|
|
172
|
+
["params", JSON.stringify({ ProductCode: TOKEN_PLAN_PRODUCT_CODE })],
|
|
173
|
+
["region", CURRENT_REGION_ID],
|
|
174
|
+
];
|
|
175
|
+
if (secToken) parts.push(["sec_token", secToken]);
|
|
176
|
+
return parts.map(function (part) {
|
|
177
|
+
return encodeURIComponent(part[0]) + "=" + encodeURIComponent(part[1]);
|
|
178
|
+
}).join("&");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function isLoginText(text) {
|
|
182
|
+
var lower = String(text || "").toLowerCase();
|
|
183
|
+
return lower.indexOf("needlogin") >= 0 || lower.indexOf("login") >= 0 ||
|
|
184
|
+
lower.indexOf("postonlyortokenerror") >= 0 || lower.indexOf("tokenerror") >= 0 ||
|
|
185
|
+
lower.indexOf("request has expired") >= 0 || lower.indexOf("refresh page") >= 0 ||
|
|
186
|
+
lower.indexOf("请求已经过期") >= 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function fetchPayload(ctx, cookie) {
|
|
190
|
+
var headers = {
|
|
191
|
+
Cookie: cookie,
|
|
192
|
+
Accept: "*/*",
|
|
193
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
194
|
+
Origin: hostBase(ctx),
|
|
195
|
+
Referer: dashboardUrl(ctx),
|
|
196
|
+
"User-Agent": USER_AGENT,
|
|
197
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
198
|
+
};
|
|
199
|
+
var csrf = cookieValue("login_aliyunid_csrf", cookie) || cookieValue("csrf", cookie);
|
|
200
|
+
if (csrf) {
|
|
201
|
+
headers["x-xsrf-token"] = csrf;
|
|
202
|
+
headers["x-csrf-token"] = csrf;
|
|
203
|
+
}
|
|
204
|
+
var resp = ctx.util.request({
|
|
205
|
+
method: "POST",
|
|
206
|
+
url: quotaUrl(ctx),
|
|
207
|
+
headers: headers,
|
|
208
|
+
bodyText: formBody(resolveSecToken(ctx, cookie)),
|
|
209
|
+
timeoutMs: 20000,
|
|
210
|
+
});
|
|
211
|
+
if (ctx.util.isAuthStatus(resp.status)) throw "Alibaba Token Plan login required.";
|
|
212
|
+
if (resp.status < 200 || resp.status >= 300) throw "Alibaba Token Plan API error: HTTP " + resp.status + ".";
|
|
213
|
+
var json = ctx.util.tryParseJson(resp.bodyText);
|
|
214
|
+
if (!json) {
|
|
215
|
+
if (/<html/i.test(String(resp.bodyText || "")) && isLoginText(resp.bodyText)) {
|
|
216
|
+
throw "Alibaba Token Plan login required.";
|
|
217
|
+
}
|
|
218
|
+
throw "Could not parse Alibaba Token Plan usage: Invalid JSON response.";
|
|
219
|
+
}
|
|
220
|
+
return expandJsonStrings(json);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function expandJsonStrings(value) {
|
|
224
|
+
if (Array.isArray(value)) return value.map(expandJsonStrings);
|
|
225
|
+
if (value && typeof value === "object") {
|
|
226
|
+
var out = {};
|
|
227
|
+
Object.keys(value).forEach(function (key) { out[key] = expandJsonStrings(value[key]); });
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
if (typeof value === "string") {
|
|
231
|
+
var text = value.trim();
|
|
232
|
+
if ((text[0] === "{" && text[text.length - 1] === "}") || (text[0] === "[" && text[text.length - 1] === "]")) {
|
|
233
|
+
try {
|
|
234
|
+
return expandJsonStrings(JSON.parse(text));
|
|
235
|
+
} catch (_) {}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return value;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function directString(obj, keys) {
|
|
242
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return null;
|
|
243
|
+
for (var i = 0; i < keys.length; i++) {
|
|
244
|
+
var value = obj[keys[i]];
|
|
245
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function parseNumber(value) {
|
|
251
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
252
|
+
if (typeof value === "string" && value.trim()) {
|
|
253
|
+
var parsed = Number(value.replace(/,/g, ""));
|
|
254
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function directNumber(obj, keys) {
|
|
260
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return null;
|
|
261
|
+
for (var i = 0; i < keys.length; i++) {
|
|
262
|
+
var value = parseNumber(obj[keys[i]]);
|
|
263
|
+
if (value !== null) return value;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function parseBool(value) {
|
|
269
|
+
if (typeof value === "boolean") return value;
|
|
270
|
+
if (typeof value === "number") return value !== 0;
|
|
271
|
+
if (typeof value === "string") {
|
|
272
|
+
var lower = value.trim().toLowerCase();
|
|
273
|
+
if (/^(true|1|yes|active|valid|normal)$/.test(lower)) return true;
|
|
274
|
+
if (/^(false|0|no|inactive|invalid|expired)$/.test(lower)) return false;
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function findFirstString(value, keys) {
|
|
280
|
+
if (Array.isArray(value)) {
|
|
281
|
+
for (var i = 0; i < value.length; i++) {
|
|
282
|
+
var inArray = findFirstString(value[i], keys);
|
|
283
|
+
if (inArray) return inArray;
|
|
284
|
+
}
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
if (!value || typeof value !== "object") return null;
|
|
288
|
+
var direct = directString(value, keys);
|
|
289
|
+
if (direct) return direct;
|
|
290
|
+
var objectKeys = Object.keys(value);
|
|
291
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
292
|
+
var nested = findFirstString(value[objectKeys[j]], keys);
|
|
293
|
+
if (nested) return nested;
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function findFirstNumber(value, keys) {
|
|
299
|
+
if (Array.isArray(value)) {
|
|
300
|
+
for (var i = 0; i < value.length; i++) {
|
|
301
|
+
var inArray = findFirstNumber(value[i], keys);
|
|
302
|
+
if (inArray !== null) return inArray;
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
if (!value || typeof value !== "object") return null;
|
|
307
|
+
var direct = directNumber(value, keys);
|
|
308
|
+
if (direct !== null) return direct;
|
|
309
|
+
var objectKeys = Object.keys(value);
|
|
310
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
311
|
+
var nested = findFirstNumber(value[objectKeys[j]], keys);
|
|
312
|
+
if (nested !== null) return nested;
|
|
313
|
+
}
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function findFirstBool(value, keys) {
|
|
318
|
+
if (Array.isArray(value)) {
|
|
319
|
+
for (var i = 0; i < value.length; i++) {
|
|
320
|
+
var inArray = findFirstBool(value[i], keys);
|
|
321
|
+
if (inArray !== null) return inArray;
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
if (!value || typeof value !== "object") return null;
|
|
326
|
+
for (var k = 0; k < keys.length; k++) {
|
|
327
|
+
var parsed = parseBool(value[keys[k]]);
|
|
328
|
+
if (parsed !== null) return parsed;
|
|
329
|
+
}
|
|
330
|
+
var objectKeys = Object.keys(value);
|
|
331
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
332
|
+
var nested = findFirstBool(value[objectKeys[j]], keys);
|
|
333
|
+
if (nested !== null) return nested;
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function parseDate(ctx, value) {
|
|
339
|
+
var n = parseNumber(value);
|
|
340
|
+
if (n !== null && n > 1000000000) return ctx.util.toIso(n);
|
|
341
|
+
var text = trim(value);
|
|
342
|
+
if (!text) return null;
|
|
343
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(text)) return ctx.util.toIso(text + "T00:00:00Z");
|
|
344
|
+
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}/.test(text)) return ctx.util.toIso(text.replace(" ", "T") + "Z");
|
|
345
|
+
return ctx.util.toIso(text);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function findFirstDate(ctx, value, keys) {
|
|
349
|
+
if (Array.isArray(value)) {
|
|
350
|
+
for (var i = 0; i < value.length; i++) {
|
|
351
|
+
var inArray = findFirstDate(ctx, value[i], keys);
|
|
352
|
+
if (inArray) return inArray;
|
|
353
|
+
}
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
if (!value || typeof value !== "object") return null;
|
|
357
|
+
for (var k = 0; k < keys.length; k++) {
|
|
358
|
+
var direct = parseDate(ctx, value[keys[k]]);
|
|
359
|
+
if (direct) return direct;
|
|
360
|
+
}
|
|
361
|
+
var objectKeys = Object.keys(value);
|
|
362
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
363
|
+
var nested = findFirstDate(ctx, value[objectKeys[j]], keys);
|
|
364
|
+
if (nested) return nested;
|
|
365
|
+
}
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function hasAnyKey(obj, keyGroups) {
|
|
370
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return false;
|
|
371
|
+
var keys = [].concat.apply([], keyGroups);
|
|
372
|
+
for (var i = 0; i < keys.length; i++) {
|
|
373
|
+
if (Object.prototype.hasOwnProperty.call(obj, keys[i])) return true;
|
|
374
|
+
}
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function activeSignalScore(obj) {
|
|
379
|
+
var status = (directString(obj, ["status", "instanceStatus", "state"]) || "").toUpperCase();
|
|
380
|
+
if (/^(VALID|ACTIVE|NORMAL)$/.test(status)) return 3;
|
|
381
|
+
if (/^(EXPIRED|INVALID|INACTIVE|DISABLED|TERMINATED|STOPPED)$/.test(status)) return -1;
|
|
382
|
+
var active = parseBool(obj && (obj.isActive !== undefined ? obj.isActive : obj.active));
|
|
383
|
+
return active === null ? 0 : active ? 3 : -1;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function findObjectByKeys(value, keys) {
|
|
387
|
+
if (Array.isArray(value)) {
|
|
388
|
+
for (var i = 0; i < value.length; i++) {
|
|
389
|
+
var inArray = findObjectByKeys(value[i], keys);
|
|
390
|
+
if (inArray) return inArray;
|
|
391
|
+
}
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
if (!value || typeof value !== "object") return null;
|
|
395
|
+
for (var k = 0; k < keys.length; k++) {
|
|
396
|
+
if (value[keys[k]] && typeof value[keys[k]] === "object" && !Array.isArray(value[keys[k]])) return value[keys[k]];
|
|
397
|
+
}
|
|
398
|
+
var objectKeys = Object.keys(value);
|
|
399
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
400
|
+
var nested = findObjectByKeys(value[objectKeys[j]], keys);
|
|
401
|
+
if (nested) return nested;
|
|
402
|
+
}
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function findArrayByKeys(value, keys) {
|
|
407
|
+
if (Array.isArray(value)) {
|
|
408
|
+
for (var i = 0; i < value.length; i++) {
|
|
409
|
+
var inArray = findArrayByKeys(value[i], keys);
|
|
410
|
+
if (inArray) return inArray;
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
if (!value || typeof value !== "object") return null;
|
|
415
|
+
for (var k = 0; k < keys.length; k++) {
|
|
416
|
+
if (Array.isArray(value[keys[k]])) return value[keys[k]];
|
|
417
|
+
}
|
|
418
|
+
var objectKeys = Object.keys(value);
|
|
419
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
420
|
+
var nested = findArrayByKeys(value[objectKeys[j]], keys);
|
|
421
|
+
if (nested) return nested;
|
|
422
|
+
}
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function findObjectWithQuotaKeys(value) {
|
|
427
|
+
if (Array.isArray(value)) {
|
|
428
|
+
for (var i = 0; i < value.length; i++) {
|
|
429
|
+
var inArray = findObjectWithQuotaKeys(value[i]);
|
|
430
|
+
if (inArray) return inArray;
|
|
431
|
+
}
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
if (!value || typeof value !== "object") return null;
|
|
435
|
+
if (hasAnyKey(value, [USED_QUOTA_KEYS, TOTAL_QUOTA_KEYS, REMAINING_QUOTA_KEYS])) return value;
|
|
436
|
+
var objectKeys = Object.keys(value);
|
|
437
|
+
for (var j = 0; j < objectKeys.length; j++) {
|
|
438
|
+
var nested = findObjectWithQuotaKeys(value[objectKeys[j]]);
|
|
439
|
+
if (nested) return nested;
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function findTokenPlanInstance(value) {
|
|
445
|
+
var object = findObjectByKeys(value, ["tokenPlanInstanceInfo", "token_plan_instance_info", "instanceInfo", "instance_info"]);
|
|
446
|
+
if (object) return object;
|
|
447
|
+
var array = findArrayByKeys(value, [
|
|
448
|
+
"tokenPlanInstanceInfos", "token_plan_instance_infos", "instanceInfos", "instances", "Data", "data", "successResponse",
|
|
449
|
+
]);
|
|
450
|
+
if (!array) return null;
|
|
451
|
+
var best = null;
|
|
452
|
+
var bestScore = -999;
|
|
453
|
+
for (var i = 0; i < array.length; i++) {
|
|
454
|
+
if (!array[i] || typeof array[i] !== "object" || Array.isArray(array[i])) continue;
|
|
455
|
+
var score = activeSignalScore(array[i]);
|
|
456
|
+
if (!best || score > bestScore) {
|
|
457
|
+
best = array[i];
|
|
458
|
+
bestScore = score;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return best;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function throwIfErrorPayload(value) {
|
|
465
|
+
var success = findFirstBool(value, ["success", "Success"]);
|
|
466
|
+
if (success === false) {
|
|
467
|
+
var msg = findFirstString(value, ["message", "msg", "Message", "errorMessage", "Code", "code"]) || "request failed";
|
|
468
|
+
if (isLoginText(msg)) throw "Alibaba Token Plan login required.";
|
|
469
|
+
throw "Alibaba Token Plan API error: " + msg;
|
|
470
|
+
}
|
|
471
|
+
var codeText = (findFirstString(value, ["code", "status", "statusCode"]) || "").toLowerCase();
|
|
472
|
+
var messageText = (findFirstString(value, ["message", "msg", "statusMessage"]) || "").toLowerCase();
|
|
473
|
+
if (isLoginText(codeText + " " + messageText)) throw "Alibaba Token Plan login required.";
|
|
474
|
+
var statusCode = findFirstNumber(value, ["statusCode", "status_code", "code"]);
|
|
475
|
+
if (statusCode !== null && statusCode !== 0 && statusCode !== 200) {
|
|
476
|
+
if (statusCode === 401 || statusCode === 403) throw "Alibaba Token Plan login required.";
|
|
477
|
+
throw "Alibaba Token Plan API error: " + (messageText || "status code " + statusCode);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function formatQuota(value) {
|
|
482
|
+
if (!Number.isFinite(value)) return "";
|
|
483
|
+
var rounded = Math.round(value);
|
|
484
|
+
if (Math.abs(rounded - value) < 0.000001) return String(rounded).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
485
|
+
return value.toFixed(2).replace(/\.?0+$/, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function usageSnapshot(ctx, payload) {
|
|
489
|
+
throwIfErrorPayload(payload);
|
|
490
|
+
var instance = findTokenPlanInstance(payload);
|
|
491
|
+
var scope = instance || payload;
|
|
492
|
+
var quota = findObjectByKeys(scope, ["quotaInfo", "quota_info", "tokenPlanQuotaInfo", "token_plan_quota_info"]) ||
|
|
493
|
+
findObjectWithQuotaKeys(scope) ||
|
|
494
|
+
findObjectWithQuotaKeys(payload);
|
|
495
|
+
var planName = directString(scope, PLAN_NAME_KEYS) || findFirstString(payload, PLAN_NAME_KEYS);
|
|
496
|
+
var used = quota ? directNumber(quota, USED_QUOTA_KEYS) : null;
|
|
497
|
+
var total = quota ? directNumber(quota, TOTAL_QUOTA_KEYS) : null;
|
|
498
|
+
var remaining = quota ? directNumber(quota, REMAINING_QUOTA_KEYS) : null;
|
|
499
|
+
if (used === null) used = findFirstNumber(scope, USED_QUOTA_KEYS);
|
|
500
|
+
if (total === null) total = findFirstNumber(scope, TOTAL_QUOTA_KEYS);
|
|
501
|
+
if (remaining === null) remaining = findFirstNumber(scope, REMAINING_QUOTA_KEYS);
|
|
502
|
+
if (used === null && total !== null && remaining !== null) used = Math.max(0, total - remaining);
|
|
503
|
+
var resetsAt = findFirstDate(ctx, scope, RESET_DATE_KEYS) || findFirstDate(ctx, payload, RESET_DATE_KEYS);
|
|
504
|
+
if (!planName && (total !== null || used !== null || remaining !== null)) planName = "TOKEN PLAN";
|
|
505
|
+
if (planName === null && total === null && used === null && remaining === null) {
|
|
506
|
+
throw "Could not parse Alibaba Token Plan usage: missing token plan data.";
|
|
507
|
+
}
|
|
508
|
+
if (total === null || total <= 0 || used === null) {
|
|
509
|
+
throw "Could not parse Alibaba Token Plan usage: quota totals missing.";
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
planName: planName,
|
|
513
|
+
used: Math.max(0, Math.min(total, used)),
|
|
514
|
+
total: total,
|
|
515
|
+
remaining: remaining,
|
|
516
|
+
resetsAt: resetsAt,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function probe(ctx) {
|
|
521
|
+
var snapshot = usageSnapshot(ctx, fetchPayload(ctx, cookieHeader(ctx)));
|
|
522
|
+
var detail = formatQuota(snapshot.used) + " / " + formatQuota(snapshot.total) + " credits used";
|
|
523
|
+
var progress = {
|
|
524
|
+
label: "Credits",
|
|
525
|
+
used: snapshot.used,
|
|
526
|
+
limit: snapshot.total,
|
|
527
|
+
format: { kind: "count", suffix: "credits" },
|
|
528
|
+
detail: detail,
|
|
529
|
+
periodDurationMs: 30 * 24 * 60 * 60 * 1000,
|
|
530
|
+
};
|
|
531
|
+
if (snapshot.resetsAt) progress.resetsAt = snapshot.resetsAt;
|
|
532
|
+
return {
|
|
533
|
+
displayName: "Alibaba Token Plan",
|
|
534
|
+
source: "web",
|
|
535
|
+
plan: snapshot.planName,
|
|
536
|
+
lines: [
|
|
537
|
+
ctx.line.progress(progress),
|
|
538
|
+
ctx.line.text({ label: "Usage", value: detail }),
|
|
539
|
+
],
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
globalThis.__openusage_plugin = { id: "alibaba-token-plan", probe: probe };
|
|
544
|
+
})();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "alibaba-token-plan",
|
|
4
|
+
"name": "Alibaba Token Plan",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"brandColor": "#FF6A00",
|
|
8
|
+
"links": [
|
|
9
|
+
{ "label": "Token Plan", "url": "https://bailian.console.aliyun.com" },
|
|
10
|
+
{ "label": "Status", "url": "https://status.aliyun.com" }
|
|
11
|
+
],
|
|
12
|
+
"supportedModes": ["web"],
|
|
13
|
+
"autoMode": "web",
|
|
14
|
+
"webUrl": "https://bailian.console.aliyun.com",
|
|
15
|
+
"lines": [
|
|
16
|
+
{ "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 1 },
|
|
17
|
+
{ "type": "text", "label": "Usage", "scope": "detail" }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Amp</title><path d="M15.087 23.18L12.03 24l-2.097-7.823-5.738 5.738-2.251-2.251 5.718-5.719-7.769-2.082.82-3.057 11.294 3.08 3.08 11.295z" fill="#F34E3F"></path><path d="M19.505 18.762l-3.057.82-2.564-9.573-9.572-2.564.819-3.057 11.295 3.079 3.08 11.295z" fill="#F34E3F"></path><path d="M23.893 14.374l-3.057.82-2.565-9.572L8.7 3.057 9.52 0l11.295 3.08 3.079 11.294z" fill="#F34E3F"></path></svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="100" height="100" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M13.9197 13.61L17.3816 26.566L14.242 27.4049L11.2645 16.2643L0.119926 13.2906L0.957817 10.15L13.9197 13.61Z" fill="currentColor"/>
|
|
3
|
+
<path d="M13.7391 16.0892L4.88169 24.9056L2.58872 22.6019L11.4461 13.7865L13.7391 16.0892Z" fill="currentColor"/>
|
|
4
|
+
<path d="M18.9386 8.58315L22.4005 21.5392L19.2609 22.3781L16.2833 11.2374L5.13879 8.26381L5.97668 5.12318L18.9386 8.58315Z" fill="currentColor"/>
|
|
5
|
+
<path d="M23.9803 3.55632L27.4422 16.5124L24.3025 17.3512L21.325 6.21062L10.1805 3.23698L11.0183 0.0963593L23.9803 3.55632Z" fill="currentColor"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Amp</title><path d="M15.087 23.18L12.03 24l-2.097-7.823-5.738 5.738-2.251-2.251 5.718-5.719-7.769-2.082.82-3.057 11.294 3.08 3.08 11.295z"></path><path d="M19.505 18.762l-3.057.82-2.564-9.573-9.572-2.564.819-3.057 11.295 3.079 3.08 11.295z"></path><path d="M23.893 14.374l-3.057.82-2.565-9.572L8.7 3.057 9.52 0l11.295 3.08 3.079 11.294z"></path></svg>
|