Merge branch '6.1' into 6.2
authorAlexander Ebert <ebert@woltlab.com>
Thu, 2 Jan 2025 15:36:03 +0000 (16:36 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 2 Jan 2025 15:36:39 +0000 (16:36 +0100)
1  2 
package-lock.json
package.json

index a0547b6407621bdc866265ee50acb742e36bf33b,2341d5e8657f34221ae1b5318024599f02db5114..881e8383b3c113e4f734faec48936260338effdf
          "@types/jquery": "^3.5.32",
          "@types/pica": "5.1.3",
          "@types/prismjs": "^1.26.5",
 +        "@types/sortablejs": "^1.15.8",
 +        "@types/supercluster": "^7.1.3",
          "@types/twitter-for-web": "0.0.6",
 -        "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#ad63ae03e8611e280d30739847a226a1ef4b332d",
 +        "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#54d7052a834e3b41e5fdacd8a17a4a4ea1b6e76c",
          "@woltlab/visual-dom-diff": "git+https://github.com/WoltLab/visual-dom-diff.git#e5b51fce3157d1eda310566fc1f86101341d1fea",
          "@woltlab/zxcvbn": "git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
-         "focus-trap": "^7.6.1",
 +        "cropperjs": "2.0.0-rc.2",
 +        "emoji-picker-element": "^1.23.0",
 +        "exifreader": "^4.25.0",
+         "focus-trap": "^7.6.2",
          "html-parsed-element": "^0.4.1",
          "perfect-scrollbar": "^1.5.6",
          "qr-creator": "^1.0.0",
          "reflect-metadata": "^0.2.2",
 +        "sortablejs": "^1.15.4",
          "tabbable": "^6.2.0",
 -        "tslib": "^2.8.1"
 +        "tslib": "^2.8.1",
 +        "webpack-cli": "^5.1.4"
        },
        "devDependencies": {
-         "@typescript-eslint/eslint-plugin": "^8.14.0",
-         "@typescript-eslint/parser": "^8.14.0",
-         "esbuild": "^0.24.0",
-         "eslint": "^9.14.0",
+         "@typescript-eslint/eslint-plugin": "^8.19.0",
+         "@typescript-eslint/parser": "^8.19.0",
+         "esbuild": "^0.24.2",
+         "eslint": "^9.17.0",
          "eslint-config-prettier": "^9.1.0",
-         "prettier": "^3.3.3",
-         "typescript": "^5.6.3"
+         "prettier": "^3.4.2",
+         "typescript": "^5.7.2"
        }
      },
      "node_modules/@aashutoshrathi/word-wrap": {
          "lodash-es": "4.17.21"
        }
      },
 +    "node_modules/@cropper/element": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element/-/element-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-4G6lTJblndwzpsb43YKeHiKcocOkDIWystGzbHNbqRysE0U0lYHuRyvV7FW6a9S63wtMFSYuwFxcdUdUcmkF8w==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-canvas": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-canvas/-/element-canvas-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-0aqbJ3ycQM6/yn4T03vw8K/OeTB8C6+Z/jimuavy4UM2CENH9ucSLM4hAG0yYCgghIyv9Zd0unaBmtgW+I5+SQ==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-crosshair": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-crosshair/-/element-crosshair-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-yopINLvaZhL3E2GNienju1zeQ1Cifkn5f/0R7ZabXcAgUI0s2sLzNqL8+2XV2J3DzEzYEIYc+49KmMle04nVWQ==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-grid": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-grid/-/element-grid-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-PzAfEya6CmIc/o/lcA/NZ1rohszz42wjq2z3E2zq2jMfNDxY/EIoFnGI6+hJrxCAaoKD8UlKOEHQdRQbtnjcMg==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-handle": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-handle/-/element-handle-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-wOWX4xpryxKcrhnJC2mHebqQQ622UN2oyQoDZcaMzvlwt7nnX3bInF+SFrIj9/aCxtCUYY0oD2gaJkfd6aNJ0g==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-image": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-image/-/element-image-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-RTKnuJrqn1K8FscS11auit2W57AG04mxRNOxBldYs3lKTkwZjzJdQFkZ/Nxu+cwVXT+c6IeEiayNKvu4B7CAQg==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/element-canvas": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-selection": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-selection/-/element-selection-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-UIgIHKHz4qNKlm5YRnC/Pu9+VrInm5TSOzkmU8kPt2swUk0WHNRv3ZcOjCQZ2ccTQnAH3FVM3FYDZ8HjRwLcBg==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/element-canvas": "^2.0.0-rc.2",
 +        "@cropper/element-image": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-shade": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-shade/-/element-shade-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-vHAGFxlqgflGZWkRYNWNHUY0zsV72YZGmCgtUu4sMrnWLZL/jMGhxmm8zZCe/aB94F829XcQ6uf3BoiApB+7Ng==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/element-canvas": "^2.0.0-rc.2",
 +        "@cropper/element-selection": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/element-viewer": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/element-viewer/-/element-viewer-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-2z9mIA7ic3enNS4xvq9Gq6hnRZ1tPr0h+lCrOHP55NL4he63lE9oTVJfDx19rL95wUS4VxL2ANvr2BVLNiBM7A==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/element-canvas": "^2.0.0-rc.2",
 +        "@cropper/element-image": "^2.0.0-rc.2",
 +        "@cropper/element-selection": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/elements": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/elements/-/elements-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-NG5kdqpv7/tGvUfNjJiIHr2Ip431v5t/P5cIXTcYAgt8PRyFJmjx3fatC7NLnP/FUlv+bbzd8PMRI4LY4Gaw3Q==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/element": "^2.0.0-rc.2",
 +        "@cropper/element-canvas": "^2.0.0-rc.2",
 +        "@cropper/element-crosshair": "^2.0.0-rc.2",
 +        "@cropper/element-grid": "^2.0.0-rc.2",
 +        "@cropper/element-handle": "^2.0.0-rc.2",
 +        "@cropper/element-image": "^2.0.0-rc.2",
 +        "@cropper/element-selection": "^2.0.0-rc.2",
 +        "@cropper/element-shade": "^2.0.0-rc.2",
 +        "@cropper/element-viewer": "^2.0.0-rc.2"
 +      }
 +    },
 +    "node_modules/@cropper/utils": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/@cropper/utils/-/utils-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-EEivNsyV6BtL496m4Q/IeAC6FGlyKjKIT1qMtwaxtkR+2ZlKnf9O7AdcGpClemIBA+TbwWAzp0UyIvYFtKUZ1Q==",
 +      "license": "MIT"
 +    },
 +    "node_modules/@discoveryjs/json-ext": {
 +      "version": "0.5.7",
 +      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
 +      "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
 +      "license": "MIT",
 +      "engines": {
 +        "node": ">=10.0.0"
 +      }
 +    },
      "node_modules/@esbuild/aix-ppc64": {
-       "version": "0.24.0",
-       "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz",
-       "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==",
+       "version": "0.24.2",
+       "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
+       "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
        "cpu": [
          "ppc64"
        ],
          "url": "https://opencollective.com/typescript-eslint"
        }
      },
