Index: frontend/node_modules/safe-array-concat/.eslintrc
===================================================================
--- frontend/node_modules/safe-array-concat/.eslintrc	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/.eslintrc	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,15 @@
+{
+	"root": true,
+
+	"extends": "@ljharb",
+
+	"rules": {
+		"id-length": "off",
+		"max-lines-per-function": "off",
+		"new-cap": ["error", {
+			"capIsNewExceptions": [
+				"GetIntrinsic",
+			],
+		}],
+	},
+}
Index: frontend/node_modules/safe-array-concat/.github/FUNDING.yml
===================================================================
--- frontend/node_modules/safe-array-concat/.github/FUNDING.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/.github/FUNDING.yml	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [ljharb]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: npm/safe-array-concat
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
Index: frontend/node_modules/safe-array-concat/.nycrc
===================================================================
--- frontend/node_modules/safe-array-concat/.nycrc	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/.nycrc	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+{
+	"all": true,
+	"check-coverage": false,
+	"reporter": ["text-summary", "text", "html", "json"],
+	"lines": 86,
+	"statements": 85.93,
+	"functions": 82.43,
+	"branches": 76.06,
+	"exclude": [
+		"coverage",
+		"test"
+	]
+}
Index: frontend/node_modules/safe-array-concat/CHANGELOG.md
===================================================================
--- frontend/node_modules/safe-array-concat/CHANGELOG.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/CHANGELOG.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,81 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [v1.1.4](https://github.com/ljharb/safe-array-concat/compare/v1.1.3...v1.1.4) - 2026-04-19
+
+### Commits
+
+- [actions] update workflows [`6747b8f`](https://github.com/ljharb/safe-array-concat/commit/6747b8fb6b6ffe374b4421de5a36d012d7971f7f)
+- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/isarray`, `@types/tape`, `eslint`, `npmignore` [`aa30c94`](https://github.com/ljharb/safe-array-concat/commit/aa30c941d4ebda29ec4dfa0e9592e44fbd145342)
+- [types] improve types [`21276eb`](https://github.com/ljharb/safe-array-concat/commit/21276eb73f9ec5ed1119655382f38cf79030c9dd)
+- [Deps] update `call-bound`, `get-intrinsic` [`efb5138`](https://github.com/ljharb/safe-array-concat/commit/efb513816ab84c1bebc0852d4aca68e5bcd27ff8)
+- [Deps] update `call-bind` [`dbe4255`](https://github.com/ljharb/safe-array-concat/commit/dbe42554607a0143e0b4c720266f81c7ecb712fb)
+- [Dev Deps] update `@ljharb/eslint-config` [`470988c`](https://github.com/ljharb/safe-array-concat/commit/470988cb3edfe1ffa7313cdb6d1e89101ed1dd15)
+- [Dev Deps] update `@ljharb/eslint-config` [`8a8f4ec`](https://github.com/ljharb/safe-array-concat/commit/8a8f4ec87aca0eca53f31d537dd523f2d60803cb)
+
+## [v1.1.3](https://github.com/ljharb/safe-array-concat/compare/v1.1.2...v1.1.3) - 2024-12-11
+
+### Commits
+
+- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/tape`, `auto-changelog`, `mock-property`, `tape` [`9452ca7`](https://github.com/ljharb/safe-array-concat/commit/9452ca7dc6e22d89fb1bbf4f604d3e058a6813c0)
+- [actions] split out node 10-20, and 20+ [`8166059`](https://github.com/ljharb/safe-array-concat/commit/8166059134d555337faf7574f40c746deaecfa99)
+- [Deps] update `call-bind`, `get-intrinsic`, `has-symbols` [`d35014a`](https://github.com/ljharb/safe-array-concat/commit/d35014a2f8240ca70c336ef694744726b03a042b)
+- [Refactor] use `call-bound` directly [`0bdddbd`](https://github.com/ljharb/safe-array-concat/commit/0bdddbdbdd887f12ecc58ee9fd1f358ec13560d3)
+- [Tests] replace `aud` with `npm audit` [`c62dae0`](https://github.com/ljharb/safe-array-concat/commit/c62dae04b6eb56c460132fdd6e10de432228757e)
+- [Dev Deps] add missing peer dep [`4860aae`](https://github.com/ljharb/safe-array-concat/commit/4860aae938375ae69ecf1c8d6caf58632ca57715)
+
+## [v1.1.2](https://github.com/ljharb/safe-array-concat/compare/v1.1.1...v1.1.2) - 2024-03-09
+
+### Commits
+
+- [types] use a generic [`a1d744d`](https://github.com/ljharb/safe-array-concat/commit/a1d744d749033c91f0c108b28ac6dbc6016ecce4)
+- [Dev Deps] update `@ljharb/tsconfig`, `set-function-length` [`3d3da0a`](https://github.com/ljharb/safe-array-concat/commit/3d3da0ab110bce21f466381c5d09f93200a20f85)
+
+## [v1.1.1](https://github.com/ljharb/safe-array-concat/compare/v1.1.0...v1.1.1) - 2024-03-09
+
+### Commits
+
+- [types] use shared config [`f509f80`](https://github.com/ljharb/safe-array-concat/commit/f509f80fb2dd9734c309ccb59ca9451c5a5de885)
+- [actions] remove redundant finisher; use reusable workflows [`b5f5ff4`](https://github.com/ljharb/safe-array-concat/commit/b5f5ff497976a48e291788b26b741cd4f3d388eb)
+- [types] use handwritten d.ts instead of emit [`e717048`](https://github.com/ljharb/safe-array-concat/commit/e717048433b52d3a3240b7c697b5736756ed296e)
+- [Dev Deps] update `set-function-length`, `tape` [`dde26a7`](https://github.com/ljharb/safe-array-concat/commit/dde26a7600ebe8ebc8f45d1bf8f1a970175604d8)
+- [Deps] update `call-bind`, `get-intrinsic` [`d5d2cde`](https://github.com/ljharb/safe-array-concat/commit/d5d2cde9e5b7179d00d85e007b80b138969c5968)
+- [Dev Deps] update `tape` [`9454c5a`](https://github.com/ljharb/safe-array-concat/commit/9454c5a3beacb08200b4b00b7ffa54a572cb76ab)
+- [Tests] add `@arethetypeswrong/cli [`00a5243`](https://github.com/ljharb/safe-array-concat/commit/00a5243a5b923ff2b694b3b5ef4ce39027e30f6e)
+- [Deps] update `get-intrinsic` [`c935764`](https://github.com/ljharb/safe-array-concat/commit/c9357646c3923a1351dca21f175b2b421dd15da5)
+
+## [v1.1.0](https://github.com/ljharb/safe-array-concat/compare/v1.0.1...v1.1.0) - 2024-01-15
+
+### Commits
+
+- [New] add types [`bd92413`](https://github.com/ljharb/safe-array-concat/commit/bd92413643b2bd0ad62e854172fad129d3899dc1)
+- [Dev Deps] update `aud`, `mock-property`, `npmignore`, `set-function-length`, `tape` [`497ffcb`](https://github.com/ljharb/safe-array-concat/commit/497ffcbb271ad61752756ec363ad5b9400e4d367)
+- [Deps] update `call-bind`, `get-intrinsic` [`770f870`](https://github.com/ljharb/safe-array-concat/commit/770f8704d3751b947c7f4772d9ee38d8bcdecf44)
+- [Dev Deps] update `mock-property`, `tape` [`be76bd9`](https://github.com/ljharb/safe-array-concat/commit/be76bd958fa73607a105122a8770677ecbdf78f0)
+- [Tests] use `set-function-length/env` [`89b1167`](https://github.com/ljharb/safe-array-concat/commit/89b116758d91ad521f963cccf056f9a3f0b18c20)
+- [meta] add missing npmrc values [`3185cc7`](https://github.com/ljharb/safe-array-concat/commit/3185cc7a6773baf625c65bb58ffb9b7ee5f3306e)
+- [meta] add `sideEffects` flag [`df6c7eb`](https://github.com/ljharb/safe-array-concat/commit/df6c7ebca7f2fd2f152fe2c2a2260d21728e70a3)
+
+## [v1.0.1](https://github.com/ljharb/safe-array-concat/compare/v1.0.0...v1.0.1) - 2023-09-05
+
+### Fixed
+
+- [Perf] set `Symbol.isConcatSpreadable` only when required [`#2`](https://github.com/ljharb/safe-array-concat/issues/2)
+
+### Commits
+
+- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`c0791b0`](https://github.com/ljharb/safe-array-concat/commit/c0791b00b74e70113921c32d4d1fd494b7e8f555)
+- [Deps] update `get-intrinsic` [`7d07ae6`](https://github.com/ljharb/safe-array-concat/commit/7d07ae69d512bb3b6fb2131f1c824b5ffd85af9f)
+
+## v1.0.0 - 2023-04-20
+
+### Commits
+
+- Initial implementation, tests, readme [`31b8e70`](https://github.com/ljharb/safe-array-concat/commit/31b8e709bbba4b01ebc51cc15cdcc7012fe58341)
+- Initial commit [`83d38c6`](https://github.com/ljharb/safe-array-concat/commit/83d38c6f4cde453063393482d9129b134d403d0a)
+- npm init [`516fdc2`](https://github.com/ljharb/safe-array-concat/commit/516fdc2bef306ec13f98b1f1b49c929b5308907f)
+- Only apps should have lockfiles [`9cfa07b`](https://github.com/ljharb/safe-array-concat/commit/9cfa07b9112107b5ba22c74baca8cb80934a09f2)
Index: frontend/node_modules/safe-array-concat/LICENSE
===================================================================
--- frontend/node_modules/safe-array-concat/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: frontend/node_modules/safe-array-concat/README.md
===================================================================
--- frontend/node_modules/safe-array-concat/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,53 @@
+# safe-array-concat <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
+
+[![github actions][actions-image]][actions-url]
+[![coverage][codecov-image]][codecov-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+[![npm badge][npm-badge-png]][package-url]
+
+`Array.prototype.concat`, but made safe by ignoring Symbol.isConcatSpreadable
+
+## Getting started
+
+```sh
+npm install --save safe-array-concat
+```
+
+## Usage/Examples
+
+```js
+var safeConcat = require('safe-array-concat');
+var assert = require('assert');
+
+assert.deepEqual([].concat([1, 2], 3, [[4]]), [1, 2, 3, [4]], 'arrays spread as expected with normal concat');
+assert.deepEqual(safeConcat([1, 2], 3, [[4]]), [1, 2, 3, [4]], 'arrays spread as expected with safe concat');
+
+String.prototype[Symbol.isConcatSpreadable] = true;
+assert.deepEqual([].concat('foo', Object('bar')), ['foo', 'b', 'a', 'r'], 'spreadable String objects are spread with normal concat!!!');
+assert.deepEqual(safeConcat('foo', Object('bar')), ['foo', Object('bar')], 'spreadable String objects are not spread with safe concat');
+
+Array.prototype[Symbol.isConcatSpreadable] = false;
+assert.deepEqual([].concat([1, 2], 3, [[4]]), [[], [1, 2], 3, [[4]]], 'non-concat-spreadable arrays do not spread with normal concat!!!');
+assert.deepEqual(safeConcat([1, 2], 3, [[4]]), [1, 2, 3, [4]], 'non-concat-spreadable arrays still spread with safe concat');
+```
+
+## Tests
+Simply clone the repo, `npm install`, and run `npm test`
+
+[package-url]: https://npmjs.org/package/safe-array-concat
+[npm-version-svg]: https://versionbadg.es/ljharb/safe-array-concat.svg
+[deps-svg]: https://david-dm.org/ljharb/safe-array-concat.svg
+[deps-url]: https://david-dm.org/ljharb/safe-array-concat
+[dev-deps-svg]: https://david-dm.org/ljharb/safe-array-concat/dev-status.svg
+[dev-deps-url]: https://david-dm.org/ljharb/safe-array-concat#info=devDependencies
+[npm-badge-png]: https://nodei.co/npm/safe-array-concat.png?downloads=true&stars=true
+[license-image]: https://img.shields.io/npm/l/safe-array-concat.svg
+[license-url]: LICENSE
+[downloads-image]: https://img.shields.io/npm/dm/safe-array-concat.svg
+[downloads-url]: https://npm-stat.com/charts.html?package=safe-array-concat
+[codecov-image]: https://codecov.io/gh/ljharb/safe-array-concat/branch/main/graphs/badge.svg
+[codecov-url]: https://app.codecov.io/gh/ljharb/safe-array-concat/
+[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/safe-array-concat
+[actions-url]: https://github.com/ljharb/safe-array-concat/actions
Index: frontend/node_modules/safe-array-concat/index.d.ts
===================================================================
--- frontend/node_modules/safe-array-concat/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+declare function safeArrayConcat<T = unknown>(
+    item: T | readonly T[],
+    ...items: (T | readonly T[])[],
+): T[];
+
+export = safeArrayConcat;
Index: frontend/node_modules/safe-array-concat/index.js
===================================================================
--- frontend/node_modules/safe-array-concat/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+'use strict';
+
+var GetIntrinsic = require('get-intrinsic');
+var $concat = GetIntrinsic('%Array.prototype.concat%');
+
+var callBind = require('call-bind');
+
+var callBound = require('call-bound');
+var $slice = callBound('Array.prototype.slice');
+
+var hasSymbols = require('has-symbols/shams')();
+var isConcatSpreadable = hasSymbols && Symbol.isConcatSpreadable;
+
+/** @type {never[]} */ var empty = [];
+var $concatApply = isConcatSpreadable ? callBind.apply($concat, empty) : null;
+
+// eslint-disable-next-line no-extra-parens
+var isArray = isConcatSpreadable ? /** @type {(value: unknown) => value is unknown[]} */ (require('isarray')) : null;
+
+/** @type {import('.')} */
+module.exports = isConcatSpreadable
+	// eslint-disable-next-line no-unused-vars
+	? function safeArrayConcat(item) {
+		for (var i = 0; i < arguments.length; i += 1) {
+			/** @type {typeof item} */ var arg = arguments[i];
+			// @ts-expect-error ts(2538) see https://github.com/microsoft/TypeScript/issues/9998#issuecomment-1890787975; works if `const`
+			if (arg && typeof arg === 'object' && typeof arg[isConcatSpreadable] === 'boolean') {
+				// @ts-expect-error ts(7015) TS doesn't yet support Symbol indexing
+				if (!empty[isConcatSpreadable]) {
+					// @ts-expect-error ts(7015) TS doesn't yet support Symbol indexing
+					empty[isConcatSpreadable] = true;
+				}
+				// @ts-expect-error ts(2721) ts(18047) not sure why TS can't figure out this can't be null
+				var arr = isArray(arg) ? $slice(arg) : [arg];
+				// @ts-expect-error ts(7015) TS can't handle expandos on an array
+				arr[isConcatSpreadable] = true; // shadow the property. TODO: use [[Define]]
+				arguments[i] = arr;
+			}
+		}
+		// @ts-expect-error ts(2345) https://github.com/microsoft/TypeScript/issues/57164 TS doesn't understand that apply can take an arguments object
+		return $concatApply(arguments);
+	}
+	: callBind($concat, empty);
Index: frontend/node_modules/safe-array-concat/package.json
===================================================================
--- frontend/node_modules/safe-array-concat/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,89 @@
+{
+	"name": "safe-array-concat",
+	"version": "1.1.4",
+	"description": "`Array.prototype.concat`, but made safe by ignoring Symbol.isConcatSpreadable",
+	"main": "index.js",
+	"exports": {
+		".": "./index.js",
+		"./package.json": "./package.json"
+	},
+	"sideEffects": false,
+	"scripts": {
+		"prepack": "npmignore --auto --commentLines=autogenerated",
+		"version": "auto-changelog && git add CHANGELOG.md",
+		"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"",
+		"prelint": "evalmd README.md",
+		"lint": "eslint --ext=js,mjs .",
+		"postlint": "tsc && attw -P",
+		"prepublish": "not-in-publish || npm run prepublishOnly",
+		"prepublishOnly": "safe-publish-latest",
+		"pretest": "npm run lint",
+		"tests-only": "nyc tape test",
+		"test": "npm run tests-only",
+		"posttest": "npx npm@'>= 10.2' audit --production"
+	},
+	"keywords": [
+		"safe",
+		"Array",
+		"concat",
+		"push",
+		"isConcatSpreadable"
+	],
+	"author": "Jordan Harband <ljharb@gmail.com>",
+	"funding": {
+		"url": "https://github.com/sponsors/ljharb"
+	},
+	"license": "MIT",
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/ljharb/safe-array-concat.git"
+	},
+	"bugs": {
+		"url": "https://github.com/ljharb/safe-array-concat/issues"
+	},
+	"homepage": "https://github.com/ljharb/safe-array-concat#readme",
+	"devDependencies": {
+		"@arethetypeswrong/cli": "^0.18.2",
+		"@ljharb/eslint-config": "^22.2.2",
+		"@ljharb/tsconfig": "^0.3.2",
+		"@types/call-bind": "^1.0.5",
+		"@types/get-intrinsic": "^1.2.3",
+		"@types/isarray": "^2.0.3",
+		"@types/tape": "^5.8.1",
+		"auto-changelog": "^2.5.0",
+		"encoding": "^0.1.13",
+		"eslint": "^8.57.1",
+		"evalmd": "^0.0.19",
+		"in-publish": "^2.0.1",
+		"mock-property": "^1.1.0",
+		"npmignore": "^0.3.5",
+		"nyc": "^10.3.2",
+		"safe-publish-latest": "^2.0.0",
+		"set-function-length": "^1.2.2",
+		"tape": "^5.9.0",
+		"typescript": "next"
+	},
+	"dependencies": {
+		"call-bind": "^1.0.9",
+		"call-bound": "^1.0.4",
+		"get-intrinsic": "^1.3.0",
+		"has-symbols": "^1.1.0",
+		"isarray": "^2.0.5"
+	},
+	"auto-changelog": {
+		"output": "CHANGELOG.md",
+		"template": "keepachangelog",
+		"unreleased": false,
+		"commitLimit": false,
+		"backfillLimit": false,
+		"hideCredit": true
+	},
+	"publishConfig": {
+		"ignore": [
+			".github/workflows"
+		]
+	},
+	"engines": {
+		"node": ">=0.4"
+	}
+}
Index: frontend/node_modules/safe-array-concat/test/index.js
===================================================================
--- frontend/node_modules/safe-array-concat/test/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/test/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,100 @@
+'use strict';
+
+var test = require('tape');
+var mockProperty = require('mock-property');
+var hasSymbols = require('has-symbols/shams')();
+var isConcatSpreadable = hasSymbols && Symbol.isConcatSpreadable;
+var species = hasSymbols && Symbol.species;
+
+var boundFnsHaveConfigurableLengths = require('set-function-length/env').boundFnsHaveConfigurableLengths;
+
+var safeConcat = require('../');
+
+test('safe-array-concat', function (t) {
+	t.equal(typeof safeConcat, 'function', 'is a function');
+	t.equal(
+		safeConcat.length,
+		boundFnsHaveConfigurableLengths ? 1 : 0,
+		'has a length of ' + (boundFnsHaveConfigurableLengths ? 1 : '0 (function lengths are not configurable)')
+	);
+
+	t.deepEqual(
+		// eslint-disable-next-line no-extra-parens
+		safeConcat(/** @type {(string | number | number[])[]} */ ([1, 2]), [3, 4], 'foo', 5, 6, [[7]]),
+		[1, 2, 3, 4, 'foo', 5, 6, [7]],
+		'works with flat and nested arrays'
+	);
+
+	t.deepEqual(
+		safeConcat(undefined, 1, 2),
+		[undefined, 1, 2],
+		'first item as undefined is not the concat receiver, which would throw via ToObject'
+	);
+	t.deepEqual(
+		safeConcat(null, 1, 2),
+		[null, 1, 2],
+		'first item as null is not the concat receiver, which would throw via ToObject'
+	);
+
+	var arr = [1, 2];
+	arr.constructor = function C() {
+		return { args: arguments };
+	};
+	t.deepEqual(
+		safeConcat(arr, 3, 4),
+		[1, 2, 3, 4],
+		'first item as an array with a nonArray .constructor; ignores constructor'
+	);
+
+	t.test('has Symbol.species', { skip: !species }, function (st) {
+		var speciesArr = [1, 2];
+		// @ts-expect-error ts(2740) TS's `constructor` type requires a function
+		speciesArr.constructor = {};
+		// @ts-expect-error ts(2538) TS can't type narrow from tape's `skip`
+		speciesArr.constructor[species] = function Species() {
+			return { args: arguments };
+		};
+
+		st.deepEqual(
+			safeConcat(speciesArr, 3, 4),
+			[1, 2, 3, 4],
+			'first item as an array with a .constructor object with a Symbol.species; ignores constructor and species'
+		);
+
+		st.end();
+	});
+
+	t.test('has isConcatSpreadable', { skip: !isConcatSpreadable }, function (st) {
+		// TS can't type narrow from tape's `skip`
+		if (isConcatSpreadable) {
+			st.teardown(mockProperty(
+				// eslint-disable-next-line no-extra-parens
+				/** @type {Record<PropertyKey, unknown>} */ (/** @type {unknown} */ (String.prototype)),
+				isConcatSpreadable,
+				{ value: true }
+			));
+
+			var nonSpreadable = [1, 2];
+			// @ts-expect-error ts(7015) TS can't handle expandos on an array
+			nonSpreadable[isConcatSpreadable] = false;
+
+			st.deepEqual(
+				safeConcat(nonSpreadable, 3, 4, 'foo', Object('bar')),
+				[1, 2, 3, 4, 'foo', Object('bar')],
+				'a non-concat-spreadable array is spreaded, and a concat-spreadable String is not spreaded'
+			);
+
+			st.teardown(mockProperty(Array.prototype, isConcatSpreadable, { value: false }));
+
+			st.deepEqual(
+				safeConcat([1, 2], 3, 4, 'foo', Object('bar')),
+				[1, 2, 3, 4, 'foo', Object('bar')],
+				'all arrays marked non-concat-spreadable are still spreaded, and a concat-spreadable String is not spreaded'
+			);
+		}
+
+		st.end();
+	});
+
+	t.end();
+});
Index: frontend/node_modules/safe-array-concat/tsconfig.json
===================================================================
--- frontend/node_modules/safe-array-concat/tsconfig.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/safe-array-concat/tsconfig.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,9 @@
+{
+  "extends": "@ljharb/tsconfig",
+  "compilerOptions": {
+    "target": "es2021",
+  },
+  "exclude": [
+    "coverage",
+  ],
+}
