mangadex-sync 2.2.0__tar.gz → 2.2.2__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangadex-sync
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Export and import your MangaDex library to/from MyAnimeList and AniList — with scores, statuses, and chapter progress
5
5
  Author-email: Spider2742 <mail@spidey.in>
6
6
  License: MIT
@@ -13,7 +13,7 @@ import pandas as pd
13
13
  from flask import Flask, Response, jsonify, request, send_from_directory
14
14
 
15
15
  # ── Config ─────────────────────────────────────────────────────────────────────
16
- APP_VERSION = "2.2.0"
16
+ APP_VERSION = "2.2.2"
17
17
  PORT = 7337
18
18
  API_BASE = "https://api.mangadex.org"
19
19
  AUTH_URL = "https://auth.mangadex.org/realms/mangadex/protocol/openid-connect/token"
@@ -244,21 +244,29 @@ class API:
244
244
  if not rating or rating <= 0: return True
245
245
  return self.post_json(f"{API_BASE}/rating/{manga_id}", {"rating": int(rating)})
246
246
 
247
- def find_by_mal_id(self, mal_id):
248
- """Search MangaDex for a manga by its MAL ID. Returns MangaDex UUID or None."""
249
- d = self.get(f"{API_BASE}/manga", {"links[mal]": str(mal_id), "limit": 1,
250
- "contentRating[]":["safe","suggestive","erotica","pornographic"]})
251
- if d and d.get("data"):
252
- return d["data"][0]["id"]
247
+ def find_by_link(self, key, value, title):
248
+ """Find a MangaDex UUID for an external ID (key "mal" or "al").
249
+ MangaDex has no reverse lookup: /manga rejects links[...] filters with
250
+ a 400. So search by title and accept only a result whose own
251
+ links[key] matches exactly; never guess on a title match alone."""
252
+ if not value or not title:
253
+ return None
254
+ d = self.get(f"{API_BASE}/manga", {"title": title, "limit": 10,
255
+ "order[relevance]": "desc",
256
+ "contentRating[]": ["safe","suggestive","erotica","pornographic"]})
257
+ for m in (d or {}).get("data", []):
258
+ links = m.get("attributes", {}).get("links") or {}
259
+ if str(links.get(key, "")).strip() == str(value).strip():
260
+ return m["id"]
253
261
  return None
254
262
 
255
- def find_by_al_id(self, al_id):
263
+ def find_by_mal_id(self, mal_id, title=""):
264
+ """Search MangaDex for a manga by its MAL ID. Returns MangaDex UUID or None."""
265
+ return self.find_by_link("mal", mal_id, title)
266
+
267
+ def find_by_al_id(self, al_id, title=""):
256
268
  """Search MangaDex for a manga by its AniList ID. Returns MangaDex UUID or None."""
257
- d = self.get(f"{API_BASE}/manga", {"links[al]": str(al_id), "limit": 1,
258
- "contentRating[]":["safe","suggestive","erotica","pornographic"]})
259
- if d and d.get("data"):
260
- return d["data"][0]["id"]
261
- return None
269
+ return self.find_by_link("al", al_id, title)
262
270
 
263
271
  # ── Helpers ────────────────────────────────────────────────────────────────────
264
272
  def _log(msg, tag="info"):
@@ -667,7 +675,7 @@ def _run_import(params):
667
675
  score = entry.get("score", 0)
668
676
  # Fallback: try AniList ID if no manga_id
669
677
  if not mdex_id and entry.get("anilist_id"):
670
- mdex_id = api.find_by_al_id(entry["anilist_id"])
678
+ mdex_id = api.find_by_al_id(entry["anilist_id"], title)
671
679
  time.sleep(0.3)
672
680
  else:
673
681
  # XML — need to look up MangaDex UUID from MAL ID
@@ -677,13 +685,13 @@ def _run_import(params):
677
685
  mdex_status = MAL_REVERSE.get(mal_status, "reading")
