├── PRODINFO.bin ├── hactool-linux ├── Atmosphere-config.zip ├── README.md ├── certificat.pem ├── .github └── workflows │ └── firmware-autodl.yml ├── firmware_downloader.py └── prod.keys /PRODINFO.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THZoria/NX_Firmware/HEAD/PRODINFO.bin -------------------------------------------------------------------------------- /hactool-linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THZoria/NX_Firmware/HEAD/hactool-linux -------------------------------------------------------------------------------- /Atmosphere-config.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THZoria/NX_Firmware/HEAD/Atmosphere-config.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NX_Firmware 2 | Firmware for the Nintendo Switch 3 | 4 | # Utility 5 | Firmware database for a discord bot 6 | 7 | image 8 | 9 | # How to update a modified Switch / Under custom firmware 10 | 11 | - Create a folder at the root of your microSD card and name it whatever you want. 12 | - Download and extract a Nintendo Switch update available from the links above into the folder you created : [Latest Firmware](https://github.com/THZoria/NX_Firmware/releases/latest) 13 | - Eject your microSD card and start your console in CFW. 14 | - Go to the HBMenu and launch DayBreak. 15 | - Click Install. 16 | - Select the folder you created earlier. 17 | - Wait a few moments (DayBreak is checking the integrity of your files). 18 | - Click Continue, then Preserve Settings, then Install (FAT32+exFAT), then Continue again. 19 | - Wait a few moments (DayBreak is installing your update) and finally, click Reboot to restart your Nintendo Switch. 20 | 21 | # More information 22 | 23 | More information will be detailed in the [wiki](https://github.com/THZoria/NX_Firmware/wiki), both the new versions that will be released, as well as their technical details. 24 | 25 | # To find us 26 | 27 | [![Discord](https://img.shields.io/discord/643436008452521984.svg?logo=discord&logoColor=white&label=Discord&color=7289DA 28 | )](https://discord.gg/6zRbG3FsJH) 29 | 30 | # Add our bot Poyo 31 | 32 | Our bot, currently developed in Discord JS V13 (click to be redirected to the link to add the bot) 33 | 34 | [![poyo](https://user-images.githubusercontent.com/50277488/156135958-a87fadb8-841e-4eec-bfb8-32340417fa17.png)](https://discord.com/oauth2/authorize?client_id=854048178907512884&scope=bot&code=GhN3fCiOkdvULwgGFbPp134oJo1FW5&guild_id=55540872135914291520applications.commands) 35 | -------------------------------------------------------------------------------- /certificat.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCq7oPfY/FW1NSU 3 | 6DOo4Pr+6/zgJNop9Eg1zps1vCaWpQKu0KzrqfT2uHrRcP/mRaCSwNiqXxM3EwDb 4 | cxerRc3dl6iHgCaPtd0QOzE5eRCuJcfTpdfhMRnzv6zJ+3xPo4ejTRzfoEB2s2XP 5 | pAE9vh0f9FbgP06eKA6U9i0ZNucAHm8z2l52HVBjiG5/VbY43guxlU0b4U96bG0d 6 | hH+zogPJNFcAI28R6+D2YaF0O6QfmF8SYgiD2Y94lx5cMQkIMO9Ypbh4BYlElLSP 7 | 6bRcmIqeiM9+QUDlrMd2mVTW362qsXiv6zpxIqRxZ9f9LwKyMo3kFA4f+Xjd6l2Z 8 | xIJB0HMXAgMBAAECggEAMTKrdC3A9fwWH7HhxJbUx3DG/QC+ZlrwOcR4ufOoq61c 9 | 41Ieo0nsvuKEPyomDXI28GZfNlJdJnnqwj8TLfHOehw/npiNAMoYkaZn2aH14hnv 10 | tQRD6YYHcTfXFN+0fPuVe7QjPl5Sj5e9ExGiZdIFcgASzUKLb0waPlfIzTwXKtoe 11 | enAOEbCJhyxDbZBLc8qusfLU/zopQLw+u0DXMjppvn7mVtQ1n/9XuMGaXo77oedi 12 | zVDv9XWz3DA+hZESRHb22Vgm6RjD6QG6L13G+6oyKVfcjSL0yjOtMtYQ1uLYC0W/ 13 | xVrrwcai9rH4k+DwQbHopSCkZRoHnhgOxgz0hlr7IQKBgQDqJ4m1N7MGiKK5nZZU 14 | TsS9F77SUiiVfU0C7GvmhM6DZwz9St0cVxpfIhDaWO6ka82an6HLzEMuI+zAR3OY 15 | vl0y8d1a9LalHSzfibCSuG+Q3p6m7VgljrysRZ6pFJgFkkg/vgBEXe3FV752DPqW 16 | +pZfL5I+K4+1+M+U1tRgvDxK0QKBgQC64PzLsR0XMkmLU/8gtzCvJ2U50fiPf2cb 17 | YATKmJE+3/QC8uw6pqpDFjbsGbjBGSvVxQL297Q4PNGiR9QsV4t2ldXPrGFLTP14 18 | JylspSlz9D8JTBiRRi8uak1CF26bnxyD95FYyPOHLeXQHTbt/tTP1uutRPRYGUqn 19 | ITWp6V0JZwKBgQDdas3ZQvZTM1lM1CuXRXTcqluTXoVp9ragERhnPyZZM1UhH22+ 20 | os8ZLolpL7daW2Zs1I6WvGy6cNYrbGVvBnPy/Ksom0crE0+fggAqfaViBGFZ0A4O 21 | Vc8ryBmkIQkwG4eeXvi5rWhtt+8uik9b/VG8aKuNhnu6w7DnOc5SOy14QQKBgCHg 22 | 8dNXi4eOBUkt9B2ROFE4miBOUXpqRV3wHU5BNGuqnAkA0xSa7Fj3KQPKcfUHxCuf 23 | 6LavF0vusq5xySQ0xsK7zSQ2AvlsvrLOnrLkikxMJjVgRz/m8ly+xrzJlLK/uKKv 24 | +fiXjZafGn+NHE0vGpOHSfiCfK2QADmmSp1AAi7XAoGBAPy0SGEVy/Wzvhoc7vBJ 25 | C8vQtIJoQnunSEVqH2BRnu1eXncSvgavzeQGjil8M3Kii+TwsOu1ssCYh5gZIOJD 26 | exm6/gwcho3m6mAamGyl2W8c7LwsNVAG7xPQuV4pzn++dwnpdbCGW3jMNiAW1IY7 27 | bk1HW2gdAFiFiA+6owV5Vr2z 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIF5jCCBM6gAwIBAgIRAI1H0xvyAM36HGTTZcv/NTUwDQYJKoZIhvcNAQELBQAw 31 | ZjELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBUt5b3RvMQ4wDAYDVQQHEwVLeW90bzEa 32 | MBgGA1UEChMRTmludGVuZG8gQ28uLEx0ZC4xGzAZBgNVBAMTEk5pbnRlbmRvTlhD 33 | QTJQcm9kMTAeFw0xNjEwMDUxMDQ3NTZaFw00OTEyMDgxMjAwMDBaMIGAMQswCQYD 34 | VQQGEwJKUDEOMAwGA1UECAwFS3lvdG8xDjAMBgNVBAcMBUt5b3RvMRowGAYDVQQK 35 | DBFOaW50ZW5kbyBDby4sTHRkLjE1MDMGA1UEAwwsTlggUHJvZCAxIC0gOEQ0N0Qz 36 | MUJGMjAwQ0RGQTFDNjREMzY1Q0JGRjM1MzUwggEiMA0GCSqGSIb3DQEBAQUAA4IB 37 | DwAwggEKAoIBAQCq7oPfY/FW1NSU6DOo4Pr+6/zgJNop9Eg1zps1vCaWpQKu0Kzr 38 | qfT2uHrRcP/mRaCSwNiqXxM3EwDbcxerRc3dl6iHgCaPtd0QOzE5eRCuJcfTpdfh 39 | MRnzv6zJ+3xPo4ejTRzfoEB2s2XPpAE9vh0f9FbgP06eKA6U9i0ZNucAHm8z2l52 40 | HVBjiG5/VbY43guxlU0b4U96bG0dhH+zogPJNFcAI28R6+D2YaF0O6QfmF8SYgiD 41 | 2Y94lx5cMQkIMO9Ypbh4BYlElLSP6bRcmIqeiM9+QUDlrMd2mVTW362qsXiv6zpx 42 | IqRxZ9f9LwKyMo3kFA4f+Xjd6l2ZxIJB0HMXAgMBAAGjggJyMIICbjAMBgNVHRMB 43 | Af8EAjAAMB0GA1UdDgQWBBRpZWqkbnQ91sVY3bFPUPrmRyrnSjAfBgNVHSMEGDAW 44 | gBRycQS2kVZUFTuZ1q/6AzD0gAzZBjCCAhwGA1UdEQSCAhMwggIPoIICCwYBaaCC 45 | AgQEggIAM0EwOEUzRjMzQzU5MEQ4NDdBMkY3MDlBNjIyNjg1OTgwQTc2RTEzNEE5 46 | MjJBQzZFRTIxODcyRkY2MDQyNDJGQ0E3ODdGQjQxMjgzQzE0OEM4MDAyNkY3NTVG 47 | RDk4MTJBNjYzQjNGOUI5MEE0MDVFMzFENjA2MDBFNDE4NjU5MDJBQjY0RTRDRUZE 48 | NkM3REEyNUYwMzJEMDQ0Qjc3NjE3ODY3NjcwMzE5RTEwNjQ5NjFFNDIyNzkwRjUx 49 | N0VBNjY3MEEwRDYyODlFRUQyQkEwNzg3QjJBMUNFNkI5MzU1ODFGRjM5MTA5NEVC 50 | QzQwOEMxQTVCQ0EzMEI4MEIzQzRFNzEyRUZDMEZCRDMwNTRFMDhFOTA2NTlBNzMz 51 | NzhCNDkxQUY2QzVDODYwRUFCOTUxRUYzOTJCOTU0N0RCRDQ0RTZEN0U3QjhCRDA1 52 | NDJBQUMyMjExRjQ5ODBCQzFEQjA1MzY0QTQ3NTZCMzhCRTQyNjYyNEFGRkZGRjlF 53 | MjlDNTdGNjU4QUZEOUJDMzE5OTM1OTJCNEVFNkI0MDE2RjUxQ0QxMkUxNEYwMDhC 54 | RDI1M0M2RENENjIwQkVGODBDMzU1NzVCOEVCNjkxNjgzQzJFMEY1ODBGQThGODc2 55 | Mzc3N0U0RTE3NEFFODEwRUQyMDlDQzM1QTJDRkYxMzhCRjJCQUIwDQYJKoZIhvcN 56 | AQELBQADggEBALe6QJ2aSDMtiN7e6WPmDmKgpFquQslvdIwA+To2PLMOqr6QcgdK 57 | 429ZGCWQqnQDW4+R0dE5bl9S/BkbGvkJ9URr/zZLu73mfx19ZnMKOCSv7XXR+80c 58 | 8Bhd3QxVocENmQJdFEFWohLLBfzytsH2I0Pwet9aIFDWc7zxUMSkbv7EPICMCkP3 59 | Gr3tWt3sJs4cpwu+62xubwr2O+G61ZD+TohulzfTKW8/8jiLPFkT2uAeqfQvkcBm 60 | 06IGCz0S9dRgZwK5CTBnW0W7MO+6pfXLWXSSoX92j31xhV6hwRhrOh5sF6zHGyAq 61 | MA3jCo/qvrzZdFdg6A28DEPZQkTxIvx6uqM= 62 | -----END CERTIFICATE----- 63 | -------------------------------------------------------------------------------- /.github/workflows/firmware-autodl.yml: -------------------------------------------------------------------------------- 1 | name: 🎮 Firmware Auto Downloader 2 | 3 | on: 4 | schedule: 5 | - cron: '0 * * * *' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | download_and_release: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | 14 | steps: 15 | - name: ⬇️ Checkout code 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: 🐍 Setup Python and dependencies 21 | uses: actions/setup-python@v5 22 | with: 23 | python-version: '3.x' 24 | 25 | - name: ⚙️ Install required Python modules 26 | run: | 27 | pip install requests anynet beautifulsoup4 28 | 29 | - name: ⬇️ Setup hactool-linux 30 | run: | 31 | cp hactool-linux hactool 32 | chmod +x hactool 33 | 34 | - name: 🔍 Check firmware version (Switch 1 only) 35 | id: version_check 36 | run: | 37 | LATEST_TITLE=$(curl -s 'https://yls8.mtheall.com/ninupdates/feed.php' | \ 38 | grep 'Switch ' | \ 39 | grep -v '<title>Switch 2 ' | \ 40 | head -n 1) 41 | 42 | if [ -z "$LATEST_TITLE" ]; then 43 | echo "::error::Could not retrieve the firmware title for Switch 1 from the RSS feed." 44 | exit 1 45 | fi 46 | 47 | LATEST_VERSION=$(echo "$LATEST_TITLE" | grep -oP 'Switch \K[0-9.]+') 48 | 49 | if [ -z "$LATEST_VERSION" ]; then 50 | echo "::error::Failed to parse LATEST_VERSION from title: $LATEST_TITLE" 51 | exit 1 52 | fi 53 | 54 | TAG_EXISTS=$(git ls-remote --tags origin $LATEST_VERSION) 55 | 56 | if [ ! -z "$TAG_EXISTS" ]; then 57 | echo "INFO: Tag $LATEST_VERSION already exists on GitHub. Stopping workflow to avoid re-upload." 58 | echo "new_version=false" >> $GITHUB_OUTPUT 59 | else 60 | echo "INFO: New version $LATEST_VERSION found! Preparing to download..." 61 | echo "new_version=true" >> $GITHUB_OUTPUT 62 | fi 63 | shell: bash 64 | 65 | - name: 💻 Execute download script and capture changelog 66 | id: download 67 | if: steps.version_check.outputs.new_version == 'true' 68 | run: | 69 | python3 firmware_downloader.py | tee firmware_output.txt 70 | 71 | FIRMWARE_VERSION=$(grep 'Folder: Firmware ' firmware_output.txt | awk '{print $NF}') 72 | 73 | echo "firmware_version=$FIRMWARE_VERSION" >> $GITHUB_OUTPUT 74 | 75 | tail -n 4 firmware_output.txt > changelog_body.txt 76 | 77 | - name: 📝 Prepare Release Body 78 | id: prepare_body 79 | if: steps.version_check.outputs.new_version == 'true' 80 | uses: actions/github-script@v7 81 | with: 82 | script: | 83 | const fs = require('fs'); 84 | const changelogBody = fs.readFileSync('changelog_body.txt', 'utf8'); 85 | core.setOutput('release_body', changelogBody); 86 | 87 | - name: 📦 Create Tag and Release 88 | if: steps.version_check.outputs.new_version == 'true' 89 | uses: softprops/action-gh-release@v2 90 | with: 91 | tag_name: ${{ steps.download.outputs.firmware_version }} 92 | name: Firmware ${{ steps.download.outputs.firmware_version }} 93 | body: | 94 | Automatic download of the official Nintendo Switch firmware version **${{ steps.download.outputs.firmware_version }}**. 95 | 96 | --- 97 | 98 | **Downloaded file details:** 99 | 100 | ${{ steps.prepare_body.outputs.release_body }} 101 | 102 | files: | 103 | Firmware ${{ steps.download.outputs.firmware_version }}.zip 104 | env: 105 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 106 | -------------------------------------------------------------------------------- /firmware_downloader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import hashlib 6 | import warnings 7 | from struct import unpack 8 | from binascii import hexlify 9 | from glob import glob 10 | from shutil import rmtree 11 | from subprocess import run, PIPE 12 | from os import makedirs, remove 13 | from os.path import basename, exists, join 14 | from configparser import ConfigParser 15 | from sys import argv 16 | from zipfile import ZipFile, ZIP_DEFLATED 17 | 18 | from requests import request 19 | from requests.exceptions import HTTPError 20 | 21 | try: 22 | from anynet import tls 23 | except ImportError: 24 | print("Module 'anynet' not found. Install it with: pip install anynet") 25 | exit(1) 26 | 27 | warnings.filterwarnings("ignore") 28 | 29 | ENV = "lp1" 30 | VERSION = argv[1] if len(argv) > 1 else "" 31 | 32 | def readdata(f, addr, size): 33 | f.seek(addr) 34 | return f.read(size) 35 | 36 | def utf8(s): 37 | return s.decode("utf-8") 38 | 39 | def sha256(s): 40 | return hashlib.sha256(s).digest() 41 | 42 | def readint(f, addr=None): 43 | if addr is not None: 44 | f.seek(addr) 45 | return unpack("<I", f.read(4))[0] 46 | 47 | def readshort(f, addr=None): 48 | if addr is not None: 49 | f.seek(addr) 50 | return unpack("<H", f.read(2))[0] 51 | 52 | def hexify(s): 53 | return hexlify(s).decode("utf-8") 54 | 55 | def ihexify(n, b): 56 | return hex(n)[2:].zfill(b * 2) 57 | 58 | def dlfile(url, out): 59 | try: 60 | run([ 61 | "aria2c", "--no-conf", "--console-log-level=error", 62 | "--file-allocation=none", "--summary-interval=0", 63 | "--download-result=hide", 64 | "--certificate=keys/switch_client.crt", 65 | "--private-key=keys/switch_client.key", 66 | f"--header=User-Agent: {user_agent}", 67 | "--check-certificate=false", 68 | f"--out={out}", "-c", url 69 | ], check=True) 70 | except FileNotFoundError: 71 | print(f"downloading {basename(out)} via requests") 72 | resp = request( 73 | "GET", url, 74 | cert=("keys/switch_client.crt", "keys/switch_client.key"), 75 | headers={"User-Agent": user_agent}, 76 | stream=True, verify=False 77 | ) 78 | resp.raise_for_status() 79 | with open(out, "wb") as f: 80 | for chunk in resp.iter_content(1024*1024): 81 | f.write(chunk) 82 | 83 | def dlfiles(dltable): 84 | with open("dl.tmp", "w") as f: 85 | for url, dirc, fname, fhash in dltable: 86 | f.write(f"{url}\n\tout={fname}\n\tdir={dirc}\n\tchecksum=sha-256={fhash}\n") 87 | try: 88 | run([ 89 | "aria2c", "--no-conf", "--console-log-level=error", 90 | "--file-allocation=none", "--summary-interval=0", 91 | "--download-result=hide", 92 | "--certificate=keys/switch_client.crt", 93 | "--private-key=keys/switch_client.key", 94 | f"--header=User-Agent: {user_agent}", 95 | "--check-certificate=false", 96 | "-x", "16", "-s", "16", "-i", "dl.tmp" 97 | ], check=True) 98 | except FileNotFoundError: 99 | for url, dirc, fname, fhash in dltable: 100 | makedirs(dirc, exist_ok=True) 101 | out = join(dirc, fname) 102 | dlfile(url, out) 103 | finally: 104 | try: 105 | remove("dl.tmp") 106 | except FileNotFoundError: 107 | pass 108 | 109 | def nin_request(method, url, headers=None): 110 | if headers is None: 111 | headers = {} 112 | headers.update({"User-Agent": user_agent}) 113 | resp = request( 114 | method, url, 115 | cert=("keys/switch_client.crt", "keys/switch_client.key"), 116 | headers=headers, verify=False 117 | ) 118 | resp.raise_for_status() 119 | return resp 120 | 121 | def parse_cnmt(nca): 122 | ncaf = basename(nca) 123 | 124 | # --- MODIFICATION CLÉ --- 125 | # Force l'utilisation de l'exécutable hactool dans le répertoire courant. 126 | # Dans le workflow, hactool-linux a été renommé en hactool et rendu exécutable. 127 | hactool_bin = "hactool.exe" if os.name == "nt" else "./hactool" 128 | # ----------------------- 129 | 130 | cnmt_temp_dir = f"cnmt_tmp_{ncaf}" 131 | 132 | # Le script tente de lancer './hactool' 133 | run( 134 | [hactool_bin, "-k", "prod.keys", nca, "--section0dir", cnmt_temp_dir], 135 | stdout=PIPE, stderr=PIPE 136 | ) 137 | 138 | cnmt_file = glob(f"{cnmt_temp_dir}/*.cnmt")[0] 139 | entries = [] 140 | with open(cnmt_file, "rb") as c: 141 | c_type = readdata(c, 0xc, 1) 142 | if c_type[0] == 0x3: 143 | n_entries = readshort(c, 0x12) 144 | offset = readshort(c, 0xe) 145 | base = 0x20 + offset 146 | for i in range(n_entries): 147 | c.seek(base + i*0x10) 148 | title_id = unpack("<Q", c.read(8))[0] 149 | version = unpack("<I", c.read(4))[0] 150 | entries.append((ihexify(title_id, 8), version)) 151 | else: 152 | n_entries = readshort(c, 0x10) 153 | offset = readshort(c, 0xe) 154 | base = 0x20 + offset 155 | for i in range(n_entries): 156 | c.seek(base + i*0x38) 157 | h = c.read(32) 158 | nid = hexify(c.read(16)) 159 | entries.append((nid, hexify(h))) 160 | 161 | rmtree(cnmt_temp_dir) 162 | return entries 163 | 164 | seen_titles = set() 165 | queued_ncas = set() 166 | 167 | def dltitle(title_id, version, is_su=False): 168 | global update_files, update_dls, sv_nca_fat, sv_nca_exfat, seen_titles, queued_ncas, ver_string_simple 169 | 170 | key = (title_id, version, is_su) 171 | if key in seen_titles: 172 | return 173 | seen_titles.add(key) 174 | 175 | p = "s" if is_su else "a" 176 | try: 177 | cnmt_id = nin_request( 178 | "HEAD", 179 | f"https://atumn.hac.{ENV}.d4c.nintendo.net/t/{p}/{title_id}/{version}?device_id={device_id}" 180 | ).headers["X-Nintendo-Content-ID"] 181 | except HTTPError as e: 182 | if e.response is not None and e.response.status_code == 404: 183 | print(f"INFO: Title {title_id} version {version} not found (404).") 184 | if title_id == "010000000000081B": 185 | sv_nca_exfat = "" 186 | return 187 | raise 188 | 189 | ver_dir = f"Firmware {ver_string_simple}" 190 | makedirs(ver_dir, exist_ok=True) 191 | 192 | cnmt_nca = f"{ver_dir}/{cnmt_id}.cnmt.nca" 193 | update_files.append(cnmt_nca) 194 | dlfile( 195 | f"https://atumn.hac.{ENV}.d4c.nintendo.net/c/{p}/{cnmt_id}?device_id={device_id}", 196 | cnmt_nca 197 | ) 198 | 199 | if is_su: 200 | for t_id, ver in parse_cnmt(cnmt_nca): 201 | dltitle(t_id, ver) 202 | else: 203 | for nca_id, nca_hash in parse_cnmt(cnmt_nca): 204 | if title_id == "0100000000000809": 205 | sv_nca_fat = f"{nca_id}.nca" 206 | elif title_id == "010000000000081B": 207 | sv_nca_exfat = f"{nca_id}.nca" 208 | 209 | if nca_id not in queued_ncas: 210 | queued_ncas.add(nca_id) 211 | update_files.append(f"{ver_dir}/{nca_id}.nca") 212 | update_dls.append(( 213 | f"https://atumn.hac.{ENV}.d4c.nintendo.net/c/c/{nca_id}?device_id={device_id}", 214 | ver_dir, 215 | f"{nca_id}.nca", 216 | nca_hash 217 | )) 218 | 219 | def zipdir(src_dir, out_zip): 220 | with ZipFile(out_zip, "w", compression=ZIP_DEFLATED) as zf: 221 | for root, _, files in os.walk(src_dir): 222 | for name in files: 223 | full = os.path.join(root, name) 224 | rel = os.path.relpath(full, start=src_dir) 225 | zf.write(full, arcname=rel) 226 | 227 | if __name__ == "__main__": 228 | if not exists("certificat.pem"): 229 | print("File 'certificat.pem' not found in root directory.") 230 | exit(1) 231 | pem_data = open("certificat.pem", "rb").read() 232 | cert = tls.TLSCertificate.parse(pem_data, tls.TYPE_PEM) 233 | priv = tls.TLSPrivateKey.parse(pem_data, tls.TYPE_PEM) 234 | makedirs("keys", exist_ok=True) 235 | cert.save("keys/switch_client.crt", tls.TYPE_PEM) 236 | priv.save("keys/switch_client.key", tls.TYPE_PEM) 237 | 238 | if not exists("prod.keys"): 239 | print("File 'prod.keys' not found in root directory.") 240 | exit(1) 241 | 242 | prod_keys = ConfigParser(strict=False) 243 | with open("prod.keys") as f: 244 | prod_keys.read_string("[keys]" + f.read()) 245 | 246 | if not exists("PRODINFO.bin"): 247 | print("File 'PRODINFO.bin' not found in root directory.") 248 | exit(1) 249 | 250 | with open("PRODINFO.bin", "rb") as pf: 251 | if pf.read(4) != b"CAL0": 252 | print("Invalid PRODINFO (invalid header)!") 253 | exit(1) 254 | device_id = utf8(readdata(pf, 0x2b56, 0x10)) 255 | print("Device ID:", device_id) 256 | 257 | user_agent = f"NintendoSDK Firmware/11.0.0-0 (platform:NX; did:{device_id}; eid:{ENV})" 258 | 259 | if VERSION == "": 260 | print("INFO: No version specified, searching for the latest version...") 261 | su_meta = nin_request( 262 | "GET", 263 | f"https://sun.hac.{ENV}.d4c.nintendo.net/v1/system_update_meta?device_id={device_id}" 264 | ).json() 265 | ver_raw = su_meta["system_update_metas"][0]["title_version"] 266 | 267 | ver_major = ver_raw // 0x4000000 268 | ver_minor = (ver_raw - ver_major*0x4000000) // 0x100000 269 | ver_sub1 = (ver_raw - ver_major*0x4000000 - ver_minor*0x100000) // 0x10000 270 | ver_sub2 = ver_raw - ver_major*0x4000000 - ver_minor*0x100000 - ver_sub1*0x10000 271 | 272 | ver_string_raw = f"{ver_major}.{ver_minor}.{ver_sub1}.{str(ver_sub2).zfill(4)}" 273 | ver_string_simple = f"{ver_major}.{ver_minor}.{ver_sub1}" 274 | else: 275 | ver_string_simple = VERSION 276 | 277 | parts = list(map(int, VERSION.split("."))) 278 | if len(parts) == 3: 279 | parts.append(0) 280 | 281 | ver_raw = parts[0]*0x4000000 + parts[1]*0x100000 + parts[2]*0x10000 + parts[3] 282 | ver_string_raw = f"{parts[0]}.{parts[1]}.{parts[2]}.{str(parts[3]).zfill(4)}" 283 | 284 | ver_dir = f"Firmware {ver_string_simple}" 285 | print(f"Downloading firmware. Internal version: {ver_string_raw}. Folder: {ver_dir}") 286 | 287 | update_files = [] 288 | update_dls = [] 289 | sv_nca_fat = "" 290 | sv_nca_exfat = "" 291 | 292 | seen_titles.clear() 293 | queued_ncas.clear() 294 | 295 | dltitle("0100000000000816", ver_raw, is_su=True) 296 | dlfiles(update_dls) 297 | 298 | if not sv_nca_exfat: 299 | print("INFO: exFAT not found via meta — direct attempt 010000000000081B…") 300 | dltitle("010000000000081B", ver_raw, is_su=False) 301 | if sv_nca_exfat: 302 | dlfiles(update_dls) 303 | else: 304 | print("INFO: No separate SystemVersion exFAT found for this firmware version.") 305 | 306 | failed = False 307 | for fpath in update_files: 308 | if not exists(fpath): 309 | print(f"DOWNLOAD FAILED: {fpath} missing") 310 | failed = True 311 | if failed: 312 | exit(1) 313 | 314 | out_zip = f"{ver_dir}.zip" 315 | if exists(out_zip): 316 | remove(out_zip) 317 | zipdir(ver_dir, out_zip) 318 | 319 | print("\nDOWNLOAD COMPLETE!") 320 | print(f"Archive created: {out_zip}") 321 | print(f"SystemVersion NCA FAT: {sv_nca_fat or 'Not Found'}") 322 | print(f"SystemVersion NCA exFAT: {sv_nca_exfat or 'Not Found'}") 323 | print("Verify hashes before installation!") -------------------------------------------------------------------------------- /prod.keys: -------------------------------------------------------------------------------- 1 | aes_kek_generation_source = 4d870986c45d20722fba1053da92e8a9 2 | aes_key_generation_source = 89615ee05c31b6805fe58f3da24f7aa8 3 | bis_kek_source = 34c1a0c48258f8b4fa9e5e6adafc7e4f 4 | bis_key_00 = e4a4ffc9ed2ea374a3640c21866e3e354c13b9bc5ed8e4f3e8c23d4f84d8e891 5 | bis_key_01 = fa75c2f34ed18a87ae43dec46dede848de9e0c761a2b67604b7de88d9bd476d9 6 | bis_key_02 = f421b1376196944e7fd1b41b166e2dbe201165d2f480781543af1a8da83935b7 7 | bis_key_03 = f421b1376196944e7fd1b41b166e2dbe201165d2f480781543af1a8da83935b7 8 | bis_key_source_00 = f83f386e2cd2ca32a89ab9aa29bfc7487d92b03aa8bfdee1a74c3b6e35cb7106 9 | bis_key_source_01 = 41003049ddccc065647a7eb41eed9c5f44424edab49dfcd98777249adc9f7ca4 10 | bis_key_source_02 = 52c2e9eb09e3ee2932a10c1fb6a0926c4d12e14b2a474c1c09cb0359f015f4e4 11 | device_key_4x = f94322f4b1123c1f79d0ad499b004a3e 12 | eticket_rsa_kek = 19c8b441d318802bad63a5beda283a84 13 | eticket_rsa_kek_personalized = d3ea417566cfc41495d24bf9c0bad036 14 | eticket_rsa_kek_source = dba451124ca0a9836814f5ed95e3125b 15 | eticket_rsa_kekek_source = 466e57b74a447f02f321cde58f2f5535 16 | eticket_rsa_keypair = d277bfef675633d05bd71031e8237f68beed2b8c0f45edc2a0b1d9253cccf6d34243645e080d2b4e71a6ed51a30b090a0af317970296905c1eb2225e77d79f0e60ee00c4f84a5c6f0dc1b9d1cefb1989f68da93342504b70c67d136955b442c85de3973941e2bb360d9552bcfe031afc64d0cad85ff38ba1542984fb3ebf6772b4a0490bd1f256cd51cba8f36bb72c6384c41b38c17bd12130ccd8a6dfb0b1ecab994e496b26364e50dea3053fe2a6ec6ae5844c36347c459b4b5fb237a208692a095fbe19a0aa2c3863e8d239a3a600f73a98e731f5b55ab0511fd8370fde1cf170af80a9535564d53668549683cb63a1b8541dc194182b8e2dc5804202c091f11b1b1511946e330e6000c19077878561e9c56e1b4bddc2dbabcac80633f8092b576fb3cdfc5f5d9aa6c59e9a492e7c1ac84b9db061d09b133d0723d9467a5c0772a39a91cbacb891bd4be2ead0d79a02a3723951fd79a03d100f47644d2153a8e6e347a906ffc1e49ec9350d670bd0d5a21b98d2ba56ae62009ad076782410f1013e92e6152dfcd3ec728d8e396a431afb1bce3135a07f5e9f1dec6d85e959d7f77deed12cc6f3161149995e96bb0b17ae83b1a881826f54b5031d503fa22560c5ebed409aed738e0180e09ff4e1721e1a7c9cd91a7733d167f3d11a9fea729b27c0eefde0795c6eaf859c68cbb37ffc62300b7cedd656f2815ca71b3ae68900010001000000000000000000000000 17 | header_kek_source = 1f12913a4acbf00d4cde3af6d523882a 18 | header_key = aeaab1ca08adf9bef12991f369e3c567d6881e4e4a6a47a51f6e4877062d542d 19 | header_key_source = 5a3ed84fdec0d82631f7e25d197bf5d01c9b7bfaf628183d71f64d73f150b9d2 20 | key_area_key_application_00 = ef979e289a132c23d39c4ec5a0bba969 21 | key_area_key_application_01 = cdedbab97b69729073dfb2440bff2c13 22 | key_area_key_application_02 = 75716ed3b524a01dfe21456ce26c7270 23 | key_area_key_application_03 = f428306544cf5707c25eaa8bc0583fd1 24 | key_area_key_application_04 = 798844ec099eb6a04b26c7c728a35a4d 25 | key_area_key_application_05 = a57c6eecc5410ada22712eb3ccbf45f1 26 | key_area_key_application_06 = 2a60f6c4275df1770651d5891b8e73ec 27 | key_area_key_application_07 = 32221bd6ed19b938bec06b9d36ed9e51 28 | key_area_key_application_08 = fb20aa9e3dbf67350e86479eb431a0b3 29 | key_area_key_application_09 = ce8d5fa79e220d5f48470e9f21be018b 30 | key_area_key_application_0a = 38b865725adcf568a81d2db3ceaa5bcc 31 | key_area_key_application_0b = bbddfd40a59d0ff555c0954239972213 32 | key_area_key_application_0c = 3fee7204e21c6b0ff1373226c0c3e055 33 | key_area_key_application_0d = 7b05d214fa554bc3e91b044fb412fc0d 34 | key_area_key_application_0e = 061667d7668b76a423e3f1aea52a8baa 35 | key_area_key_application_0f = 7ee19b046987ba2588e852cc24bc2953 36 | key_area_key_application_10 = fd8a4be923d9a464793cd2f3a27557ee 37 | key_area_key_application_11 = d8178dba2fb20ed3141612b6cb2e8e9d 38 | key_area_key_application_12 = 56debb519556d05e8ab3ddb9a1e4c1d9 39 | key_area_key_application_13 = 76a3a1e5963759e5c0c178a93b547880 40 | key_area_key_application_14 = dbd99c9834f2bb2bf8dacef3f8e090d5 41 | key_area_key_application_source = 7f59971e629f36a13098066f2144c30d 42 | key_area_key_ocean_00 = b33813e4c9c4399c75fabc673ab4947b 43 | key_area_key_ocean_01 = c54166efa8c9c0f6511fa8b580191677 44 | key_area_key_ocean_02 = 3061ce73461e0b0409d6a33da85843c8 45 | key_area_key_ocean_03 = 06f170025a64921c849df168e74d37f2 46 | key_area_key_ocean_04 = dc857fd6dc1c6213076ec7b902ec5bb6 47 | key_area_key_ocean_05 = 131d76b70bd8a60036d8218c15cb610f 48 | key_area_key_ocean_06 = 17d565492ba819b0c19bed1b4297b659 49 | key_area_key_ocean_07 = 37255186f7678324bf2b2d773ea2c412 50 | key_area_key_ocean_08 = 4115c119b7bd8522ad63c831b6c816a6 51 | key_area_key_ocean_09 = 792bfc652870cca7491d1685384be147 52 | key_area_key_ocean_0a = dfcc9e87e61c9fba54a9b1c262d41e4d 53 | key_area_key_ocean_0b = 66fe3107f5a6a8d8eda2459d920b07a1 54 | key_area_key_ocean_0c = b79b6bf3d6cdc5ec10277fc07a4fec93 55 | key_area_key_ocean_0d = 9a20ffbdcb03cfc5b8e88b058d27ae6c 56 | key_area_key_ocean_0e = 1e8bba40c91ca4d55163cdfb779a2f4e 57 | key_area_key_ocean_0f = 2a51262c614e175f22cb0bf7907418b0 58 | key_area_key_ocean_10 = 97b66913f9683a9e7b733b96a35cabf3 59 | key_area_key_ocean_11 = 42da6ca5bc5dc88dac81ba0729414af1 60 | key_area_key_ocean_12 = 0a9a14c74c9f46a3e0826c6e0857d199 61 | key_area_key_ocean_13 = f74d1295fdadce4a54d142e6f93f8f4f 62 | key_area_key_ocean_14 = 632f252b1553707e7293ab860a1af19f 63 | key_area_key_ocean_source = 327d36085ad1758dab4e6fbaa555d882 64 | key_area_key_system_00 = 6dd02aa15b440d6231236b6677de86bc 65 | key_area_key_system_01 = 4ab155e7f29a292037fd147592770b12 66 | key_area_key_system_02 = b7a74adeaf89c2a198c327bdff322d7d 67 | key_area_key_system_03 = d5aab1acd23a8aec284a316df859d377 68 | key_area_key_system_04 = 9b44b45b37de9d14754b1d22c2ca742c 69 | key_area_key_system_05 = 0012e957530d3dc7af34fbbe6fd44559 70 | key_area_key_system_06 = 01744e3b0818445cd54ee9f89da43192 71 | key_area_key_system_07 = d0d30e46f5695b875f11522c375c5a80 72 | key_area_key_system_08 = bd06cb1b86bd5c433667470a09eb63de 73 | key_area_key_system_09 = e19f788f658eda8bbf34a1dd2a9503a9 74 | key_area_key_system_0a = 7070e7ff5cfe448630143a9874903c38 75 | key_area_key_system_0b = 3fa471d4483e58b8f7756fcb64f63890 76 | key_area_key_system_0c = 7bfd381df3369407ab1c6bdd9fabf522 77 | key_area_key_system_0d = 53ed531cd657edf443b551a964f44ecc 78 | key_area_key_system_0e = fa9d4958e8f8f2c8c8ae33b1034a0a02 79 | key_area_key_system_0f = 91eae4eeb5335cc5a706c4fe81d8d8af 80 | key_area_key_system_10 = ae11fa6821b123419e0a54f3a89d9a8b 81 | key_area_key_system_11 = 6cb02ff14b6bb1145345dcbe6daaa0a9 82 | key_area_key_system_12 = 9ba3e06e93313a726e23bd2d32c494a2 83 | key_area_key_system_13 = 2215008857d08cba3fe69764d7adb0a4 84 | key_area_key_system_14 = eae7d84910294d0c5e5c9b1b26b315b5 85 | key_area_key_system_source = 8745f1bba6be79647d048ba67b5fda4a 86 | keyblob_key_source_00 = df206f594454efdc7074483b0ded9fd3 87 | keyblob_key_source_01 = 0c25615d684ceb421c2379ea822512ac 88 | keyblob_key_source_02 = 337685ee884aae0ac28afd7d63c0433b 89 | keyblob_key_source_03 = 2d1f4880edeced3e3cf248b5657df7be 90 | keyblob_key_source_04 = bb5a01f988aff5fc6cff079e133c3980 91 | keyblob_key_source_05 = d8cce1266a353fcc20f32d3b517de9c0 92 | keyblob_mac_key_source = 59c7fb6fbe9bbe87656b15c0537336a5 93 | mariko_master_kek_source_05 = 77605ad2ee6ef83c3f72e2599dac5e56 94 | mariko_master_kek_source_06 = 1e80b8173ec060aa11be1a4aa66fe4ae 95 | mariko_master_kek_source_07 = 940867bd0a00388411d31adbdd8df18a 96 | mariko_master_kek_source_08 = 5c24e3b8b4f700c23cfd0ace13c3dc23 97 | mariko_master_kek_source_09 = 8669f00987c805aeb57b4874de62a613 98 | mariko_master_kek_source_0a = 0e440cedb436c03faa1daebf62b10982 99 | mariko_master_kek_source_0b = e541acecd1a7d1abed0377f127caf8f1 100 | mariko_master_kek_source_0c = 52719bdfa78b61d8d58511e48e4f74c6 101 | mariko_master_kek_source_0d = d268c6539d94f9a8a5a8a7c88f534b7a 102 | mariko_master_kek_source_0e = ec61bc821e0f5ac32b643f9dd619222d 103 | mariko_master_kek_source_0f = a5ec16391a3016082ecf096f5e7ceea9 104 | mariko_master_kek_source_10 = 8dee9e11363a9b0a6ac7bbe9d103f780 105 | mariko_master_kek_source_11 = 4f413c3bfb6a012a689f83e953bd16d2 106 | mariko_master_kek_source_12 = 31be25fbdbb4ee495c7705c2369f3480 107 | mariko_master_kek_source_13 = 1a316287a809caf8691545c26baa5a8a 108 | mariko_master_kek_source_14 = ebf35b2d4a2dce453a6f61380b003b46 109 | master_kek_05 = 94a92da1d73c2b3e165c891ced5607fc 110 | master_kek_06 = a6c7b7870e42d5302fe6110883aa3889 111 | master_kek_07 = 5cf8c1d58063aff640aaa681f0ce426c 112 | master_kek_08 = e42f1ec8002043d746575ae6dd9f283f 113 | master_kek_09 = cec2885fbeef5f6a989db84a4cc4b393 114 | master_kek_0a = dd1a730232522b5cb4590cd43869ab6a 115 | master_kek_0b = fc6f0c891d42710180724ed9e112e72a 116 | master_kek_0c = 43f7fc20fcec22a5b2a744790371b094 117 | master_kek_0d = 8dc9a8223671daa73ccd8b93cdaaed9f 118 | master_kek_0e = f3f857257c3f63ca63b9c9710b8f673e 119 | master_kek_0f = 1e8f01c4927a76a66097df44c3bad27d 120 | master_kek_10 = 8b523b9d476508daadc2036582ce5aa8 121 | master_kek_11 = c618d3fd0ee15ffcea22bc98ad2489b5 122 | master_kek_12 = f540a14ea2cce8d0ede62a56586bfb0e 123 | master_kek_13 = 5ab6b61cf29dd5d8e40fbb43e459fa88 124 | master_kek_14 = 2698651a8c2984253767669ba71b9346 125 | master_kek_source_06 = 374b772959b4043081f6e58c6d36179a 126 | master_kek_source_07 = 9a3ea9abfd56461c9bf6487f5cfa095c 127 | master_kek_source_08 = dedce339308816f8ae97adec642d4141 128 | master_kek_source_09 = 1aec11822b32387a2bedba01477e3b67 129 | master_kek_source_0a = 303f027ed838ecd7932534b530ebca7a 130 | master_kek_source_0b = 8467b67f1311aee6589b19af136c807a 131 | master_kek_source_0c = 683bca54b86f9248c305768788707923 132 | master_kek_source_0d = f013379ad56351c3b49635bc9ce87681 133 | master_kek_source_0e = 6e7786ac830a8d3e7db766a022b76e67 134 | master_kek_source_0f = 99220957a7f95e94fe787f41d6e756e6 135 | master_kek_source_10 = 71b9a6c0ff976b0cb440b9d5815d8190 136 | master_kek_source_11 = 00045df04dcd14a31cbfde4855ba35c1 137 | master_kek_source_12 = d76374464eba780a7c9db3e87a3d71e3 138 | master_kek_source_13 = a36b0ab56f574c5e00fd5621f5066bd1 139 | master_kek_source_14 = 92bf37800e79568c5775720a48d81539 140 | master_key_00 = c2caaff089b9aed55694876055271c7d 141 | master_key_01 = 54e1b8e999c2fd16cd07b66109acaaa6 142 | master_key_02 = 4f6b10d33072af2f250562bff06b6da3 143 | master_key_03 = 84e04ec20b9373818c540829cf147f3d 144 | master_key_04 = cfa2176790a53ff74974bff2af180921 145 | master_key_05 = c1dbedcebf0dd6956079e506cfa1af6e 146 | master_key_06 = 0aa90e6330cdc12d819b3254d11a4e1e 147 | master_key_07 = 929f86fbfe4ef7732892bf3462511b0e 148 | master_key_08 = 23cfb792c3cb50cd715da0f84880c877 149 | master_key_09 = 75c93b716255319b8e03e14c19dea64e 150 | master_key_0a = 73767484c73088f629b0eeb605f64aa6 151 | master_key_0b = 8500b14bf4766b855a26ffc614097a8f 152 | master_key_0c = b3c503709135d4b35de31be4b0b9c0f7 153 | master_key_0d = 6d2b26416ab030dc504cbfd6bb2977b7 154 | master_key_0e = 3b995e3bf23207c3cacb07f8c57415e6 155 | master_key_0f = ff22454d86237004c750e2dcb4b16c80 156 | master_key_10 = 252c7d95f296d07f2369bdba6d42c615 157 | master_key_11 = 03d1d722e91bf7f2c8f3c00283bf5c6c 158 | master_key_12 = 32ecadc8986540f930f54d159fcba88e 159 | master_key_13 = 5146f2e7096bd2f8fa14030b883a98d0 160 | master_key_14 = 4c9b499cc482b0fe8c6c2f698e19ff64 161 | master_key_source = d8a2410ac6c59001c61d6a267c513f3c 162 | package2_key_00 = a35a19cb14404b2f4460d343d178638d 163 | package2_key_01 = a0dd1eacd438610c85a191f02c1db8a8 164 | package2_key_02 = 7e5ba2aafd57d47a85fd4a57f2076679 165 | package2_key_03 = bf03e9889fa18f0d7a55e8e9f684323d 166 | package2_key_04 = 09df6e361e28eb9c96c9fa0bfc897179 167 | package2_key_05 = 444b1a4f9035178b9b1fe262462acb8e 168 | package2_key_06 = 442cd9c21cfb8914587dc12e8e7ed608 169 | package2_key_07 = 70c821e7d6716feb124acbac09f7b863 170 | package2_key_08 = 8accebcc3d15a328a48365503f8369b6 171 | package2_key_09 = f562a7c6c42e3d4d3d13ffd504d77346 172 | package2_key_0a = 0803167ec7fc0bc753d8330e5592a289 173 | package2_key_0b = 341db6796aa7bdb8092f7aae6554900a 174 | package2_key_0c = 4e97dc4225d00c6ae33d49bddd17637d 175 | package2_key_0d = db13c2de2c313540b18a32b4f106d4a1 176 | package2_key_0e = 254d393b26e6d98963c1c8c4fa6d11e2 177 | package2_key_0f = 1c87f9650cca54af03df3590021e457d 178 | package2_key_10 = 2d64ee13cece88746b375f1a43b9fdf6 179 | package2_key_11 = 73a9680bbd12d3a05c6eddb9545c4077 180 | package2_key_12 = 64f022a4150139a118608f55e5621c72 181 | package2_key_13 = 56adb5ca4e65d0ce48b2d70129cb87e1 182 | package2_key_14 = d8118afae97877041ae563eff14de93c 183 | package2_key_source = fb8b6a9c7900c849efd24d854d30a0c7 184 | per_console_key_source = 4f025f0eb66d110edc327d4186c2f478 185 | retail_specific_aes_key_source = e2d6b87a119cb880e822888a46fba195 186 | save_mac_kek_source = d89c236ec9124e43c82b038743f9cf1b 187 | save_mac_key = d798cbbd382b7891c3c6ae909da62936 188 | save_mac_key_source = e4cd3d4ad50f742845a487e5a063ea1f 189 | save_mac_sd_card_kek_source = 0489ef5d326e1a59c4b7ab8c367aab17 190 | save_mac_sd_card_key_source = 6f645947c56146f9ffa045d595332918 191 | sd_card_custom_storage_key_source = 370c345e12e4cefe21b58e64db52af354f2ca5a3fc999a47c03ee004485b2fd0 192 | sd_card_kek_source = 88358d9c629ba1a00147dbe0621b5432 193 | sd_card_nca_key_source = 5841a284935b56278b8e1fc518e99f2b67c793f0f24fded075495dca006d99c2 194 | sd_card_save_key_source = 2449b722726703a81965e6e3ea582fdd9a951517b16e8f7f1f68263152ea296a 195 | sd_seed = 8b9a52ccb21081c5062bd5df46eef75f 196 | ssl_rsa_kek = b011100660d1dccbad1b1b733afa9f95 197 | ssl_rsa_kek_personalized = 57564664130531a71731195fb31069e2 198 | ssl_rsa_kek_source = 9a383bf431d0bd8132534ba964397de3 199 | ssl_rsa_kekek_source = 7f5bb0847b25aa67fac84be23d7b6903 200 | ssl_rsa_key = 2a395466565d0ca12145e9a01c50432bdbda09961a7a3dd9a655dccb31663a83e5215c0ace43a046e1655f4b0903b47b4ce3ec796241b11497c12f8204946761c6f6be5fe33b61ae8440a7364990afc9ab78a74bbb2da584777e1bd9474721f9758b61d3836fdd0a15b885b4965692444dbaf3187ffa1c7f4e9d9ad05d7499f8e7add7a0854925e72248edb478b936142cdd9ab0fcd61f9a939a795e6e448513acfa9aa2841e8ddf08a70bdd25e6c0c05b4b0884e3615aa96ba8ae99f91d234cf075e7d5ee113cab36f28700957c7e8973056d35fc5dc65b7bb2fb642be88f3a235020fde51e3754fecc90cad3e32d22e93a60ab5234497b2163bd3418fefe1d 201 | titlekek_00 = 62a24d6e6d0d0e0abf3554d259be3dc9 202 | titlekek_01 = 8821f642176969b1a18021d2665c0111 203 | titlekek_02 = 5d15b9b95a5739a0ac9b20f600283962 204 | titlekek_03 = 1b3f63bcb67d4b06da5badc7d89acce1 205 | titlekek_04 = e45c1789a69c7afbbf1a1e61f2499459 206 | titlekek_05 = ddc67f7189f4527a37b519cb051eee21 207 | titlekek_06 = b1532b9d38ab036068f074c0d78706ac 208 | titlekek_07 = 81dc1b1783df268789a6a0edbf058343 209 | titlekek_08 = 47dfe4bf0eeda88b17136b8005ab08ea 210 | titlekek_09 = adaa785d90e1a9c182ac07bc276bf600 211 | titlekek_0a = 42daa957c128f75bb1fda56a8387e17b 212 | titlekek_0b = d08903363f2c8655d3de3ccf85d79406 213 | titlekek_0c = be2682599db34caa9bc7ebb2cc7c654c 214 | titlekek_0d = 41071f95beddc4114a03e0072e6ccab7 215 | titlekek_0e = e342365a0fa0fa4a28a7bc00e45b3f68 216 | titlekek_0f = 105999eaf8b71d199bf201f525b2c68d 217 | titlekek_10 = 3796fcdb27351d58cc3f3379dda04202 218 | titlekek_11 = b16d793f4be5394e60a6e426e172c16a 219 | titlekek_12 = 0cd263cbddcbeca9ffa779edbe708664 220 | titlekek_13 = 8d4d403cd8c5ec76c3d777ac55c7ef35 221 | titlekek_14 = 2d44b28c78de6ef226d9d70e2f6362a2 222 | titlekek_source = 1edc7b3b60e6b4d878b81715985e629b 223 | --------------------------------------------------------------------------------