feat: translate the page

This commit is contained in:
max_richter 2023-11-29 15:59:16 +01:00
parent 5d1a7e98c1
commit 7cdab9c68b
19 changed files with 542 additions and 88 deletions

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"inlang.vs-code-extension"
]
}

52
messages/de.json Normal file
View File

@ -0,0 +1,52 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"invite": "Wir laden dich herzlich ein, an unserer exklusiven Silvesterparty teilzunehmen, die dieses Jahr im magischen Ambiente eines Maskenballs stattfindet. Tauche ein in eine Nacht voller Geheimnisse, Eleganz und festlichem Glanz.",
"welcome": "Willkommen zum Maskenball",
"acceptInvite": "Einladung annehmen",
"nameTooLong": "Wir bitten um Entschuldigung, aber dieser Name ist zu lang. (maximal 100 Zeichen)",
"createNameWith": "Wir werden {name} mit",
"wantAlternativePersonality": "Möchtet Ihr, dass wir eine alternative Persönlichkeit für Euch erschaffen?",
"wantNobleName": "Möchtet Ihr einen würdigen Adelsnamen für Euch in Erwägung ziehen?",
"yourNobleName": "Euer Adelsname",
"nobleName":"Adelstitel",
"name": "Name",
"titleTooLong": "Wir bitten um Entschuldigung, aber dieser Titel ist zu lang. (maximal 100 Zeichen)",
"hundredChars": "/100 Zeichen",
"accept": "akzeptieren",
"newSuggestions": "neue vorschläge",
"titleSuggestions": "Adelsname Vorschläge",
"shouldCreatePortrait": "Sollten unsere begabten Künstler ein majestätisches Porträt von Euch anfertigen?",
"skinVeryBright": "sehr heller",
"skinBright": "heller",
"skinMedium": "medium",
"skinDark": "dunkler",
"skinVeryDark": "sehr dunkler",
"skinAnd": "Haut und",
"hairTypeStraight": "glatten",
"hairTypeCurly": "lockigen",
"hairTypeWavy": "welligen",
"hairLengthLong": "langen",
"hairLengthMedium": "medium-langen",
"hairLengthShort": "kurzen",
"hairColorRed": "roten",
"hairColorBlack": "schwarzen",
"hairColorBlond": "blonden",
"hairColorBrown": "braunen",
"hairDrawing": "Haaren zeichnen",
"paintPortrait": "porträt malen (~15 Sekunden)",
"portraitIsBeingDrawn": "Euer edles Antlitz wird gemalt",
"acceptPortrait": "Porträt annehmen",
"requestNewPortrait": "Neues Porträt anfordern",
"invitationIsBeingSend": "Einladung wird abgeschickt",
"sendInvitation": "Einladung versenden",
"guestGallery": "Gallerie der Gäste",
"howSureAppearing": "Wie sicher dürfen wir mit Eurem glanzvollen Erscheinen rechnen?",
"howName": "Wie lauten Euer Vor- und Nachname, edler Gast?",
"saveName": "Name speichern",
"notAtAll": "gar nicht",
"very": "sehr",
"yes": "Ja",
"no": "Nein",
"alreadyHaveOne": "ich habe bereits einen",
"nobleTitlesAreWritten": "Adelsnamen werden geschrieben"
}

52
messages/en.json Normal file
View File

@ -0,0 +1,52 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"invite": "We cordially invite you to take part in our exclusive New Year's Eve party, which this year will take place in the magical ambience of a masked ball. Immerse yourself in a night full of mystery, elegance and festive splendor.",
"welcome": "Welcome to the Masquerade Ball",
"acceptInvite": "Accept invite",
"nameTooLong": "We apologize, but this name is too long. (maximum 100 characters)",
"createNameWith": "We will draw {name} with",
"wantAlternativePersonality": "Would you like us to create an alternative personality for you?",
"wantNobleName": "Would you like to consider a worthy noble name for yourself?",
"yourNobleName": "Your noble name",
"nobleName":"Noble Title",
"name": "Surname",
"titleTooLong": "We apologize, but this title is too long. (maximum 100 characters)",
"hundredChars": "/100 characters",
"accept": "accept",
"newSuggestions": "new suggestions",
"titleSuggestions": "Noble name suggestions",
"shouldCreatePortrait": "Should our talented artists create a majestic portrait of you?",
"skinVeryBright": "very brighter",
"skinBright": "brighter",
"skinMedium": "medium",
"skinDark": "darker",
"skinVeryDark": "very darker",
"skinAnd": "skin and",
"hairTypeStraight": "straight",
"hairTypeCurly": "curly",
"hairTypeWavy": "wavy",
"hairLengthLong": "long",
"hairLengthMedium": "medium-long",
"hairLengthShort": "short",
"hairColorRed": "red",
"hairColorBlack": "black",
"hairColorBlond": "blond",
"hairColorBrown": "brown",
"hairDrawing": "hair",
"paintPortrait": "paint portrait (~15 seconds)",
"portraitIsBeingDrawn": "Your noble face will be painted",
"acceptPortrait": "Accept portrait",
"requestNewPortrait": "Request a new portrait",
"invitationIsBeingSend": "Invitation is sent",
"sendInvitation": "Send invitation",
"guestGallery": "Gallery of guests",
"howSureAppearing": "How confident can we be of your brilliant appearance?",
"howName": "What are your first and last names, noble guest?",
"saveName": "Save name",
"notAtAll": "not at all",
"very": "very",
"yes": "Yes",
"no": "No",
"alreadyHaveOne": "I already have one",
"nobleTitlesAreWritten": "Noble names are written"
}