678
686
 
679
687
  _log(f"Looking up '{title}' (MAL #{mal_id})…", "info")
680
- mdex_id = api.find_by_mal_id(mal_id)
688
+ mdex_id = api.find_by_mal_id(mal_id, title)
681
689
  if not mdex_id:
682
690
  # Try AniList ID as fallback
683
691
  al_id = entry.get("anilist_id")
684
692
  if al_id:
685
693
  _log(f" MAL lookup failed, trying AniList #{al_id}…", "info")
686
- mdex_id = api.find_by_al_id(al_id)
694
+ mdex_id = api.find_by_al_id(al_id, title)
687
695
  time.sleep(0.3) # be nice to the API
688
696
 
689
697
  if not mdex_id:
@@ -1081,14 +1089,15 @@ HTML_PAGE = r"""<!DOCTYPE html>
1081
1089
  <meta charset="UTF-8">
1082
1090
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1083
1091
  <title>MangaDex Sync</title>
1092
+ <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22%3E%3Cmask id=%22g%22%3E%3Crect width=%2264%22 height=%2264%22 fill=%22%23fff%22/%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2215.5%22 fill=%22%23000%22/%3E%3C/mask%3E%3Cg mask=%22url(%23g)%22%3E%3Csvg width=%2256%22 height=%2256%22 viewBox=%220 0 48 48%22%3E%3Cg clip-path=%22url(%23a)%22%3E%3Cpath fill=%22%23272b30%22 d=%22M42.517 39.253A23.9 23.9 0 0 0 48 23.984c0-13.254-10.746-24-24-24s-24 10.746-24 24a23.9 23.9 0 0 0 5.483 15.27h37.034Z%22/%3E%3Cpath fill=%22%23ff6740%22 d=%22M5.483 39.253a24 24 0 0 0 2.022 2.163H40.5a24 24 0 0 0 2.021-2.163zm7.908 6.263H34.61a24 24 0 0 0 3.562-2.162H9.83a24 24 0 0 0 3.562 2.162Z%22/%3E%3Cpath fill=%22%23f1f1f1%22 d=%22M36.697 27.006a11 11 0 0 1-2.34-2.84l-.016-.032a10.9 10.9 0 0 1-1.332-3.978c-.008-.086-.02-.172-.027-.26v-.015a2.8 2.8 0 0 0-.603-1.34 2 2 0 0 0-.093-.1 19.28 19.28 0 0 0-9.8-5.911 12.15 12.15 0 0 1 1.499-6.436.699.699 0 0 0-.78-1.013A25.47 25.47 0 0 0 5.189 17.795a23 23 0 0 0-3.18-1.412c-.23-.082-.463-.157-.696-.233a24.05 24.05 0 0 0 2.51 20.834H31.01a2.81 2.81 0 0 0 2.666-1.94 2.8 2.8 0 0 1 .976-1.494h.005q.052-.044.108-.081c.05-.039.1-.07.151-.103a5.51 5.51 0 0 0 2.218-4.428 5.5 5.5 0 0 0-.31-1.826c-.046-.039-.087-.07-.127-.106m-6.322-2.05a.7.7 0 0 1-.324-.081 3.76 3.76 0 0 0-1.894-.506 3.9 3.9 0 0 0-1.835.47c-.005 0-.01.008-.016.01a.3.3 0 0 0-.059.035.68.68 0 0 1-.616-1.213 5.16 5.16 0 0 1 2.526-.656 5.1 5.1 0 0 1 2.267.524q.133.06.261.135l.068.041a.678.678 0 0 1-.375 1.242z%22/%3E%3Cpath fill=%22%23ff6740%22 d=%22M5.258 17.676c1.304 6.245 6.718 10.93 13.21 10.93 3.822 0 7.27-1.625 9.727-4.235h-.04a3.9 3.9 0 0 0-1.835.47c-.004 0-.01.008-.016.01a.3.3 0 0 0-.059.035.68.68 0 0 1-.616-1.213 5.16 5.16 0 0 1 3.608-.544 13.9 13.9 0 0 0 2.42-5.356 19.25 19.25 0 0 0-9.167-5.239 12.15 12.15 0 0 1 1.496-6.44.699.699 0 0 0-.781-1.013A25.47 25.47 0 0 0 5.258 17.676%22/%3E%3Cpath fill=%22%23272b30%22 d=%22M33.236 30.59a22 22 0 0 0-1.752-.518c-.59-.142-1.18-.296-1.776-.412a25.6 25.6 0 0 0-3.602-.482c-.302-.026-.605-.035-.907-.049a10 10 0 0 0-.908 0c-.303.013-.605.022-.908.035l-.452.036a8 8 0 0 0-.453.042 17.4 17.4 0 0 0-3.558.75l-.006-.018a15.2 15.2 0 0 1 3.547-.882c.302-.045.607-.065.91-.094.305-.03.61-.04.916-.043q.458-.005.916-.005c.305.001.61.018.915.04 1.219.084 2.43.26 3.621.527q.896.198 1.773.46c.585.174 1.165.367 1.732.596zm-.529 1.11a24 24 0 0 0-1.81-.252c-.605-.058-1.21-.117-1.817-.144a25.6 25.6 0 0 0-3.634.058c-.302.02-.603.056-.904.087q-.452.047-.9.13a67 67 0 0 0-.89.17l-.442.103c-.15.03-.296.07-.442.107q-.882.225-1.732.549-.856.32-1.675.727l-.008-.016a15.3 15.3 0 0 1 3.375-1.4c.292-.09.59-.154.887-.229.299-.06.596-.13.898-.178q.453-.072.905-.14c.303-.047.606-.074.91-.094a24 24 0 0 1 3.657-.018q.915.063 1.822.187c.603.086 1.205.188 1.8.333zm-.082 1.293c-.61.026-1.219.07-1.822.144-.602.074-1.207.146-1.805.251-1.197.197-2.379.48-3.536.844-.291.084-.576.188-.864.281s-.57.206-.844.323c-.273.117-.562.236-.835.357l-.409.196q-.207.095-.408.2a16 16 0 0 0-1.573.91q-.766.497-1.477 1.071l-.012-.014a15.2 15.2 0 0 1 2.991-2.099c.267-.15.544-.281.817-.415q.41-.2.838-.369.425-.17.854-.331.43-.16.868-.291a24 24 0 0 1 3.57-.807q.905-.135 1.82-.206a20 20 0 0 1 1.83-.064z%22/%3E%3Cpath fill=%22%23ff7bac%22 d=%22M36.697 27.006q-.305-.267-.591-.554a1.788 1.788 0 0 0 .925 3.32h.027c.012-.075.029-.148.037-.225a5.46 5.46 0 0 0-.276-2.437c-.04-.037-.082-.069-.122-.104%22/%3E%3Cpath fill=%22%23f1f1f1%22 d=%22M21.87 13.455v.254a19.2 19.2 0 0 0-5.85 3.729 10.27 10.27 0 0 1 8.032-11.514 14 14 0 0 0-2.182 7.531%22/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id=%22a%22%3E%3Cpath fill=%22%23fff%22 d=%22M0 0h48v48H0z%22/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%3C/g%3E%3Ccircle cx=%2250%22 cy=%2250%22 r=%2213%22 fill=%22%23ff6740%22/%3E%3Cg fill=%22none%22 stroke=%22%2312151c%22 stroke-width=%223%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M44 46.4h11.4M52.2 43.2l3.2 3.2-3.2 3.2%22/%3E%3Cpath d=%22M56 53.6H44.6M47.8 50.4l-3.2 3.2 3.2 3.2%22/%3E%3C/g%3E%3C/svg%3E">
1084
1093
  <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap" rel="stylesheet">
1085
1094
  <style>
1086
1095
  :root {
1087
1096
  --bg: #0b0d12; --panel: #12151c; --card: #161a23; --card-2: #1c212c; --field: #0e1117;
1088
1097
  --border: #252a36; --border-2: #323949; --divider: #1f2430;
1089
- --text: #eef0f6; --text-2: #bcc2d0; --muted: #8b93a7; --faint: #5b6272;
1090
- --accent: #e8823c; --accent-2: #f2954f; --accent-ink: #1a0f06;
1091
- --accent-tint: rgba(232,130,60,.10); --accent-line: rgba(232,130,60,.38);
1098
+ --text: #eef0f6; --text-2: #bcc2d0; --muted: #9aa2b4; --faint: #7c8496;
1099
+ --accent: #ff6740; --accent-2: #ff8361; --accent-ink: #1f0a04;
1100
+ --accent-tint: rgba(255,103,64,.10); --accent-line: rgba(255,103,64,.38);
1092
1101
  --ok: #3ecf8e; --ok-tint: rgba(62,207,142,.10); --ok-line: rgba(62,207,142,.35);
1093
1102
  --warn: #e0b23e; --warn-tint: rgba(224,178,62,.10); --warn-line: rgba(224,178,62,.35);
1094
1103
  --err: #ef5350; --err-tint: rgba(239,83,80,.10); --err-line: rgba(239,83,80,.35);
@@ -1127,11 +1136,10 @@ button { cursor: pointer; background: none; border: 0; }
1127
1136
  .sidebar { width: 232px; flex-shrink: 0; background: var(--panel); border-right: 1px solid var(--border);
1128
1137
  display: flex; flex-direction: column; }
1129
1138
  .brand { display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 16px; border-bottom: 1px solid var(--divider); }
1130
- .brand-mark { width: 28px; height: 28px; border-radius: var(--r-sm); display: grid; place-items: center;
1131
- background: linear-gradient(150deg, var(--accent-2), var(--accent)); color: var(--accent-ink);
1132
- font-size: 15px; box-shadow: 0 4px 14px -6px rgba(232,130,60,.8), inset 0 1px 0 rgba(255,255,255,.25); }
1133
- .brand-name { font-family: var(--mono); font-size: 13px; font-weight: 700; letter-spacing: .01em; line-height: 1.2; }
1134
- .brand-name b { color: var(--accent); font-size: 10px; letter-spacing: .12em; margin-left: 4px; }
1139
+ .brand-mark { width: 36px; height: 36px; flex-shrink: 0; }
1140
+ .brand-mark svg { display: block; width: 100%; height: 100%; }
1141
+ .brand-name { font-size: 14.5px; font-weight: 700; letter-spacing: -.01em; line-height: 1.2; }
1142
+ .brand-name b { color: var(--accent); font-weight: 700; }
1135
1143
  .brand-ver { display: block; font-family: var(--mono); font-size: 10px; color: var(--faint); }
1136
1144
  .nav-label { font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .12em;
1137
1145
  text-transform: uppercase; color: var(--faint); padding: 18px 16px 8px; }
@@ -1177,7 +1185,7 @@ nav { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
1177
1185
  .page { display: none; max-width: 1360px; margin: 0 auto; }
1178
1186
  .page.active { display: block; }
1179
1187
  .page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
1180
- .page-head h1 { font-family: var(--mono); font-size: 20px; font-weight: 700; letter-spacing: -.01em; line-height: 1.2; }
1188
+ .page-head h1 { font-size: 22px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
1181
1189
  .page-head p { color: var(--muted); font-size: 13px; margin-top: 4px; max-width: 70ch; }
1182
1190
  .head-meta { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
1183
1191
 
@@ -1208,6 +1216,7 @@ nav { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
1208
1216
  .pill.info { color: var(--info); border-color: var(--info-line); background: var(--info-tint); }
1209
1217
  .pill .val { color: var(--text); }
1210
1218
  .sub-note { font-family: var(--mono); font-size: 10.5px; color: var(--faint); }
1219
+ p.sub-note { font-family: var(--sans); font-size: 12px; line-height: 1.45; }
1211
1220
 
1212
1221
  /* ── Fields ── */
1213
1222
  .field + .field, .row-2 + .field, .field + .row-2 { margin-top: 12px; }
@@ -1249,7 +1258,7 @@ nav { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
1249
1258
  .btn-ghost { border-color: transparent; color: var(--muted); }
1250
1259
  .btn-ghost:hover:not(:disabled) { color: var(--text); }
1251
1260
  .btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
1252
- box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 6px 18px -8px rgba(232,130,60,.7); }
1261
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 6px 18px -8px rgba(255,103,64,.7); }
1253
1262
  .btn-primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }
1254
1263
  .btn-lg { height: 42px; font-size: 12px; padding: 0 16px; }
1255
1264
  .btn-lg .i { font-size: 16px; }
@@ -1288,11 +1297,11 @@ nav { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
1288
1297
  .opt { display: flex; gap: 10px; align-items: flex-start; padding: 10px; background: var(--field); border: 1px solid var(--border);
1289
1298
  border-radius: var(--r-sm); cursor: pointer; transition: border-color .15s, background-color .15s; }
1290
1299
  .opt:hover { border-color: var(--border-2); }
1291
- .opt:has(input:checked) { border-color: var(--accent-line); background: rgba(232,130,60,.05); }
1300
+ .opt:has(input:checked) { border-color: var(--accent-line); background: rgba(255,103,64,.05); }
1292
1301
  .opt input { appearance: none; -webkit-appearance: none; width: 16px; height: 16px; margin-top: 1px; flex-shrink: 0;
1293
1302
  border: 1px solid var(--border-2); border-radius: var(--r-xs); background: var(--panel); cursor: pointer;
1294
1303
  transition: background-color .15s, border-color .15s; }
1295
- .opt input:checked { background: var(--accent) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' fill='none' stroke='%231a0f06' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/12px no-repeat;
1304
+ .opt input:checked { background: var(--accent) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.5 8.5l3 3 6-7' fill='none' stroke='%231f0a04' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/12px no-repeat;
1296
1305
  border-color: var(--accent); }
1297
1306
  .opt input:focus-visible { box-shadow: var(--ring); }
1298
1307
  .opt .ot { display: block; font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.3; }
@@ -1324,7 +1333,7 @@ nav { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
1324
1333
  .prog-pct { font-family: var(--mono); font-size: 30px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
1325
1334
  .prog-pct small { font-size: 14px; color: var(--muted); margin-left: 2px; }
1326
1335
  .prog-pct.idle { color: var(--faint); }
1327
- .prog-label { font-size: 12.5px; color: var(--text-2); text-align: right; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1336
+ .prog-label { font-size: 12.5px; color: var(--text-2); text-align: right; max-width: 70%; text-wrap: balance; }
1328
1337
  .track { position: relative; height: 8px; border-radius: var(--r-xs); background: var(--field); border: 1px solid var(--border); overflow: hidden; }
1329
1338
  .track::after { content: ""; position: absolute; inset: 0; pointer-events: none;
1330
1339
  background: repeating-linear-gradient(90deg, transparent 0 calc(5% - 1px), rgba(11,13,18,.9) calc(5% - 1px) 5%); }
@@ -1494,10 +1503,10 @@ td.files { font-family: var(--mono); font-size: 11px; color: var(--faint); max-w
1494
1503
 
1495
1504
  <aside class="sidebar">
1496
1505
  <div class="brand">
1497
- <span class="brand-mark"><svg class="i"><use href="#i-bolt"/></svg></span>
1506
+ <span class="brand-mark"><svg viewBox="0 0 64 64" aria-hidden="true"><mask id="brandGap"><rect width="64" height="64" fill="#fff"/><circle cx="50" cy="50" r="15.5" fill="#000"/></mask><g mask="url(#brandGap)"><svg width="56" height="56" viewBox="0 0 48 48"><g clip-path="url(#a)"><path fill="#272b30" d="M42.517 39.253A23.9 23.9 0 0 0 48 23.984c0-13.254-10.746-24-24-24s-24 10.746-24 24a23.9 23.9 0 0 0 5.483 15.27h37.034Z"/><path fill="#ff6740" d="M5.483 39.253a24 24 0 0 0 2.022 2.163H40.5a24 24 0 0 0 2.021-2.163zm7.908 6.263H34.61a24 24 0 0 0 3.562-2.162H9.83a24 24 0 0 0 3.562 2.162Z"/><path fill="#f1f1f1" d="M36.697 27.006a11 11 0 0 1-2.34-2.84l-.016-.032a10.9 10.9 0 0 1-1.332-3.978c-.008-.086-.02-.172-.027-.26v-.015a2.8 2.8 0 0 0-.603-1.34 2 2 0 0 0-.093-.1 19.28 19.28 0 0 0-9.8-5.911 12.15 12.15 0 0 1 1.499-6.436.699.699 0 0 0-.78-1.013A25.47 25.47 0 0 0 5.189 17.795a23 23 0 0 0-3.18-1.412c-.23-.082-.463-.157-.696-.233a24.05 24.05 0 0 0 2.51 20.834H31.01a2.81 2.81 0 0 0 2.666-1.94 2.8 2.8 0 0 1 .976-1.494h.005q.052-.044.108-.081c.05-.039.1-.07.151-.103a5.51 5.51 0 0 0 2.218-4.428 5.5 5.5 0 0 0-.31-1.826c-.046-.039-.087-.07-.127-.106m-6.322-2.05a.7.7 0 0 1-.324-.081 3.76 3.76 0 0 0-1.894-.506 3.9 3.9 0 0 0-1.835.47c-.005 0-.01.008-.016.01a.3.3 0 0 0-.059.035.68.68 0 0 1-.616-1.213 5.16 5.16 0 0 1 2.526-.656 5.1 5.1 0 0 1 2.267.524q.133.06.261.135l.068.041a.678.678 0 0 1-.375 1.242z"/><path fill="#ff6740" d="M5.258 17.676c1.304 6.245 6.718 10.93 13.21 10.93 3.822 0 7.27-1.625 9.727-4.235h-.04a3.9 3.9 0 0 0-1.835.47c-.004 0-.01.008-.016.01a.3.3 0 0 0-.059.035.68.68 0 0 1-.616-1.213 5.16 5.16 0 0 1 3.608-.544 13.9 13.9 0 0 0 2.42-5.356 19.25 19.25 0 0 0-9.167-5.239 12.15 12.15 0 0 1 1.496-6.44.699.699 0 0 0-.781-1.013A25.47 25.47 0 0 0 5.258 17.676"/><path fill="#272b30" d="M33.236 30.59a22 22 0 0 0-1.752-.518c-.59-.142-1.18-.296-1.776-.412a25.6 25.6 0 0 0-3.602-.482c-.302-.026-.605-.035-.907-.049a10 10 0 0 0-.908 0c-.303.013-.605.022-.908.035l-.452.036a8 8 0 0 0-.453.042 17.4 17.4 0 0 0-3.558.75l-.006-.018a15.2 15.2 0 0 1 3.547-.882c.302-.045.607-.065.91-.094.305-.03.61-.04.916-.043q.458-.005.916-.005c.305.001.61.018.915.04 1.219.084 2.43.26 3.621.527q.896.198 1.773.46c.585.174 1.165.367 1.732.596zm-.529 1.11a24 24 0 0 0-1.81-.252c-.605-.058-1.21-.117-1.817-.144a25.6 25.6 0 0 0-3.634.058c-.302.02-.603.056-.904.087q-.452.047-.9.13a67 67 0 0 0-.89.17l-.442.103c-.15.03-.296.07-.442.107q-.882.225-1.732.549-.856.32-1.675.727l-.008-.016a15.3 15.3 0 0 1 3.375-1.4c.292-.09.59-.154.887-.229.299-.06.596-.13.898-.178q.453-.072.905-.14c.303-.047.606-.074.91-.094a24 24 0 0 1 3.657-.018q.915.063 1.822.187c.603.086 1.205.188 1.8.333zm-.082 1.293c-.61.026-1.219.07-1.822.144-.602.074-1.207.146-1.805.251-1.197.197-2.379.48-3.536.844-.291.084-.576.188-.864.281s-.57.206-.844.323c-.273.117-.562.236-.835.357l-.409.196q-.207.095-.408.2a16 16 0 0 0-1.573.91q-.766.497-1.477 1.071l-.012-.014a15.2 15.2 0 0 1 2.991-2.099c.267-.15.544-.281.817-.415q.41-.2.838-.369.425-.17.854-.331.43-.16.868-.291a24 24 0 0 1 3.57-.807q.905-.135 1.82-.206a20 20 0 0 1 1.83-.064z"/><path fill="#ff7bac" d="M36.697 27.006q-.305-.267-.591-.554a1.788 1.788 0 0 0 .925 3.32h.027c.012-.075.029-.148.037-.225a5.46 5.46 0 0 0-.276-2.437c-.04-.037-.082-.069-.122-.104"/><path fill="#f1f1f1" d="M21.87 13.455v.254a19.2 19.2 0 0 0-5.85 3.729 10.27 10.27 0 0 1 8.032-11.514 14 14 0 0 0-2.182 7.531"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h48v48H0z"/></clipPath></defs></svg></g><circle cx="50" cy="50" r="13" fill="#ff6740"/><g fill="none" stroke="#12151c" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M44 46.4h11.4M52.2 43.2l3.2 3.2-3.2 3.2"/><path d="M56 53.6H44.6M47.8 50.4l-3.2 3.2 3.2 3.2"/></g></svg></span>
1498
1507
  <div>
1499
- <div class="brand-name">MangaDex<b>SYNC</b></div>
1500
- <span class="brand-ver" id="brandVer">v2.2.0</span>
1508
+ <div class="brand-name">MangaDex <b>Sync</b></div>
1509
+ <span class="brand-ver" id="brandVer">v2.2.2</span>
1501
1510
  </div>
1502
1511
  </div>
1503
1512
  <div class="nav-label">Workspace</div>
@@ -1759,7 +1768,7 @@ td.files { font-family: var(--mono); font-size: 11px; color: var(--faint); max-w
1759
1768
  <div class="card">
1760
1769
  <div class="card-hd"><div class="card-t"><span class="step">03 //</span>Generate</div><span class="pill" id="convState">Ready</span></div>
1761
1770
  <div class="card-bd">
1762
- <button class="btn btn-ok btn-lg" style="width:100%" id="btnGenerate" onclick="generateXml()"><svg class="i"><use href="#i-bolt"/></svg>Generate import files</button>
1771
+ <button class="btn btn-primary btn-lg" style="width:100%" id="btnGenerate" onclick="generateXml()"><svg class="i"><use href="#i-bolt"/></svg>Generate import files</button>
1763
1772
  <div id="convResult" style="margin-top:12px" hidden></div>
1764
1773
  </div>
1765
1774
  </div>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangadex-sync
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Export and import your MangaDex library to/from MyAnimeList and AniList — with scores, statuses, and chapter progress
5
5
  Author-email: Spider2742 <mail@spidey.in>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mangadex-sync"
7
- version = "2.2.0"
7
+ version = "2.2.2"
8
8
  description = "Export and import your MangaDex library to/from MyAnimeList and AniList — with scores, statuses, and chapter progress"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes