@sjtdev/koishi-plugin-dota2tracker 2.2.3 → 2.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.
- package/changelog.md +22 -0
- package/lib/index.js +127 -94
- package/{queries → lib/queries}/MatchInfo.graphql +13 -0
- package/lib/templates/common/components/building_icons.ejs +20 -0
- package/lib/templates/common/styles/normalize.min.css +1 -0
- package/lib/templates/hero/hero_1.ejs +69 -0
- package/lib/templates/images/7.38_simple_minimap.png +0 -0
- package/lib/templates/item/item/recipe.ejs +9 -0
- package/lib/templates/item/item/style.css +1 -0
- package/lib/templates/item/item.ejs +52 -0
- package/lib/templates/item/itemlist.ejs +11 -0
- package/lib/templates/match/match_1/base.css +1 -0
- package/lib/templates/match/match_1/item.ejs +1 -0
- package/lib/templates/match/match_1/main.ejs +8 -0
- package/lib/templates/match/match_1/player.ejs +1 -0
- package/lib/templates/match/match_1/style.css +1 -0
- package/lib/templates/match/match_1.ejs +18 -0
- package/lib/templates/match/match_2/original.css +1 -0
- package/lib/templates/match/match_2/original.ejs +10 -0
- package/lib/templates/match/match_2+/charts.ejs +1 -0
- package/lib/templates/match/match_2+/extra.css +1 -0
- package/lib/templates/match/match_2+/lane_outcome.ejs +56 -0
- package/lib/templates/match/match_2+/map.ejs +160 -0
- package/lib/templates/match/match_2+.ejs +1 -0
- package/lib/templates/match/match_2.ejs +1 -0
- package/lib/templates/player/player_1/base.css +1 -0
- package/lib/templates/player/player_1/private.ejs +1 -0
- package/lib/templates/player/player_1.ejs +78 -0
- package/lib/templates/rank/rank_fun.ejs +1 -0
- package/lib/templates/report/daily/base.css +1 -0
- package/lib/templates/report/daily.ejs +29 -0
- package/package.json +2 -2
- package/template/hero/hero_1.ejs +0 -900
- package/template/item/item/recipe.ejs +0 -51
- package/template/item/item/style.css +0 -244
- package/template/item/item.ejs +0 -140
- package/template/item/itemlist.ejs +0 -99
- package/template/match/match_1/item.ejs +0 -11
- package/template/match/match_1/main.ejs +0 -37
- package/template/match/match_1/player.ejs +0 -154
- package/template/match/match_1/style.css +0 -764
- package/template/match/match_1.ejs +0 -56
- package/template/match/match_2/original.css +0 -463
- package/template/match/match_2/original.ejs +0 -192
- package/template/match/match_2+/charts.ejs +0 -261
- package/template/match/match_2+/extra.css +0 -143
- package/template/match/match_2+/lane_outcome.ejs +0 -157
- package/template/match/match_2+.ejs +0 -27
- package/template/match/match_2.ejs +0 -18
- package/template/player/player_1/private.ejs +0 -5
- package/template/player/player_1.ejs +0 -654
- package/template/rank/rank_fun.ejs +0 -131
- package/template/report/daily.ejs +0 -191
- /package/{queries → lib/queries}/Constants.graphql +0 -0
- /package/{queries → lib/queries}/GetWeeklyMetaByPosition.graphql +0 -0
- /package/{queries → lib/queries}/PlayerExtraInfo.graphql +0 -0
- /package/{queries → lib/queries}/PlayerInfoWith25Matches.graphql +0 -0
- /package/{queries → lib/queries}/PlayerPerformanceForHeroRecommendation.graphql +0 -0
- /package/{queries → lib/queries}/PlayersInfoWith10MatchesForGuild.graphql +0 -0
- /package/{queries → lib/queries}/PlayersLastmatchRankinfo.graphql +0 -0
- /package/{queries → lib/queries}/PlayersMatchesForDaily.graphql +0 -0
- /package/{queries → lib/queries}/RequestMatchDataAnalysis.graphql +0 -0
- /package/{queries → lib/queries}/VerifyingPlayer.graphql +0 -0
- /package/{template → lib/templates}/images/bei.jpg +0 -0
- /package/{template → lib/templates}/images/disconnected.png +0 -0
- /package/{template → lib/templates}/images/flag_dire.png +0 -0
- /package/{template → lib/templates}/images/flag_radiant.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_1.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_2.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_3.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_4.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_5.png +0 -0
- /package/{template → lib/templates}/images/hero_badge_6.png +0 -0
- /package/{template → lib/templates}/images/lane_fail.svg +0 -0
- /package/{template → lib/templates}/images/lane_jungle.svg +0 -0
- /package/{template → lib/templates}/images/lane_stomp.svg +0 -0
- /package/{template → lib/templates}/images/lane_stomped.svg +0 -0
- /package/{template → lib/templates}/images/lane_tie.svg +0 -0
- /package/{template → lib/templates}/images/lane_victory.svg +0 -0
- /package/{template → lib/templates}/images/logo_dire.png +0 -0
- /package/{template → lib/templates}/images/logo_radiant.png +0 -0
- /package/{template → lib/templates}/images/medal_0.png +0 -0
- /package/{template → lib/templates}/images/medal_1.png +0 -0
- /package/{template → lib/templates}/images/medal_2.png +0 -0
- /package/{template → lib/templates}/images/medal_3.png +0 -0
- /package/{template → lib/templates}/images/medal_4.png +0 -0
- /package/{template → lib/templates}/images/medal_5.png +0 -0
- /package/{template → lib/templates}/images/medal_6.png +0 -0
- /package/{template → lib/templates}/images/medal_7.png +0 -0
- /package/{template → lib/templates}/images/medal_8.png +0 -0
- /package/{template → lib/templates}/images/medal_8b.png +0 -0
- /package/{template → lib/templates}/images/medal_8c.png +0 -0
- /package/{template → lib/templates}/images/scepter.png +0 -0
- /package/{template → lib/templates}/images/scepter_0.png +0 -0
- /package/{template → lib/templates}/images/scepter_1.png +0 -0
- /package/{template → lib/templates}/images/shard.png +0 -0
- /package/{template → lib/templates}/images/shard_0.png +0 -0
- /package/{template → lib/templates}/images/shard_1.png +0 -0
- /package/{template → lib/templates}/images/star_0.png +0 -0
- /package/{template → lib/templates}/images/star_1.png +0 -0
- /package/{template → lib/templates}/images/star_2.png +0 -0
- /package/{template → lib/templates}/images/star_3.png +0 -0
- /package/{template → lib/templates}/images/star_4.png +0 -0
- /package/{template → lib/templates}/images/star_5.png +0 -0
- /package/{template → lib/templates}/images/xi.jpg +0 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## [2.3.0](https://github.com/sjtdev/koishi-plugin-dota2tracker/compare/v2.2.3...v2.3.0) (2025-12-17)
|
|
4
|
+
|
|
5
|
+
### ✨ 新增功能
|
|
6
|
+
|
|
7
|
+
* 适配`7.40`新英雄 **朗戈**,更新`dotaconstants`依赖。 ([8308ed9](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/8308ed96c641519ec52a39329e2c3312b0fa2dc8))
|
|
8
|
+
* **templates/match_2+:** 添加小地图,显示防御塔、兵营、基地的存活状态,数据可用时显示建筑被拆毁时间。(高地仅显示各路近战兵营被破时间、4塔被全部拆除时间、基地时间) ([923b40f](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/923b40fc8f24e05ce4b28dfa9a20ad3166c8e2f5))
|
|
9
|
+
|
|
10
|
+
### 🚀 功能优化
|
|
11
|
+
|
|
12
|
+
* **api:** 将超时时间从10秒统一上调到15秒,解决某些数据量大的耗时任务失败概率高的问题。 ([b3f51de](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/b3f51defd49ac7c9c176f894aa9d94d9b392b3aa))
|
|
13
|
+
* **logger:** 优化部分查询情况下的报错提示日志。 ([79ba28b](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/79ba28b4822df8858e4f4c8d71303b339d407569))
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug 修复
|
|
16
|
+
|
|
17
|
+
* **command/query-hero:** 修复了指令`查询英雄`无参数但携带`-r/--random`选项无响应的问题。(即无法通过`查询英雄 -r`直接随机查询英雄的问题) ([c56a22c](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/c56a22caacf65eef573e6434b1032b06f589c2b8))
|
|
18
|
+
* **command/query-match:** 修复`2.2.2`更新导致指令`查询比赛`不可用的问题。 ([be5061c](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/be5061c9b67593cceb8067d480b965cb47c53d4d))
|
|
19
|
+
|
|
20
|
+
### ⚡ 性能提升
|
|
21
|
+
|
|
22
|
+
* **command/query-match:** 清理`2.0.0`大型重构时遗留耗时代码,提升执行速度。 ([4c0bf34](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/4c0bf34c358af3d508bf1be6be88fd1e86fefc17))
|
|
23
|
+
* **templates:** 重构大部分模板,使其构建打包后体积更小,略微提升生成速度。 ([fdf1d33](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/fdf1d3367e12f8e46124df31d6f432e7fd0a7187))
|
|
24
|
+
|
|
3
25
|
### [2.2.3](https://github.com/sjtdev/koishi-plugin-dota2tracker/compare/v2.2.2...v2.2.3) (2025-11-20)
|
|
4
26
|
|
|
5
27
|
### 🎨 样式
|
package/lib/index.js
CHANGED
|
@@ -259,7 +259,8 @@ var require_en_US_constants = __commonJS({
|
|
|
259
259
|
"136": "Marci",
|
|
260
260
|
"137": "Primal Beast",
|
|
261
261
|
"138": "Muerta",
|
|
262
|
-
"145": "Kez"
|
|
262
|
+
"145": "Kez",
|
|
263
|
+
"155": "Largo"
|
|
263
264
|
},
|
|
264
265
|
behavior: {
|
|
265
266
|
"Unit Target": "Unit Target",
|
|
@@ -571,7 +572,8 @@ var require_zh_CN_constants = __commonJS({
|
|
|
571
572
|
"136": "玛西",
|
|
572
573
|
"137": "獸",
|
|
573
574
|
"138": "琼英碧灵",
|
|
574
|
-
"145": "凯"
|
|
575
|
+
"145": "凯",
|
|
576
|
+
"155": "朗戈"
|
|
575
577
|
},
|
|
576
578
|
behavior: {
|
|
577
579
|
"Unit Target": "单位目标",
|
|
@@ -1520,9 +1522,9 @@ __name(handleError, "handleError");
|
|
|
1520
1522
|
|
|
1521
1523
|
// src/app/core/match.service.ts
|
|
1522
1524
|
var MatchService = class _MatchService extends import_koishi4.Service {
|
|
1523
|
-
constructor(ctx,
|
|
1525
|
+
constructor(ctx, pluginVersion) {
|
|
1524
1526
|
super(ctx, "dota2tracker.match", true);
|
|
1525
|
-
this.pluginVersion =
|
|
1527
|
+
this.pluginVersion = pluginVersion;
|
|
1526
1528
|
}
|
|
1527
1529
|
static {
|
|
1528
1530
|
__name(this, "MatchService");
|
|
@@ -2027,12 +2029,12 @@ var PlayerService = class _PlayerService extends import_koishi5.Service {
|
|
|
2027
2029
|
const lastMatchQuery = await this.ctx.dota2tracker.stratzAPI.queryPlayersLastMatchRankInfo({
|
|
2028
2030
|
steamAccountIds: [steamId]
|
|
2029
2031
|
});
|
|
2030
|
-
if (lastMatchQuery.players[0].steamAccount.isAnonymous) return {
|
|
2032
|
+
if (lastMatchQuery.players[0].steamAccount.isAnonymous) return { id: 0, isAnonymous: true };
|
|
2031
2033
|
lastMatchId = lastMatchQuery.players[0].matches[0]?.id;
|
|
2032
2034
|
} catch (error) {
|
|
2033
2035
|
this.logger.error(error);
|
|
2034
2036
|
}
|
|
2035
|
-
return {
|
|
2037
|
+
return { id: lastMatchId };
|
|
2036
2038
|
}
|
|
2037
2039
|
async getFormattedPlayerData(steamId, heroId, languageTag) {
|
|
2038
2040
|
const playerQuery = await this.ctx.dota2tracker.stratzAPI.queryPlayerInfoWith25Matches({
|
|
@@ -2258,8 +2260,8 @@ var CacheService = class extends import_koishi6.Service {
|
|
|
2258
2260
|
async getMatchCache(matchId) {
|
|
2259
2261
|
return this.ctx.cache.get("dt_previous_query_results", String(matchId));
|
|
2260
2262
|
}
|
|
2261
|
-
setMatchCache(matchId, matchQuery,
|
|
2262
|
-
this.ctx.cache.set("dt_previous_query_results", String(matchQuery.match.id), { data: matchQuery, pluginVersion
|
|
2263
|
+
setMatchCache(matchId, matchQuery, pluginVersion) {
|
|
2264
|
+
this.ctx.cache.set("dt_previous_query_results", String(matchQuery.match.id), { data: matchQuery, pluginVersion }, DAYS_30);
|
|
2263
2265
|
}
|
|
2264
2266
|
markMatchAsSended(matchId) {
|
|
2265
2267
|
this.ctx.cache.set("dt_sended_match_id", String(matchId), void 0, DAYS_30);
|
|
@@ -2388,14 +2390,6 @@ var import_path = __toESM(require("path"));
|
|
|
2388
2390
|
var import_axios2 = __toESM(require("axios"));
|
|
2389
2391
|
var import_https_proxy_agent = require("https-proxy-agent");
|
|
2390
2392
|
var StratzAPI = class extends import_koishi8.Service {
|
|
2391
|
-
constructor(ctx, pluginDir3) {
|
|
2392
|
-
super(ctx, "dota2tracker.stratz-api", true);
|
|
2393
|
-
this.pluginDir = pluginDir3;
|
|
2394
|
-
this.config = ctx.config;
|
|
2395
|
-
this.queue = new MiniQueue(ctx, { interval: 200 });
|
|
2396
|
-
this.http = import_axios2.default.create({ timeout: 1e4, signal: this.abortController.signal });
|
|
2397
|
-
ctx.on("dispose", () => this.dispose());
|
|
2398
|
-
}
|
|
2399
2393
|
static {
|
|
2400
2394
|
__name(this, "StratzAPI");
|
|
2401
2395
|
}
|
|
@@ -2403,12 +2397,21 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2403
2397
|
queue;
|
|
2404
2398
|
http;
|
|
2405
2399
|
abortController = new AbortController();
|
|
2400
|
+
graphqlQueriesDir;
|
|
2401
|
+
constructor(ctx, currentDir) {
|
|
2402
|
+
super(ctx, "dota2tracker.stratz-api", true);
|
|
2403
|
+
this.config = ctx.config;
|
|
2404
|
+
this.graphqlQueriesDir = import_path.default.join(currentDir, "queries");
|
|
2405
|
+
this.queue = new MiniQueue(ctx, { interval: 200 });
|
|
2406
|
+
this.http = import_axios2.default.create({ timeout: 15e3, signal: this.abortController.signal });
|
|
2407
|
+
ctx.on("dispose", () => this.dispose());
|
|
2408
|
+
}
|
|
2406
2409
|
dispose() {
|
|
2407
2410
|
this.queue.dispose();
|
|
2408
2411
|
this.abortController.abort();
|
|
2409
2412
|
}
|
|
2410
2413
|
async queryGetWeeklyMetaByPosition({ bracketIds }) {
|
|
2411
|
-
return this.query("GetWeeklyMetaByPosition", { bracketIds }, (data) => !!data
|
|
2414
|
+
return this.query("GetWeeklyMetaByPosition", { bracketIds }, (data) => !!data?.heroStats);
|
|
2412
2415
|
}
|
|
2413
2416
|
async queryPlayerPerformanceForHeroRecommendation({ steamAccountId, recentDateTime }) {
|
|
2414
2417
|
return this.query(
|
|
@@ -2417,7 +2420,7 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2417
2420
|
steamAccountId,
|
|
2418
2421
|
recentDateTime
|
|
2419
2422
|
},
|
|
2420
|
-
(data) => !!data
|
|
2423
|
+
(data) => !!data?.player
|
|
2421
2424
|
);
|
|
2422
2425
|
}
|
|
2423
2426
|
async queryPlayersMatchesForDaily(steamAccountIds, seconds) {
|
|
@@ -2427,11 +2430,11 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2427
2430
|
steamAccountIds,
|
|
2428
2431
|
seconds
|
|
2429
2432
|
},
|
|
2430
|
-
(data) => !!data
|
|
2433
|
+
(data) => !!data?.players
|
|
2431
2434
|
);
|
|
2432
2435
|
}
|
|
2433
2436
|
async queryVerifyingPlayer(steamAccountId) {
|
|
2434
|
-
return this.query("VerifyingPlayer", { steamAccountId }, (data) => !!data
|
|
2437
|
+
return this.query("VerifyingPlayer", { steamAccountId }, (data) => !!data?.player);
|
|
2435
2438
|
}
|
|
2436
2439
|
async queryPlayerExtraInfo({ steamAccountId, matchCount, heroIds }) {
|
|
2437
2440
|
return this.query(
|
|
@@ -2441,11 +2444,11 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2441
2444
|
matchCount,
|
|
2442
2445
|
heroIds
|
|
2443
2446
|
},
|
|
2444
|
-
(data) => !!data
|
|
2447
|
+
(data) => !!data?.player
|
|
2445
2448
|
);
|
|
2446
2449
|
}
|
|
2447
2450
|
async queryPlayersInfoWith10MatchesForGuild({ steamAccountIds }) {
|
|
2448
|
-
return this.query("PlayersInfoWith10MatchesForGuild", { steamAccountIds }, (data) => !!data
|
|
2451
|
+
return this.query("PlayersInfoWith10MatchesForGuild", { steamAccountIds }, (data) => !!data?.players);
|
|
2449
2452
|
}
|
|
2450
2453
|
async queryPlayerInfoWith25Matches({ steamAccountId, heroIds }) {
|
|
2451
2454
|
return this.query(
|
|
@@ -2454,17 +2457,17 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2454
2457
|
steamAccountId,
|
|
2455
2458
|
heroIds
|
|
2456
2459
|
},
|
|
2457
|
-
(data) => !!data
|
|
2460
|
+
(data) => !!data?.player
|
|
2458
2461
|
);
|
|
2459
2462
|
}
|
|
2460
2463
|
async queryPlayersLastMatchRankInfo({ steamAccountIds }) {
|
|
2461
|
-
return this.query("PlayersLastmatchRankinfo", { steamAccountIds }, (data) => !!data
|
|
2464
|
+
return this.query("PlayersLastmatchRankinfo", { steamAccountIds }, (data) => !!data?.players);
|
|
2462
2465
|
}
|
|
2463
2466
|
async queryConstants(languageTag) {
|
|
2464
|
-
return this.query("Constants", { language: this.ctx.dota2tracker.i18n.getGraphqlLanguageTag(languageTag) }, (data) => !!data
|
|
2467
|
+
return this.query("Constants", { language: this.ctx.dota2tracker.i18n.getGraphqlLanguageTag(languageTag) }, (data) => !!data?.constants);
|
|
2465
2468
|
}
|
|
2466
2469
|
async queryMatchInfo(matchId) {
|
|
2467
|
-
return this.query("MatchInfo", { matchId }, (data) => !!data
|
|
2470
|
+
return this.query("MatchInfo", { matchId }, (data) => !!data?.match);
|
|
2468
2471
|
}
|
|
2469
2472
|
async requestParseMatch(matchId) {
|
|
2470
2473
|
const response = await this.query("RequestMatchDataAnalysis", {
|
|
@@ -2525,7 +2528,7 @@ var StratzAPI = class extends import_koishi8.Service {
|
|
|
2525
2528
|
});
|
|
2526
2529
|
}
|
|
2527
2530
|
loadGraphqlFile(queryName) {
|
|
2528
|
-
return import_fs.default.readFileSync(import_path.default.join(this.
|
|
2531
|
+
return import_fs.default.readFileSync(import_path.default.join(this.graphqlQueriesDir, `${queryName}.graphql`), { encoding: "utf-8" }).replace(/[\r\n]+/g, " ");
|
|
2529
2532
|
}
|
|
2530
2533
|
};
|
|
2531
2534
|
var MiniQueue = class {
|
|
@@ -2592,7 +2595,7 @@ var ValveAPI = class extends import_koishi9.Service {
|
|
|
2592
2595
|
constructor(ctx) {
|
|
2593
2596
|
super(ctx, "dota2tracker.valve-api", true);
|
|
2594
2597
|
this.config = ctx.config;
|
|
2595
|
-
this.http = import_axios3.default.create({ timeout:
|
|
2598
|
+
this.http = import_axios3.default.create({ timeout: 15e3, signal: this.abortController.signal, baseURL: this.baseURL });
|
|
2596
2599
|
ctx.on("dispose", () => this.dispose());
|
|
2597
2600
|
}
|
|
2598
2601
|
dispose() {
|
|
@@ -2666,14 +2669,15 @@ var ImageFormat = /* @__PURE__ */ ((ImageFormat2) => {
|
|
|
2666
2669
|
// src/app/presentation/image.renderer.ts
|
|
2667
2670
|
var import_luxon5 = require("luxon");
|
|
2668
2671
|
var ImageRenderer = class extends import_koishi10.Service {
|
|
2669
|
-
constructor(ctx, pluginDir3) {
|
|
2670
|
-
super(ctx, "dota2tracker.image", true);
|
|
2671
|
-
this.pluginDir = pluginDir3;
|
|
2672
|
-
this.config = ctx.config;
|
|
2673
|
-
}
|
|
2674
2672
|
static {
|
|
2675
2673
|
__name(this, "ImageRenderer");
|
|
2676
2674
|
}
|
|
2675
|
+
templateDir;
|
|
2676
|
+
constructor(ctx, currentDir) {
|
|
2677
|
+
super(ctx, "dota2tracker.image", true);
|
|
2678
|
+
this.config = ctx.config;
|
|
2679
|
+
this.templateDir = import_path2.default.join(currentDir, "templates");
|
|
2680
|
+
}
|
|
2677
2681
|
async renderToImageByFile(data, templateName, type, languageTag) {
|
|
2678
2682
|
const html = await this.generateHTML(data, { source: "FILE", templateName, type }, languageTag);
|
|
2679
2683
|
return this.ctx.puppeteer.render(html);
|
|
@@ -2701,7 +2705,7 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2701
2705
|
try {
|
|
2702
2706
|
let html;
|
|
2703
2707
|
if (template.source === "FILE") {
|
|
2704
|
-
const templatePath = import_path2.default.join(this.
|
|
2708
|
+
const templatePath = import_path2.default.join(this.templateDir, template.type, `${template.templateName}.ejs`);
|
|
2705
2709
|
html = await import_ejs.default.renderFile(templatePath, templateData, {
|
|
2706
2710
|
strict: false
|
|
2707
2711
|
});
|
|
@@ -2711,7 +2715,7 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2711
2715
|
async: true
|
|
2712
2716
|
});
|
|
2713
2717
|
}
|
|
2714
|
-
if (process.env.NODE_ENV === "development") import_fs2.default.writeFileSync(import_path2.default.
|
|
2718
|
+
if (process.env.NODE_ENV === "development") import_fs2.default.writeFileSync(import_path2.default.resolve(process.cwd(), "temp.html"), html);
|
|
2715
2719
|
return html;
|
|
2716
2720
|
} catch (error) {
|
|
2717
2721
|
this.logger.error(error);
|
|
@@ -2721,8 +2725,8 @@ var ImageRenderer = class extends import_koishi10.Service {
|
|
|
2721
2725
|
getImageUrl(image, type = "local" /* Local */, format = "png" /* png */) {
|
|
2722
2726
|
if (type === "local" /* Local */) {
|
|
2723
2727
|
try {
|
|
2724
|
-
if (format === "svg" /* svg */) return import_fs2.default.readFileSync(import_path2.default.join(this.
|
|
2725
|
-
const imageData = import_fs2.default.readFileSync(import_path2.default.join(this.
|
|
2728
|
+
if (format === "svg" /* svg */) return import_fs2.default.readFileSync(import_path2.default.join(this.templateDir, "images", `${image}.svg`));
|
|
2729
|
+
const imageData = import_fs2.default.readFileSync(import_path2.default.join(this.templateDir, "images", `${image}.${format}`));
|
|
2726
2730
|
const base64Data = imageData.toString("base64");
|
|
2727
2731
|
return `data:image/png;base64,${base64Data}`;
|
|
2728
2732
|
} catch (error) {
|
|
@@ -3456,20 +3460,25 @@ __name(resolvePlayerAndHandleErrors, "resolvePlayerAndHandleErrors");
|
|
|
3456
3460
|
// src/app/commands/hero-of-the-day.command.ts
|
|
3457
3461
|
var import_luxon10 = require("luxon");
|
|
3458
3462
|
function registerHeroOfTheDayCommand(ctx) {
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3463
|
+
const name2 = "hero-of-the-day";
|
|
3464
|
+
ctx.command(`dota2tracker.${name2} <input_data>`).alias("今日英雄").option("days", "-d <value:number>").action(async ({ session, options }, input_data) => {
|
|
3465
|
+
try {
|
|
3466
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3467
|
+
if (steamId === null) return;
|
|
3468
|
+
const days = clamp(options.days, 1, 180, 30);
|
|
3469
|
+
const result = await ctx.dota2tracker.stratzAPI.queryPlayerPerformanceForHeroRecommendation({
|
|
3470
|
+
steamAccountId: steamId,
|
|
3471
|
+
recentDateTime: import_luxon10.DateTime.now().minus({ days }).toUnixInteger()
|
|
3472
|
+
});
|
|
3473
|
+
const recommendationPromise = ctx.dota2tracker.player.getHeroRecommendation(steamId, result.player);
|
|
3474
|
+
const metaPromise = ctx.dota2tracker.hero.getWeeklyHeroMeta(PlayerService.estimateWeightedRank(result.player));
|
|
3475
|
+
const [recommendation, weeklyHeroMeta] = await Promise.all([recommendationPromise, metaPromise]);
|
|
3476
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3477
|
+
const message = ctx.dota2tracker.messageBuilder.buildHeroOfTheDayMessage(languageTag, recommendation, weeklyHeroMeta);
|
|
3478
|
+
return message;
|
|
3479
|
+
} catch (error) {
|
|
3480
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3481
|
+
}
|
|
3473
3482
|
});
|
|
3474
3483
|
}
|
|
3475
3484
|
__name(registerHeroOfTheDayCommand, "registerHeroOfTheDayCommand");
|
|
@@ -3477,14 +3486,19 @@ __name(registerHeroOfTheDayCommand, "registerHeroOfTheDayCommand");
|
|
|
3477
3486
|
// src/app/commands/query-hero.command.ts
|
|
3478
3487
|
function registerQueryHeroCommand(ctx) {
|
|
3479
3488
|
ctx.command("dota2tracker.query-hero <input_data>").option("random", "-r").alias("查询英雄").action(async ({ session, options }, input_data) => {
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3489
|
+
const name2 = "query-hero";
|
|
3490
|
+
try {
|
|
3491
|
+
if (input_data || options.random) {
|
|
3492
|
+
await session.send(session.text(".querying_hero"));
|
|
3493
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3494
|
+
const heroData = await ctx.dota2tracker.hero.getHeroDetails(input_data, languageTag, options.random);
|
|
3495
|
+
if (!heroData) return session.text(".not_found");
|
|
3496
|
+
const image = await ctx.dota2tracker.image.renderToImageByFile(heroData, ctx.config.template_hero, "hero" /* Hero */, languageTag);
|
|
3497
|
+
const message = ctx.dota2tracker.messageBuilder.buildHeroMessage(heroData);
|
|
3498
|
+
await session.send(message + image);
|
|
3499
|
+
}
|
|
3500
|
+
} catch (error) {
|
|
3501
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3488
3502
|
}
|
|
3489
3503
|
});
|
|
3490
3504
|
}
|
|
@@ -3540,25 +3554,40 @@ __name(registerQueryItemCommand, "registerQueryItemCommand");
|
|
|
3540
3554
|
// src/app/commands/query-match.command.ts
|
|
3541
3555
|
function registerQueryMatchCommand(ctx) {
|
|
3542
3556
|
ctx.command("dota2tracker.query-match <match_id>").alias("查询比赛").option("parse", "-p").option("template", "-t <value:string>").action(async ({ session, options }, match_id) => {
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3557
|
+
const name2 = "query-match";
|
|
3558
|
+
try {
|
|
3559
|
+
if (!match_id) return session.text(".empty_input");
|
|
3560
|
+
if (!/^\d{1,11}$/.test(match_id)) return session.text(".match_id_invalid");
|
|
3561
|
+
await session.send(session.text(".querying_match"));
|
|
3562
|
+
return await handleQueryMatchCommand(ctx, ctx.config, session, options, match_id);
|
|
3563
|
+
} catch (error) {
|
|
3564
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3565
|
+
}
|
|
3547
3566
|
});
|
|
3548
3567
|
ctx.command("dota2tracker.query-recent-match [input_data]").alias("查询最近比赛").option("parse", "-p").option("template", "-t <value:string>").action(async ({ session, options }, input_data) => {
|
|
3549
|
-
const
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3568
|
+
const name2 = "query-recent-match";
|
|
3569
|
+
try {
|
|
3570
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3571
|
+
if (steamId === null) return;
|
|
3572
|
+
session.send(session.text(".querying_match"));
|
|
3573
|
+
let lastMatch;
|
|
3574
|
+
try {
|
|
3575
|
+
lastMatch = await ctx.dota2tracker.player.getLastMatchId(Number(steamId));
|
|
3576
|
+
} catch (error) {
|
|
3577
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3578
|
+
}
|
|
3579
|
+
if (!lastMatch?.id) return session.text(".query_failed");
|
|
3580
|
+
if (lastMatch.isAnonymous) return session.text(".is_anonymous");
|
|
3581
|
+
return await handleQueryMatchCommand(ctx, ctx.config, session, options, lastMatch.id);
|
|
3582
|
+
} catch (error) {
|
|
3583
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3584
|
+
}
|
|
3556
3585
|
});
|
|
3557
3586
|
}
|
|
3558
3587
|
__name(registerQueryMatchCommand, "registerQueryMatchCommand");
|
|
3559
3588
|
async function handleQueryMatchCommand(ctx, config, session, options, matchId) {
|
|
3560
3589
|
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3561
|
-
const result = await ctx.dota2tracker.match.getMatchResult({ matchId: Number(matchId),
|
|
3590
|
+
const result = await ctx.dota2tracker.match.getMatchResult({ matchId: Number(matchId), waitForParse: options.parse, allowFallback: config.enableOpenDotaFallback });
|
|
3562
3591
|
if (result.status === "PENDING") {
|
|
3563
3592
|
const subscriber = ctx.dota2tracker.parsePolling.createSubscriberByCommand(session, languageTag, { templateName: options?.template });
|
|
3564
3593
|
ctx.dota2tracker.parsePolling.add(result.matchId, [subscriber]);
|
|
@@ -3569,7 +3598,6 @@ async function handleQueryMatchCommand(ctx, config, session, options, matchId) {
|
|
|
3569
3598
|
const formattedMatchData = await ctx.dota2tracker.match.generateMatchData(result.matchData, languageTag);
|
|
3570
3599
|
const message = ctx.dota2tracker.messageBuilder.buildMatchMessage(languageTag, formattedMatchData, []);
|
|
3571
3600
|
const image = await ctx.dota2tracker.image.renderToImageByFile(formattedMatchData, options.template || config.template_match, "match" /* Match */, languageTag);
|
|
3572
|
-
await ctx.dota2tracker.image.renderToImageByFile(formattedMatchData, options.template || config.template_match, "match" /* Match */, languageTag);
|
|
3573
3601
|
return message + image;
|
|
3574
3602
|
}
|
|
3575
3603
|
}
|
|
@@ -3590,18 +3618,23 @@ __name(registerQueryMembersCommand, "registerQueryMembersCommand");
|
|
|
3590
3618
|
// src/app/commands/query-player.command.ts
|
|
3591
3619
|
function registerQueryPlayerCommand(ctx) {
|
|
3592
3620
|
ctx.command("dota2tracker.query-player <input_data>").option("hero", "-o <value:string>").alias("查询玩家").action(async ({ session, options }, input_data) => {
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
if (
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3621
|
+
const name2 = "query-player";
|
|
3622
|
+
try {
|
|
3623
|
+
if (session.guild || !session.guild && input_data) {
|
|
3624
|
+
const steamId = await resolvePlayerAndHandleErrors(ctx, session, input_data);
|
|
3625
|
+
if (steamId === null) return;
|
|
3626
|
+
session.send(session.text(".querying_player"));
|
|
3627
|
+
const heroId = ctx.dota2tracker.i18n.findHeroIdInLocale(options.hero);
|
|
3628
|
+
const languageTag = await ctx.dota2tracker.i18n.getLanguageTag({ session });
|
|
3629
|
+
const formattedPlayerData = await ctx.dota2tracker.player.getFormattedPlayerData(steamId, heroId, languageTag);
|
|
3630
|
+
const image = await ctx.dota2tracker.image.renderToImageByFile(formattedPlayerData, ctx.config.template_player, "player" /* Player */, languageTag);
|
|
3631
|
+
const message = ctx.dota2tracker.messageBuilder.buildPlayerMessage(steamId);
|
|
3632
|
+
return message + image;
|
|
3633
|
+
} else {
|
|
3634
|
+
return session.text("commands.dota2tracker.common.messages.user_not_in_group");
|
|
3635
|
+
}
|
|
3636
|
+
} catch (error) {
|
|
3637
|
+
handleError(error, ctx.logger(name2), ctx.dota2tracker.i18n, ctx.config);
|
|
3605
3638
|
}
|
|
3606
3639
|
});
|
|
3607
3640
|
}
|
|
@@ -3686,7 +3719,7 @@ var OpenDotaAPI = class extends import_koishi15.Service {
|
|
|
3686
3719
|
constructor(ctx) {
|
|
3687
3720
|
super(ctx, "dota2tracker.opendota-api", true);
|
|
3688
3721
|
this.config = ctx.config;
|
|
3689
|
-
this.http = import_axios4.default.create({ timeout:
|
|
3722
|
+
this.http = import_axios4.default.create({ timeout: 15e3, signal: this.abortController.signal, baseURL: this.BASE_URL });
|
|
3690
3723
|
ctx.on("dispose", () => this.dispose());
|
|
3691
3724
|
}
|
|
3692
3725
|
dispose() {
|
|
@@ -4178,7 +4211,7 @@ var globRequire_locales_schema_yml = __glob({
|
|
|
4178
4211
|
});
|
|
4179
4212
|
|
|
4180
4213
|
// src/config.ts
|
|
4181
|
-
var
|
|
4214
|
+
var templateDir = import_path4.default.join(__dirname, "templates");
|
|
4182
4215
|
var allI18nConfigs = Object.fromEntries(Object.keys(LanguageTags).map((lang) => [lang, globRequire_locales_schema_yml(`./locales/${lang}.schema.yml`)._config]));
|
|
4183
4216
|
var Config = import_koishi17.Schema.intersect([
|
|
4184
4217
|
import_koishi17.Schema.intersect([
|
|
@@ -4249,9 +4282,9 @@ var Config = import_koishi17.Schema.intersect([
|
|
|
4249
4282
|
]).i18n(getI18n("report"))
|
|
4250
4283
|
]),
|
|
4251
4284
|
import_koishi17.Schema.object({
|
|
4252
|
-
template_match: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4253
|
-
template_player: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4254
|
-
template_hero: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(
|
|
4285
|
+
template_match: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "match"))]).default("match_1"),
|
|
4286
|
+
template_player: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "player"))]).default("player_1"),
|
|
4287
|
+
template_hero: import_koishi17.Schema.union([...readDirectoryFilesSync(import_path4.default.join(templateDir, "hero"))]).default("hero_1"),
|
|
4255
4288
|
playerRankEstimate: import_koishi17.Schema.boolean().default(true),
|
|
4256
4289
|
templateFonts: import_koishi17.Schema.array(String).default([]).role("table")
|
|
4257
4290
|
}).i18n(getI18n("template"))
|
|
@@ -4285,13 +4318,13 @@ var inject = {
|
|
|
4285
4318
|
required: ["database", "puppeteer", "cache"],
|
|
4286
4319
|
optional: ["cron", "console"]
|
|
4287
4320
|
};
|
|
4288
|
-
var pluginDir2 = import_path5.default.resolve(__dirname, "..");
|
|
4289
|
-
var pluginVersion = require(import_path5.default.join(pluginDir2, "package.json")).version;
|
|
4290
4321
|
async function apply(ctx, config) {
|
|
4291
4322
|
const logger = ctx.logger("dota2tracker");
|
|
4323
|
+
const currentDir = import_path5.default.resolve(__dirname);
|
|
4324
|
+
const pluginVersion = require(import_path5.default.join(currentDir, "..", "package.json")).version;
|
|
4292
4325
|
ctx.dota2tracker = {};
|
|
4293
4326
|
ctx.dota2tracker.i18n = new I18NService(ctx);
|
|
4294
|
-
ctx.dota2tracker.image = new ImageRenderer(ctx,
|
|
4327
|
+
ctx.dota2tracker.image = new ImageRenderer(ctx, currentDir);
|
|
4295
4328
|
ctx.dota2tracker.messageBuilder = new MessageBuilder(ctx);
|
|
4296
4329
|
ctx.dota2tracker.match = new MatchService(ctx, pluginVersion);
|
|
4297
4330
|
ctx.dota2tracker.player = new PlayerService(ctx);
|
|
@@ -4311,7 +4344,7 @@ async function apply(ctx, config) {
|
|
|
4311
4344
|
ctx.dota2tracker.cache = new CacheService(ctx);
|
|
4312
4345
|
ctx.dota2tracker.database = new DatabaseService(ctx);
|
|
4313
4346
|
ctx.dota2tracker.valveAPI = new ValveAPI(ctx);
|
|
4314
|
-
ctx.dota2tracker.stratzAPI = new StratzAPI(ctx,
|
|
4347
|
+
ctx.dota2tracker.stratzAPI = new StratzAPI(ctx, currentDir);
|
|
4315
4348
|
if (config.enableOpenDotaFallback) {
|
|
4316
4349
|
ctx.dota2tracker.opendotaAPI = new OpenDotaAPI(ctx);
|
|
4317
4350
|
ctx.dota2tracker.opendotaAdapter = new OpenDotaAdapter(ctx);
|
|
@@ -4327,7 +4360,7 @@ async function apply(ctx, config) {
|
|
|
4327
4360
|
registerQueryHeroCommand(ctx);
|
|
4328
4361
|
registerQueryItemCommand(ctx);
|
|
4329
4362
|
registerHeroOfTheDayCommand(ctx);
|
|
4330
|
-
if (config.enableConsole) registerConsolePage(ctx);
|
|
4363
|
+
if (ctx.console && config.enableConsole) registerConsolePage(ctx);
|
|
4331
4364
|
}
|
|
4332
4365
|
__name(apply, "apply");
|
|
4333
4366
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -20,6 +20,19 @@ query MatchInfo($matchId: Long!) {
|
|
|
20
20
|
radiantNetworthLeads
|
|
21
21
|
radiantExperienceLeads
|
|
22
22
|
winRates
|
|
23
|
+
|
|
24
|
+
towerStatusRadiant
|
|
25
|
+
towerStatusDire
|
|
26
|
+
barracksStatusRadiant
|
|
27
|
+
barracksStatusDire
|
|
28
|
+
|
|
29
|
+
playbackData {
|
|
30
|
+
buildingEvents {
|
|
31
|
+
time
|
|
32
|
+
npcId
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
players {
|
|
24
37
|
steamAccountId
|
|
25
38
|
steamAccount {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<svg style="display:none"><defs><symbol id="tower" viewBox="0 0 64 64"><rect x="8" y="8" width="48" height="48" fill="#000"/><rect x="14" y="14" width="36" height="36" fill="currentColor"/><rect x="14" y="36" width="36" height="14" fill="#000" fill-opacity="0.2"/></symbol><symbol id="tower_angle" viewBox="0 0 64 64"><path d="M32,4 L8,22 L8,40 L32,58 L56,40 L56,22 Z" stroke="#000" stroke-width="10" stroke-linejoin="round"/><path d="M32,4 L8,22 L8,40 L32,58 L56,40 L56,22 Z" fill="currentColor"/><path d="M8,22 L32,40 L32,58 L8,40 Z" fill="#000" fill-opacity="0.2"/><path d="M56,22 L32,40 L32,58 L56,40 Z" fill="#000" fill-opacity="0.4"/></symbol><symbol id="rax" viewBox="0 0 64 64"><rect x="8" y="8" width="48" height="48" fill="#000"/><rect x="14" y="14" width="36" height="36" fill="currentColor"/><path d="M 14 14 L 14 39 L 19 34 L 19 16 Z" fill="#000" fill-opacity="0.05"/><path d="M 14 14 L 50 14 L 45 16 L 19 16 Z" fill="#000" fill-opacity="0.5"/><path d="M 45 16 L 50 14 L 50 39 L 45 34 Z" fill="#000" fill-opacity="0.25"/><path d="M 14 39 L 19 34 L 45 34 L 50 39 Z" fill="#000" fill-opacity="0.15"/><rect x="14" y="39" width="36" height="11" fill="#000" fill-opacity="0.25"/><rect x="19" y="8" width="26" height="26" fill="#000"/><rect x="20" y="9" width="24" height="24" fill="currentColor"/><path d="M 20 9 L 32 13 L 20 25 Z" fill="#000" fill-opacity="0.05"/><path d="M 20 9 L 32 13 L 44 9 Z" fill="#000" fill-opacity="0.5"/><path d="M 44 9 L 32 13 L 44 25 Z" fill="#000" fill-opacity="0.25"/><path d="M 20 25 L 32 13 L 44 25 Z" fill="#000" fill-opacity="0.15"/><rect x="20" y="25" width="24" height="8" fill="#000" fill-opacity="0.25"/></symbol><symbol id="rax_angle" viewBox="0 0 48 48"><path d="M14 12 L24 4 L34 12 L34 18 L24 26 L14 18 Z" fill="#000" stroke="#000" stroke-width="8" stroke-linejoin="round"/><path d="M6 22 L24 6 L42 22 L42 30 L24 44 L6 30 Z" fill="#000" stroke="#000" stroke-width="8" stroke-linejoin="round"/><path d="M6 22 L24 6 L42 22 L42 30 L24 44 L6 30 Z" fill="currentColor"/><path d="M6 22 L24 36 L24 44 L6 30 Z" fill="#000" fill-opacity="0.25"/><path d="M42 22 L24 36 L24 44 L42 30 Z" fill="#000" fill-opacity="0.35"/><path d="M6 22 L24 13 L24 6 Z" fill="#000" fill-opacity="0.22"/><path d="M42 22 L24 13 L24 6 Z" fill="#000" fill-opacity="0.38"/><path d="M42 22 L24 13 L24 36 Z" fill="#000" fill-opacity="0.32"/><path d="M14 12 L24 4 L34 12 L34 18 L24 26 L14 18 Z" fill="#000" stroke="#000" stroke-width="2"/><path d="M14 12 L24 4 L34 12 L34 18 L24 26 L14 18 Z" fill="currentColor"/><path d="M14 12 L24 20 L24 26 L14 18 Z" fill="#000" fill-opacity="0.25"/><path d="M34 12 L24 20 L24 26 L34 18 Z" fill="#000" fill-opacity="0.35"/><path d="M14 12 L24 4 L24 7Z" fill="#000" fill-opacity="0.22"/><path d="M34 12 L24 4 L24 7Z" fill="#000" fill-opacity="0.38"/><path d="M24 20 L24 7L34 12 Z" fill="#000" fill-opacity="0.32"/></symbol><symbol id="fort" viewBox="0 0 64 64"><path fill="#000" stroke="#000" stroke-width="10" stroke-linejoin="round" d="M 50.5 23.7
|
|
2
|
+
L 48.4 20.2
|
|
3
|
+
L 45.4 15.1 L 41.0 18.0 L 39.1 15.8 L 38.2 9.9 L 37.7 6.9 L 35.3 6.9
|
|
4
|
+
L 32.5 8.3 L 27.2 14.5 L 24.1 19.5 L 22.9 20.2 L 21.7 20.4 L 19.3 19.7
|
|
5
|
+
L 15.4 23.5 L 15.4 24.9 L 19.7 29.6 L 19.5 32.8 L 17.9 34.5 L 15.4 34.9 L 15.3 37.2
|
|
6
|
+
L 23.7 49.2 L 37.1 57.5 L 52.4 37.8 L 52.5 27.7 L 47.1 30.0 L 50.5 23.7 Z"/><path fill="currentColor" d="M 50.5 23.7
|
|
7
|
+
L 48.4 20.2
|
|
8
|
+
L 45.4 15.1 L 41.0 18.0 L 39.1 15.8 L 38.2 9.9 L 37.7 6.9 L 35.3 6.9
|
|
9
|
+
L 32.5 8.3 L 27.2 14.5 L 24.1 19.5 L 22.9 20.2 L 21.7 20.4 L 19.3 19.7
|
|
10
|
+
L 15.4 23.5 L 15.4 24.9 L 19.7 29.6 L 19.5 32.8 L 17.9 34.5 L 15.4 34.9 L 15.3 37.2
|
|
11
|
+
L 23.7 49.2 L 37.1 57.5 L 52.4 37.8 L 52.5 27.7 L 47.1 30.0 L 50.5 23.7 Z"/><path fill="#000" fill-opacity="0.25" d="M 39.1 15.8 L 29.3 28.5 L 31.1 34.2 L 26.5 40.5 L 28.2 49.5 L 37.1 57.5
|
|
12
|
+
L 23.7 49.2 L 15.3 37.2 L 22.1 39.9 L 22.3 34.9 L 21.1 33.3 L 19.5 32.8
|
|
13
|
+
L 19.7 29.6 L 15.4 24.9 C 15.4 25.0 15.4 23.5 15.4 23.5 L 16.8 22.3
|
|
14
|
+
L 23.2 30.1 L 26.1 27.2 L 25.9 23.2 L 27.4 20.6 L 29.1 17.0 L 38.2 9.9 L 39.1 15.8 Z
|
|
15
|
+
M 36.3 52.7 L 41.4 39.0 L 45.8 34.8 L 52.5 31.5 L 52.5 27.7 L 47.1 30.0
|
|
16
|
+
L 44.3 33.0 L 39.9 30.7 L 33.8 36.0 L 38.6 39.0 L 29.7 46.5 L 36.3 52.7 Z"/><path fill="#000" fill-opacity="0.4" d="M 33.8 36.0 L 39.9 30.7 L 44.3 33.0 L 47.1 30.0
|
|
17
|
+
L 50.5 23.7 L 48.4 20.2 L 37.0 27.9 L 41.0 18.0 L 39.1 15.8
|
|
18
|
+
L 29.3 28.5 L 31.1 34.2 L 33.8 36.0 Z
|
|
19
|
+
M 26.5 40.5 L 29.7 46.5 L 36.3 52.7 L 41.4 39.0 L 45.8 34.8 L 52.5 31.5
|
|
20
|
+
L 52.5 37.8 L 37.1 57.5 L 28.2 49.5 L 26.5 40.5 Z"/></symbol></defs></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
|