diff --git a/docs/docs/03-recipes/01-adding-custom-content.mdx b/docs/docs/03-recipes/01-adding-custom-content.mdx new file mode 100644 index 00000000..f44a2b1f --- /dev/null +++ b/docs/docs/03-recipes/01-adding-custom-content.mdx @@ -0,0 +1,148 @@ +--- +sidebar_position: 1 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Adding custom content + +Proxies and servers could need custom content like maps, plugins, mods +or any other file. + +## Ways of retrieving content + +Additional content can be retrieved in several ways, all of them could +by used for any content. + + + + +The most straightforward way of downloading files is via a direct URL. +It is attended that the URL is a direct link to the file, without any +authentication layer. Otherwise it should be specified directly in the +URL, thus exposing the credentials to the public. + +```yaml showLineNumbers +url: https://example.com/my-file.tar.gz +``` + + + + + +Most useful for JAR archives, Maven repositories can be used to download +files. The URL is composed of the repository URL, the group ID, the +artifact ID and the version. Optionally, one can specify a secret name +containing the credentials to use to authenticate agaisnt the repository. + +```yaml showLineNumbers +urlFrom: + mavenRef: + repository: https://example.com/maven + groupId: com.example + artifactId: myplugin + version: '1.0.0' + credentialsSecretName: example-repo-secret +``` + + + + +## Adding plugins + +> Applicable to: proxies, servers + +Shulker can automatically download plugins from different sources and +place them in the `plugins` folder of your proxy or server. It is +expected to download JAR files. They should not be packed in an archive. + +Here is how to add two plugins, one using a direct URL, the other from +a Maven repository. + +:::note + +While the following example is a `MinecraftServerFleet`, the same applies +for a `ProxyFleet`. + +::: + +```yaml title="server.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: my-server +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + config: + plugins: + - url: https://example.com/my-plugin.jar + - urlFrom: + mavenRef: + repository: https://example.com/maven + groupId: com.example + artifactId: myplugin + version: '1.0.0' + credentialsSecretName: example-repo-secret +``` + +## Adding maps + +> Applicable to: servers + +Some servers may need maps to be downloaded before the server is started. +This may be used for ephemeral servers using the same map, like minigames. + +Shulker can download a tar-gzipped archive and extract it at the server +root directory. + +```yaml title="server.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: my-server +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + config: + world: + url: https://example.com/my-worlds.tar.gz +``` + +## Adding patches + +> Applicable to: proxies, servers + +Patches are tar-gzipped archives that are extracted at the root of the +server, overwriting existing files. They can be used to _patch_ the server +content. They are applied in the order specified in the configuration. + +```yaml title="server.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: my-server +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + config: + patches: + - url: https://example.com/my-first-patch.tar.gz + - url: https://example.com/my-second-patch.tar.gz +``` + +## Real-world example + +You can find a real-world example of a `ProxyFleet` and `MinecraftServerFleet` +with additional content by looking at the `with-custom-configuration` example +**[from the repository](https://github.com/jeremylvln/Shulker/tree/main/examples/with-custom-configuration)**. \ No newline at end of file diff --git a/docs/docs/03-recipes/01-minecraft-cluster.md b/docs/docs/03-recipes/01-minecraft-cluster.md deleted file mode 100644 index c73fdf71..00000000 --- a/docs/docs/03-recipes/01-minecraft-cluster.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Minecraft Cluster - -TODO diff --git a/docs/docs/03-recipes/enabling-proxy-protocol.md b/docs/docs/03-recipes/enabling-proxy-protocol.md new file mode 100644 index 00000000..686794e6 --- /dev/null +++ b/docs/docs/03-recipes/enabling-proxy-protocol.md @@ -0,0 +1,54 @@ +# Enabling Proxy Protocol + +Most of the time, the IP address received by your proxy will be the +one of the cloud provider's load balancer, thus not the one of the +connecting player. + +This is a problem because Shulker configures the proxies to expect +that the connecting IP is the same than the one the player used to +authenticate agaisn't Mojang's servers. This is one way to prevent +spoofing attacks. + +The Proxy Protocol is a protocol that allows the load balancer to +send the real IP address of the client to the underlying service, here +the proxy. It is supported by most cloud providers. + +To enable it, you need to set the `proxyProtocol` option to `true` in +the configuration of your proxy: + +```yaml title="proxy.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: ProxyFleet +metadata: + name: proxy +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + config: + proxyProtocol: true +``` + +:::note + +You'll may need to set the `externalTrafficPolicy` of the Kubernetes +Service created for the `ProxyFleet` to `Local`, to avoid having one of +your node forwarding traffic to another. + +::: + +:::note + +Your cloud provider *may* also expect you of adding some annotations to +the Service as well for them to configure properly your load balancer. +Check out your cloud provider documentation to learn more. + +::: + +## Real-world example + +You can find a real-world example of a `ProxyFleet` with proxy protocol +enabled, for Scaleway Cloud Provider, by looking at the `with-proxy-protocol` +example **[from the repository](https://github.com/jeremylvln/Shulker/tree/main/examples/with-proxy-protocol)**. diff --git a/docs/docs/03-recipes/overriding-pod-properties.md b/docs/docs/03-recipes/overriding-pod-properties.md new file mode 100644 index 00000000..b86c3db4 --- /dev/null +++ b/docs/docs/03-recipes/overriding-pod-properties.md @@ -0,0 +1,75 @@ +# Overriding Pod properties + +To suit your needs, you may need to override or complete some +properties filled to the underlying Pod. The `podOverrides` +property of both the `ProxyFleet` and `MinecraftServerFleet` +allows you to customize the Pod properties as you were writing +a Pod directly (i.e. the supported sub-properties are identical +to the Pod specification). + +You can find all the properties overridable by looking at the +`shulker-crds` package of the repository: + +- [ProxyFleet](https://github.com/jeremylvln/Shulker/blob/main/packages/shulker-crds/v1alpha1/proxyfleet_types.go) +- [MinecraftServerFleet](https://github.com/jeremylvln/Shulker/blob/main/packages/shulker-crds/v1alpha1/minecraftserverfleet_types.go) + +## Add environment variables + +Shulker already injects some environment variables that could +be useful. But adding your own is fully supported: + +```yaml title="server.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: my-server +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + podOverrides: + env: + - name: OPENMATCH_HOST + value: open-match-frontend.open-match.svc + - name: OPENMATCH_PORT + value: '50504' +``` + +## Setting custom affinities + +By default, Agones adds a **preferred* scheduling on nodes +labelled with `agones.dev/role=gameserver`. However you +may want to customize more the scheduling behavior. + +For instance, you may want to restrict some servers to some +nodes: + +```yaml title="server.yaml" showLineNumbers +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: my-server +spec: + clusterRef: + name: my-cluster + replicas: 1 + template: + spec: + podOverrides: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: devops.example.com/gameserver + operator: In + values: + - my-server + tolerations: + - key: "devops.example.com/gameserver" + operator: "Equal" + value: "my-server" + effect: "NoSchedule" +``` diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ed525bdd..d70836ab 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -55,7 +55,7 @@ const config = { }, { type: 'doc', - docId: 'recipes/minecraft-cluster', + docId: 'recipes/adding-custom-content', position: 'left', label: 'Recipes', }, @@ -82,7 +82,7 @@ const config = { }, { label: 'Recipes', - to: '/recipes/minecraft-cluster', + to: '/recipes/adding-custom-content', }, ], }, diff --git a/examples/with-custom-configuration/cluster.yaml b/examples/with-custom-configuration/cluster.yaml new file mode 100644 index 00000000..39e046bf --- /dev/null +++ b/examples/with-custom-configuration/cluster.yaml @@ -0,0 +1,5 @@ +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftCluster +metadata: + name: getting-started +spec: {} diff --git a/examples/with-custom-configuration/kustomization.yaml b/examples/with-custom-configuration/kustomization.yaml new file mode 100644 index 00000000..073869c1 --- /dev/null +++ b/examples/with-custom-configuration/kustomization.yaml @@ -0,0 +1,4 @@ +resources: +- cluster.yaml +- proxy.yaml +- minecraftserver.yaml diff --git a/examples/with-custom-configuration/minecraftserver.yaml b/examples/with-custom-configuration/minecraftserver.yaml new file mode 100644 index 00000000..c3ba7dae --- /dev/null +++ b/examples/with-custom-configuration/minecraftserver.yaml @@ -0,0 +1,31 @@ +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftServerFleet +metadata: + name: limbo +spec: + clusterRef: + name: getting-started + replicas: 1 + template: + spec: + tags: + - limbo + version: + channel: Paper + name: '1.19.3' + config: + world: + url: https://example.com/my-world.tar.gz + plugins: + - urlFrom: + mavenRef: + repository: https://example.com/maven + groupId: com.example + artifactId: myplugin + version: '1.0.0' + credentialsSecretName: example-repo-secret + patches: + - url: https://example.com/add-config-to-myplugin.tar.gz + - url: https://example.com/add-something-after.tar.gz + - url: https://example.com/remove-everything-at-the-end.tar.gz + maxPlayers: 100 diff --git a/examples/with-custom-configuration/proxy.yaml b/examples/with-custom-configuration/proxy.yaml new file mode 100644 index 00000000..b5e637c6 --- /dev/null +++ b/examples/with-custom-configuration/proxy.yaml @@ -0,0 +1,30 @@ +apiVersion: shulkermc.io/v1alpha1 +kind: ProxyFleet +metadata: + name: public +spec: + clusterRef: + name: getting-started + replicas: 1 + service: + type: LoadBalancer + externalTrafficPolicy: Local + template: + spec: + version: + channel: Velocity + name: latest + config: + plugins: + - urlFrom: + mavenRef: + repository: https://example.com/maven + groupId: com.example + artifactId: myplugin + version: '1.0.0' + credentialsSecretName: example-repo-secret + patches: + - url: https://example.com/add-config-to-myplugin.tar.gz + - url: https://example.com/add-something-after.tar.gz + - url: https://example.com/remove-everything-at-the-end.tar.gz + maxPlayers: 100 diff --git a/examples/with-proxy-protocol/cluster.yaml b/examples/with-proxy-protocol/cluster.yaml new file mode 100644 index 00000000..39e046bf --- /dev/null +++ b/examples/with-proxy-protocol/cluster.yaml @@ -0,0 +1,5 @@ +apiVersion: shulkermc.io/v1alpha1 +kind: MinecraftCluster +metadata: + name: getting-started +spec: {} diff --git a/examples/with-proxy-protocol/kustomization.yaml b/examples/with-proxy-protocol/kustomization.yaml new file mode 100644 index 00000000..e059831a --- /dev/null +++ b/examples/with-proxy-protocol/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- cluster.yaml +- proxy.yaml diff --git a/examples/with-proxy-protocol/proxy.yaml b/examples/with-proxy-protocol/proxy.yaml new file mode 100644 index 00000000..513b9335 --- /dev/null +++ b/examples/with-proxy-protocol/proxy.yaml @@ -0,0 +1,21 @@ +apiVersion: shulkermc.io/v1alpha1 +kind: ProxyFleet +metadata: + name: public +spec: + clusterRef: + name: getting-started + replicas: 1 + service: + type: LoadBalancer + externalTrafficPolicy: Local + annotations: + service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: "true" + service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true" + template: + spec: + version: + channel: Velocity + name: latest + config: + proxyProtocol: true diff --git a/package-lock.json b/package-lock.json index a0d183b1..02a29e15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12128,7 +12128,6 @@ "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15323,7 +15322,8 @@ "@mdx-js/react": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==" + "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", + "requires": {} }, "@mdx-js/util": { "version": "1.6.22", @@ -15497,42 +15497,50 @@ "@svgr/babel-plugin-add-jsx-attribute": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==" + "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "requires": {} }, "@svgr/babel-plugin-remove-jsx-attribute": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.5.0.tgz", - "integrity": "sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==" + "integrity": "sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==", + "requires": {} }, "@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.5.0.tgz", - "integrity": "sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==" + "integrity": "sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==", + "requires": {} }, "@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==" + "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "requires": {} }, "@svgr/babel-plugin-svg-dynamic-title": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==" + "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "requires": {} }, "@svgr/babel-plugin-svg-em-dimensions": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==" + "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "requires": {} }, "@svgr/babel-plugin-transform-react-native-svg": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==" + "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "requires": {} }, "@svgr/babel-plugin-transform-svg-component": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==" + "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "requires": {} }, "@svgr/babel-preset": { "version": "6.5.1", @@ -16110,7 +16118,8 @@ "acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "requires": {} }, "acorn-walk": { "version": "8.2.0", @@ -16171,7 +16180,8 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} }, "algoliasearch": { "version": "4.14.3", @@ -17163,7 +17173,8 @@ "css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==" + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", + "requires": {} }, "css-loader": { "version": "6.7.3", @@ -17333,7 +17344,8 @@ "cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "requires": {} }, "csso": { "version": "4.2.0", @@ -18715,7 +18727,8 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} }, "ieee754": { "version": "1.2.1", @@ -19974,22 +19987,26 @@ "postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "requires": {} }, "postcss-discard-unused": { "version": "5.1.0", @@ -20087,7 +20104,8 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -20118,7 +20136,8 @@ "postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -20262,7 +20281,8 @@ "postcss-zindex": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", - "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==" + "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", + "requires": {} }, "prepend-http": { "version": "2.0.0", @@ -20292,7 +20312,8 @@ "prism-react-renderer": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", - "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==" + "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==", + "requires": {} }, "prismjs": { "version": "1.29.0", @@ -21984,8 +22005,7 @@ "typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" }, "ua-parser-js": { "version": "0.7.32", @@ -22232,12 +22252,14 @@ "use-composed-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==" + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "requires": {} }, "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} }, "use-latest": { "version": "1.2.1", @@ -22556,7 +22578,8 @@ "ws": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==" + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} } } }, @@ -22689,7 +22712,8 @@ "ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} }, "xdg-basedir": { "version": "4.0.0",