@sjtdev/koishi-plugin-dota2tracker 1.2.20-pre.3 → 1.3.0-pre.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sjtdev/koishi-plugin-dota2tracker",
3
3
  "description": "koishi插件-追踪群友的DOTA2对局",
4
- "version": "1.2.20-pre.3",
4
+ "version": "1.3.0-pre.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -14,7 +14,7 @@
14
14
  "contributors": [
15
15
  "sjtdev <sh1j1n9ta0@foxmail.com>"
16
16
  ],
17
- "homepage": "https://github.com/sjtdev/koishi-plugin-dota2tracker",
17
+ "homepage": "https://sjtdev.github.io/koishi-plugin-dota2tracker/",
18
18
  "repository": {
19
19
  "type": "git",
20
20
  "url": "git+https://github.com/sjtdev/koishi-plugin-dota2tracker.git"
@@ -43,7 +43,8 @@
43
43
  "http",
44
44
  "database",
45
45
  "puppeteer",
46
- "cron"
46
+ "cron",
47
+ "cache"
47
48
  ],
48
49
  "locales": [
49
50
  "zh-CN",
@@ -0,0 +1,16 @@
1
+ query Constants($language: LanguageEnum = ENGLISH) {
2
+ constants {
3
+ gameVersions {
4
+ id
5
+ }
6
+ facets(language: $language) {
7
+ name
8
+ id
9
+ color
10
+ icon
11
+ language {
12
+ displayName
13
+ }
14
+ }
15
+ }
16
+ }
@@ -122,14 +122,8 @@ query MatchInfo($matchId: Long!) {
122
122
  }
123
123
  }
124
124
  constants {
125
- facets(language: S_CHINESE) {
126
- name
125
+ gameVersions {
127
126
  id
128
- color
129
- icon
130
- language {
131
- displayName
132
- }
133
127
  }
134
128
  }
135
- }
129
+ }
package/readme.md CHANGED
@@ -46,8 +46,9 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
46
46
  `查询英雄`指令已适配7.36改动,所以此指令已废弃
47
47
 
48
48
  ### 英雄ID|英雄名|英雄常用别名 列表