View File

@ -13,6 +13,8 @@
"compress-s3": "bun ./bin/compress_s3.ts" "compress-s3": "bun ./bin/compress_s3.ts"
}, },
"devDependencies": { "devDependencies": {
"@inlang/paraglide-js": "1.0.0-prerelease.12",
"@inlang/paraglide-js-adapter-vite": "1.0.0-prerelease.2",
"@sveltejs/adapter-node": "^1.3.1", "@sveltejs/adapter-node": "^1.3.1",
"@sveltejs/kit": "^1.27.5", "@sveltejs/kit": "^1.27.5",
"@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/eslint-plugin": "^6.10.0",

View File

@ -1,5 +1,9 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies: dependencies:
googleapis: googleapis:
specifier: ^128.0.0 specifier: ^128.0.0
@ -18,6 +22,12 @@ dependencies:
version: 0.32.6 version: 0.32.6
devDependencies: devDependencies:
'@inlang/paraglide-js':
specifier: 1.0.0-prerelease.12
version: 1.0.0-prerelease.12
'@inlang/paraglide-js-adapter-vite':
specifier: 1.0.0-prerelease.2
version: 1.0.0-prerelease.2
'@sveltejs/adapter-node': '@sveltejs/adapter-node':
specifier: ^1.3.1 specifier: ^1.3.1
version: 1.3.1(@sveltejs/kit@1.27.5) version: 1.3.1(@sveltejs/kit@1.27.5)
@ -339,6 +349,138 @@ packages:
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
dev: true dev: true
/@inlang/json-types@1.1.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-n6vS6AqETsCFbV4TdBvR/EH57waVXzKsMqeUQ+eH2Q6NUATfKhfLabgNms2A+QV3aedH/hLtb1pRmjl2ykBVZg==}
peerDependencies:
'@sinclair/typebox': ^0.31.0
dependencies:
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/language-tag@1.2.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-AwKNPYPgJrhM9ebEYQvcG5PGM4v79jMPlsv2bUYEhEZzMpwIJKQo4t7P7EekMhO086sXOmeTu410Lm8abX/2Yw==}
peerDependencies:
'@sinclair/typebox': ^0.31.0
dependencies:
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/message-lint-rule@1.4.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-imOvpxKFP2ESaWTI5W5aQiW1ukvXMvGa4KhVknssfA1ZkCkVu2EDM4aGxw11U5Rli4QQ70bxztUvfLVhd3J84A==}
peerDependencies:
'@sinclair/typebox': ^0.31.17
dependencies:
'@inlang/json-types': 1.1.0(@sinclair/typebox@0.31.28)
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@inlang/message': 2.0.0(@sinclair/typebox@0.31.28)
'@inlang/project-settings': 2.2.0(@sinclair/typebox@0.31.28)
'@inlang/translatable': 1.2.0(@sinclair/typebox@0.31.28)
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/message@2.0.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-RPFcbega2Cnxi78d08O7SbuXyuhEqsB819QjgloNTXWtlBFwVDkF87xAMIZN37hpM6JZzMaYv2O1ipyncU3Ccg==}
peerDependencies:
'@sinclair/typebox': ^0.31.0
dependencies:
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/module@1.2.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-Z91zJUgliX+ddfRK+Ce4aZYlMjeNwZJOMmJ2dEUgg2cfqIFRB+gDsC5gLEY5LTkZspf/XUHoECTpK8ErVVYF5w==}
peerDependencies:
'@sinclair/typebox': ^0.31.17
dependencies:
'@inlang/message-lint-rule': 1.4.0(@sinclair/typebox@0.31.28)
'@inlang/plugin': 2.4.0(@sinclair/typebox@0.31.28)
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/paraglide-js-adapter-unplugin@1.0.0-prerelease.2:
resolution: {integrity: sha512-Z2AGwc5zLkZyhDjlD/W17uASttlxalgnMUfT8gcsjBOEHr4h1KV6zJfo8mha0/YQRpSveBPbRhruY+4EQ6CNvA==}
dependencies:
'@inlang/paraglide-js': 1.0.0-prerelease.12
'@inlang/sdk': 0.18.0
kleur: 4.1.5
unplugin: 1.5.1
transitivePeerDependencies:
- babel-plugin-macros
dev: true
/@inlang/paraglide-js-adapter-vite@1.0.0-prerelease.2:
resolution: {integrity: sha512-M1Za1FUlR7wKUnA8wIJkLO+Z0gEr/WU7EJ1KZsmPzJFE7NUuKqYTqgTqumEWGo23p1XJ/cAQOzXNLKYzbqK3Ug==}
dependencies:
'@inlang/paraglide-js-adapter-unplugin': 1.0.0-prerelease.2
transitivePeerDependencies:
- babel-plugin-macros
dev: true
/@inlang/paraglide-js@1.0.0-prerelease.12:
resolution: {integrity: sha512-YOXpLYfG8XgdinF6ZSEB0TQPtvXGQzLTbhxJY7aGBJzt+zmAtqaXpxresw7Hp++7EBd/2DMmMiiuKz6ch3OzrA==}
hasBin: true
dev: true
/@inlang/plugin@2.4.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-4+T7ZfuqcW4GFp3G+Vb+RTlYF8kKPY/BH0BcvOV2HX5B9UzgyC+dpXiI3TRQTUj7vz0yqp4K+onsaehPb2NGvw==}
peerDependencies:
'@sinclair/typebox': ^0.31.17
dependencies:
'@inlang/json-types': 1.1.0(@sinclair/typebox@0.31.28)
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@inlang/message': 2.0.0(@sinclair/typebox@0.31.28)
'@inlang/project-settings': 2.2.0(@sinclair/typebox@0.31.28)
'@inlang/translatable': 1.2.0(@sinclair/typebox@0.31.28)
'@lix-js/fs': 0.4.0
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/project-settings@2.2.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-M1D150KYiYoyiHhQp627zhvo/w/M1B11ROEu2u7Jn9005mKEWZS1DDlEOsLuNRl5doHSPHfkGa9qItMtrqr0dA==}
peerDependencies:
'@sinclair/typebox': ^0.31.0
dependencies:
'@inlang/json-types': 1.1.0(@sinclair/typebox@0.31.28)
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@sinclair/typebox': 0.31.28
dev: true
/@inlang/result@1.1.0:
resolution: {integrity: sha512-zLGroi9EUiHuOjUOaglUVTFO7EWdo2OARMJLBO1Q5Ga/xJmSQb6XS1lhqEXBFAjgFarfEMX5YEJWWALogYV3wA==}
dev: true
/@inlang/sdk@0.18.0:
resolution: {integrity: sha512-HLZhR+w3gxoSs5sTUFIaSVjX7XPkTCzOzd1/QzdMVlRXucSTXViztJ6UJZ3aULAkuixfnkMSS1WfjE9TA1SOeA==}
engines: {node: '>=18.0.0'}
dependencies:
'@inlang/json-types': 1.1.0(@sinclair/typebox@0.31.28)
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@inlang/message': 2.0.0(@sinclair/typebox@0.31.28)
'@inlang/message-lint-rule': 1.4.0(@sinclair/typebox@0.31.28)
'@inlang/module': 1.2.0(@sinclair/typebox@0.31.28)
'@inlang/plugin': 2.4.0(@sinclair/typebox@0.31.28)
'@inlang/project-settings': 2.2.0(@sinclair/typebox@0.31.28)
'@inlang/result': 1.1.0
'@inlang/translatable': 1.2.0(@sinclair/typebox@0.31.28)
'@lix-js/fs': 0.4.0
'@sinclair/typebox': 0.31.28
dedent: 1.5.1
deepmerge-ts: 5.1.0
solid-js: 1.6.12
throttle-debounce: 5.0.0
transitivePeerDependencies:
- babel-plugin-macros
dev: true
/@inlang/translatable@1.2.0(@sinclair/typebox@0.31.28):
resolution: {integrity: sha512-Od/nBm3qigfSpYJKu/Isg0rb34ohZApNk+fOtmZ0vBZXsTBzKaYFW0SeBVqwociRCr1tj40N659Ky+RoyLcv8A==}
peerDependencies:
'@sinclair/typebox': ^0.31.0
dependencies:
'@inlang/language-tag': 1.2.0(@sinclair/typebox@0.31.28)
'@sinclair/typebox': 0.31.28
dev: true
/@jridgewell/gen-mapping@0.3.3: /@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
@ -369,6 +511,12 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
dev: true dev: true
/@lix-js/fs@0.4.0:
resolution: {integrity: sha512-IOno98FwY+TPinwXzg5dx6xkCwyBCvkv6DMAQjI1Us4rvI9zObfjXd4E2VIGyT7vfUhpXIs4KXmne+onkCDzsg==}
dependencies:
js-base64: 3.7.5
dev: true
/@nodelib/fs.scandir@2.1.5: /@nodelib/fs.scandir@2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -458,6 +606,10 @@ packages:
rollup: 3.29.4 rollup: 3.29.4
dev: true dev: true
/@sinclair/typebox@0.31.28:
resolution: {integrity: sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ==}
dev: true
/@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.27.5): /@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.27.5):
resolution: {integrity: sha512-A0VgRQDCDPzdLNoiAbcOxGw4zT1Mc+n1LwT1OmO350R7WxrEqdMUChPPOd1iMfIDWlP4ie6E2d/WQf5es2d4Zw==} resolution: {integrity: sha512-A0VgRQDCDPzdLNoiAbcOxGw4zT1Mc+n1LwT1OmO350R7WxrEqdMUChPPOd1iMfIDWlP4ie6E2d/WQf5es2d4Zw==}
peerDependencies: peerDependencies:
@ -1019,6 +1171,10 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/csstype@3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
dev: true
/debug@4.3.4: /debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -1042,6 +1198,15 @@ packages:
mimic-response: 3.1.0 mimic-response: 3.1.0
dev: false dev: false
/dedent@1.5.1:
resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==}
peerDependencies:
babel-plugin-macros: ^3.1.0
peerDependenciesMeta:
babel-plugin-macros:
optional: true
dev: true
/deep-extend@0.6.0: /deep-extend@0.6.0:
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}
@ -1051,6 +1216,11 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true dev: true
/deepmerge-ts@5.1.0:
resolution: {integrity: sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==}
engines: {node: '>=16.0.0'}
dev: true
/deepmerge@4.3.1: /deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1819,6 +1989,10 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true dev: true
/js-base64@3.7.5:
resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==}
dev: true
/js-yaml@4.1.0: /js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true hasBin: true
@ -2506,6 +2680,12 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/solid-js@1.6.12:
resolution: {integrity: sha512-JFqRobfG3q5r1l4RYVOAukk6+FWtHpXGIjgh/GEsHKweN/kK+iHOtzUALE6+P5t/jIcSNeGiVitX8gmJg+cYvQ==}
dependencies:
csstype: 3.1.2
dev: true
/sorcery@0.11.0: /sorcery@0.11.0:
resolution: {integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==} resolution: {integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==}
hasBin: true hasBin: true
@ -2744,6 +2924,11 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true dev: true
/throttle-debounce@5.0.0:
resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==}
engines: {node: '>=12.22'}
dev: true
/through2@4.0.2: /through2@4.0.2:
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
dependencies: dependencies:
@ -2821,6 +3006,15 @@ packages:
'@fastify/busboy': 2.0.0 '@fastify/busboy': 2.0.0
dev: true dev: true
/unplugin@1.5.1:
resolution: {integrity: sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==}
dependencies:
acorn: 8.11.2
chokidar: 3.5.3
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.1
dev: true
/uri-js@4.4.1: /uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies: dependencies:
@ -2917,6 +3111,15 @@ packages:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: false dev: false
/webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
dev: true
/webpack-virtual-modules@0.6.1:
resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==}
dev: true
/whatwg-url@5.0.0: /whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies: dependencies:
@ -2975,7 +3178,3 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