+     "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+       "version": "4.2.0",
+       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+       "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+       "dev": true,
+       "license": "Apache-2.0",
+       "engines": {
+         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+       },
+       "funding": {
+         "url": "https://opencollective.com/eslint"
+       }
+     },
 +    "node_modules/@webassemblyjs/ast": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
 +      "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/helper-numbers": "1.11.6",
 +        "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/floating-point-hex-parser": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
 +      "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/@webassemblyjs/helper-api-error": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
 +      "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/@webassemblyjs/helper-buffer": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
 +      "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/@webassemblyjs/helper-numbers": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
 +      "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/floating-point-hex-parser": "1.11.6",
 +        "@webassemblyjs/helper-api-error": "1.11.6",
 +        "@xtuc/long": "4.2.2"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
 +      "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/@webassemblyjs/helper-wasm-section": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
 +      "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@webassemblyjs/helper-buffer": "1.12.1",
 +        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
 +        "@webassemblyjs/wasm-gen": "1.12.1"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/ieee754": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
 +      "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@xtuc/ieee754": "^1.2.0"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/leb128": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
 +      "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
 +      "license": "Apache-2.0",
 +      "peer": true,
 +      "dependencies": {
 +        "@xtuc/long": "4.2.2"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/utf8": {
 +      "version": "1.11.6",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
 +      "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/@webassemblyjs/wasm-edit": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
 +      "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@webassemblyjs/helper-buffer": "1.12.1",
 +        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
 +        "@webassemblyjs/helper-wasm-section": "1.12.1",
 +        "@webassemblyjs/wasm-gen": "1.12.1",
 +        "@webassemblyjs/wasm-opt": "1.12.1",
 +        "@webassemblyjs/wasm-parser": "1.12.1",
 +        "@webassemblyjs/wast-printer": "1.12.1"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/wasm-gen": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
 +      "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
 +        "@webassemblyjs/ieee754": "1.11.6",
 +        "@webassemblyjs/leb128": "1.11.6",
 +        "@webassemblyjs/utf8": "1.11.6"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/wasm-opt": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
 +      "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@webassemblyjs/helper-buffer": "1.12.1",
 +        "@webassemblyjs/wasm-gen": "1.12.1",
 +        "@webassemblyjs/wasm-parser": "1.12.1"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/wasm-parser": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
 +      "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@webassemblyjs/helper-api-error": "1.11.6",
 +        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
 +        "@webassemblyjs/ieee754": "1.11.6",
 +        "@webassemblyjs/leb128": "1.11.6",
 +        "@webassemblyjs/utf8": "1.11.6"
 +      }
 +    },
 +    "node_modules/@webassemblyjs/wast-printer": {
 +      "version": "1.12.1",
 +      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
 +      "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@webassemblyjs/ast": "1.12.1",
 +        "@xtuc/long": "4.2.2"
 +      }
 +    },
 +    "node_modules/@webpack-cli/configtest": {
 +      "version": "2.1.1",
 +      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
 +      "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
 +      "license": "MIT",
 +      "engines": {
 +        "node": ">=14.15.0"
 +      },
 +      "peerDependencies": {
 +        "webpack": "5.x.x",
 +        "webpack-cli": "5.x.x"
 +      }
 +    },
 +    "node_modules/@webpack-cli/info": {
 +      "version": "2.0.2",
 +      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
 +      "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
 +      "license": "MIT",
 +      "engines": {
 +        "node": ">=14.15.0"
 +      },
 +      "peerDependencies": {
 +        "webpack": "5.x.x",
 +        "webpack-cli": "5.x.x"
 +      }
 +    },
 +    "node_modules/@webpack-cli/serve": {
 +      "version": "2.0.5",
 +      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
 +      "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
 +      "license": "MIT",
 +      "engines": {
 +        "node": ">=14.15.0"
 +      },
 +      "peerDependencies": {
 +        "webpack": "5.x.x",
 +        "webpack-cli": "5.x.x"
 +      },
 +      "peerDependenciesMeta": {
 +        "webpack-dev-server": {
 +          "optional": true
 +        }
 +      }
 +    },
      "node_modules/@woltlab/editor": {
 -      "resolved": "git+ssh://git@github.com/WoltLab/editor.git#ad63ae03e8611e280d30739847a226a1ef4b332d",
 -      "integrity": "sha512-x6xLW+/YjGuimnHuI34u0q+Ho97gpawG6o/osugSY7tPjJKOMNeaA3kvNya/1ZHDKbVs6Pnz5Oszb3fMYil+xw==",
 +      "resolved": "git+ssh://git@github.com/WoltLab/editor.git#54d7052a834e3b41e5fdacd8a17a4a4ea1b6e76c",
 +      "integrity": "sha512-AE1p/5Nc6SH/tdMa0WgIM55BG0Feg1pgfbV0SrZkcLqAqPT/hAiQuYt8Nt8+6vNiG1jDfNlya0Jk6O38VQrbvA==",
        "dependencies": {
          "@ckeditor/ckeditor5-alignment": "^43.3.1",
          "@ckeditor/ckeditor5-autosave": "^43.3.1",
        "dev": true,
        "license": "MIT"
      },
 +    "node_modules/cropperjs": {
 +      "version": "2.0.0-rc.2",
 +      "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-2.0.0-rc.2.tgz",
 +      "integrity": "sha512-BTuz+UeZphGOEnBCuQiNT4rk1uFfKJaKmTgoH9XU7Q8IMkLdodW7YPWINmXJXwWMt1nXiKze5qKADVbz9xtVFg==",
 +      "license": "MIT",
 +      "dependencies": {
 +        "@cropper/elements": "^2.0.0-rc.2",
 +        "@cropper/utils": "^2.0.0-rc.2"
 +      }
 +    },
      "node_modules/cross-spawn": {
-       "version": "7.0.3",
-       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-       "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+       "version": "7.0.6",
+       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+       "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
 -      "dev": true,
+       "license": "MIT",
        "dependencies": {
          "path-key": "^3.1.0",
          "shebang-command": "^2.0.0",
        "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
        "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
      },
 -    "node_modules/esbuild": {
 -      "version": "0.24.2",
 -      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
 -      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
 -      "dev": true,
 -      "hasInstallScript": true,
 +    "node_modules/electron-to-chromium": {
 +      "version": "1.5.41",
 +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz",
 +      "integrity": "sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==",
 +      "license": "ISC",
 +      "peer": true
 +    },
 +    "node_modules/emoji-picker-element": {
 +      "version": "1.25.0",
 +      "resolved": "https://registry.npmjs.org/emoji-picker-element/-/emoji-picker-element-1.25.0.tgz",
 +      "integrity": "sha512-UcUMxqIuneLCsEJ5KpqTD1xaHZyUpg6Oa7uCVe5AMXXpsW3C2TNegbNLXj2/rlbyr6qVMf7lXTFyzvFEarOIUg==",
 +      "license": "Apache-2.0"
 +    },
 +    "node_modules/enhanced-resolve": {
 +      "version": "5.17.1",
 +      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
 +      "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "graceful-fs": "^4.2.4",
 +        "tapable": "^2.2.0"
 +      },
 +      "engines": {
 +        "node": ">=10.13.0"
 +      }
 +    },
 +    "node_modules/envinfo": {
 +      "version": "7.14.0",
 +      "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
 +      "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
 +      "license": "MIT",
 +      "bin": {
 +        "envinfo": "dist/cli.js"
 +      },
 +      "engines": {
 +        "node": ">=4"
 +      }
 +    },
 +    "node_modules/es-module-lexer": {
 +      "version": "1.5.4",
 +      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
 +      "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
 +      "license": "MIT",
 +      "peer": true
 +    },
 +    "node_modules/esbuild": {
-       "version": "0.24.0",
-       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz",
-       "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==",
++      "version": "0.24.2",
++      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
++      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
 +      "dev": true,
 +      "hasInstallScript": true,
        "license": "MIT",
        "bin": {
          "esbuild": "bin/esbuild"
          "node": ">=18"
        },
        "optionalDependencies": {
-         "@esbuild/aix-ppc64": "0.24.0",
-         "@esbuild/android-arm": "0.24.0",
-         "@esbuild/android-arm64": "0.24.0",
-         "@esbuild/android-x64": "0.24.0",
-         "@esbuild/darwin-arm64": "0.24.0",
-         "@esbuild/darwin-x64": "0.24.0",
-         "@esbuild/freebsd-arm64": "0.24.0",
-         "@esbuild/freebsd-x64": "0.24.0",
-         "@esbuild/linux-arm": "0.24.0",
-         "@esbuild/linux-arm64": "0.24.0",
-         "@esbuild/linux-ia32": "0.24.0",
-         "@esbuild/linux-loong64": "0.24.0",
-         "@esbuild/linux-mips64el": "0.24.0",
-         "@esbuild/linux-ppc64": "0.24.0",
-         "@esbuild/linux-riscv64": "0.24.0",
-         "@esbuild/linux-s390x": "0.24.0",
-         "@esbuild/linux-x64": "0.24.0",
-         "@esbuild/netbsd-x64": "0.24.0",
-         "@esbuild/openbsd-arm64": "0.24.0",
-         "@esbuild/openbsd-x64": "0.24.0",
-         "@esbuild/sunos-x64": "0.24.0",
-         "@esbuild/win32-arm64": "0.24.0",
-         "@esbuild/win32-ia32": "0.24.0",
-         "@esbuild/win32-x64": "0.24.0"
+         "@esbuild/aix-ppc64": "0.24.2",
+         "@esbuild/android-arm": "0.24.2",
+         "@esbuild/android-arm64": "0.24.2",
+         "@esbuild/android-x64": "0.24.2",
+         "@esbuild/darwin-arm64": "0.24.2",
+         "@esbuild/darwin-x64": "0.24.2",
+         "@esbuild/freebsd-arm64": "0.24.2",
+         "@esbuild/freebsd-x64": "0.24.2",
+         "@esbuild/linux-arm": "0.24.2",
+         "@esbuild/linux-arm64": "0.24.2",
+         "@esbuild/linux-ia32": "0.24.2",
+         "@esbuild/linux-loong64": "0.24.2",
+         "@esbuild/linux-mips64el": "0.24.2",
+         "@esbuild/linux-ppc64": "0.24.2",
+         "@esbuild/linux-riscv64": "0.24.2",
+         "@esbuild/linux-s390x": "0.24.2",
+         "@esbuild/linux-x64": "0.24.2",
+         "@esbuild/netbsd-arm64": "0.24.2",
+         "@esbuild/netbsd-x64": "0.24.2",
+         "@esbuild/openbsd-arm64": "0.24.2",
+         "@esbuild/openbsd-x64": "0.24.2",
+         "@esbuild/sunos-x64": "0.24.2",
+         "@esbuild/win32-arm64": "0.24.2",
+         "@esbuild/win32-ia32": "0.24.2",
+         "@esbuild/win32-x64": "0.24.2"
        }
      },
 +    "node_modules/escalade": {
 +      "version": "3.2.0",
 +      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
 +      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
 +      "license": "MIT",
 +      "peer": true,
 +      "engines": {
 +        "node": ">=6"
 +      }
 +    },
      "node_modules/escape-string-regexp": {
        "version": "4.0.0",
        "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
          "url": "https://opencollective.com/eslint"
        }
      },
 -    "node_modules/eslint/node_modules/@humanwhocodes/retry": {
 -      "version": "0.4.1",
 -      "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
 -      "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
 -      "dev": true,
 -      "license": "Apache-2.0",
 -      "engines": {
 -        "node": ">=18.18"
 -      },
 -      "funding": {
 -        "type": "github",
 -        "url": "https://github.com/sponsors/nzakas"
 -      }
 -    },
+     "node_modules/eslint/node_modules/brace-expansion": {
+       "version": "1.1.11",
+       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+       "dev": true,
+       "license": "MIT",
+       "dependencies": {
+         "balanced-match": "^1.0.0",
+         "concat-map": "0.0.1"
+       }
+     },
      "node_modules/eslint/node_modules/eslint-visitor-keys": {
        "version": "4.2.0",
        "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
        "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
        "dev": true
      },
 +    "node_modules/fastest-levenshtein": {
 +      "version": "1.0.16",
 +      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
 +      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
 +      "license": "MIT",
 +      "engines": {
 +        "node": ">= 4.9.1"
 +      }
 +    },
      "node_modules/fastq": {
-       "version": "1.17.1",
-       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-       "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+       "version": "1.18.0",
+       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
+       "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
        "dev": true,
        "license": "ISC",
        "dependencies": {
          "node": ">=8.6"
        }
      },
 +    "node_modules/mime-db": {
 +      "version": "1.52.0",
 +      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
 +      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
 +      "license": "MIT",
 +      "peer": true,
 +      "engines": {
 +        "node": ">= 0.6"
 +      }
 +    },
 +    "node_modules/mime-types": {
 +      "version": "2.1.35",
 +      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
 +      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "mime-db": "1.52.0"
 +      },
 +      "engines": {
 +        "node": ">= 0.6"
 +      }
 +    },
      "node_modules/minimatch": {
-       "version": "3.1.2",
-       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+       "version": "9.0.5",
+       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+       "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
        "dev": true,
        "license": "ISC",
        "dependencies": {
        "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
        "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
      },
-     "node_modules/text-table": {
-       "version": "0.2.0",
-       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-       "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-       "dev": true
-     },
 +    "node_modules/tapable": {
 +      "version": "2.2.1",
 +      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
 +      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
 +      "license": "MIT",
 +      "peer": true,
 +      "engines": {
 +        "node": ">=6"
 +      }
 +    },
 +    "node_modules/terser": {
 +      "version": "5.36.0",
 +      "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz",
 +      "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==",
 +      "license": "BSD-2-Clause",
 +      "peer": true,
 +      "dependencies": {
 +        "@jridgewell/source-map": "^0.3.3",
 +        "acorn": "^8.8.2",
 +        "commander": "^2.20.0",
 +        "source-map-support": "~0.5.20"
 +      },
 +      "bin": {
 +        "terser": "bin/terser"
 +      },
 +      "engines": {
 +        "node": ">=10"
 +      }
 +    },
 +    "node_modules/terser-webpack-plugin": {
 +      "version": "5.3.10",
 +      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
 +      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
 +      "license": "MIT",
 +      "peer": true,
 +      "dependencies": {
 +        "@jridgewell/trace-mapping": "^0.3.20",
 +        "jest-worker": "^27.4.5",
 +        "schema-utils": "^3.1.1",
 +        "serialize-javascript": "^6.0.1",
 +        "terser": "^5.26.0"
 +      },
 +      "engines": {
 +        "node": ">= 10.13.0"
 +      },
 +      "funding": {
 +        "type": "opencollective",
 +        "url": "https://opencollective.com/webpack"
 +      },
 +      "peerDependencies": {
 +        "webpack": "^5.1.0"
 +      },
 +      "peerDependenciesMeta": {
 +        "@swc/core": {
 +          "optional": true
 +        },
 +        "esbuild": {
 +          "optional": true
 +        },
 +        "uglify-js": {
 +          "optional": true
 +        }
 +      }
 +    },
      "node_modules/to-regex-range": {
        "version": "5.0.1",
        "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
diff --cc package.json
index d70360a220bbdfcfd9e6ffb74aeae138a290138c,976561349cd1a84579ddbe5a1ff377874a9c3086..ea639fe764be114afcdf681bb5f33176f838dce9
@@@ -1,17 -1,16 +1,17 @@@
  {
    "name": "@woltlab/wcf",
    "scripts": {
 -    "bundle-web-components": "npx esbuild ts/WoltLabSuite/WebComponent/index.ts --minify --bundle --watch --outfile=wcfsetup/install/files/js/WoltLabSuite/WebComponent.min.js"
 +    "bundle-web-components": "npx esbuild ts/WoltLabSuite/WebComponent/index.ts --minify --bundle --watch --outfile=wcfsetup/install/files/js/WoltLabSuite/WebComponent.min.js",
 +    "bundle-emoji-picker": "npx webpack build --config emoji-picker-webpack.config.js"
    },
    "devDependencies": {
-     "@typescript-eslint/eslint-plugin": "^8.14.0",
-     "@typescript-eslint/parser": "^8.14.0",
-     "esbuild": "^0.24.0",
-     "eslint": "^9.14.0",
+     "@typescript-eslint/eslint-plugin": "^8.19.0",
+     "@typescript-eslint/parser": "^8.19.0",
+     "esbuild": "^0.24.2",
+     "eslint": "^9.17.0",
      "eslint-config-prettier": "^9.1.0",
-     "prettier": "^3.3.3",
-     "typescript": "^5.6.3"
+     "prettier": "^3.4.2",
+     "typescript": "^5.7.2"
    },
    "dependencies": {
      "@ckeditor/ckeditor5-inspector": "^4.1.0",
      "@types/jquery": "^3.5.32",
      "@types/pica": "5.1.3",
      "@types/prismjs": "^1.26.5",
 +    "@types/sortablejs": "^1.15.8",
 +    "@types/supercluster": "^7.1.3",
      "@types/twitter-for-web": "0.0.6",
 -    "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#ad63ae03e8611e280d30739847a226a1ef4b332d",
 +    "@woltlab/editor": "git+https://github.com/WoltLab/editor.git#54d7052a834e3b41e5fdacd8a17a4a4ea1b6e76c",
      "@woltlab/visual-dom-diff": "git+https://github.com/WoltLab/visual-dom-diff.git#e5b51fce3157d1eda310566fc1f86101341d1fea",
      "@woltlab/zxcvbn": "git+https://github.com/WoltLab/zxcvbn.git#5b582b24e437f1883ccad3c37dae7c3c5f1e7da3",
-     "focus-trap": "^7.6.1",
 +    "cropperjs": "2.0.0-rc.2",
 +    "emoji-picker-element": "^1.23.0",
 +    "exifreader": "^4.25.0",
+     "focus-trap": "^7.6.2",
      "html-parsed-element": "^0.4.1",
      "perfect-scrollbar": "^1.5.6",
      "qr-creator": "^1.0.0",