49
- [dotaconstants_add.json](https://github.com/sjtdev/koishi-plugin-dota2tracker/blob/master/src/dotaconstants_add.json#L102-L226)
50
- 补充或纠错请提issue
49
+ <del>[dotaconstants_add.json](https://github.com/sjtdev/koishi-plugin-dota2tracker/blob/master/src/dotaconstants_add.json#L102-L226)
50
+ 补充或纠错请提issue</del>
51
+ 已可在本地化中定义
51
52
 
52
53
  ### 图片模板列表
53
54
  展示见[wiki](https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki)
@@ -55,4 +56,4 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
55
56
 
56
57
  ## 灵感来源&鸣谢
57
58
  * 感谢[SonodaHanami](https://github.com/SonodaHanami)大佬的[Steam_watcher](https://github.com/SonodaHanami/Steam_watcher)项目,是本插件最重要的灵感来源,并授权提供了战报称号系统、英雄代称与播报信息的代码数据。
58
- * 也受到了[koishi-plugin-dota2track(npm)](https://www.npmjs.com/package/koishi-plugin-dota2track)的启发,为我的代码提供了一些思路。
59
+ * 也受到了[koishi-plugin-dota2track(npm)](https://www.npmjs.com/package/koishi-plugin-dota2track)的启发,为我的代码提供了一些思路。
@@ -139,9 +139,9 @@
139
139
  <div class="info">
140
140
  <img class="avatar user" src="${user?.user?.avatar}" alt="" />
141
141
  <div class="name">
142
- <span class="nick_name">${escapeHTML(user.nickName)}</span>
143
- <span class="user name">${escapeHTML(user.nick || user.user?.name)}</span>
144
- <span class="steam name">${escapeHTML(user.steamAccount.name)}</span>
142
+ <span class="nick_name">${eh(user.nickName)}</span>
143
+ <span class="user name">${eh(user.nick || user.user?.name)}</span>
144
+ <span class="steam name">${eh(user.steamAccount.name)}</span>
145
145
  <span class="user id">${user.userId}</span>
146
146
  <span class="steam id">${user.steamId}</span>
147
147
  </div>
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en">
2
+ <html lang="<%= languageTag %>">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -121,20 +121,17 @@
121
121
  width: 50%;
122
122
  }
123
123
 
124
- .details .hype_talents {
125
- display: flex;
126
- flex-direction: column;
127
- }
128
-
129
- .details .hype {
124
+ .wrapper .hype {
125
+ display: block;
130
126
  padding: 8px;
131
127
  line-height: 1.25;
132
128
  }
133
129
 
134
- .details .hype .npe {
130
+ .wrapper .hype .npe {
135
131
  color: #a5e0f3;
136
132
  font-weight: bold;
137
- line-height: 2;
133
+ line-height: 1.25;
134
+ margin-bottom: 8px;
138
135
  }
139
136
 
140
137
  .talents {
@@ -189,22 +186,83 @@
189
186
  background-color: #444;
190
187
  }
191
188
 
192
- .details .list td {
189
+ .details .list table td {
193
190
  width: 50%;
194
191
  text-align: center;
195
192
  }
196
193
 
197
- .details .list tr:nth-child(even) {
194
+ .details .list table tr:nth-child(even) {
198
195
  background-color: #333;
199
196
  }
200
197
 
198
+ .details .list {
199
+ display: flex;
200
+ flex-direction: column;
201
+ padding: 6px;
202
+ }
203
+
204
+ .details .list > * {
205
+ flex-grow: 1;
206
+ }
207
+
208
+ .details .bars {
209
+ height: 64px;
210
+ flex-grow: 0;
211
+ }
212
+
213
+ .details .bars > div {
214
+ height: 28px;
215
+ margin-bottom: 4px;
216
+ border-radius: 5px; /* 可选:圆角效果 */
217
+ box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.3);
218
+ position: relative;
219
+ display: flex;
220
+ align-items: center;
221
+ }
222
+ .details .bars .health {
223
+ background: linear-gradient(to top, #279027 0%, #27a329 56%, #96e891 83%, #366a35 100%);
224
+ }
225
+ .details .bars .mana {
226
+ background: linear-gradient(to top, #4676c4 0%, #2b76d5 56%, #95cdff 100%);
227
+ }
228
+ .details .bars .mana.zero {
229
+ background: none;
230
+ }
231
+ .details .bars span {
232
+ text-shadow: #000 1px 1px 4px;
233
+ }
234
+ .details .bars .number {
235
+ font-size: 18px; /* 数字文本大小 */
236
+ position: absolute; /* 绝对定位 */
237
+ left: 50%; /* 左侧50% */
238
+ transform: translateX(-50%); /* 水平居中 */
239
+ }
240
+ .details .bars .suffix {
241
+ margin-left: auto; /* 将右侧文本推到容器的最右边 */
242
+ font-size: 14px; /* 较小的字体 */
243
+ padding-right: 10px; /* 右侧留些间距 */
244
+ }
245
+
246
+ .details .stats {
247
+ display: flex;
248
+ justify-content: space-around;
249
+ line-height: 1.3;
250
+ }
251
+ .details .stats > .column > p{
252
+ padding: 4px;
253
+ color: #B2B2B2;
254
+ }
255
+ .details .stats .stat img {
256
+ width: 20px;
257
+ }
258
+
201
259
  .facets {
202
260
  display: flex;
203
261
  flex-wrap: wrap;
204
262
  gap: 10px; /* 可选:设置项目之间的间距 */
205
263
  }
206
264
 
207
- .facets > .facet ,
265
+ .facets > .facet,
208
266
  .skill > .facet {
209
267
  flex: 1 1 calc(50% - 10px); /* 每行两个项目 */
210
268
  box-sizing: border-box; /* 包含padding和border在宽度和高度的计算中 */
@@ -216,7 +274,7 @@
216
274
  .facets > .facet:nth-child(odd):last-child {
217
275
  flex-basis: 100%; /* 最后一个奇数项目占据整行 */
218
276
  }
219
- .facets > .facet > .name_back ,
277
+ .facets > .facet > .name_back,
220
278
  .skill > .facet > .name_back {
221
279
  position: absolute;
222
280
  height: 50px;
@@ -361,7 +419,7 @@
361
419
  background-color: #5b93d1;
362
420
  }
363
421
 
364
- .skill > .title.name_back > img{
422
+ .skill > .title.name_back > img {
365
423
  width: 16px;
366
424
  }
367
425
 
@@ -390,36 +448,34 @@
390
448
  padding: 8px;
391
449
  }
392
450
 
393
- .skill .stats .dmg_type.Physical::after {
394
- content: "物理";
451
+ .skill .stats .dmg_type.Physical span {
395
452
  color: #ae2f28;
396
453
  }
397
454
 
398
- .skill .stats .dmg_type.Magical::after {
399
- content: "魔法";
455
+ .skill .stats .dmg_type.Magical span {
400
456
  color: #5b93d1;
401
457
  }
402
458
 
403
- .skill .stats .dmg_type.Pure::after {
404
- content: "纯粹";
459
+ .skill .stats .dmg_type.Pure span {
405
460
  color: #c29c4a;
406
461
  }
407
462
 
408
- .skill .stats .dispellable.Yes::after {
409
- content: "是";
463
+ .skill .stats .dispellable.Yes span {
410
464
  /* color: #c29c4a; */
411
465
  }
412
466
 
413
- .skill .stats .dispellable.No::after {
414
- content: "无法驱散";
467
+ .skill .stats .dispellable.No span {
415
468
  color: #f00;
416
469
  }
417
470
 
418
- .skill .stats .dispellable.Strong::after {
419
- content: "仅强驱散";
471
+ .skill .stats .dispellable.Strong span {
420
472
  color: #9828ae;
421
473
  }
422
474
 
475
+ .skill .stats .bkbpierce.Yes span {
476
+ color: #6add71;
477
+ }
478
+
423
479
  .skill > .description {
424
480
  color: #9bb1ce;
425
481
  margin-bottom: 32px;
@@ -567,15 +623,17 @@
567
623
  hero.damage_max+=base_damage;
568
624
  hero.damage_min+=base_damage;
569
625
  } %>
626
+ <% const primary_attrs = { "3": "hero_universal", "0": "hero_strength", "1": "hero_agility", "2": "hero_intelligence" }; %>
627
+ <% const hero_dc = dotaconstants.heroes[hero.id]; %>
570
628
  <div class="wrapper">
571
629
  <%- `
572
630
  <div class="hero" id="${hero.id}">
573
631
  <img src="${utils.getImageUrl(hero["name"].match(/^npc_dota_hero_(.+)$/)[1], ImageType.Heroes)}"/>
574
- <img class="pri_attr" src="${utils.getImageUrl(d2a.primary_attrs[hero.primary_attr], ImageType.Icons)}"/>
632
+ <img class="pri_attr" src="${utils.getImageUrl(primary_attrs[hero.primary_attr], ImageType.Icons)}"/>
575
633
  <div class="info">
576
634
  <p class="name">${hero.name_loc}</p>
577
635
  <p class="roles">
578
- ${hero.role_levels.map((item, index) => item>0?`<span class="role level${item}">${d2a.roles[index]}</span>`:"").join("")}
636
+ ${hero.role_levels.map((item, index) => item>0?`<span class="role level${item}">${$t("dota2tracker.template.roles."+index)}</span>`:"").join("")}
579
637
  </p>
580
638
  <p class="attrs">
581
639
  <span class="str">${hero.str_base} <span class="gain">+${hero.str_gain.toFixed(1)}</span></span>
@@ -584,83 +642,86 @@
584
642
  </p>
585
643
  </div>
586
644
  </div>
645
+ <div class="hype">
646
+ <p class="npe">${hero.npe_desc_loc}</p>
647
+ ${hero.hype_loc}
648
+ </div>
587
649
  <div class="details">
588
- <div class="hype_talents">
589
- <div class="hype">
590
- <p class="npe">${hero.npe_desc_loc}</p>
591
- ${hero.hype_loc}
650
+ <div class="talents">
651
+ <div class="talent">
652
+ <div class="left">${hero.talents[7].name_loc}</div>
653
+ <div class="level">25</div>
654
+ <div class="right">${hero.talents[6].name_loc}</div>
592
655
  </div>
593
- <div class="talents">
594
- <div class="talent">
595
- <div class="left">${hero.talents[7].name_loc}</div>
596
- <div class="level">25</div>
597
- <div class="right">${hero.talents[6].name_loc}</div>
598
- </div>
599
- <div class="talent">
600
- <div class="left">${hero.talents[5].name_loc}</div>
601
- <div class="level">20</div>
602
- <div class="right">${hero.talents[4].name_loc}</div>
656
+ <div class="talent">
657
+ <div class="left">${hero.talents[5].name_loc}</div>
658
+ <div class="level">20</div>
659
+ <div class="right">${hero.talents[4].name_loc}</div>
660
+ </div>
661
+ <div class="talent">
662
+ <div class="left">${hero.talents[3].name_loc}</div>
663
+ <div class="level">15</div>
664
+ <div class="right">${hero.talents[2].name_loc}</div>
665
+ </div>
666
+ <div class="talent">
667
+ <div class="left">${hero.talents[1].name_loc}</div>
668
+ <div class="level">10</div>
669
+ <div class="right">${hero.talents[0].name_loc}</div>
670
+ </div>
671
+ </div>
672
+ <div class="list">
673
+ <div class="bars">
674
+ <div class="health"><span class="number">${hero.max_health}</span><span class="suffix">+${hero.health_regen.toFixed(1)}</span></div>
675
+ <div class="mana${!hero.max_mana?" zero":""}"><span class="number">${hero.max_mana}</span><span class="suffix">+${hero.mana_regen.toFixed(1)}</span></div>
676
+ </div>
677
+ <div class="stats">
678
+ <div class="column">
679
+ <p>${$t("dota2tracker.template.attack")}</p>
680
+ <div class="stat">
681
+ <img src="${utils.getImageUrl("icon_damage", ImageType.HeroStats)}"/>
682
+ <span>${hero.damage_min}~${hero.damage_max}</span>
683
+ </div>
684
+ <div class="stat">
685
+ <img src="${utils.getImageUrl("icon_attack_time", ImageType.HeroStats)}"/>
686
+ <span>${hero.attack_rate.toFixed(1)}</span>
687
+ </div>
688
+ <div class="stat">
689
+ <img src="${utils.getImageUrl("icon_attack_range", ImageType.HeroStats)}"/>
690
+ <span>${hero.attack_range}</span>
691
+ </div>
692
+ <div class="stat${hero_dc.attack_type=="Melee"?" hide":""}">
693
+ <img src="${utils.getImageUrl("icon_projectile_speed", ImageType.HeroStats)}"/>
694
+ <span>${hero.projectile_speed}</span>
695
+ </div>
603
696
  </div>
604
- <div class="talent">
605
- <div class="left">${hero.talents[3].name_loc}</div>
606
- <div class="level">15</div>
607
- <div class="right">${hero.talents[2].name_loc}</div>
697
+ <div class="column">
698
+ <p>${$t("dota2tracker.template.defense")}</p>
699
+ <div class="stat">
700
+ <img src="${utils.getImageUrl("icon_armor", ImageType.HeroStats)}"/>
701
+ <span>${hero.armor.toFixed(1)}</span>
702
+ </div>
703
+ <div class="stat">
704
+ <img src="${utils.getImageUrl("icon_magic_resist", ImageType.HeroStats)}"/>
705
+ <span>${hero.magic_resistance}%</span>
706
+ </div>
608
707
  </div>
609
- <div class="talent">
610
- <div class="left">${hero.talents[1].name_loc}</div>
611
- <div class="level">10</div>
612
- <div class="right">${hero.talents[0].name_loc}</div>
708
+ <div class="column">
709
+ <p>${$t("dota2tracker.template.mobility")}</p>
710
+ <div class="stat">
711
+ <img src="${utils.getImageUrl("icon_movement_speed", ImageType.HeroStats)}"/>
712
+ <span>${hero.movement_speed}</span>
713
+ </div>
714
+ <div class="stat">
715
+ <img src="${utils.getImageUrl("icon_turn_rate", ImageType.HeroStats)}"/>
716
+ <span>${hero.turn_rate.toFixed(1)}</span>
717
+ </div>
718
+ <div class="stat">
719
+ <img src="${utils.getImageUrl("icon_vision", ImageType.HeroStats)}"/>
720
+ <span>${hero.sight_range_day} / ${hero.sight_range_night}</span>
721
+ </div>
613
722
  </div>
614
723
  </div>
615
724
  </div>
616
- <table class="list">
617
- <tbody>
618
- <tr>
619
- <td>初始生命值</td>
620
- <td>${hero.max_health}</td>
621
- </tr>
622
- <tr>
623
- <td>初始生命回复</td>
624
- <td>${hero.health_regen.toFixed(2)}</td>
625
- </tr>
626
- <tr>
627
- <td>初始魔法值</td>
628
- <td>${hero.max_mana}</td>
629
- </tr>
630
- <tr>
631
- <td>初始魔法回复</td>
632
- <td>${hero.mana_regen.toFixed(2)}</td>
633
- </tr>
634
- <tr>
635
- <td>初始攻击力</td>
636
- <td>${hero.damage_min}~${hero.damage_max}</td>
637
- </tr>
638
- <tr>
639
- <td>基础攻击间隔</td>
640
- <td>${hero.attack_rate.toFixed(1)}</td>
641
- </tr>
642
- <tr>
643
- <td>基础攻击前摇</td>
644
- <td>${dotaconstants.heroes[hero.id].attack_point.toFixed(1)}</td>
645
- </tr>
646
- <tr>
647
- <td>攻击范围</td>
648
- <td>${hero.attack_range}</td>
649
- </tr>
650
- <tr>
651
- <td>护甲</td>
652
- <td>${hero.armor.toFixed(1)}</td>
653
- </tr>
654
- <tr>
655
- <td>移动速度</td>
656
- <td>${hero.movement_speed}</td>
657
- </tr>
658
- <tr>
659
- <td>视野范围</td>
660
- <td>${hero.sight_range_day}(${hero.sight_range_night})</td>
661
- </tr>
662
- </tbody>
663
- </table>
664
725
  </div>
665
726
  <div class="facets">
666
727
  ${hero.facets.map(facet=>`
@@ -692,32 +753,32 @@
692
753
  </div>
693
754
  <div class="skills">
694
755
  ${hero.abilities//.filter((item) => dotaconstants.abilities[item.name]?.behavior != "Hidden")
695
- .map((item) => `
756
+ .map((item) => {const ability_dc = dotaconstants.abilities[item.name]; return `
696
757
  <div class="skill${item.facet?' facet':''}" data-innate="${item.ability_is_innate&&!item.ability_is_facet}">
697
758
  <p class="title${item.facet?(' name_back type_' + item.facet?.color):''}">
698
759
  ${item.facet?`<img src="${utils.getImageUrl(item.facet?.icon, ImageType.IconsFacets)}">`:""}
699
760
  <span class="name">${item.name_loc}</span>
700
- ${item.ability_is_innate&&!item.ability_is_facet?`<span class="is_innate">先天技能</span>`:""}
761
+ ${item.ability_is_innate&&!item.ability_is_facet?`<span class="is_innate">${$t("dota2tracker.template.innate")}</span>`:""}
701
762
  ${item.ability_is_granted_by_scepter ?`<img src="${utils.getImageUrl("scepter")}" class="scepter">`:""}
702
763
  ${item.ability_is_granted_by_shard ?`<img src="${utils.getImageUrl("shard")}" class="shard">`:""}
703
764
  </p>
704
765
  <div class="img_stats">
705
766
  <img src="${utils.getImageUrl(item.name, ImageType.Abilities)}" onerror="this.onerror=null; this.src='${utils.getImageUrl(`innate_icon`,ImageType.Icons)}';"/>
706
767
  <div class="stats">
707
- <p class="behavior">技能:${[].concat(dotaconstants.abilities[item.name]?.behavior)
768
+ <p class="behavior">${$t("dota2tracker.template.ability")}${[].concat(ability_dc?.behavior)
708
769
  .filter((beh) => beh !== "Hidden" || !(item.ability_is_granted_by_shard || item.ability_is_granted_by_scepter))
709
- .map((beh) => d2a.behavior[beh]).join("/")}
770
+ .map((beh) => $t("dota2tracker.template.behavior."+beh)).join("/")}
710
771
  </p>
711
- ${dotaconstants.abilities[item.name]?.target_team ?
712
- `<p class="target_team">影响:${[].concat(dotaconstants.abilities[item.name]?.target_team)
713
- .map((tt) => d2a.target_team[tt]).join("/")}
772
+ ${ability_dc?.target_team ?
773
+ `<p class="target_team">${$t("dota2tracker.template.affects")}${[].concat(ability_dc?.target_team)
774
+ .map((tt) => $t("dota2tracker.template.target_team."+tt)).join("/")}
714
775
  </p>` : ""}
715
- ${!Array.isArray(dotaconstants.abilities[item.name]?.dmg_type) && dotaconstants.abilities[item.name]?.dmg_type ?
716
- `<p class="dmg_type ${dotaconstants.abilities[item.name]?.dmg_type}">伤害类型:</p>` : ""}
717
- ${dotaconstants.abilities[item.name]?.dispellable ?
718
- `<p class="dispellable ${dotaconstants.abilities[item.name]?.dispellable == "Strong Dispels Only" ? "Strong" : dotaconstants.abilities[item.name]?.dispellable}">能否驱散:</p>` : ""}
719
- ${!Array.isArray(dotaconstants.abilities[item.name]?.bkbpierce) && dotaconstants.abilities[item.name]?.bkbpierce ?
720
- `<p class="bkbpierce">无视减益免疫: ${dotaconstants.abilities[item.name]?.bkbpierce == "Yes" ? "" : ""}</p>` : ""}
776
+ ${!Array.isArray(ability_dc?.dmg_type) && ability_dc?.dmg_type ?
777
+ `<p class="dmg_type ${ability_dc?.dmg_type}">${$t("dota2tracker.template.damage_type")}<span>${$t("dota2tracker.template.damage_type_"+ability_dc?.dmg_type)}</span></p>` : ""}
778
+ ${ability_dc?.dispellable ?
779
+ `<p class="dispellable ${ability_dc?.dispellable == "Strong Dispels Only" ? "Strong" : ability_dc?.dispellable}">${$t("dota2tracker.template.dispellable")}<span>${$t("dota2tracker.template."+(ability_dc?.dispellable == "Strong Dispels Only" ? "dispellable_Strong" : ability_dc?.dispellable))}</span></p>` : ""}
780
+ ${!Array.isArray(ability_dc?.bkbpierce) && ability_dc?.bkbpierce ?
781
+ `<p class="bkbpierce ${ability_dc?.bkbpierce}"> ${$t("dota2tracker.template.bkbpierce")}<span>${$t("dota2tracker.template."+ability_dc?.bkbpierce)}</span></p>` : ""}
721
782
  </div>
722
783
  </div>
723
784
  <p class="description">${item.desc_loc}</p>
@@ -743,12 +804,12 @@
743
804
  `:"")).join("")}
744
805
  ${item.ability_has_scepter&&!item.ability_is_granted_by_scepter&&item.scepter_loc
745
806
  ? `<p class="aghanim_description">
746
- <span class="title"><img src="${utils.getImageUrl("scepter")}"class="scepter">阿哈利姆神杖</span>
807
+ <span class="title"><img src="${utils.getImageUrl("scepter")}"class="scepter">${$t("dota2tracker.template.scepter")}</span>
747
808
  <span class="desc">${item.scepter_loc}</span>
748
809
  </p>` : ""}
749
810
  ${item.ability_has_shard&&!item.ability_is_granted_by_shard&&item.shard_loc
750
811
  ? `<p class="aghanim_description">
751
- <span class="title"><img src="${utils.getImageUrl("shard")}"class="shard">阿哈利姆魔晶</span>
812
+ <span class="title"><img src="${utils.getImageUrl("shard")}"class="shard">${$t("dota2tracker.template.shard")}</span>
752
813
  <span class="desc">${item.shard_loc}</span>
753
814
  </p>` : ""}
754
815
  <div class="notes"${!item.notes_loc.length ? ` style="display:none;"` : ""}>
@@ -795,7 +856,7 @@
795
856
  </span>` : ""}
796
857
  </p>
797
858
  <p class="lore"${!item.lore_loc ? ` style="display:none;"` : ""}>${item.lore_loc}</p>
798
- </div>`).join("")}
859
+ </div>`}).join("")}
799
860
  </div>
800
861
  <div class="lore">
801
862
  ${hero.bio_loc}