mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-12 21:05:19 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e98909f11 | |||
| a6f1c3cecd |
@@ -3,3 +3,9 @@
|
||||
.col-result-md { width: 20%; }
|
||||
|
||||
.modal-content > turbo-frame { display: contents; }
|
||||
|
||||
.release-notes {
|
||||
overflow-wrap: break-word;
|
||||
|
||||
> :last-child { margin-bottom: 0; }
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"doctrine/doctrine-bundle": "^3.2.2",
|
||||
"doctrine/doctrine-migrations-bundle": "^4.0",
|
||||
"doctrine/orm": "^3.6.2",
|
||||
"league/commonmark": "^2.7",
|
||||
"martin-georgiev/postgresql-for-doctrine": "^4.4",
|
||||
"phpdocumentor/reflection-docblock": "^6.0.3",
|
||||
"phpoffice/phpspreadsheet": "^5.5",
|
||||
@@ -27,6 +28,7 @@
|
||||
"symfony/flex": "^2.11.0",
|
||||
"symfony/form": "8.1.*",
|
||||
"symfony/framework-bundle": "8.1.*",
|
||||
"symfony/http-client": "8.1.*",
|
||||
"symfony/mailer": "8.1.*",
|
||||
"symfony/object-mapper": "8.1.*",
|
||||
"symfony/property-access": "8.1.*",
|
||||
@@ -48,6 +50,7 @@
|
||||
"thecodingmachine/safe": "^3.4.0",
|
||||
"twig/extra-bundle": "^3.24.0",
|
||||
"twig/intl-extra": "^3.24.0",
|
||||
"twig/markdown-extra": "^3.24.0",
|
||||
"twig/twig": "^3.27.1"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
Generated
+495
-1
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ccae654dd9c952e8920d9cb9c0f35ff5",
|
||||
"content-hash": "519e76dd9df3bca43c3e32e347c600e7",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
@@ -159,6 +159,81 @@
|
||||
],
|
||||
"time": "2025-08-20T19:15:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
|
||||
"reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f",
|
||||
"reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.42",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
|
||||
"scrutinizer/ocular": "1.6.0",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"vimeo/psalm": "^4.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dflydev\\DotAccessData\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dragonfly Development Inc.",
|
||||
"email": "info@dflydev.com",
|
||||
"homepage": "http://dflydev.com"
|
||||
},
|
||||
{
|
||||
"name": "Beau Simensen",
|
||||
"email": "beau@dflydev.com",
|
||||
"homepage": "http://beausimensen.com"
|
||||
},
|
||||
{
|
||||
"name": "Carlos Frutos",
|
||||
"email": "carlos@kiwing.it",
|
||||
"homepage": "https://github.com/cfrutos"
|
||||
},
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com"
|
||||
}
|
||||
],
|
||||
"description": "Given a deep data structure, access data by dot notation.",
|
||||
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
|
||||
"keywords": [
|
||||
"access",
|
||||
"data",
|
||||
"dot",
|
||||
"notation"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
|
||||
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3"
|
||||
},
|
||||
"time": "2024-07-08T12:26:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
"version": "2.6.0",
|
||||
@@ -1652,6 +1727,195 @@
|
||||
},
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "1902f60f984235023acbe03db6ad614a37b3c3e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/1902f60f984235023acbe03db6ad614a37b3c3e7",
|
||||
"reference": "1902f60f984235023acbe03db6ad614a37b3c3e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"league/config": "^1.1.1",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.1 || ^3.0",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"cebe/markdown": "^1.0",
|
||||
"commonmark/cmark": "0.31.1",
|
||||
"commonmark/commonmark.js": "0.31.1",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"embed/embed": "^4.4",
|
||||
"erusev/parsedown": "^1.0",
|
||||
"ext-json": "*",
|
||||
"github/gfm": "0.29.0",
|
||||
"michelf/php-markdown": "^1.4 || ^2.0",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"phpstan/phpstan": "^2.0.0",
|
||||
"phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0 || ^12.0.0 || ^13.0.0",
|
||||
"scrutinizer/ocular": "^1.8.1",
|
||||
"symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0",
|
||||
"symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0",
|
||||
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0",
|
||||
"unleashedtech/php-coding-standard": "^3.1.1",
|
||||
"vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\CommonMark\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
|
||||
"homepage": "https://commonmark.thephpleague.com",
|
||||
"keywords": [
|
||||
"commonmark",
|
||||
"flavored",
|
||||
"gfm",
|
||||
"github",
|
||||
"github-flavored",
|
||||
"markdown",
|
||||
"md",
|
||||
"parser"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://commonmark.thephpleague.com/",
|
||||
"forum": "https://github.com/thephpleague/commonmark/discussions",
|
||||
"issues": "https://github.com/thephpleague/commonmark/issues",
|
||||
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
|
||||
"source": "https://github.com/thephpleague/commonmark"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.colinodell.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.paypal.me/colinpodell/10.00",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/colinodell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-07-12T15:29:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/config",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/config.git",
|
||||
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
|
||||
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dflydev/dot-access-data": "^3.0.1",
|
||||
"nette/schema": "^1.2",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.8.2",
|
||||
"phpunit/phpunit": "^9.5.5",
|
||||
"scrutinizer/ocular": "^1.8.1",
|
||||
"unleashedtech/php-coding-standard": "^3.1",
|
||||
"vimeo/psalm": "^4.7.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Config\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Define configuration arrays with strict schemas and access values with dot notation",
|
||||
"homepage": "https://config.thephpleague.com",
|
||||
"keywords": [
|
||||
"array",
|
||||
"config",
|
||||
"configuration",
|
||||
"dot",
|
||||
"dot-access",
|
||||
"nested",
|
||||
"schema"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://config.thephpleague.com/",
|
||||
"issues": "https://github.com/thephpleague/config/issues",
|
||||
"rss": "https://github.com/thephpleague/config/releases.atom",
|
||||
"source": "https://github.com/thephpleague/config"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.colinodell.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.paypal.me/colinpodell/10.00",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/colinodell",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-11T20:36:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
"version": "3.2.2",
|
||||
@@ -1966,6 +2230,164 @@
|
||||
],
|
||||
"time": "2026-07-01T18:17:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/schema.git",
|
||||
"reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002",
|
||||
"reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nette/utils": "^4.0",
|
||||
"php": "8.1 - 8.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/phpstan-rules": "^1.0",
|
||||
"nette/tester": "^2.6",
|
||||
"phpstan/extension-installer": "^1.4@stable",
|
||||
"phpstan/phpstan": "^2.1.39@stable",
|
||||
"tracy/tracy": "^2.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nette\\": "src"
|
||||
},
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause",
|
||||
"GPL-2.0-only",
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Grudl",
|
||||
"homepage": "https://davidgrudl.com"
|
||||
},
|
||||
{
|
||||
"name": "Nette Community",
|
||||
"homepage": "https://nette.org/contributors"
|
||||
}
|
||||
],
|
||||
"description": "📐 Nette Schema: validating data structures against a given Schema.",
|
||||
"homepage": "https://nette.org",
|
||||
"keywords": [
|
||||
"config",
|
||||
"nette"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/schema/issues",
|
||||
"source": "https://github.com/nette/schema/tree/v1.3.5"
|
||||
},
|
||||
"time": "2026-02-23T03:47:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
"version": "v4.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/utils.git",
|
||||
"reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7",
|
||||
"reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "8.2 - 8.5"
|
||||
},
|
||||
"conflict": {
|
||||
"nette/finder": "<3",
|
||||
"nette/schema": "<1.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"jetbrains/phpstorm-attributes": "^1.2",
|
||||
"nette/phpstan-rules": "^1.0",
|
||||
"nette/tester": "^2.5",
|
||||
"phpstan/extension-installer": "^1.4@stable",
|
||||
"phpstan/phpstan": "^2.1@stable",
|
||||
"tracy/tracy": "^2.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "to use Image",
|
||||
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
|
||||
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
|
||||
"ext-json": "to use Nette\\Utils\\Json",
|
||||
"ext-mbstring": "to use Strings::lower() etc...",
|
||||
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nette\\": "src"
|
||||
},
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause",
|
||||
"GPL-2.0-only",
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Grudl",
|
||||
"homepage": "https://davidgrudl.com"
|
||||
},
|
||||
{
|
||||
"name": "Nette Community",
|
||||
"homepage": "https://nette.org/contributors"
|
||||
}
|
||||
],
|
||||
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
|
||||
"homepage": "https://nette.org",
|
||||
"keywords": [
|
||||
"array",
|
||||
"core",
|
||||
"datetime",
|
||||
"images",
|
||||
"json",
|
||||
"nette",
|
||||
"paginator",
|
||||
"password",
|
||||
"slugify",
|
||||
"string",
|
||||
"unicode",
|
||||
"utf-8",
|
||||
"utility",
|
||||
"validation"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/utils/issues",
|
||||
"source": "https://github.com/nette/utils/tree/v4.1.4"
|
||||
},
|
||||
"time": "2026-05-11T20:49:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
"version": "2.2.0",
|
||||
@@ -8711,6 +9133,78 @@
|
||||
],
|
||||
"time": "2026-05-19T20:44:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/markdown-extra",
|
||||
"version": "v3.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/markdown-extra.git",
|
||||
"reference": "5f7b27e41a382fc988fffa6e588d8f9d55b9d896"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/5f7b27e41a382fc988fffa6e588d8f9d55b9d896",
|
||||
"reference": "5f7b27e41a382fc988fffa6e588d8f9d55b9d896",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"twig/twig": "^3.13|^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"erusev/parsedown": "dev-master as 1.x-dev",
|
||||
"league/commonmark": "^2.7",
|
||||
"league/html-to-markdown": "^4.8|^5.0",
|
||||
"michelf/php-markdown": "^1.8|^2.0",
|
||||
"symfony/phpunit-bridge": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Twig\\Extra\\Markdown\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "A Twig extension for Markdown",
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"keywords": [
|
||||
"html",
|
||||
"markdown",
|
||||
"twig"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/twigphp/markdown-extra/tree/v3.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-06-05T19:47:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.28.0",
|
||||
|
||||
@@ -30,6 +30,7 @@ security:
|
||||
|
||||
access_control:
|
||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||
- { path: ^/backoffice/releases$, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/backoffice, roles: IS_AUTHENTICATED }
|
||||
|
||||
when@test:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
twig_extra:
|
||||
commonmark:
|
||||
allow_unsafe_links: false
|
||||
html_input: escape
|
||||
|
||||
services:
|
||||
League\CommonMark\Extension\Autolink\AutolinkExtension:
|
||||
tags: ['twig.markdown.league_extension']
|
||||
Generated
+1
-1
@@ -1271,7 +1271,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* },
|
||||
* markdown?: bool|array{
|
||||
* enabled?: bool|Param, // Default: false
|
||||
* enabled?: bool|Param, // Default: true
|
||||
* },
|
||||
* intl?: bool|array{
|
||||
* enabled?: bool|Param, // Default: true
|
||||
|
||||
@@ -33,6 +33,10 @@ if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# var/ is a Docker volume that survives redeploys, so cache.app (e.g. the GitHub releases cache)
|
||||
# can carry stale entries from the previous image into the new one unless cleared here.
|
||||
php bin/console cache:pool:clear cache.app
|
||||
|
||||
setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
|
||||
setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Controller\Backoffice;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Tvdt\Controller\AbstractController;
|
||||
use Tvdt\Service\GitHubReleasesService;
|
||||
|
||||
final class ReleasesController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GitHubReleasesService $gitHubReleasesService,
|
||||
) {}
|
||||
|
||||
#[Route('/backoffice/releases', name: 'tvdt_backoffice_releases', methods: ['GET'])]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('backoffice/releases/_frame.html.twig', [
|
||||
'releases' => $this->gitHubReleasesService->getReleases(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,7 @@ class DataExportService
|
||||
}
|
||||
}
|
||||
|
||||
/** Raw crosstab: one row per candidate, one column per question, cell = the answer text they gave. */
|
||||
/** Raw crosstab: one row per candidate, one column per question, cell = the answer text they gave (bold when correct). */
|
||||
private function fillRawAnswersSheet(Worksheet $sheet, Quiz $quiz): void
|
||||
{
|
||||
/** @var list<Question> $questions */
|
||||
@@ -240,11 +240,14 @@ class DataExportService
|
||||
|
||||
/** @var array<string, array<string, string>> $answersByCandidateAndQuestion */
|
||||
$answersByCandidateAndQuestion = [];
|
||||
/** @var array<string, array<string, bool>> $correctnessByCandidateAndQuestion */
|
||||
$correctnessByCandidateAndQuestion = [];
|
||||
foreach ($questions as $question) {
|
||||
foreach ($question->answers as $answer) {
|
||||
foreach ($answer->givenAnswers as $givenAnswer) {
|
||||
$candidateId = $givenAnswer->candidate->id->toString();
|
||||
$answersByCandidateAndQuestion[$candidateId][$question->id->toString()] = $answer->text;
|
||||
$correctnessByCandidateAndQuestion[$candidateId][$question->id->toString()] = $answer->isRightAnswer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,13 +255,22 @@ class DataExportService
|
||||
$row = 2;
|
||||
foreach ($quiz->candidateData as $quizCandidate) {
|
||||
$candidate = $quizCandidate->candidate;
|
||||
$candidateId = $candidate->id->toString();
|
||||
|
||||
$line = [$candidate->name];
|
||||
foreach ($questions as $question) {
|
||||
$line[] = $answersByCandidateAndQuestion[$candidate->id->toString()][$question->id->toString()] ?? '';
|
||||
$line[] = $answersByCandidateAndQuestion[$candidateId][$question->id->toString()] ?? '';
|
||||
}
|
||||
|
||||
$sheet->fromArray($line, null, 'A'.$row);
|
||||
|
||||
foreach ($questions as $columnIndex => $question) {
|
||||
if ($correctnessByCandidateAndQuestion[$candidateId][$question->id->toString()] ?? false) {
|
||||
$column = Coordinate::stringFromColumnIndex(2 + $columnIndex);
|
||||
$sheet->getStyle($column.$row)->getFont()->setBold(true);
|
||||
}
|
||||
}
|
||||
|
||||
++$row;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Service;
|
||||
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
final readonly class GitHubReleasesService
|
||||
{
|
||||
private const string RELEASES_URL = 'https://api.github.com/repos/MarijnDoeve/TijdVoorDeTest/releases';
|
||||
|
||||
public function __construct(
|
||||
private HttpClientInterface $httpClient,
|
||||
private CacheInterface $cache,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return list<array{tagName: string, name: string, publishedAt: ?\DateTimeImmutable, body: string, url: string}>
|
||||
*/
|
||||
public function getReleases(): array
|
||||
{
|
||||
return $this->cache->get('github_releases', $this->fetchReleases(...));
|
||||
}
|
||||
|
||||
/** @return list<array{tagName: string, name: string, publishedAt: ?\DateTimeImmutable, body: string, url: string}> */
|
||||
private function fetchReleases(ItemInterface $item, bool &$save): array
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->request('GET', self::RELEASES_URL, [
|
||||
'timeout' => 5,
|
||||
'headers' => [
|
||||
'Accept' => 'application/vnd.github+json',
|
||||
'User-Agent' => 'TijdVoorDeTest',
|
||||
],
|
||||
]);
|
||||
|
||||
/** @var list<array{tag_name: string, name: ?string, published_at: ?string, body: ?string, html_url: string}> $releases */
|
||||
$releases = $response->toArray();
|
||||
} catch (ExceptionInterface) {
|
||||
$save = false;
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$item->expiresAfter(3600);
|
||||
|
||||
usort($releases, static fn (array $a, array $b): int => ($b['published_at'] ?? '') <=> ($a['published_at'] ?? ''));
|
||||
|
||||
return array_map(static fn (array $release): array => [
|
||||
'tagName' => $release['tag_name'],
|
||||
'name' => $release['name'] ?: $release['tag_name'],
|
||||
'publishedAt' => $release['published_at'] ? new DateTimeImmutable($release['published_at']) : null,
|
||||
'body' => (string) $release['body'],
|
||||
'url' => $release['html_url'],
|
||||
], $releases);
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,9 @@
|
||||
aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
{% if is_granted('IS_AUTHENTICATED') %}
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
{% if is_granted('IS_AUTHENTICATED') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if 'tvdt_backoffice_index' == app.current_route() %} active{% endif %}"
|
||||
href="{{ path('tvdt_backoffice_index') }}">{{ 'Seasons'|trans }}</a>
|
||||
@@ -21,8 +21,27 @@
|
||||
<a class="nav-link"
|
||||
href="{{ path('tvdt_backoffice_template') }}">{{ 'Download Template'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav mb-auto me-2 me-lg-0">
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="navbar-nav mb-auto me-2 me-lg-0">
|
||||
<li class="nav-item" data-controller="bo--modal"
|
||||
data-action="turbo:submit-end->bo--modal#frameSubmitEnd">
|
||||
<button type="button" class="nav-link border-0 bg-transparent"
|
||||
data-action="click->bo--modal#open"
|
||||
data-src="{{ path('tvdt_backoffice_releases') }}"
|
||||
data-modal-title="{{ 'Releases'|trans }}">{{ 'Releases'|trans }}</button>
|
||||
|
||||
<div class="modal fade" tabindex="-1" data-bo--modal-target="modal"
|
||||
data-action="hidden.bs.modal->bo--modal#resetDirty"
|
||||
aria-labelledby="releasesModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<turbo-frame id="releases-modal-frame" data-bo--modal-target="frame"></turbo-frame>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% if is_granted('IS_AUTHENTICATED') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if 'tvdt_backoffice_settings' == app.current_route() %} active{% endif %}"
|
||||
href="{{ path('tvdt_backoffice_settings') }}">{{ 'Settings'|trans }}</a>
|
||||
@@ -31,8 +50,8 @@
|
||||
<a class="nav-link"
|
||||
href="{{ path('tvdt_login_logout') }}">{{ 'Logout'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<turbo-frame id="releases-modal-frame">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="releasesModalLabel">
|
||||
{{ 'Releases'|trans }}
|
||||
{% if releases[0] is defined %}
|
||||
<span class="text-muted fs-6 ms-2">{{ 'Current version'|trans }}: {{ releases[0].tagName }}</span>
|
||||
{% endif %}
|
||||
</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% if releases is empty %}
|
||||
<p class="text-muted mb-0">{{ 'Could not load releases from GitHub.'|trans }}</p>
|
||||
{% else %}
|
||||
<div class="accordion" id="releasesAccordion">
|
||||
{% for release in releases %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button{% if not loop.first %} collapsed{% endif %}" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#release-{{ loop.index }}">
|
||||
{{ release.name }}
|
||||
{% if release.publishedAt %}
|
||||
<span class="text-muted ms-2 small">{{ release.publishedAt|date('d-m-Y') }}</span>
|
||||
{% endif %}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="release-{{ loop.index }}"
|
||||
class="accordion-collapse collapse{% if loop.first %} show{% endif %}"
|
||||
data-bs-parent="#releasesAccordion">
|
||||
<div class="accordion-body">
|
||||
<div class="release-notes">{{ release.body|markdown_to_html }}</div>
|
||||
<a href="{{ release.url }}" target="_blank" rel="noopener noreferrer" class="small">{{ 'View on GitHub'|trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</turbo-frame>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Tests\Controller\Backoffice;
|
||||
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Tvdt\Controller\Backoffice\ReleasesController;
|
||||
use Tvdt\Service\GitHubReleasesService;
|
||||
use Tvdt\Tests\Controller\AbstractControllerWebTestCase;
|
||||
|
||||
#[CoversClass(ReleasesController::class)]
|
||||
final class ReleasesControllerTest extends AbstractControllerWebTestCase
|
||||
{
|
||||
public function testReleasesFrameRendersReleaseNotes(): void
|
||||
{
|
||||
$this->loginAs('user2@example.org');
|
||||
$this->mockReleasesService();
|
||||
|
||||
$this->client->request(Request::METHOD_GET, '/backoffice/releases');
|
||||
|
||||
self::assertResponseIsSuccessful();
|
||||
self::assertSelectorTextContains('body', 'v0.8.0');
|
||||
self::assertSelectorTextContains('body', 'Some release notes');
|
||||
self::assertSelectorTextContains('#releasesModalLabel', 'Huidige versie: v0.8.0');
|
||||
}
|
||||
|
||||
public function testReleasesFrameIsAccessibleWithoutAuthentication(): void
|
||||
{
|
||||
$this->mockReleasesService();
|
||||
|
||||
$this->client->request(Request::METHOD_GET, '/backoffice/releases');
|
||||
|
||||
self::assertResponseIsSuccessful();
|
||||
}
|
||||
|
||||
private function mockReleasesService(): void
|
||||
{
|
||||
$body = json_encode([
|
||||
[
|
||||
'tag_name' => 'v0.8.0',
|
||||
'name' => 'v0.8.0',
|
||||
'published_at' => '2026-07-12T10:00:00Z',
|
||||
'body' => 'Some release notes',
|
||||
'html_url' => 'https://github.com/MarijnDoeve/TijdVoorDeTest/releases/tag/v0.8.0',
|
||||
],
|
||||
], \JSON_THROW_ON_ERROR);
|
||||
$httpClient = new MockHttpClient([new MockResponse((string) $body, ['response_headers' => ['content-type' => 'application/json']])]);
|
||||
self::getContainer()->set(GitHubReleasesService::class, new GitHubReleasesService($httpClient, new ArrayAdapter()));
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Tests\Service;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Reader;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
@@ -201,6 +202,50 @@ final class DataExportServiceTest extends DatabaseTestCase
|
||||
$this->assertSame('Man', $claudiaRow[$questionColumnIndex]);
|
||||
}
|
||||
|
||||
public function testRawAnswersSheetBoldsCorrectAnswersOnly(): void
|
||||
{
|
||||
$season = $this->getSeasonByCode('krtek');
|
||||
$quiz = $this->entityManager->getRepository(Quiz::class)->findOneBy(['name' => 'Quiz 1', 'season' => $season]);
|
||||
$this->assertInstanceOf(Quiz::class, $quiz);
|
||||
|
||||
/** @var Question $firstQuestion */
|
||||
$firstQuestion = $quiz->questions->first();
|
||||
$correctAnswer = $firstQuestion->answers->filter(static fn (Answer $answer): bool => $answer->isRightAnswer)->first();
|
||||
$wrongAnswer = $firstQuestion->answers->filter(static fn (Answer $answer): bool => !$answer->isRightAnswer)->first();
|
||||
$this->assertInstanceOf(Answer::class, $correctAnswer);
|
||||
$this->assertInstanceOf(Answer::class, $wrongAnswer);
|
||||
|
||||
$candidateWithCorrectAnswer = $this->getCandidateBySeasonAndName($season, 'Claudia');
|
||||
$candidateWithWrongAnswer = $this->getCandidateBySeasonAndName($season, 'Eelco');
|
||||
|
||||
$this->quizCandidateRepository->createIfNotExist($quiz, $candidateWithCorrectAnswer);
|
||||
$this->quizCandidateRepository->createIfNotExist($quiz, $candidateWithWrongAnswer);
|
||||
|
||||
$this->entityManager->persist(new GivenAnswer($candidateWithCorrectAnswer, $quiz, $correctAnswer));
|
||||
$this->entityManager->persist(new GivenAnswer($candidateWithWrongAnswer, $quiz, $wrongAnswer));
|
||||
$this->entityManager->flush();
|
||||
|
||||
$zip = $this->openZip($this->getUserByEmail('user2@example.org'));
|
||||
$quizContent = $zip->getFromName('krtek-Krtek-Weekend/Quiz-1.xlsx');
|
||||
$this->assertIsString($quizContent);
|
||||
$zip->close();
|
||||
|
||||
$sheet = $this->loadSheet($quizContent, 'Raw answers');
|
||||
$rows = $sheet->toArray();
|
||||
$header = $rows[0];
|
||||
|
||||
$questionColumnIndex = array_search($firstQuestion->question, $header, true);
|
||||
$this->assertIsInt($questionColumnIndex);
|
||||
$column = Coordinate::stringFromColumnIndex($questionColumnIndex + 1);
|
||||
|
||||
$candidateNames = array_column(\array_slice($rows, 1), 0);
|
||||
$correctRowNumber = 2 + array_search('Claudia', $candidateNames, true);
|
||||
$wrongRowNumber = 2 + array_search('Eelco', $candidateNames, true);
|
||||
|
||||
$this->assertTrue($sheet->getStyle($column.$correctRowNumber)->getFont()->getBold(), 'Expected the correct answer to be bold');
|
||||
$this->assertFalse($sheet->getStyle($column.$wrongRowNumber)->getFont()->getBold(), 'Expected the wrong answer to not be bold');
|
||||
}
|
||||
|
||||
public function testQuizInfoSheetShowsDropoutsFinalizationAndDisabledQuestions(): void
|
||||
{
|
||||
$season = $this->getSeasonByCode('krtek');
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tvdt\Tests\Service;
|
||||
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||
use Tvdt\Service\GitHubReleasesService;
|
||||
|
||||
#[CoversClass(GitHubReleasesService::class)]
|
||||
final class GitHubReleasesServiceTest extends TestCase
|
||||
{
|
||||
public function testGetReleasesMapsGitHubResponse(): void
|
||||
{
|
||||
$body = json_encode([
|
||||
[
|
||||
'tag_name' => 'v0.8.0',
|
||||
'name' => 'v0.8.0',
|
||||
'published_at' => '2026-07-12T10:00:00Z',
|
||||
'body' => "## Added\n- Something new",
|
||||
'html_url' => 'https://github.com/MarijnDoeve/TijdVoorDeTest/releases/tag/v0.8.0',
|
||||
],
|
||||
], \JSON_THROW_ON_ERROR);
|
||||
|
||||
$httpClient = new MockHttpClient([new MockResponse((string) $body, ['response_headers' => ['content-type' => 'application/json']])]);
|
||||
$subject = new GitHubReleasesService($httpClient, new ArrayAdapter());
|
||||
|
||||
$releases = $subject->getReleases();
|
||||
|
||||
$this->assertEquals([
|
||||
'tagName' => 'v0.8.0',
|
||||
'name' => 'v0.8.0',
|
||||
'publishedAt' => new DateTimeImmutable('2026-07-12T10:00:00Z'),
|
||||
'body' => "## Added\n- Something new",
|
||||
'url' => 'https://github.com/MarijnDoeve/TijdVoorDeTest/releases/tag/v0.8.0',
|
||||
], $releases[0]);
|
||||
}
|
||||
|
||||
public function testGetReleasesReturnsEmptyArrayOnHttpFailure(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient(static fn (): MockResponse => new MockResponse('', ['http_code' => 500]));
|
||||
$subject = new GitHubReleasesService($httpClient, new ArrayAdapter());
|
||||
|
||||
$this->assertSame([], $subject->getReleases());
|
||||
}
|
||||
|
||||
public function testHttpFailureIsNotCached(): void
|
||||
{
|
||||
$requestCount = 0;
|
||||
$httpClient = new MockHttpClient(static function () use (&$requestCount): MockResponse {
|
||||
++$requestCount;
|
||||
|
||||
return new MockResponse('', ['http_code' => 500]);
|
||||
});
|
||||
$subject = new GitHubReleasesService($httpClient, new ArrayAdapter());
|
||||
|
||||
$subject->getReleases();
|
||||
$subject->getReleases();
|
||||
|
||||
$this->assertSame(2, $requestCount);
|
||||
}
|
||||
|
||||
public function testGetReleasesSortsNewestFirst(): void
|
||||
{
|
||||
$body = json_encode([
|
||||
[
|
||||
'tag_name' => 'v0.7.0',
|
||||
'name' => 'v0.7.0',
|
||||
'published_at' => '2026-07-10T10:00:00Z',
|
||||
'body' => 'Older release',
|
||||
'html_url' => 'https://github.com/MarijnDoeve/TijdVoorDeTest/releases/tag/v0.7.0',
|
||||
],
|
||||
[
|
||||
'tag_name' => 'v0.8.0',
|
||||
'name' => 'v0.8.0',
|
||||
'published_at' => '2026-07-12T10:00:00Z',
|
||||
'body' => 'Newer release',
|
||||
'html_url' => 'https://github.com/MarijnDoeve/TijdVoorDeTest/releases/tag/v0.8.0',
|
||||
],
|
||||
], \JSON_THROW_ON_ERROR);
|
||||
|
||||
$httpClient = new MockHttpClient([new MockResponse((string) $body, ['response_headers' => ['content-type' => 'application/json']])]);
|
||||
$subject = new GitHubReleasesService($httpClient, new ArrayAdapter());
|
||||
|
||||
$releases = $subject->getReleases();
|
||||
|
||||
$this->assertSame('v0.8.0', $releases[0]['tagName']);
|
||||
$this->assertSame('v0.7.0', $releases[1]['tagName']);
|
||||
}
|
||||
}
|
||||
@@ -241,6 +241,10 @@
|
||||
<source>Could not find candidate with name {name} in elimination.</source>
|
||||
<target>Kon geen kandidaat vinden met de naam {name} in de eliminatie</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="HL5QYZd" resname="Could not load releases from GitHub.">
|
||||
<source>Could not load releases from GitHub.</source>
|
||||
<target>Kan releases niet laden van GitHub.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="0DvmToq" resname="Create a season">
|
||||
<source>Create a season</source>
|
||||
<target>Maak een seizoen aan</target>
|
||||
@@ -265,6 +269,10 @@
|
||||
<source>Current password</source>
|
||||
<target>Huidig wachtwoord</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="xreXHN5" resname="Current version">
|
||||
<source>Current version</source>
|
||||
<target>Huidige versie</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="PkrbQOH" resname="Cyan">
|
||||
<source>Cyan</source>
|
||||
<target>Cyaan</target>
|
||||
@@ -745,6 +753,10 @@
|
||||
<source>Register</source>
|
||||
<target>Registreren</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="3s37xTt" resname="Releases">
|
||||
<source>Releases</source>
|
||||
<target>Releases</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="WevL4T_" resname="Remember me">
|
||||
<source>Remember me</source>
|
||||
<target>Onthoud mij</target>
|
||||
@@ -977,6 +989,10 @@
|
||||
<source>View</source>
|
||||
<target>Bekijken</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="a1.g0sm" resname="View on GitHub">
|
||||
<source>View on GitHub</source>
|
||||
<target>Bekijk op GitHub</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="JWRtx_o" resname="White">
|
||||
<source>White</source>
|
||||
<target>Wit</target>
|
||||
|
||||
Reference in New Issue
Block a user