mtg-playerinfo 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +18 -0
- package/README.md +13 -6
- package/package.json +1 -1
- package/scripts/update-test-data.js +1 -1
- package/src/fetchers/untapped.js +42 -12
- package/test/data/topdeck.html +2 -2
- package/test/data/untapped.json +1 -104
- package/test/untapped.test.js +53 -12
- package/test/verboseLogging.test.js +12 -14
package/.github/workflows/ci.yml
CHANGED
|
@@ -7,7 +7,25 @@ on:
|
|
|
7
7
|
branches: [ main ]
|
|
8
8
|
|
|
9
9
|
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Use Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 24
|
|
19
|
+
cache: 'npm'
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: npm install
|
|
23
|
+
|
|
24
|
+
- name: Run linter
|
|
25
|
+
run: npm run lint
|
|
26
|
+
|
|
10
27
|
test:
|
|
28
|
+
needs: [lint]
|
|
11
29
|
runs-on: ${{ matrix.os }}
|
|
12
30
|
|
|
13
31
|
strategy:
|
package/README.md
CHANGED
|
@@ -53,7 +53,8 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
53
53
|
"facebook": "bjoern.kimminich",
|
|
54
54
|
"twitch": "koshiii",
|
|
55
55
|
"youtube": "@BjörnKimminich",
|
|
56
|
-
"
|
|
56
|
+
"mtga_rank": "Platinum 4",
|
|
57
|
+
"win rate": "47.37%"
|
|
57
58
|
},
|
|
58
59
|
"sources": {
|
|
59
60
|
"Unity League": {
|
|
@@ -67,11 +68,11 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
67
68
|
"local organizer": "Mulligan TCG Shop",
|
|
68
69
|
"team": "Mull to Five",
|
|
69
70
|
"bio": "Smugly held back on an Untimely Malfunction against a Storm player going off, being totally sure that you can redirect the summed-up damage of their Grapeshots back to their face with its \"Change the target of target spell or ability with a single target\" mode.",
|
|
70
|
-
"rank germany": "
|
|
71
|
-
"rank europe": "
|
|
72
|
-
"rank points": "
|
|
73
|
-
"record": "45-
|
|
74
|
-
"win rate": "
|
|
71
|
+
"rank germany": "62",
|
|
72
|
+
"rank europe": "503",
|
|
73
|
+
"rank points": "325",
|
|
74
|
+
"record": "50-45-5",
|
|
75
|
+
"win rate": "51.7%"
|
|
75
76
|
}
|
|
76
77
|
},
|
|
77
78
|
"MTG Elo Project": {
|
|
@@ -105,6 +106,12 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
105
106
|
"win rate": "36.36%",
|
|
106
107
|
"conversion": "0%"
|
|
107
108
|
}
|
|
109
|
+
},
|
|
110
|
+
"Untapped.gg": {
|
|
111
|
+
"url": "https://mtga.untapped.gg/profile/7de50700-c3f6-48e4-a38d-2add5b0d9b71/76DCDWCZS5FX5PIEEMUVY6GV74",
|
|
112
|
+
"data": {
|
|
113
|
+
"mtga_rank": "Platinum 4"
|
|
114
|
+
}
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
117
|
}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ const targets = [
|
|
|
8
8
|
{ id: 'k0shiii', url: 'https://melee.gg/Profile/Index/k0shiii', file: 'melee.html' },
|
|
9
9
|
{ id: 'k0shiii', url: 'https://topdeck.gg/profile/@k0shiii', file: 'topdeck.html' },
|
|
10
10
|
{ id: 'm4VSTJShiXR1PCSCWaM9TBY0rcg1', url: 'https://topdeck.gg/profile/m4VSTJShiXR1PCSCWaM9TBY0rcg1/stats', file: 'topdeck.json' },
|
|
11
|
-
{ id: '
|
|
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
12
|
]
|
|
13
13
|
|
|
14
14
|
async function updateTestData () {
|
package/src/fetchers/untapped.js
CHANGED
|
@@ -2,7 +2,6 @@ const { request } = require('../utils/httpClient')
|
|
|
2
2
|
|
|
3
3
|
class UntappedFetcher {
|
|
4
4
|
async fetchById (id) {
|
|
5
|
-
// Split the two-part ID
|
|
6
5
|
const parts = id.split('/')
|
|
7
6
|
if (parts.length !== 2) {
|
|
8
7
|
console.error('Untapped ID must be in format "userId/playerCode"')
|
|
@@ -23,32 +22,63 @@ class UntappedFetcher {
|
|
|
23
22
|
return null
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
return (current.match_start > latest.match_start) ? current : latest
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
return this.parseMatch(mostRecentMatch, url)
|
|
25
|
+
return this.parseMatches(matches, url)
|
|
31
26
|
} catch (error) {
|
|
32
27
|
console.error(`Error fetching Untapped profile ${id}:`, error.message)
|
|
33
28
|
return null
|
|
34
29
|
}
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
|
|
32
|
+
parseMatches (matches, url) {
|
|
38
33
|
const data = {
|
|
39
34
|
source: 'Untapped.gg',
|
|
40
35
|
url,
|
|
41
|
-
mtga_rank:
|
|
36
|
+
mtga_rank: {}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const constructedMatch = this.findMostRecentByFormat(matches, 2)
|
|
40
|
+
const constructedRank = this.formatRank(constructedMatch)
|
|
41
|
+
if (constructedRank) {
|
|
42
|
+
data.mtga_rank.constructed = constructedRank
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
const limitedMatch = this.findMostRecentByFormat(matches, 1)
|
|
46
|
+
const limitedRank = this.formatRank(limitedMatch)
|
|
47
|
+
if (limitedRank) {
|
|
48
|
+
data.mtga_rank.limited = limitedRank
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
return data
|
|
49
52
|
}
|
|
50
|
-
}
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
formatRank (match) {
|
|
55
|
+
if (!match || !match.friendly_ranking_class_after) {
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (match.friendly_ranking_class_after === 'Mythic') {
|
|
60
|
+
if (match.friendly_mythic_leaderboard_place_after !== null && match.friendly_mythic_leaderboard_place_after !== undefined) {
|
|
61
|
+
return `Mythic #${match.friendly_mythic_leaderboard_place_after}`
|
|
62
|
+
}
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (match.friendly_ranking_tier_after !== null && match.friendly_ranking_tier_after !== undefined) {
|
|
67
|
+
return `${match.friendly_ranking_class_after} ${match.friendly_ranking_tier_after}`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return null
|
|
71
|
+
}
|
|
53
72
|
|
|
73
|
+
findMostRecentByFormat (matches, superFormat) {
|
|
74
|
+
const filteredMatches = matches.filter(match => match.super_format === superFormat)
|
|
75
|
+
if (filteredMatches.length === 0) {
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
return filteredMatches.reduce((latest, current) => {
|
|
79
|
+
return (current.match_start > latest.match_start) ? current : latest
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
54
83
|
|
|
84
|
+
module.exports = UntappedFetcher
|
package/test/data/topdeck.html
CHANGED
|
@@ -96,7 +96,7 @@ gtag('config', 'G-56527VG23P');
|
|
|
96
96
|
}).then((ret) => {
|
|
97
97
|
location.reload();
|
|
98
98
|
});
|
|
99
|
-
}</script><!-- Page content--><div class="offcanvas offcanvas-end w-100" id="viewDecklistOffcanvas" tabindex="-1" aria-labelledby="viewDecklistOffcanvasLabel" aria-hidden="true"><div class="offcanvas-header bg-primary"><h5 class="offcanvas-title" id="viewDecklistOffcanvasLabel">Decklist</h5><button class="btn-close btn-close-white" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button></div><div class="offcanvas-body bg-dark"><pre class="mb-3"><code class="language-json" id="decklistContent"></code></pre></div></div><script src="/js/supportedGames?t=
|
|
99
|
+
}</script><!-- Page content--><div class="offcanvas offcanvas-end w-100" id="viewDecklistOffcanvas" tabindex="-1" aria-labelledby="viewDecklistOffcanvasLabel" aria-hidden="true"><div class="offcanvas-header bg-primary"><h5 class="offcanvas-title" id="viewDecklistOffcanvasLabel">Decklist</h5><button class="btn-close btn-close-white" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button></div><div class="offcanvas-body bg-dark"><pre class="mb-3"><code class="language-json" id="decklistContent"></code></pre></div></div><script src="/js/supportedGames?t=1770922016018"></script><script>function viewTextDecklist(decklist, title, tournamentId = null, playerId = null, game = null) {
|
|
100
100
|
// Use dynamically served games list
|
|
101
101
|
const supportedGames = window.SUPPORTED_GAMES;
|
|
102
102
|
|
|
@@ -139,7 +139,7 @@ gtag('config', 'G-56527VG23P');
|
|
|
139
139
|
#viewDecklistOffcanvas {
|
|
140
140
|
width: 660px !important;
|
|
141
141
|
}
|
|
142
|
-
}</style><!-- Hero Section with Cover Photo--><div class="position-relative overflow-hidden"><div class="position-relative" style="height: 280px; background-image: url(https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/aa6d70ad-de73-4c09-a4d7-1e64d5ed6d00/cover); background-size: cover; background-position: center;"><div class="position-absolute top-0 start-0 w-100 h-100 bg-dark" style="opacity: 0.2"></div></div><!-- Decorative wave divider--><div class="position-absolute bottom-0 w-100"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 100" preserveAspectRatio="none" style="height: 50px; width: 100%;"><path fill="#0a0e17" d="M0,32L60,42.7C120,53,240,75,360,74.7C480,75,600,53,720,42.7C840,32,960,32,1080,37.3C1200,43,1320,53,1380,58.7L1440,64L1440,100L1380,100C1320,100,1200,100,1080,100C960,100,840,100,720,100C600,100,480,100,360,100C240,100,120,100,60,100L0,100Z"></path></svg></div></div><!-- Profile Card--><div class="container position-relative"><div class="card bg-dark text-white shadow-lg border-0 rounded-4 mt-n5 position-relative" style="z-index: 2;"><div class="card-body py-4 px-md-4"><div class="row align-items-start"><!-- Avatar Column--><div class="col-lg-2 col-md-3 text-center text-md-start mb-4 mb-md-0"><div class="position-relative mx-auto" style="width: fit-content;"><img class="rounded-circle shadow-lg" src="https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/2a7b8d12-5924-4a58-5f9c-c0bf55766800/square" alt="Profile Picture" style="width: 140px; height: 140px; object-fit: cover; margin-top: -70px; border: 4px solid #0a0e17; background-color: #0a0e17;"></div></div><!-- Player Info & About--><div class="col-lg-5 col-md-9 my-sm-auto mb-4"><h2 class="text-white fw-bold mb-1">Björn Kimminich</h2><div class="d-flex flex-wrap mt-2 gap-2"><a class="btn btn-social bs-outline bs-twitter bs-dark me-2" href="https://twitter.com/bkimminich" target="_blank"><i class="fa-brands fa-twitter"></i></a></div><div class="d-flex flex-wrap gap-2 mt-3" id="badgeContainer"></div></div><!-- Stats Card--><div class="col-lg-5 mx-auto"><div class="card bg-dark border-0 shadow-lg rounded-4 position-relative overflow-hidden"><!-- Decorative gradient background--><div class="position-absolute top-0 start-0 w-100 h-100" style="background: linear-gradient(45deg, rgba(90, 79, 158, 0.2), rgba(0, 0, 0, 0)); opacity: 0.7; z-index: 0;"></div><div class="card-body position-relative p-4" style="z-index: 1;"><h4 class="text-white fw-bold mb-4" id="statsTitle">Player Stats</h4><div class="row g-3"><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-trophy text-warning fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="totalTournaments">0</h5><p class="text-light small mb-0">Tournaments</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-chart-line text-success fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallRecord">0-0-0</h5><p class="text-light small mb-0">Record</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-percentage text-info fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallWinRate">0%</h5><p class="text-light small mb-0">Win Rate</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-bolt text-danger fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="conversionRate">0%</h5><p class="text-light small mb-0">Conversion</p></div></div></div></div></div></div></div></div></div></div><!-- Modern Pill Tabs--><div class="card bg-dark border-0 shadow-sm rounded-4 mt-4 p-3"><div class="card-body p-0"><ul class="nav nav-pills gap-2 mb-0" role="tablist"><li class="nav-item"><a class="nav-link active py-3 rounded-3" href="#history" data-bs-toggle="tab"><i class="fa-solid fa-trophy me-2"></i>Tournaments</a></li></ul></div></div><!-- Content tabs--><div class="tab-content mt-4 mb-5"><!-- Tournament History Tab--><div class="tab-pane fade show active" id="history"><div class="card bg-dark border-0 rounded-4 shadow-lg py-4 px-3 px-sm-4"><!-- Filters Section--><div class="d-flex flex-wrap gap-3 mb-4 align-items-center"><!-- Format Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="formatDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-layer-group me-2"></i><span id="formatDropdownLabel">All Formats</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Formats</a></li></ul></div><!-- Year Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="yearDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-calendar-alt me-2"></i><span id="yearDropdownLabel">All Years</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Years</a></li></ul></div></div><h3 class="card-title text-white fw-bold"><i class="fa-solid fa-history me-2 text-info"></i>Tournament History</h3><div class="tournament-list" id="tournamentList"></div></div></div></div></div></main><footer class="footer bg-black py-5"><div class="container pt-md-2 pt-lg-3"><div class="row pt-sm-2"><!-- Logo, description, and social column--><div class="col-md-4 col-lg-3 pb-2 pb-md-0 mb-4 mb-md-0"><a class="d-block mb-3 mb-md-4" href="/"><img class="img-fluid" src="/img/logo/TopDeckFullWhiteNS.png" alt="TopDeck.gg" style="max-width: 200px;"></a><p class="text-muted pb-2 pb-md-3 mb-3 fs-sm">Discover, organize, and compete in trading card game events. Connect with players worldwide and elevate your game.</p><div class="d-flex gap-1"><a class="btn-social bs-outline bs-light bs-facebook bs-lg me-2" href="https://discord.gg/RjS3mDf3wt" target="_blank"><i class="fa-brands fa-discord"></i></a><a class="btn-social bs-outline bs-light bs-youtube bs-lg me-2" href="https://www.youtube.com/@TopDeckGG_" target="_blank"><i class="fa-brands fa-youtube"></i></a></div></div><!-- Nested columns for links--><div class="col-md-8 col-lg-7 offset-lg-2"><div class="row row-cols-1 row-cols-sm-3"><!-- Company column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Company</h4><ul><li><a class="widget-link" href="/subscribe">Run a Tournament</a></li><li><a class="widget-link" href="https://newsletter.topdeck.gg/">Newsletter</a></li><li><a class="widget-link" href="/docs/tournaments-v2">API Documentation</a></li><li><a class="widget-link" href="/championship-series-2026">Championship Series</a></li></ul></div></div><!-- Support column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Support</h4><ul><li><a class="widget-link" href="/cdn-cgi/l/email-protection#
|
|
142
|
+
}</style><!-- Hero Section with Cover Photo--><div class="position-relative overflow-hidden"><div class="position-relative" style="height: 280px; background-image: url(https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/aa6d70ad-de73-4c09-a4d7-1e64d5ed6d00/cover); background-size: cover; background-position: center;"><div class="position-absolute top-0 start-0 w-100 h-100 bg-dark" style="opacity: 0.2"></div></div><!-- Decorative wave divider--><div class="position-absolute bottom-0 w-100"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 100" preserveAspectRatio="none" style="height: 50px; width: 100%;"><path fill="#0a0e17" d="M0,32L60,42.7C120,53,240,75,360,74.7C480,75,600,53,720,42.7C840,32,960,32,1080,37.3C1200,43,1320,53,1380,58.7L1440,64L1440,100L1380,100C1320,100,1200,100,1080,100C960,100,840,100,720,100C600,100,480,100,360,100C240,100,120,100,60,100L0,100Z"></path></svg></div></div><!-- Profile Card--><div class="container position-relative"><div class="card bg-dark text-white shadow-lg border-0 rounded-4 mt-n5 position-relative" style="z-index: 2;"><div class="card-body py-4 px-md-4"><div class="row align-items-start"><!-- Avatar Column--><div class="col-lg-2 col-md-3 text-center text-md-start mb-4 mb-md-0"><div class="position-relative mx-auto" style="width: fit-content;"><img class="rounded-circle shadow-lg" src="https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/2a7b8d12-5924-4a58-5f9c-c0bf55766800/square" alt="Profile Picture" style="width: 140px; height: 140px; object-fit: cover; margin-top: -70px; border: 4px solid #0a0e17; background-color: #0a0e17;"></div></div><!-- Player Info & About--><div class="col-lg-5 col-md-9 my-sm-auto mb-4"><h2 class="text-white fw-bold mb-1">Björn Kimminich</h2><div class="d-flex flex-wrap mt-2 gap-2"><a class="btn btn-social bs-outline bs-twitter bs-dark me-2" href="https://twitter.com/bkimminich" target="_blank"><i class="fa-brands fa-twitter"></i></a></div><div class="d-flex flex-wrap gap-2 mt-3" id="badgeContainer"></div></div><!-- Stats Card--><div class="col-lg-5 mx-auto"><div class="card bg-dark border-0 shadow-lg rounded-4 position-relative overflow-hidden"><!-- Decorative gradient background--><div class="position-absolute top-0 start-0 w-100 h-100" style="background: linear-gradient(45deg, rgba(90, 79, 158, 0.2), rgba(0, 0, 0, 0)); opacity: 0.7; z-index: 0;"></div><div class="card-body position-relative p-4" style="z-index: 1;"><h4 class="text-white fw-bold mb-4" id="statsTitle">Player Stats</h4><div class="row g-3"><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-trophy text-warning fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="totalTournaments">0</h5><p class="text-light small mb-0">Tournaments</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-chart-line text-success fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallRecord">0-0-0</h5><p class="text-light small mb-0">Record</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-percentage text-info fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallWinRate">0%</h5><p class="text-light small mb-0">Win Rate</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-bolt text-danger fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="conversionRate">0%</h5><p class="text-light small mb-0">Conversion</p></div></div></div></div></div></div></div></div></div></div><!-- Modern Pill Tabs--><div class="card bg-dark border-0 shadow-sm rounded-4 mt-4 p-3"><div class="card-body p-0"><ul class="nav nav-pills gap-2 mb-0" role="tablist"><li class="nav-item"><a class="nav-link active py-3 rounded-3" href="#history" data-bs-toggle="tab"><i class="fa-solid fa-trophy me-2"></i>Tournaments</a></li></ul></div></div><!-- Content tabs--><div class="tab-content mt-4 mb-5"><!-- Tournament History Tab--><div class="tab-pane fade show active" id="history"><div class="card bg-dark border-0 rounded-4 shadow-lg py-4 px-3 px-sm-4"><!-- Filters Section--><div class="d-flex flex-wrap gap-3 mb-4 align-items-center"><!-- Format Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="formatDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-layer-group me-2"></i><span id="formatDropdownLabel">All Formats</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Formats</a></li></ul></div><!-- Year Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="yearDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-calendar-alt me-2"></i><span id="yearDropdownLabel">All Years</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Years</a></li></ul></div></div><h3 class="card-title text-white fw-bold"><i class="fa-solid fa-history me-2 text-info"></i>Tournament History</h3><div class="tournament-list" id="tournamentList"></div></div></div></div></div></main><footer class="footer bg-black py-5"><div class="container pt-md-2 pt-lg-3"><div class="row pt-sm-2"><!-- Logo, description, and social column--><div class="col-md-4 col-lg-3 pb-2 pb-md-0 mb-4 mb-md-0"><a class="d-block mb-3 mb-md-4" href="/"><img class="img-fluid" src="/img/logo/TopDeckFullWhiteNS.png" alt="TopDeck.gg" style="max-width: 200px;"></a><p class="text-muted pb-2 pb-md-3 mb-3 fs-sm">Discover, organize, and compete in trading card game events. Connect with players worldwide and elevate your game.</p><div class="d-flex gap-1"><a class="btn-social bs-outline bs-light bs-facebook bs-lg me-2" href="https://discord.gg/RjS3mDf3wt" target="_blank"><i class="fa-brands fa-discord"></i></a><a class="btn-social bs-outline bs-light bs-youtube bs-lg me-2" href="https://www.youtube.com/@TopDeckGG_" target="_blank"><i class="fa-brands fa-youtube"></i></a></div></div><!-- Nested columns for links--><div class="col-md-8 col-lg-7 offset-lg-2"><div class="row row-cols-1 row-cols-sm-3"><!-- Company column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Company</h4><ul><li><a class="widget-link" href="/subscribe">Run a Tournament</a></li><li><a class="widget-link" href="https://newsletter.topdeck.gg/">Newsletter</a></li><li><a class="widget-link" href="/docs/tournaments-v2">API Documentation</a></li><li><a class="widget-link" href="/championship-series-2026">Championship Series</a></li></ul></div></div><!-- Support column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Support</h4><ul><li><a class="widget-link" href="/cdn-cgi/l/email-protection#f695999882979582b68299869293959dd89191">Contact Us</a></li><li><a class="widget-link" href="/cdn-cgi/l/email-protection#c5a8a0a1aca485b1aab5a1a0a6aeeba2a2">Media Inquiries</a></li><li><a class="widget-link" href="/privacy-policy" target="_blank">Privacy Policy</a></li><li><a class="widget-link" href="/terms-and-conditions" target="_blank">Terms & Conditions</a></li></ul></div></div><!-- Install App column--><div class="col"><h4 class="h6 fw-bold pb-2 mb-0 mb-lg-1">Install App</h4><a class="btn btn-outline-secondary d-inline-flex align-items-center px-3 py-2 mt-3 me-3 me-md-0" href="https://apple.co/3A4Z0FK" role="button" style="min-width: 160px;"><i class="fa-brands fa-apple fs-xl me-2"></i><span class="d-flex flex-column align-items-start"><small class="fs-xs text-white-50">Download on the</small><span class="fs-sm">App Store</span></span></a><a class="btn btn-outline-secondary d-inline-flex align-items-center px-3 py-2 mt-3 me-3 me-md-0" href="https://play.google.com/store/apps/details?id=com.topdeck.app" role="button" style="min-width: 160px;"><i class="fa-brands fa-google-play fs-xl me-2"></i><span class="d-flex flex-column align-items-start"><small class="fs-xs text-white-50">Get it on</small><span class="fs-sm">Google Play</span></span></a></div></div></div></div></div></footer><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>document.addEventListener('DOMContentLoaded', function () {
|
|
143
143
|
// Template variables for decklist viewing
|
|
144
144
|
const playerUsername = "@k0shiii";
|
|
145
145
|
const playerId = "m4VSTJShiXR1PCSCWaM9TBY0rcg1";
|