19
project.inlang.json Normal file
View File

@ -0,0 +1,19 @@
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "de",
"languageTags": [
"en",
"de"
],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js"
],
"plugin.inlang.messageFormat": {
"pathPattern": "./messages/{languageTag}.json"
}
}

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import * as m from '$paraglide/messages';
export let min = 0; export let min = 0;
export let max = 100; export let max = 100;
export let value = 50; export let value = 50;
@ -6,8 +7,8 @@
<div class="wrapper"> <div class="wrapper">
<input type="range" {min} {max} bind:value step={10} /> <input type="range" {min} {max} bind:value step={10} />
<p class="left">gar nicht</p> <p class="left">{m.notAtAll()}</p>
<p class="right">sehr</p> <p class="right">{m.very()}</p>
</div> </div>
<style> <style>

View File

@ -0,0 +1,81 @@
<script lang="ts">
import {
availableLanguageTags,
setLanguageTag,
onSetLanguageTag,
sourceLanguageTag,
languageTag
} from '$paraglide/runtime';
import { getContext, setContext } from 'svelte';
import { page } from '$app/stores';
import { redirect } from '@sveltejs/kit';
// We check if the language tag is valid, if it is, we set it,
// if not, we redirect to the same page without the language tag
setContext(
'languageTag',
$page.params.lang
? (availableLanguageTags as readonly string[]).includes($page.params.lang)
? $page.params.lang
: (() => {
throw redirect(
302,
('/' + $page.url.href.split($page.params.lang)[1]).replace('//', '/')
);
})()
: sourceLanguageTag
);
setLanguageTag(() => getContext('languageTag'));
// We save the old language tag to check if the language tag has changed
let oldLanguageTag = languageTag();
if (import.meta.env.SSR === false) {
onSetLanguageTag((newLanguageTag) => {
// If the language tag is the same as the current language tag, we don't want to do anything
if (newLanguageTag === oldLanguageTag) return;
// If we set the language tag to the source language tag, we want to remove the language tag from the url
if (newLanguageTag === sourceLanguageTag) {
// this returns the route without the language tag
const route = window.location.href.match(/^https?:\/\/[^\/]+\/[^\/]*(\/.*)/);
// Redirect to the same page with the new language
window.location.href = route ? route[1] : '/';
// renew the old language tag
oldLanguageTag = newLanguageTag;
// if we set the language tag from the source language tag, we want to add the language tag to the url
} else if (oldLanguageTag === sourceLanguageTag) {
// this simply returns the route, since we don't have to remove the language tag,
// beacuse the preveous language was the source language.
// It also does not matter if for some reason "en" language tag is still given, it removes it anyway.
const route = window.location.href
.replace(/^https?:\/\/[^\/]+\/(en)(\/|$)/, '')
.match(/^https?:\/\/[^\/]+(\/.*)/);
// Redirect to the same page with the new language
window.location.href = route ? '/' + newLanguageTag + route[1] : '/' + newLanguageTag;
// renew the old language tag
oldLanguageTag = newLanguageTag;
// if we change the language tag not from and not to the source language, we want to keep the url
} else {
// this returns the route without the language tag
const route = window.location.href.match(/^https?:\/\/[^\/]+\/[^\/]*(\/.*)/);
// Redirect to the same page with the new language
window.location.href =
route && route[1] ? '/' + newLanguageTag + route[1] : '/' + newLanguageTag;
// renew the old language tag
oldLanguageTag = newLanguageTag;
}
});
}
</script>
<slot />

