mtg-playerinfo 1.4.2 → 1.5.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.
@@ -31,7 +31,7 @@ jobs:
31
31
  strategy:
32
32
  matrix:
33
33
  os: [ubuntu-latest, macos-latest, windows-latest]
34
- node-version: [20, 22, 24]
34
+ node-version: [22, 24, 25]
35
35
 
36
36
  steps:
37
37
  - uses: actions/checkout@v4
@@ -24,6 +24,8 @@ jobs:
24
24
  run: npm install
25
25
 
26
26
  - name: Fetch new test data
27
+ env:
28
+ UNTAPPED_SET_CODE: ${{ vars.UNTAPPED_SET_CODE }}
27
29
  run: node scripts/update-test-data.js
28
30
 
29
31
  - name: Commit and push changes
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "mtg-playerinfo",
3
- "version": "1.4.2",
3
+ "version": "1.5.1",
4
4
  "description": "A simple NPM module and CLI tool to pull Magic: The Gathering player data from various sources",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "mtg-playerinfo": "./cli.js"
8
8
  },
9
9
  "scripts": {
10
- "test": "node --test \"**/*.test.js\"",
11
- "test:coverage": "nyc --reporter=lcov --produce-source-map node --test \"**/*.test.js\"",
10
+ "test": "node --test",
11
+ "test:coverage": "nyc --reporter=lcov --produce-source-map node --test",
12
12
  "lint": "standard",
13
13
  "lint:fix": "standard --fix"
14
14
  },
@@ -31,10 +31,10 @@
31
31
  "commander": "^14.0.3"
32
32
  },
33
33
  "devDependencies": {
34
- "nyc": "^17.1.0",
34
+ "nyc": "^18.0.0",
35
35
  "standard": "^17.1.2"
36
36
  },
37
37
  "engines": {
38
- "node": "20 - 24"
38
+ "node": "22 - 25"
39
39
  }
40
40
  }
@@ -2,18 +2,19 @@ const fs = require('fs')
2
2
  const path = require('path')
3
3
  const { request } = require('../src/utils/httpClient')
4
4
 
5
+ const setCode = process.env.UNTAPPED_SET_CODE || 'TMT'
5
6
  const targets = [
6
7
  { id: '16215', url: 'https://unityleague.gg/player/16215/', file: 'unityLeague.html' },
7
8
  { id: '3irvwtmk', url: 'https://mtgeloproject.net/profile/3irvwtmk', file: 'mtgElo.html' },
8
9
  { id: 'k0shiii', url: 'https://melee.gg/Profile/Index/k0shiii', file: 'melee.html' },
9
10
  { id: 'k0shiii', url: 'https://topdeck.gg/profile/@k0shiii', file: 'topdeck.html' },
10
11
  { id: 'm4VSTJShiXR1PCSCWaM9TBY0rcg1', url: 'https://topdeck.gg/profile/m4VSTJShiXR1PCSCWaM9TBY0rcg1/stats', file: 'topdeck.json' },
11
- { id: 'e9d6fb9b-1f91-4063-8b28-0d46458d01a9/ZTATRXEQEJHUDOO52NWQCJGMQY', url: 'https://api.mtga.untapped.gg/api/v1/games/users/e9d6fb9b-1f91-4063-8b28-0d46458d01a9/players/ZTATRXEQEJHUDOO52NWQCJGMQY/?card_set=ECL', file: 'untapped.json' }
12
+ { id: 'e9d6fb9b-1f91-4063-8b28-0d46458d01a9/ZTATRXEQEJHUDOO52NWQCJGMQY', url: `https://api.mtga.untapped.gg/api/v1/games/users/e9d6fb9b-1f91-4063-8b28-0d46458d01a9/players/ZTATRXEQEJHUDOO52NWQCJGMQY/?card_set=${setCode}`, file: 'untapped.json' }
12
13
  ]
13
14
 
