Bump deps and refactor layouts/styles
All checks were successful
Build, Test & Push Frontend / quality-check (push) Successful in 1m40s
Build, Test & Push Frontend / docker (push) Successful in 1m8s

Update package-lock with multiple dependency bumps (Angular CLI/DevKit/schematics to 21.1.5, ajv to 8.18.0, minimatch/brace-expansion updates, tar, qs, swiper, hono, etc.). Wrap the generic grid canvas in a container and clean up HTML structure/indentation in algorithms and pathfinding templates (add card-grid wrapper and reformat content). Adjust global styles: refine .algo-container and app-root margins/gaps, and refactor hero/photo/intro styles for responsive layout. Changes are primarily dependency updates and UI/layout refinements.
This commit is contained in:
2026-02-25 08:50:28 +01:00
parent 28bde29c8b
commit f4104d02e8
5 changed files with 251 additions and 217 deletions

257
package-lock.json generated
View File

@@ -310,13 +310,13 @@
} }
}, },
"node_modules/@angular-devkit/schematics": { "node_modules/@angular-devkit/schematics": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.1.5.tgz",
"integrity": "sha512-Ps7bRl5uOcM7WpNJHbSls/jz5/wAI0ldkTlKyiBFA7RtNeQIABAV+hvlw5DJuEb1Lo5hnK0hXj90AyZdOxzY+w==", "integrity": "sha512-CGmoorQL5+mVCJEHwHWOrhSd1hFxB3h66i9wUDizJAEQUM3mSml5SiglHArpWY/G4GmFwi6XVe+Jm3U8J/mcFg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@angular-devkit/core": "21.1.3", "@angular-devkit/core": "21.1.5",
"jsonc-parser": "3.3.1", "jsonc-parser": "3.3.1",
"magic-string": "0.30.21", "magic-string": "0.30.21",
"ora": "9.0.0", "ora": "9.0.0",
@@ -329,13 +329,13 @@
} }
}, },
"node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.5.tgz",
"integrity": "sha512-huEXd1tWQHwwN+0VGRT+vSVplV0KNrGFUGJzkIW6iJE1SQElxn6etMai+pSd5DJcePkx6+SuscVsxbfwf70hnA==", "integrity": "sha512-KUKbllHvHefkAbTBjWNpRPyrpBqecW+6HBBAR+XNbKBuFTHkG+gxtuwMXNsvO5KECKwQphvQt5h3g05Xtaf0LQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "8.17.1", "ajv": "8.18.0",
"ajv-formats": "3.0.1", "ajv-formats": "3.0.1",
"jsonc-parser": "3.3.1", "jsonc-parser": "3.3.1",
"picomatch": "4.0.3", "picomatch": "4.0.3",
@@ -356,6 +356,23 @@
} }
} }
}, },
"node_modules/@angular-devkit/schematics/node_modules/ajv": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@angular-eslint/builder": { "node_modules/@angular-eslint/builder": {
"version": "21.2.0", "version": "21.2.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.2.0.tgz", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.2.0.tgz",
@@ -613,19 +630,19 @@
} }
}, },
"node_modules/@angular/cli": { "node_modules/@angular/cli": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.1.5.tgz",
"integrity": "sha512-UPtDcpKyrKZRPfym9gTovcibPzl2O/Woy7B8sm45sAnjDH+jDUCcCvuIak7GpH47shQkC2J4yvnHZbD4c6XxcQ==", "integrity": "sha512-ljqvAzSk8FKMaYW/aZhR+SXjudbQViYYkMlJvJUClGpokjDM9KfJWPX+QZfr2J+piW5yaaHmFaIMddO9QxkUDQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@angular-devkit/architect": "0.2101.3", "@angular-devkit/architect": "0.2101.5",
"@angular-devkit/core": "21.1.3", "@angular-devkit/core": "21.1.5",
"@angular-devkit/schematics": "21.1.3", "@angular-devkit/schematics": "21.1.5",
"@inquirer/prompts": "7.10.1", "@inquirer/prompts": "7.10.1",
"@listr2/prompt-adapter-inquirer": "3.0.5", "@listr2/prompt-adapter-inquirer": "3.0.5",
"@modelcontextprotocol/sdk": "1.26.0", "@modelcontextprotocol/sdk": "1.26.0",
"@schematics/angular": "21.1.3", "@schematics/angular": "21.1.5",
"@yarnpkg/lockfile": "1.1.0", "@yarnpkg/lockfile": "1.1.0",
"algoliasearch": "5.46.2", "algoliasearch": "5.46.2",
"ini": "6.0.0", "ini": "6.0.0",
@@ -649,13 +666,13 @@
} }
}, },
"node_modules/@angular/cli/node_modules/@angular-devkit/architect": { "node_modules/@angular/cli/node_modules/@angular-devkit/architect": {
"version": "0.2101.3", "version": "0.2101.5",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2101.3.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2101.5.tgz",
"integrity": "sha512-vKz8aPA62W+e9+pF6ct4CRDG/MjlIH7sWFGYkxPPRst2g46ZQsRkrzfMZAWv/wnt6OZ1OwyRuO3RW83EMhag8g==", "integrity": "sha512-eTo6wWzUW5AyBBLTbaUTpBHhGbZhzteErtNGklWkhjicCr/soNH+2mVtvg8bqA8sNreYffK1VXKFsq5NyMh5qg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@angular-devkit/core": "21.1.3", "@angular-devkit/core": "21.1.5",
"rxjs": "7.8.2" "rxjs": "7.8.2"
}, },
"bin": { "bin": {
@@ -668,13 +685,13 @@
} }
}, },
"node_modules/@angular/cli/node_modules/@angular-devkit/core": { "node_modules/@angular/cli/node_modules/@angular-devkit/core": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.5.tgz",
"integrity": "sha512-huEXd1tWQHwwN+0VGRT+vSVplV0KNrGFUGJzkIW6iJE1SQElxn6etMai+pSd5DJcePkx6+SuscVsxbfwf70hnA==", "integrity": "sha512-KUKbllHvHefkAbTBjWNpRPyrpBqecW+6HBBAR+XNbKBuFTHkG+gxtuwMXNsvO5KECKwQphvQt5h3g05Xtaf0LQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "8.17.1", "ajv": "8.18.0",
"ajv-formats": "3.0.1", "ajv-formats": "3.0.1",
"jsonc-parser": "3.3.1", "jsonc-parser": "3.3.1",
"picomatch": "4.0.3", "picomatch": "4.0.3",
@@ -695,6 +712,23 @@
} }
} }
}, },
"node_modules/@angular/cli/node_modules/ajv": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@angular/common": { "node_modules/@angular/common": {
"version": "21.1.2", "version": "21.1.2",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-21.1.2.tgz", "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.1.2.tgz",
@@ -1705,9 +1739,9 @@
} }
}, },
"node_modules/@eslint/config-array/node_modules/minimatch": { "node_modules/@eslint/config-array/node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@@ -1768,9 +1802,9 @@
} }
}, },
"node_modules/@eslint/eslintrc/node_modules/ajv": { "node_modules/@eslint/eslintrc/node_modules/ajv": {
"version": "6.12.6", "version": "6.14.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1813,9 +1847,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@eslint/eslintrc/node_modules/minimatch": { "node_modules/@eslint/eslintrc/node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@@ -2333,29 +2367,6 @@
} }
} }
}, },
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/brace-expansion": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz",
"integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/fs-minipass": { "node_modules/@isaacs/fs-minipass": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
@@ -5191,14 +5202,14 @@
] ]
}, },
"node_modules/@schematics/angular": { "node_modules/@schematics/angular": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.1.5.tgz",
"integrity": "sha512-obJvWBhzRdsYL2msM4+8bQD21vFl3VxaVsuiq6iIfYsxhU5i2Iar2wM9NaRaIIqAYhZ8ehQQ/moB9BEbWvDCTw==", "integrity": "sha512-AndJ17ePYUoqJqiIF9VaXbGAFfOqDcHuAxhwozsQlWDzwgQSOUC/WWeG9hKVCgMD6tE02Sxr2ova9DiBKsLQNg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@angular-devkit/core": "21.1.3", "@angular-devkit/core": "21.1.5",
"@angular-devkit/schematics": "21.1.3", "@angular-devkit/schematics": "21.1.5",
"jsonc-parser": "3.3.1" "jsonc-parser": "3.3.1"
}, },
"engines": { "engines": {
@@ -5208,13 +5219,13 @@
} }
}, },
"node_modules/@schematics/angular/node_modules/@angular-devkit/core": { "node_modules/@schematics/angular/node_modules/@angular-devkit/core": {
"version": "21.1.3", "version": "21.1.5",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.3.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.5.tgz",
"integrity": "sha512-huEXd1tWQHwwN+0VGRT+vSVplV0KNrGFUGJzkIW6iJE1SQElxn6etMai+pSd5DJcePkx6+SuscVsxbfwf70hnA==", "integrity": "sha512-KUKbllHvHefkAbTBjWNpRPyrpBqecW+6HBBAR+XNbKBuFTHkG+gxtuwMXNsvO5KECKwQphvQt5h3g05Xtaf0LQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "8.17.1", "ajv": "8.18.0",
"ajv-formats": "3.0.1", "ajv-formats": "3.0.1",
"jsonc-parser": "3.3.1", "jsonc-parser": "3.3.1",
"picomatch": "4.0.3", "picomatch": "4.0.3",
@@ -5235,6 +5246,23 @@
} }
} }
}, },
"node_modules/@schematics/angular/node_modules/ajv": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@sentry-internal/tracing": { "node_modules/@sentry-internal/tracing": {
"version": "7.120.4", "version": "7.120.4",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.4.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.4.tgz",
@@ -5438,16 +5466,16 @@
} }
}, },
"node_modules/@tufjs/models/node_modules/minimatch": { "node_modules/@tufjs/models/node_modules/minimatch": {
"version": "10.1.1", "version": "10.2.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz",
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==",
"dev": true, "dev": true,
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"@isaacs/brace-expansion": "^5.0.0" "brace-expansion": "^5.0.2"
}, },
"engines": { "engines": {
"node": "20 || >=22" "node": "18 || 20 || >=22"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
@@ -6649,13 +6677,26 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "2.0.2", "version": "5.0.3",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0" "balanced-match": "^4.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/brace-expansion/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
@@ -7877,9 +7918,9 @@
} }
}, },
"node_modules/eslint/node_modules/ajv": { "node_modules/eslint/node_modules/ajv": {
"version": "6.12.6", "version": "6.14.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -7952,9 +7993,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/eslint/node_modules/minimatch": { "node_modules/eslint/node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@@ -8609,16 +8650,16 @@
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/glob/node_modules/minimatch": { "node_modules/glob/node_modules/minimatch": {
"version": "10.1.1", "version": "10.2.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz",
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==",
"dev": true, "dev": true,
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"@isaacs/brace-expansion": "^5.0.0" "brace-expansion": "^5.0.2"
}, },
"engines": { "engines": {
"node": "20 || >=22" "node": "18 || 20 || >=22"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
@@ -8694,9 +8735,9 @@
} }
}, },
"node_modules/hono": { "node_modules/hono": {
"version": "4.11.8", "version": "4.12.2",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.11.8.tgz", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.2.tgz",
"integrity": "sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q==", "integrity": "sha512-gJnaDHXKDayjt8ue0n8Gs0A007yKXj4Xzb8+cNjZeYsSzzwKc0Lr+OZgYwVfB0pHfUs17EPoLvrOsEaJ9mj+Tg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -8865,16 +8906,16 @@
} }
}, },
"node_modules/ignore-walk/node_modules/minimatch": { "node_modules/ignore-walk/node_modules/minimatch": {
"version": "10.1.1", "version": "10.2.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz",
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==",
"dev": true, "dev": true,
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"@isaacs/brace-expansion": "^5.0.0" "brace-expansion": "^5.0.2"
}, },
"engines": { "engines": {
"node": "20 || >=22" "node": "18 || 20 || >=22"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
@@ -10441,13 +10482,13 @@
} }
}, },
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "9.0.5", "version": "9.0.7",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"brace-expansion": "^2.0.1" "brace-expansion": "^5.0.2"
}, },
"engines": { "engines": {
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
@@ -11673,9 +11714,9 @@
} }
}, },
"node_modules/qs": { "node_modules/qs": {
"version": "6.14.1", "version": "6.14.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
"dev": true, "dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
@@ -11878,9 +11919,9 @@
} }
}, },
"node_modules/rimraf/node_modules/minimatch": { "node_modules/rimraf/node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@@ -12583,9 +12624,9 @@
} }
}, },
"node_modules/swiper": { "node_modules/swiper": {
"version": "12.1.0", "version": "12.1.2",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-12.1.0.tgz", "resolved": "https://registry.npmjs.org/swiper/-/swiper-12.1.2.tgz",
"integrity": "sha512-BD4CpAOOyEvZ2f0CDx362ea+vmOwukVcmbsQx+0BhRIaBUz8wvcCd//E7RFmvBZCrfyqXCHUVqmgUwts6ywlxw==", "integrity": "sha512-4gILrI3vXZqoZh71I1PALqukCFgk+gpOwe1tOvz5uE9kHtl2gTDzmYflYCwWvR4LOvCrJi6UEEU+gnuW5BtkgQ==",
"funding": [ "funding": [
{ {
"type": "patreon", "type": "patreon",
@@ -12602,9 +12643,9 @@
} }
}, },
"node_modules/tar": { "node_modules/tar": {
"version": "7.5.7", "version": "7.5.9",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz",
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==",
"dev": true, "dev": true,
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {

View File

@@ -1,5 +1,7 @@
<div class="card-grid">
<h1>{{ 'ALGORITHM.TITLE' |translate }}</h1> <h1>{{ 'ALGORITHM.TITLE' |translate }}</h1>
<div class="card-grid"> </div>
<div class="card-grid">
@for (category of categories$ | async; track category.id) { @for (category of categories$ | async; track category.id) {
<mat-card class="algo-card" [routerLink]="[category.routerLink]"> <mat-card class="algo-card" [routerLink]="[category.routerLink]">
<mat-card-header> <mat-card-header>

View File

@@ -1,80 +1,80 @@
<mat-card class="algo-container"> <mat-card class="algo-container">
<mat-card-header> <mat-card-header>
<mat-card-title>{{ 'PATHFINDING.TITLE' | translate }}</mat-card-title> <mat-card-title>{{ 'PATHFINDING.TITLE' | translate }}</mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<app-information [algorithmInformation]="algoInformation"/> <app-information [algorithmInformation]="algoInformation"/>
<div class="controls-container"> <div class="controls-container">
<div class="controls-panel"> <div class="controls-panel">
<button matButton="filled" (click)="visualize('dijkstra')">{{ 'PATHFINDING.DIJKSTRA' | translate }}</button> <button matButton="filled" (click)="visualize('dijkstra')">{{ 'PATHFINDING.DIJKSTRA' | translate }}</button>
<button matButton="filled" (click)="visualize('astar')">{{ 'PATHFINDING.ASTAR' | translate }}</button> <button matButton="filled" (click)="visualize('astar')">{{ 'PATHFINDING.ASTAR' | translate }}</button>
</div> </div>
<div class="controls-panel"> <div class="controls-panel">
<button matButton="filled" (click)="createCase({withWalls: true, scenario: 'normal'})">{{ 'PATHFINDING.NORMAL_CASE' | translate }}</button> <button matButton="filled" (click)="createCase({withWalls: true, scenario: 'normal'})">{{ 'PATHFINDING.NORMAL_CASE' | translate }}</button>
<button matButton="filled" (click)="createCase({withWalls: true, scenario: 'random'})">{{ 'PATHFINDING.RANDOM_CASE' | translate }}</button> <button matButton="filled" (click)="createCase({withWalls: true, scenario: 'random'})">{{ 'PATHFINDING.RANDOM_CASE' | translate }}</button>
<button matButton="filled" (click)="createCase({withWalls: true, scenario: 'edge'})">{{ 'PATHFINDING.EDGE_CASE' | translate }}</button> <button matButton="filled" (click)="createCase({withWalls: true, scenario: 'edge'})">{{ 'PATHFINDING.EDGE_CASE' | translate }}</button>
<button matButton="filled" (click)="createCase({withWalls: false, scenario: 'normal'})">{{ 'PATHFINDING.CLEAR_BOARD' | translate }}</button> <button matButton="filled" (click)="createCase({withWalls: false, scenario: 'normal'})">{{ 'PATHFINDING.CLEAR_BOARD' | translate }}</button>
</div> </div>
<div class="controls-panel"> <div class="controls-panel">
<mat-button-toggle-group [(ngModel)]="selectedNodeType" aria-label="Node Type Selection"> <mat-button-toggle-group [(ngModel)]="selectedNodeType" aria-label="Node Type Selection">
<mat-button-toggle [value]="NodeType.Start">{{ 'PATHFINDING.START_NODE' | translate }}</mat-button-toggle> <mat-button-toggle [value]="NodeType.Start">{{ 'PATHFINDING.START_NODE' | translate }}</mat-button-toggle>
<mat-button-toggle [value]="NodeType.End">{{ 'PATHFINDING.END_NODE' | translate }}</mat-button-toggle> <mat-button-toggle [value]="NodeType.End">{{ 'PATHFINDING.END_NODE' | translate }}</mat-button-toggle>
<mat-button-toggle [value]="NodeType.Wall">{{ 'PATHFINDING.WALL' | translate }}</mat-button-toggle> <mat-button-toggle [value]="NodeType.Wall">{{ 'PATHFINDING.WALL' | translate }}</mat-button-toggle>
<mat-button-toggle [value]="NodeType.None">{{ 'PATHFINDING.CLEAR_NODE' | translate }}</mat-button-toggle> <mat-button-toggle [value]="NodeType.None">{{ 'PATHFINDING.CLEAR_NODE' | translate }}</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div class="controls-panel"> <div class="controls-panel">
<div class="input-container"> <div class="input-container">
<mat-form-field appearance="outline" class="input-field"> <mat-form-field appearance="outline" class="input-field">
<mat-label>{{ 'ALGORITHM.GRID_HEIGHT' | translate }}</mat-label> <mat-label>{{ 'ALGORITHM.GRID_HEIGHT' | translate }}</mat-label>
<input <input
matInput matInput
type="number" type="number"
[min]="MIN_GRID_SIZE" [min]="MIN_GRID_SIZE"
[max]="MAX_GRID_SIZE" [max]="MAX_GRID_SIZE"
[(ngModel)]="gridRows" [(ngModel)]="gridRows"
(ngModelChange)="genericGridComponent.gridRows = gridRows; genericGridComponent.applyGridSize()" (ngModelChange)="genericGridComponent.gridRows = gridRows; genericGridComponent.applyGridSize()"
/> </mat-form-field> /> </mat-form-field>
<mat-form-field appearance="outline" class="input-field"> <mat-form-field appearance="outline" class="input-field">
<mat-label>{{ 'ALGORITHM.GRID_WIDTH' | translate }}</mat-label> <mat-label>{{ 'ALGORITHM.GRID_WIDTH' | translate }}</mat-label>
<input <input
matInput matInput
type="number" type="number"
[min]="MIN_GRID_SIZE" [min]="MIN_GRID_SIZE"
[max]="MAX_GRID_SIZE" [max]="MAX_GRID_SIZE"
[(ngModel)]="gridCols" [(ngModel)]="gridCols"
(ngModelChange)="genericGridComponent.gridCols = gridCols; genericGridComponent.applyGridSize()" (ngModelChange)="genericGridComponent.gridCols = gridCols; genericGridComponent.applyGridSize()"
/> </mat-form-field> /> </mat-form-field>
</div>
</div>
<div class="legend">
<span><span class="legend-color start"></span> {{ 'PATHFINDING.START_NODE' | translate }}</span>
<span><span class="legend-color end"></span> {{ 'PATHFINDING.END_NODE' | translate }}</span>
<span><span class="legend-color wall"></span> {{ 'PATHFINDING.WALL' | translate }}</span>
<span><span class="legend-color visited"></span> {{ 'PATHFINDING.VISITED' | translate }}</span>
<span><span class="legend-color path"></span> {{ 'PATHFINDING.PATH' | translate }}</span>
</div>
<div class="controls-panel">
<p>{{ 'PATHFINDING.PATH_LENGTH' | translate }}: {{ pathLength }}</p>
<p>{{ 'PATHFINDING.EXECUTION_TIME' | translate }}: {{ executionTime | number:'1.2-2' }} ms</p>
</div> </div>
</div> </div>
<div class="legend"> <app-generic-grid
<span><span class="legend-color start"></span> {{ 'PATHFINDING.START_NODE' | translate }}</span> [gridRows]="gridRows"
<span><span class="legend-color end"></span> {{ 'PATHFINDING.END_NODE' | translate }}</span> [gridCols]="gridCols"
<span><span class="legend-color wall"></span> {{ 'PATHFINDING.WALL' | translate }}</span> [minGridSize]="MIN_GRID_SIZE"
<span><span class="legend-color visited"></span> {{ 'PATHFINDING.VISITED' | translate }}</span> [maxGridSize]="MAX_GRID_SIZE"
<span><span class="legend-color path"></span> {{ 'PATHFINDING.PATH' | translate }}</span> [maxGridPx]="MAX_GRID_PX"
</div> [createNodeFn]="createPathfindingNode"
<div class="controls-panel"> [getNodeColorFn]="getPathfindingNodeColor"
<p>{{ 'PATHFINDING.PATH_LENGTH' | translate }}: {{ pathLength }}</p> [applySelectionFn]="applyPathfindingSelection"
<p>{{ 'PATHFINDING.EXECUTION_TIME' | translate }}: {{ executionTime | number:'1.2-2' }} ms</p> [backgroundColor]="'lightgray'"
</div> (gridChange)="grid = $event"
</div> ></app-generic-grid>
</mat-card-content>
<app-generic-grid </mat-card>
[gridRows]="gridRows"
[gridCols]="gridCols"
[minGridSize]="MIN_GRID_SIZE"
[maxGridSize]="MAX_GRID_SIZE"
[maxGridPx]="MAX_GRID_PX"
[createNodeFn]="createPathfindingNode"
[getNodeColorFn]="getPathfindingNodeColor"
[applySelectionFn]="applyPathfindingSelection"
[backgroundColor]="'lightgray'"
(gridChange)="grid = $event"
></app-generic-grid>
</mat-card-content>
</mat-card>

View File

@@ -1 +1,3 @@
<canvas #gridCanvas></canvas> <div class="canvas-container">
<canvas #gridCanvas></canvas>
</div>

View File

@@ -230,10 +230,11 @@ a {
// algos // algos
.algo-container { .algo-container {
width: 100%;
max-width: var(--app-maxWidth); max-width: var(--app-maxWidth);
margin: 0 auto; gap: clamp(1rem, 3vw, 1.5rem);
padding: clamp(1rem, 4vw, 2rem); margin-right: 1rem;
margin-left: 0.5rem;
margin-top: auto;
} }
.algo-info { .algo-info {
@@ -473,7 +474,9 @@ app-root {
display: grid; display: grid;
gap: clamp(1rem, 3vw, 1.5rem); gap: clamp(1rem, 3vw, 1.5rem);
max-width: var(--app-maxWidth); max-width: var(--app-maxWidth);
margin: 0 auto; margin-right: 1rem;
margin-left: 1rem;
margin-top: auto;
} }
.hero { .hero {
@@ -488,40 +491,26 @@ app-root {
gap: clamp(1rem, 4vw, 2rem); gap: clamp(1rem, 4vw, 2rem);
padding: clamp(1rem, 3vw, 1.5rem); padding: clamp(1rem, 3vw, 1.5rem);
align-items: flex-start; align-items: flex-start;
}
.hero .photo { .photo {
flex: 0 0 auto; flex: 1 1 min(100%, 425px);
max-width: 100%; max-width: 100%;
}
.hero .photo img {
display: block;
width: 100%;
height: auto;
max-width: 425px;
border-radius: 12px;
box-shadow: 0 6px 24px rgba(0, 0, 0, .25);
object-fit: cover;
}
.hero .intro {
flex: 1 1 400px;
}
@media (max-width: 850px) {
.hero-flex-container {
justify-content: center;
}
.hero .photo {
width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
img {
display: block;
width: 100%;
height: auto;
max-width: 425px;
border-radius: 12px;
box-shadow: 0 6px 24px rgba(0, 0, 0, .25);
object-fit: cover;
}
} }
.hero .intro { .intro {
flex-basis: 100%; flex: 999 1 min(100%, 400px);
} }
} }