View File

@ -7,6 +7,7 @@
import InputRange from './InputRange.svelte'; import InputRange from './InputRange.svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import Loader from './Loader.svelte'; import Loader from './Loader.svelte';
import * as m from '$paraglide/messages';
let data = persisted<{ let data = persisted<{
name: string; name: string;
@ -104,32 +105,29 @@
<div class="wrapper"> <div class="wrapper">
<section in:slide={{ delay: 500 }}> <section in:slide={{ delay: 500 }}>
<TextSplit content="Wie lauten Euer Vor- und Nachname, edler Gast?" /> <TextSplit content={m.howName()} />
<input placeholder="Name" type="text" bind:value={$data.name} /> <input placeholder="Name" type="text" bind:value={$data.name} />
{#if $data.name.length > 99} {#if $data.name.length > 99}
<p class="error"> <p class="error">
Wir bitten um Entschuldigung, aber dieser Name ist zu lang. (maximal 100 Zeichen) {m.nameTooLong()}
</p> </p>
{:else if $data.showNameLengthError} {:else if $data.showNameLengthError}
<p class="hint">{$data.name.length}/100 Zeichen</p> <p class="hint">{$data.name.length}{m.hundredChars()}</p>
{/if} {/if}
{#if !$data.nameAccepted} {#if !$data.nameAccepted}
<button <button
disabled={$data.name.length > 99} disabled={$data.name.length > 99}
on:click={() => { on:click={() => {
$data.nameAccepted = true; $data.nameAccepted = true;
}}>Name speichern</button }}>{m.saveName()}</button
> >
{/if} {/if}
</section> </section>
{#if ($data.name && $data.nameAccepted) || $data.confidence !== undefined} {#if ($data.name && $data.nameAccepted) || $data.confidence !== undefined}
<section in:slide={{ delay: 0, duration: 500 }}> <section in:slide={{ delay: 0, duration: 500 }}>
<TextSplit <TextSplit content={m.howSureAppearing()} delay={0} />
content="Wie sicher dürfen wir mit Eurem glanzvollen Erscheinen rechnen?"
delay={0}
/>
<div in:fade={{ delay: 1200 }}> <div in:fade={{ delay: 1200 }}>
<InputRange bind:value={$data.confidence} /> <InputRange bind:value={$data.confidence} />
</div> </div>
@ -145,19 +143,17 @@
{#if $data.confidence !== undefined && $data.confidenceAccepted && $data.createPersonality === undefined} {#if $data.confidence !== undefined && $data.confidenceAccepted && $data.createPersonality === undefined}
<section in:slide out:slide> <section in:slide out:slide>
<TextSplit <TextSplit content={m.wantAlternativePersonality()} />
content="Möchtet Ihr, dass wir eine alternative Persönlichkeit für Euch erschaffen?"
/>
<div> <div>
<button <button
on:click={() => { on:click={() => {
$data.createPersonality = true; $data.createPersonality = true;
}}>Ja</button }}>{m.yes()}</button
> >
<button <button
on:click={() => { on:click={() => {
$data.createPersonality = false; $data.createPersonality = false;
}}>Nein</button }}>{m.no()}</button
> >
</div> </div>
{#if $data.adelsTitel} {#if $data.adelsTitel}
@ -169,7 +165,7 @@
{#if $data.createPersonality === true} {#if $data.createPersonality === true}
<section in:fade out:slide> <section in:fade out:slide>
{#if $data.provideAdelsTitel === undefined} {#if $data.provideAdelsTitel === undefined}
<TextSplit content="Möchtet Ihr einen würdigen Adelsnamen für Euch in Erwägung ziehen?" /> <TextSplit content={m.wantNobleName()} />
<div> <div>
<button <button
on:click={() => { on:click={() => {
@ -177,7 +173,7 @@
$data.provideAdelsTitel = true; $data.provideAdelsTitel = true;
}} }}
> >
ja</button {m.yes()}</button
> >
<button <button
on:click={() => { on:click={() => {
@ -185,7 +181,7 @@
$data.provideAdelsTitel = true; $data.provideAdelsTitel = true;
}} }}
> >
ich habe bereits einen {m.alreadyHaveOne()}
</button> </button>
<button <button
on:click={() => { on:click={() => {
@ -193,7 +189,7 @@
$data.provideAdelsTitel = false; $data.provideAdelsTitel = false;
}} }}
> >
nein</button {m.no()}</button
> >
</div> </div>
{/if} {/if}
@ -201,34 +197,34 @@
{#if loadingAdelsTitel} {#if loadingAdelsTitel}
<div style="display: flex; gap: 20px; align-items: center;"> <div style="display: flex; gap: 20px; align-items: center;">
<Loader /> <Loader />
<p>Adelsnamen werden geschrieben</p> <p>{m.nobleTitlesAreWritten()}</p>
</div> </div>
{:else if typeof $data.adelsTitel === 'string'} {:else if typeof $data.adelsTitel === 'string'}
<TextSplit content="Euer Adelsname" /> <TextSplit content={m.yourNobleName()} />
<input placeholder="Name" type="text" bind:value={$data.adelsTitel} /> <input placeholder={m.nobleName()} type="text" bind:value={$data.adelsTitel} />
{#if $data.adelsTitel.length > 98} {#if $data.adelsTitel.length > 98}
<p class="error"> <p class="error">
Wir bitten um Entschuldigung, aber dieser Titel ist zu lang. (maximal 100 Zeichen) {m.titleTooLong()}
</p> </p>
{:else if $data.showAdelsTitelLengthError} {:else if $data.showAdelsTitelLengthError}
<p class="hint">{$data.adelsTitel.length}/100 Zeichen</p> <p class="hint">{$data.adelsTitel.length}{m.hundredChars()}</p>
{/if} {/if}
{#if !$data.adelsTitelAccepted} {#if !$data.adelsTitelAccepted}
<button <button
disabled={$data.adelsTitel.length > 99} disabled={$data.adelsTitel.length > 99}
on:click={() => { on:click={() => {
$data.adelsTitelAccepted = true; $data.adelsTitelAccepted = true;
}}>akzeptieren</button }}>{m.accept()}</button
> >
<button <button
on:click={() => { on:click={() => {
$data.adelsTitel = undefined; $data.adelsTitel = undefined;
fetchAdelsTitel(); fetchAdelsTitel();
}}>neue vorschläge</button }}>{m.newSuggestions()}</button
> >
{/if} {/if}
{:else if $data.adelsTitelSuggestions?.length} {:else if $data.adelsTitelSuggestions?.length}
<p>Adelsname Vorschläge</p> <p>{m.titleSuggestions()}</p>
<hr /> <hr />
{#each $data.adelsTitelSuggestions as suggestion} {#each $data.adelsTitelSuggestions as suggestion}
<button <button
@ -241,7 +237,7 @@
<button <button
on:click={() => { on:click={() => {
fetchAdelsTitel(); fetchAdelsTitel();
}}>neue vorschläge</button }}>{m.newSuggestions()}</button
> >
{/if} {/if}
</section> </section>
@ -250,56 +246,55 @@
{#if $data.adelsTitel && $data.adelsTitelAccepted && $data.providePortrait !== false} {#if $data.adelsTitel && $data.adelsTitelAccepted && $data.providePortrait !== false}
<section transition:slide class="portrait-frame" class:loaded={!!$data.portraitUrl}> <section transition:slide class="portrait-frame" class:loaded={!!$data.portraitUrl}>
{#if $data.providePortrait === undefined} {#if $data.providePortrait === undefined}
<TextSplit <TextSplit content={m.shouldCreatePortrait()} />
content="Sollten unsere begabten Künstler ein majestätisches Porträt von Euch anfertigen?"
/>
<div> <div>
<button <button
on:click={() => { on:click={() => {
$data.providePortrait = true; $data.providePortrait = true;
}}>ja</button }}>{m.yes()}</button
> >
<button <button
on:click={() => { on:click={() => {
$data.providePortrait = true; $data.providePortrait = true;
}}>false</button }}>{m.no()}</button
> >
</div> </div>
{/if} {/if}
{#if $data.providePortrait && !loadingPortrait && !$data.portraitUrl} {#if $data.providePortrait && !loadingPortrait && !$data.portraitUrl}
<p> <p>
Wir werden {$data.adelsTitel || $data.name} mit {m.createNameWith({ name: $data.adelsTitel || $data.name })}
<select placeholder="Typ" bind:value={$data.portraitSkinColor}> <select placeholder="Typ" bind:value={$data.portraitSkinColor}>
<option value="very light">sehr heller</option> <option value="very light">{m.skinVeryBright()}</option>
<option value="light">heller</option> <option value="light">{m.skinBright()}</option>
<option value="medium">medium</option> <option value="medium">{m.skinMedium()}</option>
<option value="dark">dunkler</option> <option value="dark">{m.skinDark()}</option>
<option value="very dark">sehr dunkler</option> <option value="very dark">{m.skinVeryDark()}</option>
</select> </select>
Haut und {m.skinAnd()}
<select placeholder="Typ" bind:value={$data.portraitHairType}> <select placeholder="Typ" bind:value={$data.portraitHairType}>
<option value="straight">glatten</option> <option value="straight">{m.hairTypeStraight()}</option>
<option value="curly">lockigen</option> <option value="curly">{m.hairTypeCurly()}</option>
<option value="wavy">welligen</option> <option value="wavy">{m.hairTypeWavy()}</option>
</select> </select>
<select placeholder="Länge" bind:value={$data.portraitHairLength}> <select placeholder="Länge" bind:value={$data.portraitHairLength}>
<option value="long">langen</option> <option value="long">{m.hairLengthLong()}</option>
<option value="medium">medium-langen</option> <option value="medium">{m.hairLengthMedium()}</option>
<option value="short">kurzen</option> <option value="short">{m.hairLengthShort()}</option>
</select>, </select>,
<select placeholder="Farbe" bind:value={$data.portraitHairColor}> <select placeholder="Farbe" bind:value={$data.portraitHairColor}>
<option value="red">roten</option> <option value="red">{m.hairColorRed()}</option>
<option value="black">schwarzen</option> <option value="black">{m.hairColorBlack()}</option>
<option value="blond">blonden</option> <option value="blond">{m.hairColorBlond()}</option>
<option value="brown">braunen</option> <option value="brown">{m.hairColorBrown()}</option>
</select> Haaren zeichnen </select>
{m.hairDrawing()}
</p> </p>
<button on:click={() => fetchPortrait()}> porträt malen (~15 Sekunden)</button> <button on:click={() => fetchPortrait()}> {m.paintPortrait()}</button>
{:else if loadingPortrait} {:else if loadingPortrait}
<div style="display: flex; gap: 20px; align-items: center;"> <div style="display: flex; gap: 20px; align-items: center;">
<Loader /> <Loader />
<p>Euer edles Antlitz wird gemalt</p> <p>{m.portraitIsBeingDrawn()}</p>
</div> </div>
{:else if $data.portraitUrl} {:else if $data.portraitUrl}
<div in:slide={{ duration: 2000 }} class="portrait"> <div in:slide={{ duration: 2000 }} class="portrait">
@ -309,12 +304,12 @@
<button <button
on:click={() => { on:click={() => {
$data.portraitAccepted = true; $data.portraitAccepted = true;
}}>Porträt annehmen</button }}>{m.acceptPortrait()}</button
> >
<button <button
on:click={() => { on:click={() => {
$data.portraitUrl = undefined; $data.portraitUrl = undefined;
}}>Neues Porträt anfordern</button }}>{m.requestNewPortrait()}</button
> >
{/if} {/if}
</div> </div>
@ -327,12 +322,12 @@
<section in:slide style="border: none;"> <section in:slide style="border: none;">
<div style="display: flex; gap: 20px; align-items: center;"> <div style="display: flex; gap: 20px; align-items: center;">
<Loader /> <Loader />
<p>Einladung wird abgeschickt</p> <p>{m.invitationIsBeingSend()}</p>
</div> </div>
</section> </section>
{:else} {:else}
<div class="button-wrapper"> <div class="button-wrapper">
<Button on:click={() => submit()}>Einladung versenden</Button> <Button on:click={() => submit()}>{m.sendInvitation()}</Button>
</div> </div>
{/if} {/if}
{/if} {/if}

View File

@ -1,7 +1,8 @@
<script lang="ts"> <script lang="ts">
import * as m from '$paraglide/messages';
</script> </script>
<p>Willkommen zum Maskenball</p> <p>{m.welcome()}</p>
<style> <style>
p { p {

View File

@ -0,0 +1,27 @@
import type { LayoutServerLoad } from "./$types";
import { availableLanguageTags } from "$paraglide/runtime";
import { redirect } from "@sveltejs/kit";
type AvailableLanguages = typeof availableLanguageTags[number];
export const load: LayoutServerLoad = function ({ request, cookies }) {
const url = new URL(request.url);
let language = cookies.get("lang") as unknown as AvailableLanguages;
const acceptLanguage = request.headers.get('accept-language')?.split(",")?.[0]?.split("-")?.[0] as AvailableLanguages;
if (!language || !availableLanguageTags.includes(language)) {
if (availableLanguageTags.includes(acceptLanguage)) {
language = acceptLanguage;
cookies.set("lang", language);
} else {
language = "de"
}
}
if (!url.pathname.startsWith("/" + language) && language !== "de") {
throw redirect(302, `/${language}/${url.pathname}`.replaceAll("//", "/"))
}
return
}

View File

@ -1,5 +1,8 @@
<script lang="ts"> <script lang="ts">
import ParaglideAdapter from '$lib/components/ParaglideAdapter.svelte';
import './global.css'; import './global.css';
</script> </script>
<slot /> <ParaglideAdapter>
<slot />
</ParaglideAdapter>

View File

@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import Loader from '$lib/components/Loader.svelte';
import Questions from '$lib/components/Questions.svelte'; import Questions from '$lib/components/Questions.svelte';
import TextSplit from '$lib/components/TextSplit.svelte'; import TextSplit from '$lib/components/TextSplit.svelte';
import Button from '$lib/components/button.svelte'; import Button from '$lib/components/button.svelte';
@ -9,6 +8,7 @@
import Maskenball from '$lib/components/maskenball.svelte'; import Maskenball from '$lib/components/maskenball.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import * as m from '$paraglide/messages';
let curtainsVisible = false; let curtainsVisible = false;
let buttonVisible = false; let buttonVisible = false;
@ -59,10 +59,7 @@
{#if contentVisible} {#if contentVisible}
<div class="einladung" out:fade> <div class="einladung" out:fade>
<TextSplit <TextSplit center content={m.invite()} />
center
content="Wir laden dich herzlich ein, an unserer exklusiven Silvesterparty teilzunehmen, die dieses Jahr im magischen Ambiente eines Maskenballs stattfindet. Tauche ein in eine Nacht voller Geheimnisse, Eleganz und festlichem Glanz."
/>
<span in:fade={{ delay: 8000, duration: 1000 }}> <span in:fade={{ delay: 8000, duration: 1000 }}>
<Button <Button
@ -70,7 +67,7 @@
on:click={() => { on:click={() => {
contentVisible = false; contentVisible = false;
questionVisible = true; questionVisible = true;
}}>Einladung annehmen</Button }}>{m.acceptInvite()}</Button
> >
</span> </span>
</div> </div>

View File

@ -2,6 +2,7 @@
import ImageFrame from '$lib/components/ImageFrame.svelte'; import ImageFrame from '$lib/components/ImageFrame.svelte';
import Confetti from '$lib/components/confetti.svelte'; import Confetti from '$lib/components/confetti.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import * as m from '$paraglide/messages';
export let data; export let data;
@ -29,7 +30,7 @@
</svelte:head> </svelte:head>
<div class="wrapper"> <div class="wrapper">
<h1>Gallerie der Gäste</h1> <h1>{m.guestGallery()}</h1>
<div class="grid"> <div class="grid">
{#each items as item} {#each items as item}
<div <div

3
src/routes/load.ts Normal file
View File

@ -0,0 +1,3 @@
export const load: Handler = async (req, res) => {
};

View File

@ -11,8 +11,11 @@ const config = {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter. // If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters. // See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter() adapter: adapter(),
} alias: {
$paraglide: "./src/paraglide",
},
},
}; };
export default config; export default config;

View File

@ -1,17 +1,18 @@
{ {
"extends": "./.svelte-kit/tsconfig.json", "extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"allowJs": true, "allowJs": true,
"checkJs": true, "checkJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "moduleResolution": "Bundler",
"sourceMap": true, "skipLibCheck": true,
"strict": true "sourceMap": true,
} "strict": true
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias }
// // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes //
// from the referenced tsconfig.json - TypeScript does not merge them in // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
} }

View File

@ -1,6 +1,18 @@
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import { paraglide } from "@inlang/paraglide-js-adapter-vite"
import path from "path"
export default defineConfig({ export default defineConfig({
plugins: [sveltekit()] plugins: [sveltekit(), paraglide({
project: "./project.inlang.json",
outdir: "./src/paraglide"
})],
resolve: {
alias: {
// This is the alias you can use in your code
// you can change it to whatever you want
"$paraglide": path.resolve(__dirname, "src/paraglide")
}
}
}); });