14
15
  async function updateTestData () {
15
16
  for (const target of targets) {
16
- console.log(`Fetching ${target.url}...`)
17
+ console.log(`Fetching ${target.url} ...`)
17
18
  try {
18
19
  const { data } = await request(target.url, { maxRedirects: 10 })
19
20
  const filePath = path.join(__dirname, '..', 'test', 'data', target.file)
@@ -66,8 +66,12 @@ class TopdeckFetcher {
66
66
 
67
67
  parseHtml (html, url, handle) {
68
68
  const $ = cheerio.load(html)
69
- const name = $('h2.text-white.fw-bold.mb-1').first().text().trim() || $('h1').first().text().trim() || handle
70
- const photo = $('img.rounded-circle.shadow-lg').first().attr('src') || $('img[src*="avatar"], img[src*="profile"]').first().attr('src')
69
+
70
+ const nameElement = $('.pp-name').first().length ? $('.pp-name').first().clone() : $('h2.text-white.fw-bold.mb-1').first().clone()
71
+ nameElement.find('.pp-pronouns').remove()
72
+ const name = nameElement.text().trim() || $('h1').first().text().trim() || handle
73
+
74
+ const photo = $('.pp-avatar').first().attr('src') || $('img.rounded-circle.shadow-lg').first().attr('src') || $('img[src*="avatar"], img[src*="profile"]').first().attr('src')
71
75
 
72
76
  const data = {
73
77
  source: 'Topdeck',
@@ -76,14 +80,14 @@ class TopdeckFetcher {
76
80
  photo: photo ? (photo.startsWith('http') ? photo : `https://topdeck.gg${photo}`) : null
77
81
  }
78
82
 
79
- const pronounsBadge = $('span.badge').filter((i, el) => {
83
+ const pronounsBadge = $('.pp-pronouns').first().text().trim() || $('span.badge').filter((i, el) => {
80
84
  return $(el).text().includes('/')
81
85
  }).first().text().trim()
82
86
  if (pronounsBadge) {
83
87
  data.pronouns = pronounsBadge
84
88
  }
85
89
 
86
- const twitterLink = $('a[href*="twitter.com"]').attr('href')
90
+ const twitterLink = $('.pp-social-link[href*="twitter.com"]').attr('href') || $('a[href*="twitter.com"]').attr('href')
87
91
  if (twitterLink) {
88
92
  const handle = extractHandle(twitterLink)
89
93
  if (handle) {
@@ -91,7 +95,7 @@ class TopdeckFetcher {
91
95
  }
92
96
  }
93
97
 
94
- const youtubeLink = $('a[href*="youtube.com"]').attr('href')
98
+ const youtubeLink = $('.pp-social-link[href*="youtube.com"]').attr('href') || $('a[href*="youtube.com"]').attr('href')
95
99
  if (youtubeLink) {
96
100
  const handle = extractHandle(youtubeLink)
97
101
  if (handle) {
@@ -115,12 +119,12 @@ class TopdeckFetcher {
115
119
 
116
120
  const currentStats = Object.keys(data).filter(k => Object.values(statsMap).includes(k))
117
121
  if (currentStats.length <= 1) {
118
- $('.stats-container, .player-stats').each((i, el) => {
119
- $(el).find('.stat').each((j, statEl) => {
120
- const label = $(statEl).find('.label').text().trim().toLowerCase()
121
- const value = $(statEl).find('.value').text().trim()
122
+ $('.stats-container, .player-stats, .pp-stats').each((i, el) => {
123
+ $(el).find('.stat, .pp-stat').each((j, statEl) => {
124
+ const label = ($(statEl).find('.label').text().trim() || $(statEl).find('.pp-stat-label').text().trim()).toLowerCase()
125
+ const value = $(statEl).find('.value').text().trim() || $(statEl).find('.pp-stat-value').text().trim()
122
126
  if (label && value) {
123
- data[label] = value
127
+ data[label === 'events' ? 'tournaments' : label] = value
124
128
  }
125
129
  })
126
130
  })
@@ -10,8 +10,9 @@ class UntappedFetcher {
10
10
 
11
11
  const userId = parts[0]
12
12
  const playerCode = parts[1]
13
+ const setCode = process.env.UNTAPPED_SET_CODE || 'ECL'
13
14
  const url = `https://mtga.untapped.gg/profile/${userId}/${playerCode}`
14
- const apiUrl = `https://api.mtga.untapped.gg/api/v1/games/users/${userId}/players/${playerCode}/?card_set=ECL`
15
+ const apiUrl = `https://api.mtga.untapped.gg/api/v1/games/users/${userId}/players/${playerCode}/?card_set=${setCode}`
15
16
 
16
17
  try {
17
18
  const { data } = await httpClient.request(apiUrl)
@@ -7,7 +7,7 @@
7
7
  <title>Profile k0shiii | Melee</title>
8
8
  <impact-site-verification value="4c243f18-8267-493f-a951-c8659ec151bc"></impact-site-verification>
9
9
  <meta content="@MeleePlatform" property="twitter:site"></meta>
10
- <meta content="0.3.63.85" name="version"></meta>
10
+ <meta content="0.3.63.253" name="version"></meta>
11
11
  <meta content="https://cdn.melee.gg/images/blankbrandimage.png" property="og:image"></meta>
12
12
  <meta content="Melee.gg Logo" property="twitter:image:alt"></meta>
13
13
  <meta content="https://melee.gg/" property="og:url"></meta>
@@ -36,9 +36,9 @@
36
36
  <meta name="author" content="Keyrune Incorporated"/>
37
37
  <meta property="og:site_name" content="Melee.gg"/>
38
38
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
39
- <link href="https://cdn.melee.gg/content/site.dependencies.min.css?v=0.3.63.85" rel="stylesheet"/>
39
+ <link href="https://cdn.melee.gg/content/site.dependencies.min.css?v=0.3.63.253" rel="stylesheet"/>
40
40
 
41
- <link href="/Content/site.min.css?v=0.3.63.85&lg=en" rel="stylesheet"/>
41
+ <link href="/Content/site.min.css?v=0.3.63.253&lg=en" rel="stylesheet"/>
42
42
 
43
43
 
44
44
 
@@ -579,36 +579,36 @@
579
579
  </div>
580
580
  </script>
581
581
 
582
- <script src="https://cdn.melee.gg/scripts/site.min.js?v=0.3.63.85"></script>
583
- <script src="https://cdn.melee.gg/scripts/font-awesome.min.js?v=0.3.63.85"></script>
584
- <script src="/Scripts/flattsware.core.min.js?v=0.3.63.85&lg=en"></script>
585
- <script src="/Scripts/flattsware.filters.min.js?v=0.3.63.85&lg=en"></script>
586
- <script src="/Scripts/flattsware.enums.min.js?v=0.3.63.85&lg=en"></script>
587
- <script src="/Scripts/flattsware.standings.min.js?v=0.3.63.85&lg=en"></script>
588
- <script src="/Scripts/flattsware.datatables.min.js?v=0.3.63.85&lg=en"></script>
589
- <script src="/Scripts/flattsware.datetime.min.js?v=0.3.63.85&lg=en"></script>
590
- <script src="/Scripts/flattsware.encode.min.js?v=0.3.63.85&lg=en"></script>
591
- <script src="/Scripts/flattsware.regex.min.js?v=0.3.63.85&lg=en"></script>
592
- <script src="/Scripts/flattsware.notify.min.js?v=0.3.63.85&lg=en"></script>
593
- <script src="/Scripts/flattsware.spinner.min.js?v=0.3.63.85&lg=en"></script>
594
- <script src="/Scripts/flattsware.forms.min.js?v=0.3.63.85&lg=en"></script>
595
- <script src="/Scripts/flattsware.decklist.min.js?v=0.3.63.85&lg=en"></script>
596
- <script src="/Scripts/flattsware.idle.min.js?v=0.3.63.85&lg=en"></script>
597
- <script src="/Scripts/flattsware.hovercard.min.js?v=0.3.63.85&lg=en"></script>
598
- <script src="/Scripts/flattsware.chart.min.js?v=0.3.63.85&lg=en"></script>
599
- <script src="/Scripts/flattsware.formats.min.js?v=0.3.63.85&lg=en"></script>
600
- <script src="/Scripts/flattsware.star-rating.min.js?v=0.3.63.85&lg=en"></script>
601
- <script src="/Scripts/flattsware.progress.min.js?v=0.3.63.85&lg=en"></script>
602
- <script src="/Scripts/flattsware.location.min.js?v=0.3.63.85&lg=en"></script>
603
- <script src="/Scripts/flattsware.players.min.js?v=0.3.63.85&lg=en"></script>
604
- <script src="/signalr/hubs?v=0.3.63.85"></script>
605
-
606
-
607
-
608
-
609
- <script src="/Scripts/wp-banners.min.js?v=0.3.63.85&lg=en"></script>
582
+ <script src="https://cdn.melee.gg/scripts/site.min.js?v=0.3.63.253"></script>
583
+ <script src="https://cdn.melee.gg/scripts/font-awesome.min.js?v=0.3.63.253"></script>
584
+ <script src="/Scripts/flattsware.core.min.js?v=0.3.63.253&lg=en"></script>
585
+ <script src="/Scripts/flattsware.filters.min.js?v=0.3.63.253&lg=en"></script>
586
+ <script src="/Scripts/flattsware.enums.min.js?v=0.3.63.253&lg=en"></script>
587
+ <script src="/Scripts/flattsware.standings.min.js?v=0.3.63.253&lg=en"></script>
588
+ <script src="/Scripts/flattsware.datatables.min.js?v=0.3.63.253&lg=en"></script>
589
+ <script src="/Scripts/flattsware.datetime.min.js?v=0.3.63.253&lg=en"></script>
590
+ <script src="/Scripts/flattsware.encode.min.js?v=0.3.63.253&lg=en"></script>
591
+ <script src="/Scripts/flattsware.regex.min.js?v=0.3.63.253&lg=en"></script>
592
+ <script src="/Scripts/flattsware.notify.min.js?v=0.3.63.253&lg=en"></script>
593
+ <script src="/Scripts/flattsware.spinner.min.js?v=0.3.63.253&lg=en"></script>
594
+ <script src="/Scripts/flattsware.forms.min.js?v=0.3.63.253&lg=en"></script>
595
+ <script src="/Scripts/flattsware.decklist.min.js?v=0.3.63.253&lg=en"></script>
596
+ <script src="/Scripts/flattsware.idle.min.js?v=0.3.63.253&lg=en"></script>
597
+ <script src="/Scripts/flattsware.hovercard.min.js?v=0.3.63.253&lg=en"></script>
598
+ <script src="/Scripts/flattsware.chart.min.js?v=0.3.63.253&lg=en"></script>
599
+ <script src="/Scripts/flattsware.formats.min.js?v=0.3.63.253&lg=en"></script>
600
+ <script src="/Scripts/flattsware.star-rating.min.js?v=0.3.63.253&lg=en"></script>
601
+ <script src="/Scripts/flattsware.progress.min.js?v=0.3.63.253&lg=en"></script>
602
+ <script src="/Scripts/flattsware.location.min.js?v=0.3.63.253&lg=en"></script>
603
+ <script src="/Scripts/flattsware.players.min.js?v=0.3.63.253&lg=en"></script>
604
+ <script src="/signalr/hubs?v=0.3.63.253"></script>
605
+
606
+
607
+
608
+
609
+ <script src="/Scripts/wp-banners.min.js?v=0.3.63.253&lg=en"></script>
610
610
  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-162951615-1"></script>
611
- <script src="/Scripts/google-analytics.min.js?v=0.3.63.85&lg=en"></script>
611
+ <script src="/Scripts/google-analytics.min.js?v=0.3.63.253&lg=en"></script>
612
612
 
613
613
  <!-- Datadog RUM (CDN async) -->
614
614
  <script>
@@ -1761,7 +1761,7 @@ $(() => {
1761
1761
  <h6>Tournaments</h6>
1762
1762
  <div>
1763
1763
  <a class="footer-link" href="/Tournament/Index">Tournaments</a>
1764
- <a class="footer-link" href="/Organization/Create">Become an Organizer</a>
1764
+ <a class="footer-link add-organization-modal" href="#">Become an Organizer</a>
1765
1765
  <a class="footer-link" href="/Decklists">Decklists</a>
1766
1766
  </div>
1767
1767
  </div>
@@ -1790,7 +1790,7 @@ $(() => {
1790
1790
  <div class="footer-corp">
1791
1791
  <img width="40" height="54" src="/images/keyrune-logo.png"/>
1792
1792
  <span>
1793
- All original content on this page is &copy; 2019-2026 Keyrune Incorporated, its licensors, or its partners and may not be used or reproduced without explicit permission. All trademarks are the property of their respective owners. v0.3.63.85
1793
+ All original content on this page is &copy; 2019-2026 Keyrune Incorporated, its licensors, or its partners and may not be used or reproduced without explicit permission. All trademarks are the property of their respective owners. v0.3.63.253
1794
1794
  </span>
1795
1795
  </div>
1796
1796
 
@@ -1857,29 +1857,33 @@ $(() => {
1857
1857
 
1858
1858
  <div id="popup-form-modal" class="modal fade" tabindex="-1" role="dialog"><div class="modal-dialog modal-xl" role="document"><div class="modal-content"><div class="modal-header"><h5 id="popup-form-modal-title" class="modal-title">-</h5> <button type="button" class="close close-modal" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div id="popup-form-modal-body" class="modal-body"></div></div></div></div>
1859
1859
  <div id="audit-logging-modal" class="modal fade" tabindex="-1" role="dialog"><div class="modal-dialog modal-xl" role="document"><div class="modal-content"><div class="modal-header"><h5 id="audit-logging-modal-title" class="modal-title">Audit Logs</h5> <button type="button" class="close close-modal" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div id="audit-logging-modal-body" class="modal-body"></div></div></div></div>
1860
- <div id="site-persistent-notification-modal" class="modal" tabindex="-1">
1860
+ <div id="site-persistent-notification-modal" class="modal site-error-notification" tabindex="-1">
1861
1861
  <div class="modal-dialog modal-dialog-centered">
1862
1862
  <div class="modal-content">
1863
+ <div class="modal-header justify-content-end">
1864
+ <button type="button" class="close close-modal" data-dismiss="modal" aria-label="Close">
1865
+ <span aria-hidden="true">×</span>
1866
+ </button>
1867
+ </div>
1863
1868
  <div class="modal-body">
1864
- <div class="d-flex flex-row flex-gap-1 mb-3">
1865
- <div id="site-persistent-notification-modal-icon"></div>
1866
- <div id="site-persistent-notification-modal-content" class="flex-grow-1"></div>
1869
+ <div class="d-flex flex-row justify-content-center pl-20px pr-20px">
1870
+ <div id="site-error-title-container" class="d-flex">
1871
+ <div id="site-persistent-notification-modal-icon" class="flex-fill text-start mr-8px"></div>
1872
+ <div id="site-persistent-notification-modal-title" class="flex-fill text-start">Something went wrong</div>
1873
+ </div>
1867
1874
  </div>
1868
- <div class="w-100 text-center">
1869
- <button type="button" class="btn btn-outline-warning" data-dismiss="modal">Ok</button>
1875
+ <div>
1876
+ <div id="site-persistent-notification-modal-content" class="flex-grow-1"></div>
1870
1877
  </div>
1871
- <hr class="modal-divider my-3"/>
1872
- <div id="site-persistent-notification-modal-content-buttons" class="d-flex flex-row flex-gap-1 w-100">
1873
- <div class="gateway-button-help-links flex-grow-1 my-auto">
1874
- <a class="my-auto" href="https://discord.melee.gg/">Get help via Discord</a>
1875
- &bullet;
1876
- <a class="my-auto" href="mailto:contact@melee.gg">Get help via email</a>
1877
- </div>
1878
- <a type="button" class="btn btn-outline-warning" href="https://help.melee.gg">Learn More</a>
1878
+
1879
+ <div class="w-100 text-center top-divider">
1880
+ <button type="button" class="btn btn-warning" data-dismiss="modal">Ok</button>
1879
1881
  </div>
1880
1882
  </div>
1881
1883
  </div>
1882
1884
  </div>
1883
1885
  </div>
1886
+
1887
+
1884
1888
  </body>
1885
1889
  </html>
@@ -1,8 +1,8 @@
1
- <!DOCTYPE html><html lang="en"> <head><link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin"><meta charset="UTF-8"><meta property="og:title" content="MTG Elo Project - MTG Elo Project - Bjoern Kimminich"><meta property="og:type" content="website"><meta property="og:url" content="https://www.mtgeloproject.net"><meta property="og:description" content="Stats and match history for Bjoern Kimminich"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="MTG Elo Project - MTG Elo Project - Bjoern Kimminich"><meta name="twitter:description" content="Stats and match history for Bjoern Kimminich"><meta name="description" content="MTG Elo Project"><meta name="viewport" content="width=device-width"><meta name="generator" content="Astro v4.15.12"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><title>MTG Elo Project - Bjoern Kimminich</title><link rel="stylesheet" href="/_astro/_slug_php.CEHXRJOi.css">
1
+ <!DOCTYPE html><html lang="en"> <head><link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin"><meta charset="UTF-8"><meta property="og:title" content="MTG Elo Project - MTG Elo Project - Bjoern Kimminich"><meta property="og:type" content="website"><meta property="og:url" content="https://www.mtgeloproject.net"><meta property="og:description" content="Stats and match history for Bjoern Kimminich"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="MTG Elo Project - MTG Elo Project - Bjoern Kimminich"><meta name="twitter:description" content="Stats and match history for Bjoern Kimminich"><meta name="description" content="MTG Elo Project"><meta name="viewport" content="width=device-width"><meta name="generator" content="Astro v4.16.19"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><title>MTG Elo Project - Bjoern Kimminich</title><link rel="stylesheet" href="/_astro/_slug_php.8ARMTW4b.css">
2
2
  <style>.dropdown-content{font-size:14px;position:absolute;background-color:#f9f9f9;right:0;box-shadow:0 8px 16px #0003;z-index:+1;cursor:pointer}.tournament-list,.year-list{list-style:none;padding:0;margin:0;flex-direction:column;display:inline-flex;max-width:400px}.dropdown-year{color:#000;padding:4px 24px;text-decoration:none;z-index:+1;display:flex;width:-moz-max-content;width:max-content;position:relative}.year-list>li>.year-events{display:none;flex-direction:column;list-style:none;padding:0;margin:0;position:absolute;right:100%;top:0;box-shadow:0 8px 16px #0003;text-align:left;z-index:2;background:#fff;max-width:400px}.dropdown-tournament{color:#000;padding:4px 8px 4px 4px;text-decoration:none;z-index:+2;display:block;white-space:nowrap;position:relative}.dropdown-tournament:hover{background:#f1f1f1}.year-list li:hover>.year-events{display:inline-flex}.year-list ul li:focus>.year-events{display:inline-flex}.summary>div{height:16px}
3
3
  </style>
4
- <link rel="stylesheet" href="/_astro/_slug_.D75Bqdw4.css"></head> <body class="w-[710px] lg:w-[100dvw] leading-tight p-2"> <div class="block mb-1"> <!-- <span class="block w-full lg:w-[860px] text-center text-[16px] py-1 bg-red-300">
4
+ <link rel="stylesheet" href="/_astro/_slug_.B8ZPnTZI.css"></head> <body class="w-[710px] lg:w-[100dvw] leading-tight p-2"> <div class="block mb-1"> <!-- <span class="block w-full lg:w-[860px] text-center text-[16px] py-1 bg-red-300">
5
5
  Sep 5, 11pm Eastern: The site is being refreshed. Some data may be a little wonky. Thanks for your patience!
6
6
  </span> --> <span class="block w-full lg:w-[860px] text-center text-[16px] py-1 bg-green-300">
7
7
  Welcome to Elo 2.0! See the recent <a href="/blog/58" class="text-blink hover:underline">blog post</a> to learn more.
8
- </span> </div> <div class="linkdiv hidden lg:block" data-astro-cid-lxcip4ca> <ul class="list-none w-[145px] text-[13pt]" data-astro-cid-lxcip4ca> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/" data-astro-cid-lxcip4ca>home</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/leaders/all" data-astro-cid-lxcip4ca>leaders</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/stats" data-astro-cid-lxcip4ca>statistics</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/headtohead" data-astro-cid-lxcip4ca>head to head</a></li> <!--<li><a href="proteams.php">pro teams</a></li>--> <!--<li><a href="team.php">custom team</a></li>--> <!--<li><a href="mplseason.php">MPL</a></li>--> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/faq" data-astro-cid-lxcip4ca>FAQ</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/blog" data-astro-cid-lxcip4ca>blog</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/links" data-astro-cid-lxcip4ca>links</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/contact" data-astro-cid-lxcip4ca>contact</a></li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>events</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>coverage</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>custom team</li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="https://www.patreon.com/mtgeloproject" style="color:#060" data-astro-cid-lxcip4ca>Patreon</a></li> </ul> </div> <!-- <MobileMenu client:only /> --> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();;(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(s+=` (export ${v})`),console.error(`[hydrate] Error parsing props for component ${s}`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(`astro:${c}`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();</script><astro-island uid="12oLMo" prefix="r0" component-url="/_astro/Search.BA4QD767.js" component-export="default" renderer-url="/_astro/client.csHNARWA.js" props="{&quot;first&quot;:[0],&quot;last&quot;:[0]}" ssr="" client="load" opts="{&quot;name&quot;:&quot;Search&quot;,&quot;value&quot;:true}" await-children=""><div class="lg:block lg:w-auto w-full inline-flex flex-row justify-between"><div class="lg:hidden z-10 inline-block" data-headlessui-state=""><button class=" lg:hidden relative inline-flex items-center justify-center rounded-md p-2 hover:bg-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-gray-500" id="headlessui-disclosure-button-:r0R5:" type="button" aria-expanded="false" data-headlessui-state=""><span class="absolute -inset-0.5"></span><span class="sr-only">Open main menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="block h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path></svg></button></div><form class="inline-flex flex-row gap-1 lg:inline-block lg:h-[80px] pt-[2px]" autoComplete="off"><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="last_name[last]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="Last Name" placeholder="last name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1mm:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="first_name[first_name]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="First Name" placeholder="first name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1n6:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="submit" class="text-[14px] bg-gray border border-nines p-1 rounded-[5px] focus:bg-nuts hover:bg-nuts" value="Search"/></form></div><!--astro:end--></astro-island> <main class="mx-4 lg:mx-[150px]"> <div class="w-[710px] inline-block"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="Z1Nr0tb" component-url="/_astro/Profile.D6E0cspP.js" component-export="default" renderer-url="/_astro/client.csHNARWA.js" props="{&quot;playerid&quot;:[0,&quot;3irvwtmk&quot;],&quot;info&quot;:[0,{&quot;id&quot;:[0,&quot;3irvwtmk&quot;],&quot;first_name&quot;:[0,&quot;Bjoern&quot;],&quot;last_name&quot;:[0,&quot;Kimminich&quot;],&quot;record&quot;:[1,[[0,9],[0,12],[0,1]]],&quot;pro_record&quot;:[1,[[0,null],[0,null],[0,null]]],&quot;current_rating&quot;:[0,1465.76],&quot;ranking&quot;:[0,161345],&quot;active_ranking&quot;:[0,28491],&quot;best_event&quot;:[0,&quot;ssutr25&quot;],&quot;best_round&quot;:[0,&quot;7&quot;],&quot;best_id&quot;:[0,3852351],&quot;nakamura_number&quot;:[0,2],&quot;nakamura_match_id&quot;:[0,3962471]}]}" ssr="" client="only" opts="{&quot;name&quot;:&quot;Profile&quot;,&quot;value&quot;:&quot;react&quot;}"></astro-island> </div> </main> </body></html>
8
+ </span> </div> <div class="linkdiv hidden lg:block" data-astro-cid-lxcip4ca> <ul class="list-none w-[145px] text-[13pt]" data-astro-cid-lxcip4ca> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/" data-astro-cid-lxcip4ca>home</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/leaders/all" data-astro-cid-lxcip4ca>leaders</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/stats" data-astro-cid-lxcip4ca>statistics</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/headtohead" data-astro-cid-lxcip4ca>head to head</a></li> <!--<li><a href="proteams.php">pro teams</a></li>--> <!--<li><a href="team.php">custom team</a></li>--> <!--<li><a href="mplseason.php">MPL</a></li>--> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/faq" data-astro-cid-lxcip4ca>FAQ</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/blog" data-astro-cid-lxcip4ca>blog</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/links" data-astro-cid-lxcip4ca>links</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/contact" data-astro-cid-lxcip4ca>contact</a></li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>events</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>coverage</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>custom team</li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="https://www.patreon.com/mtgeloproject" style="color:#060" data-astro-cid-lxcip4ca>Patreon</a></li> </ul> </div> <!-- <MobileMenu client:only /> --> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();;(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(s+=` (export ${v})`),console.error(`[hydrate] Error parsing props for component ${s}`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(`astro:${c}`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();</script><astro-island uid="12oLMo" prefix="r0" component-url="/_astro/Search.Cy44HT0L.js" component-export="default" renderer-url="/_astro/client.CyiKcvb7.js" props="{&quot;first&quot;:[0],&quot;last&quot;:[0]}" ssr="" client="load" opts="{&quot;name&quot;:&quot;Search&quot;,&quot;value&quot;:true}" await-children=""><div class="lg:block lg:w-auto w-full inline-flex flex-row justify-between"><div class="lg:hidden z-10 inline-block" data-headlessui-state=""><button class=" lg:hidden relative inline-flex items-center justify-center rounded-md p-2 hover:bg-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-gray-500" id="headlessui-disclosure-button-:r0R5:" type="button" aria-expanded="false" data-headlessui-state=""><span class="absolute -inset-0.5"></span><span class="sr-only">Open main menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="block h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path></svg></button></div><form class="inline-flex flex-row gap-1 lg:inline-block lg:h-[80px] pt-[2px]" autoComplete="off"><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="last_name[last]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="Last Name" placeholder="last name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1mm:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="first_name[first_name]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="First Name" placeholder="first name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1n6:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="submit" class="text-[14px] bg-gray border border-nines p-1 rounded-[5px] focus:bg-nuts hover:bg-nuts" value="Search"/></form></div><!--astro:end--></astro-island> <main class="mx-4 lg:mx-[150px]"> <div class="w-[710px] inline-block"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="Z23hUoU" component-url="/_astro/Profile.AWCtGaC_.js" component-export="default" renderer-url="/_astro/client.CyiKcvb7.js" props="{&quot;playerid&quot;:[0,&quot;3irvwtmk&quot;],&quot;info&quot;:[0,{&quot;id&quot;:[0,&quot;3irvwtmk&quot;],&quot;first_name&quot;:[0,&quot;Bjoern&quot;],&quot;last_name&quot;:[0,&quot;Kimminich&quot;],&quot;record&quot;:[1,[[0,9],[0,12],[0,1]]],&quot;pro_record&quot;:[1,[[0,null],[0,null],[0,null]]],&quot;current_rating&quot;:[0,1465.68],&quot;ranking&quot;:[0,162645],&quot;active_ranking&quot;:[0,30079],&quot;best_event&quot;:[0,&quot;ssutr25&quot;],&quot;best_round&quot;:[0,&quot;7&quot;],&quot;best_id&quot;:[0,3856758],&quot;nakamura_number&quot;:[0,2],&quot;nakamura_match_id&quot;:[0,3965812]}]}" ssr="" client="only" opts="{&quot;name&quot;:&quot;Profile&quot;,&quot;value&quot;:&quot;react&quot;}"></astro-island> </div> </main> </body></html>