diff --git a/latest/404.html b/latest/404.html index 0aea49c..3bc7e6c 100644 --- a/latest/404.html +++ b/latest/404.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../v2.0.1/404.html... + Redirecting to ../v2.0.2/404.html... \ No newline at end of file diff --git a/latest/admin-guide/admin-configuration/index.html b/latest/admin-guide/admin-configuration/index.html index 07d4263..9832a93 100644 --- a/latest/admin-guide/admin-configuration/index.html +++ b/latest/admin-guide/admin-configuration/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/admin-guide/admin-configuration/... + Redirecting to ../../../v2.0.2/admin-guide/admin-configuration/... \ No newline at end of file diff --git a/latest/admin-guide/admin-getting-started/index.html b/latest/admin-guide/admin-getting-started/index.html index dbf76ab..bcc323a 100644 --- a/latest/admin-guide/admin-getting-started/index.html +++ b/latest/admin-guide/admin-getting-started/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/admin-guide/admin-getting-started/... + Redirecting to ../../../v2.0.2/admin-guide/admin-getting-started/... \ No newline at end of file diff --git a/latest/articles/authn-authz/index.html b/latest/articles/authn-authz/index.html index e750771..004a67c 100644 --- a/latest/articles/authn-authz/index.html +++ b/latest/articles/authn-authz/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/authn-authz/... + Redirecting to ../../../v2.0.2/articles/authn-authz/... \ No newline at end of file diff --git a/latest/articles/benchmarking-with-zb/index.html b/latest/articles/benchmarking-with-zb/index.html index b3416b7..4053ba9 100644 --- a/latest/articles/benchmarking-with-zb/index.html +++ b/latest/articles/benchmarking-with-zb/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/benchmarking-with-zb/... + Redirecting to ../../../v2.0.2/articles/benchmarking-with-zb/... \ No newline at end of file diff --git a/latest/articles/building-ci-cd-pipeline/index.html b/latest/articles/building-ci-cd-pipeline/index.html index 93c2ddc..148ca9b 100644 --- a/latest/articles/building-ci-cd-pipeline/index.html +++ b/latest/articles/building-ci-cd-pipeline/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/building-ci-cd-pipeline/... + Redirecting to ../../../v2.0.2/articles/building-ci-cd-pipeline/... \ No newline at end of file diff --git a/latest/articles/clustering/index.html b/latest/articles/clustering/index.html index 9cfcc66..d0ca945 100644 --- a/latest/articles/clustering/index.html +++ b/latest/articles/clustering/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/clustering/... + Redirecting to ../../../v2.0.2/articles/clustering/... \ No newline at end of file diff --git a/latest/articles/graphql/index.html b/latest/articles/graphql/index.html index a403ca8..63e9092 100644 --- a/latest/articles/graphql/index.html +++ b/latest/articles/graphql/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/graphql/... + Redirecting to ../../../v2.0.2/articles/graphql/... \ No newline at end of file diff --git a/latest/articles/immutable-tags/index.html b/latest/articles/immutable-tags/index.html new file mode 100644 index 0000000..1f81012 --- /dev/null +++ b/latest/articles/immutable-tags/index.html @@ -0,0 +1,17 @@ + + + + + Redirecting + + + + + Redirecting to ../../../v2.0.2/articles/immutable-tags/... + + \ No newline at end of file diff --git a/latest/articles/kind-deploy/index.html b/latest/articles/kind-deploy/index.html index 3cb6e65..f67927f 100644 --- a/latest/articles/kind-deploy/index.html +++ b/latest/articles/kind-deploy/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/kind-deploy/... + Redirecting to ../../../v2.0.2/articles/kind-deploy/... \ No newline at end of file diff --git a/latest/articles/mirroring/index.html b/latest/articles/mirroring/index.html index 27f210f..15af30b 100644 --- a/latest/articles/mirroring/index.html +++ b/latest/articles/mirroring/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/mirroring/... + Redirecting to ../../../v2.0.2/articles/mirroring/... \ No newline at end of file diff --git a/latest/articles/monitoring/index.html b/latest/articles/monitoring/index.html index f06afc7..116248f 100644 --- a/latest/articles/monitoring/index.html +++ b/latest/articles/monitoring/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/monitoring/... + Redirecting to ../../../v2.0.2/articles/monitoring/... \ No newline at end of file diff --git a/latest/articles/pprofiling/index.html b/latest/articles/pprofiling/index.html index 1eb49f2..066784b 100644 --- a/latest/articles/pprofiling/index.html +++ b/latest/articles/pprofiling/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/pprofiling/... + Redirecting to ../../../v2.0.2/articles/pprofiling/... \ No newline at end of file diff --git a/latest/articles/retention/index.html b/latest/articles/retention/index.html index e70ba71..1abae58 100644 --- a/latest/articles/retention/index.html +++ b/latest/articles/retention/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/retention/... + Redirecting to ../../../v2.0.2/articles/retention/... \ No newline at end of file diff --git a/latest/articles/security-posture/index.html b/latest/articles/security-posture/index.html index 7a8fdef..fa02dfb 100644 --- a/latest/articles/security-posture/index.html +++ b/latest/articles/security-posture/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/security-posture/... + Redirecting to ../../../v2.0.2/articles/security-posture/... \ No newline at end of file diff --git a/latest/articles/storage/index.html b/latest/articles/storage/index.html index 5310b8f..7c629ed 100644 --- a/latest/articles/storage/index.html +++ b/latest/articles/storage/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/storage/... + Redirecting to ../../../v2.0.2/articles/storage/... \ No newline at end of file diff --git a/latest/articles/verifying-signatures/index.html b/latest/articles/verifying-signatures/index.html index ba89d02..09e06de 100644 --- a/latest/articles/verifying-signatures/index.html +++ b/latest/articles/verifying-signatures/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/verifying-signatures/... + Redirecting to ../../../v2.0.2/articles/verifying-signatures/... \ No newline at end of file diff --git a/latest/articles/workflow/index.html b/latest/articles/workflow/index.html index 53c5599..6ad0f1c 100644 --- a/latest/articles/workflow/index.html +++ b/latest/articles/workflow/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/workflow/... + Redirecting to ../../../v2.0.2/articles/workflow/... \ No newline at end of file diff --git a/latest/developer-guide/api-reference/index.html b/latest/developer-guide/api-reference/index.html index 0fa1549..db98591 100644 --- a/latest/developer-guide/api-reference/index.html +++ b/latest/developer-guide/api-reference/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/api-reference/... + Redirecting to ../../../v2.0.2/developer-guide/api-reference/... \ No newline at end of file diff --git a/latest/developer-guide/api-user-guide/index.html b/latest/developer-guide/api-user-guide/index.html index 33fa4c6..2a77f4f 100644 --- a/latest/developer-guide/api-user-guide/index.html +++ b/latest/developer-guide/api-user-guide/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/api-user-guide/... + Redirecting to ../../../v2.0.2/developer-guide/api-user-guide/... \ No newline at end of file diff --git a/latest/developer-guide/contributing/index.html b/latest/developer-guide/contributing/index.html index 15c00b0..c3fa106 100644 --- a/latest/developer-guide/contributing/index.html +++ b/latest/developer-guide/contributing/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/contributing/... + Redirecting to ../../../v2.0.2/developer-guide/contributing/... \ No newline at end of file diff --git a/latest/developer-guide/extensions-dev/index.html b/latest/developer-guide/extensions-dev/index.html index 180f863..fe7c709 100644 --- a/latest/developer-guide/extensions-dev/index.html +++ b/latest/developer-guide/extensions-dev/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/extensions-dev/... + Redirecting to ../../../v2.0.2/developer-guide/extensions-dev/... \ No newline at end of file diff --git a/latest/developer-guide/onboarding/index.html b/latest/developer-guide/onboarding/index.html index 6f0d5fc..fd33037 100644 --- a/latest/developer-guide/onboarding/index.html +++ b/latest/developer-guide/onboarding/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/onboarding/... + Redirecting to ../../../v2.0.2/developer-guide/onboarding/... \ No newline at end of file diff --git a/latest/general/architecture/index.html b/latest/general/architecture/index.html index 4819a3d..1435238 100644 --- a/latest/general/architecture/index.html +++ b/latest/general/architecture/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/architecture/... + Redirecting to ../../../v2.0.2/general/architecture/... \ No newline at end of file diff --git a/latest/general/concepts/index.html b/latest/general/concepts/index.html index 4430e56..c6e00c2 100644 --- a/latest/general/concepts/index.html +++ b/latest/general/concepts/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/concepts/... + Redirecting to ../../../v2.0.2/general/concepts/... \ No newline at end of file diff --git a/latest/general/extensions/index.html b/latest/general/extensions/index.html index a994523..51a37cc 100644 --- a/latest/general/extensions/index.html +++ b/latest/general/extensions/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/extensions/... + Redirecting to ../../../v2.0.2/general/extensions/... \ No newline at end of file diff --git a/latest/general/features/index.html b/latest/general/features/index.html index 490b3f8..c26a00d 100644 --- a/latest/general/features/index.html +++ b/latest/general/features/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/features/... + Redirecting to ../../../v2.0.2/general/features/... \ No newline at end of file diff --git a/latest/general/glossary/index.html b/latest/general/glossary/index.html index 4b862be..919affd 100644 --- a/latest/general/glossary/index.html +++ b/latest/general/glossary/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/glossary/... + Redirecting to ../../../v2.0.2/general/glossary/... \ No newline at end of file diff --git a/latest/general/project/index.html b/latest/general/project/index.html index 21c9878..3dd2cdc 100644 --- a/latest/general/project/index.html +++ b/latest/general/project/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/project/... + Redirecting to ../../../v2.0.2/general/project/... \ No newline at end of file diff --git a/latest/general/releases/index.html b/latest/general/releases/index.html index 1b13a50..916673f 100644 --- a/latest/general/releases/index.html +++ b/latest/general/releases/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/releases/... + Redirecting to ../../../v2.0.2/general/releases/... \ No newline at end of file diff --git a/latest/general/whats-new/index.html b/latest/general/whats-new/index.html index 3a6f2a5..3b9665e 100644 --- a/latest/general/whats-new/index.html +++ b/latest/general/whats-new/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/whats-new/... + Redirecting to ../../../v2.0.2/general/whats-new/... \ No newline at end of file diff --git a/latest/index.html b/latest/index.html index c3657da..1959f8f 100644 --- a/latest/index.html +++ b/latest/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../v2.0.1/... + Redirecting to ../v2.0.2/... \ No newline at end of file diff --git a/latest/install-guides/install-guide-k8s/index.html b/latest/install-guides/install-guide-k8s/index.html index 7b3560f..fee5175 100644 --- a/latest/install-guides/install-guide-k8s/index.html +++ b/latest/install-guides/install-guide-k8s/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/install-guides/install-guide-k8s/... + Redirecting to ../../../v2.0.2/install-guides/install-guide-k8s/... \ No newline at end of file diff --git a/latest/install-guides/install-guide-linux/index.html b/latest/install-guides/install-guide-linux/index.html index eae4aca..9e121ec 100644 --- a/latest/install-guides/install-guide-linux/index.html +++ b/latest/install-guides/install-guide-linux/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/install-guides/install-guide-linux/... + Redirecting to ../../../v2.0.2/install-guides/install-guide-linux/... \ No newline at end of file diff --git a/latest/user-guides/user-guide-datapath/index.html b/latest/user-guides/user-guide-datapath/index.html index cbb58e1..58e66de 100644 --- a/latest/user-guides/user-guide-datapath/index.html +++ b/latest/user-guides/user-guide-datapath/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/user-guide-datapath/... + Redirecting to ../../../v2.0.2/user-guides/user-guide-datapath/... \ No newline at end of file diff --git a/latest/user-guides/user-guide-gui/index.html b/latest/user-guides/user-guide-gui/index.html index 90a80d0..6276cef 100644 --- a/latest/user-guides/user-guide-gui/index.html +++ b/latest/user-guides/user-guide-gui/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/user-guide-gui/... + Redirecting to ../../../v2.0.2/user-guides/user-guide-gui/... \ No newline at end of file diff --git a/latest/user-guides/zli/index.html b/latest/user-guides/zli/index.html index afc343f..c0d758b 100644 --- a/latest/user-guides/zli/index.html +++ b/latest/user-guides/zli/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/zli/... + Redirecting to ../../../v2.0.2/user-guides/zli/... \ No newline at end of file diff --git a/v2.0.2/404.html b/v2.0.2/404.html new file mode 100644 index 0000000..a4d0111 --- /dev/null +++ b/v2.0.2/404.html @@ -0,0 +1 @@ + zotregistry.dev
\ No newline at end of file diff --git a/v2.0.2/admin-guide/admin-configuration/index.html b/v2.0.2/admin-guide/admin-configuration/index.html new file mode 100644 index 0000000..daee26d --- /dev/null +++ b/v2.0.2/admin-guide/admin-configuration/index.html @@ -0,0 +1,121 @@ + Configuring zot - zotregistry.dev
Skip to content

Configuring zot

👉 The registry administrator configures zot primarily through settings in the configuration file.

Using the information in this guide, you can compose a configuration file with the settings and features you require for your zot registry server.

💡 Before launching zot with a new configuration, we recommend that you verify the syntax of your configuration as described in Verifying the configuration file.

Configuration file

The configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:

  • network
  • storage
  • authentication
  • authorization
  • logging
  • metrics
  • synchronization with other registries
  • clustering

The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:

zot serve config.json

✏ The instructions and examples in this guide use zot as the name of the zot executable file. The examples do not include the path to the executable file.

When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. This initial file is similar to the following example:

{
+    "distSpecVersion": "1.0.1",
+    "storage": {
+        "rootDirectory": "/tmp/zot"
+    },
+    "http": {
+        "address": "127.0.0.1",
+        "port": "8080"
+    },
+    "log": {
+        "level": "debug"
+    }
+}
+

The configuration file contains the Distribution Specification version (distSpecVersion). The structure and content of other attributes are described in the later sections of this guide.

Extensions

Additional registry features that are not a part of the Distribution Specification are allowed to be added as Extensions.

With a full (not minimal) zot image, the following extension features can be enabled and configured under an extensions attribute in the configuration file as shown in the following example.

{
+  ...
+  "extensions": {
+    "metrics": {},
+    "sync": {},
+    "search": {},
+    "scrub": {},
+    "lint": {},
+    "trust": {},
+    "ui": {}
+  }
+}
+

⚠ The extension features are available only with a full zot image. With a minimal zot image, the extensions section is ignored if present.

The following features are configured under the extensions attribute.

An extension feature is usually enabled by the presence of the feature’s attribute under extensions. An extension feature can then be disabled by either omitting the feature attribute or by including an enable attribute with a value of false.

✏ Two API-only extensions, User Preferences and Mgmt, are not enabled or configured under the extensions section of the configuration file. These API-only extensions are enabled as follows:

  • Mgmt is enabled when the Search extension is enabled.

  • User Preferences is enabled when both the Search and UI extensions are enabled.

Enabling and disabling extensions

Following is an example of enabling or disabling a feature in the extensions section. The scrub feature is enabled in these two configurations:

"extensions": {
+  "scrub": {}
+}
+
"extensions": {
+  "scrub": {
+    "enable": true
+  }
+}
+

The scrub feature is disabled in these two configurations:

"extensions": {
+}
+
"extensions": {
+  "scrub": {
+    "enable": false
+  }
+}
+

Developing custom extensions

New functionality can be added to the zot registry by developing custom extensions for integration into zot. For information about developing extensions, see Developing New Extensions.

Network configuration

Use the http attribute in the configuration file to configure the zot network settings, as shown in the following example.

"http": {
+  "address":"127.0.0.1",
+  "port":"8080",
+  "realm":"zot",
+  "tls": {
+    "cert":"test/data/server.cert",
+    "key":"test/data/server.key"
+  }
+}
+

The following table lists the configurable attributes.

Attribute Description
address The IP address of the zot server.
port The port number of the zot server.
realm The security policy domain defined for the server.
tls The included attributes in this section specify the Transport Layer Security (TLS) settings for the server.
cert The path and filename of the server’s SSL/TLS certificate.
key The path and filename of the server’s registry key.

Storage

Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.

Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following simple example.

"storage":{
+  "rootDirectory":"/tmp/zot",
+  "commit": true,
+  "dedupe": true,
+  "gc": true,
+  "gcDelay": "1h",
+  "gcInterval": "24h"
+}
+

With zot, you have the option to store your registry image files either in local filesystem storage or in cloud storage, such as an Amazon Simple Storage Service (S3) bucket.

Local storage

zot can store and serve files from one or more local directories (folders). A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.

✏ Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.

Remote storage

zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS S3 storage service.

For detailed information about configuring S3 storage, see the AWS S3 documentation and Storage Planning with zot.

Storage features

Commit

Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.

Deduplication

Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.

Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.

Garbage collection

After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. The zot configuration model allows for enabling and disabling garbage collection (gc). The model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs.

Scrub

The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.

Configuring storage

For detailed information about configuring local or remote storage and storage features for your zot registry, see Storage Planning with zot.

Security and hardening

Authentication

zot supports authentication by the following methods:

  • TLS mutual authentication

  • Basic local authentication using an htpasswd file

  • LDAP authentication

  • Bearer (OAuth2) authentication using an HTTP Bearer token

For detailed information about configuring authentication for your zot registry, see User Authentication and Authorization with zot.

Identity-based authorization

User identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific repository paths.

For detailed information about configuring access control policies for your zot registry, see User Authentication and Authorization with zot.

Preventing automated attacks with failure delay

Use the auth and failDelay attributes under http in the configuration file to delay the response to an authentication failure. A delayed response helps to prevent automated attacks. The configuration is shown in the following example.

"http": {
+  "auth": {
+    "failDelay": 5
+  }
+}
+

The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.

Rate limiting

You can limit the rate of API calls from users by configuring the Ratelimit attribute in the configuration file, as shown in the following example:

"http": {
+    "address": "127.0.0.1",
+    "port": "8080",
+    "Ratelimit": {
+        "Rate": 10,
+        "Methods": [
+            {
+                "Method": "GET",
+                "Rate": 5
+            }
+        ]
+    }
+}
+

In this example, the Rate attribute directly under Ratelimit sets a global rate limit of ten API calls per second. You can optionally override the global limit for specific API Methods. In this example, API GET calls are limited to five per second.

Additional security features

For detailed information about configuring additional security features for your zot registry, see Security Posture.

Monitoring

zot supports a range of monitoring tools including the following:

  • Logging

    Logging for zot operations is configured with the log attribute in the configuration file.

  • Metrics

    Metrics data is available in a Prometheus format. A full zot image with extensions includes a node exporter. A minimal zot image can use an external node exporter such as zxp.

  • Benchmarking

    The zot project includes the zb tool, which allows you to benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification.

  • Performance profiling

    Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

When zot is deployed in a Kubernetes setup, a site reliability engineering (SRE) operator can monitor service level indicators (SLI) such as metrics and logs. Metrics will appear in Prometheus using the zot metrics extension, while logs will appear in the Elasticsearch stack (ELK stack) using Filebeat.

For detailed information about the monitoring tools, see Monitoring the registry.

For detailed information about benchmarking, see Benchmarking zot with zb.

For detailed information about performance profiling, see Performance Profiling in zot.

Clustering zot

To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.

For detailed information about clustering with zot, see zot Clustering.

Syncing and mirroring registries

A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync extension feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Synchronization between registries can be implemented by periodic polling of the upstream registry or synchronization can occur on demand, when a user pulls an image from the downstream registry.

As with git, wherein every clone is a full repository, you can configure a local zot instance to be a full OCI mirror registry. This allows for a fully distributed disconnected container image build pipeline.

For detailed information about syncing and mirroring, see OCI Registry Mirroring With zot.

Linting uploaded images

The lint extension can check an uploaded image to enforce the presence of required annotations such as the author or the license.

To configure linting, add the lint attribute under extensions in the configuration file, as shown in the following example:

"extensions": {
+    "lint": {
+      "enable": true,
+      "mandatoryAnnotations": ["annot1", "annot2", "annot3"]
+      }
+  }
+

The following table lists the configurable attributes of the lint extension.

Attribute Description
enable If this attribute is missing, incoming image linting is disabled by default. Linting can be enabled by including this attribute and setting it to true.
mandatoryAnnotations A list of annotations that are required to be present in the image being pushed to the repository.

If the mandatory annotations option is configured when you push an image, linter will verify that the mandatory annotations list present in the configuration is also found in the manifest's annotations list. If any annotations are missing, the push is denied.

Verifying the signatures of uploaded images

The trust extension provides a mechanism to verify image signatures using certificates and public keys.

To enable image signature verification, you must add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:

"extensions": {
+  "trust": {
+    "enable": true,
+    "cosign": true,
+    "notation": true
+  }
+}
+

You must also upload public keys (for cosign) or certificates (for notation) that can be used to verify the image signatures.

For detailed information about configuring image signature verification, see Verifying image signatures.

Enabling the registry's graphical user interface

Using the zot graphical user interface (GUI), a user can browse a zot registry for container images and artifacts.

To configure zot's GUI, add the ui attribute under extensions in the configuration file, as shown in the following example:

"extensions": {
+  "ui": {
+    "enable": true
+  }
+}
+

The following table lists the configurable attributes of the ui extension.

Attribute Description
enable If this attribute is missing, the zot GUI is disabled by default. The GUI can be enabled by including this attribute and setting it to true.

Scrubbing the image registry

To check the integrity of the filesystem and the data in the registry, you can schedule a periodic scrub operation. The scrub process traverses the filesystem, verifying that all data blocks are readable. While running, the process may slightly reduce the registry performance.

To enable scrubbing, add the scrub attribute under extensions in the configuration file, as shown in the following example:

"extensions": {
+  "scrub": {
+    "enable": true,
+    "interval": "24h"
+  }
+}
+

The following table lists the configurable attributes for scrubbing the registry.

Attribute Description
enable If this attribute is missing, registry scrubbing is enabled by default. Scrubbing can be disabled by setting this attribute to false.
interval The time interval between periodic scrub operations. This value must be at least two hours (2h).

Scheduling background tasks

Some zot functions, such as garbage collection and registry synchronization, run as background tasks. These tasks are queued and executed by the scheduler.

The scheduler is by default allowed to simultaneously run a maximum number of tasks equal to four times the number of CPUs available to the zot process. For most users, there should be no need to modify this maximum number. If such a need arises, you can configure a new maximum number of simultaneous tasks in the numWorkers property of the scheduler attribute in the configuration file, as shown in the following example.

{
+  "distSpecVersion": "1.1.0-dev",
+  "scheduler": {
+    "numWorkers": 3
+  },
+...
+}
+

Enhanced searching and querying images

While basic searching is always enabled for images in the zot registry, you can enable enhanced registry searching and filtering using graphQL.

Add the search attribute under extensions in the configuration file to enable and configure the enhanced search extension, as shown in the following example.

"extensions": {
+  "search": {
+    "enable": true,
+    "cve": {
+      "updateInterval": "2h"
+    }
+  }
+}
+

The following table lists the configurable attributes for enhanced search.

Attribute Description
enable If this attribute is missing, enhanced search is enabled by default. Enhanced search can be disabled by setting this attribute to false.
cve Extends enhanced search to allow searching of Common Vulnerabilities and Exposures (CVE).
updateInterval Sets the interval at which the searchable database of CVE items is refreshed.

Setting user preferences

The user preferences extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.

The user preferences extension is enabled by default when the search and ui extensions are enabled. There are no other configuration file fields for this extension.

A userprefs API endpoint accepts as a query parameter an action to perform along with any other required parameters for the specified action. The actions currently implemented do not require an HTTP payload, nor do they return any related data other than an HTTP response code.

Current functionality

The current functions implemented by this extension include:

  • Toggling the star (favorites) icon for a repository.
  • Toggling the bookmark icon for a repository.

Toggle repository star

This action sets the repository star property to true if it is false, and to false if it is true.

Action Parameter Parameter Description
toggleStar repo The name of the repository whose star is to be changed

This example toggles a star on a repository named repoName:

PUT
+http://localhost:5000/v2/_zot/ext/userprefs?
+action=toggleStar&repo=repoName
+

Toggle repository bookmark

This action sets the repository bookmark property to true if it is false, and to false if it is true.

Action Parameter Parameter Description
toggleBookmark repo The name of the repository whose bookmark is to be changed

This example toggles a bookmark on a repository named repoName:

PUT
+http://localhost:5000/v2/_zot/ext/userprefs?
+action=toggleBookmark&repo=repoName
+

Verifying the configuration file

Before launching zot, verify the syntax of your configuration file using the following command:

zot verify <configfile>

✏ Verifying the configuration file protects against operator errors and any conflicts arising from zot release version changes.

After verifying your configuration file, you can launch zot with the following command:

zot serve <configfile>


Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.2/admin-guide/admin-getting-started/index.html b/v2.0.2/admin-guide/admin-getting-started/index.html new file mode 100644 index 0000000..d696e3e --- /dev/null +++ b/v2.0.2/admin-guide/admin-getting-started/index.html @@ -0,0 +1,19 @@ + Getting Started - zotregistry.dev
Skip to content

Getting Started with zot Administration

👉 This document helps you to deploy an appropriate zot image or to build zot if desired.

After deploying zot, proceed to Configuring zot to choose and configure the features you need.

Installing zot

How to get zot

The zot project is hosted on GitHub at project-zot. From GitHub, you can download zot executable binary images or full source code.

Supported platforms

zot is officially supported on Linux and Apple MacOS platforms, using Intel or ARM processors. However, development should be possible on any platform that supports the golang toolchain.

OS ARCH Platform
linux amd64 Intel-based Linux servers
linux arm64 ARM-based servers and Raspberry Pi4
darwin amd64 Intel-based MacOS
darwin arm64 ARM-based MacOS
freebsd amd64 Intel-based FreeBSD*
freebsd arm64 ARM-based FreeBSD*

* NOTE: While binary images are available for FreeBSD, building container images is not supported at this time.

About binary images

Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.

Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

Deployment methods

Several options exist for deploying zot:

  • You can launch a zot binary as a container service using a container management tool such as Podman, Docker, or Helm.

  • You can launch zot as a host-level service by downloading a binary image and running it as a systemd service.

  • You can copy or clone the full zot source code and build an image with custom build flags.

Deploying a zot binary image

Executable binary images for supported server platforms and architectures are available from the zot package repository in GitHub.

You can download the appropriate binary image and run it directly on your server, or you can use a container management tool such as Podman, runc, Helm, or Docker to fetch and deploy the image in a container on your server.

💡 For convenience, you can rename the binary image file to simply zot.

Example: Deploying with a container manager

Using a container manager such as Podman, runc, Helm, or Docker, you can install a zot binary image, as in the following examples.

Using podman

podman run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest
+
+podman run -p 5000:5000 ghcr.io/project-zot/zot-minimal-linux-amd64:latest
+
Click here to view an example of deploying using podman.

Using docker

docker run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest
+

Each of these example commands pulls a zot binary image from the GitHub Container Registry (ghcr.io) and launches a zot image registry at http://localhost:5000.

Click here to view an example of deploying using docker.

Building zot from source

Prerequisites

Install golang

Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.

✏ You must use a golang version of at least the minimum specified in go.mod or the build will fail.

Building an executable binary from source

Download or clone the full zot project from GitHub at project-zot. To clone the zot project from GitHub, use this command:

git clone https://github.com/project-zot/zot.git
+

To build zot, execute the make command in the zot directory using the following general syntax:

make OS=os ARCH=architecture {binary | binary-minimal}

  • The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.

  • The binary option builds the full zot binary image with all extensions.

  • The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.

For example, to build a zot image with extensions for an Intel-based linux server, use the following command:

make OS=linux ARCH=amd64 binary
+

The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-linux-amd64-minimal.

💡 For convenience, you can rename the binary image file to simply zot.

Building a zot container image from source

with Stacker

Using the settings in stacker.yaml, you can build a container image that runs the latest zot by running the following command:

make binary-stacker
+

with Docker

A sample Dockerfile is provided on the zot project page in GitHub. You can edit the sample file with your specific values, such as the desired operating system, hardware architecture, and full or minimal build, as in this example:

ARG OS=linux
+ARG ARCH=amd64
+
+RUN make COMMIT=$COMMIT OS=$OS ARCH=$ARCH clean binary-minimal
+

Using your edited Dockerfile, you can build a container image that runs the latest zot by running the following command:

make image
+

Deploying the container image

Deploy the image using your container manager, such as Podman, runc, Helm, or Docker, as in these examples:

with Podman

podman run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest
+

with Docker

docker run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest
+

A container image built with the sample Dockerfile and deployed with the example command results in a running registry at http://localhost:5000. Registry content is stored at .registry, which is bind mounted to /var/lib/registry in the container. By default, auth is disabled. As part of the build, a YAML configuration file is created at /etc/zot/config.yml in the container.

You can override the configuration file with custom configuration settings in the deployment command and in a local configuration file as shown in this example:

podman run --rm -p 8080:8080 \
+  -v $(pwd)/custom-config.yml:/etc/zot/config.yml \
+  -v $(pwd)/registry:/tmp/zot \
+  zot:latest
+

This command causes the registry to listen on port 8080 and to use /tmp/zot for content storage.

We recommend that, when deploying zot, you also install the command line (zli) and benchmarking (zb) packages.

Launching zot

The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:

zot serve config.yml

💡 For convenience, you can rename the binary image file to simply zot.The instructions and examples in this guide use zot as the name of the zot executable file and do not include the path to the executable file.

Next Steps

Configuring zot

You configure zot primarily through adding and modifying settings in the zot configuration file. The configuration file is a JSON or YAML file that contains all configuration settings for zot functions.

When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. You can modify the initial file or you can create a new file.

Follow the instructions in Configuring zot, to compose a configuration file with the settings and features you require for your zot registry server.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/authn-authz/index.html b/v2.0.2/articles/authn-authz/index.html new file mode 100644 index 0000000..820b0b0 --- /dev/null +++ b/v2.0.2/articles/authn-authz/index.html @@ -0,0 +1,188 @@ + Authentication and Authorization - zotregistry.dev
Skip to content

User Authentication and Authorization with zot

👉 A robust set of authentication/authorization options are supported:

  • Authentication

    • TLS, including mTLS
    • Username/password or token-based user authentication
    • LDAP
    • htpasswd
    • OAuth2 with bearer token
  • Authorization

    • Powerful identity-based access controls for repositories or specific repository paths
    • OpenID/OAuth2 social login with Google, GitHub, GitLab, and dex

The zot configuration model supports both authentication and authorization. Authentication credentials allow access to zot HTTP APIs. Authorization policies provide fine-grained control of the actions each authenticated user can perform in the registry.

Authentication

TLS authentication

Because authentication credentials are passed over HTTP, it is imperative that TLS be enabled. You can enable and configure TLS authentication in the zot configuration file, as shown in the following example.

"http": {
+...
+  "tls": {
+    "cert": "/etc/zot/certs/server.cert",
+    "key": "/etc/zot/certs/server.key"
+  }
+

See Mutual TLS authentication for additional information about TLS.

HTTP basic authentication

When basic HTTP authentication is used, the username and password credentials are joined by a colon (:), base64 encoded, and passed in the HTTP Authorization header.

HTTP bearer authentication

To avoid passing the username and password credentials for every HTTP request, a zot client can use bearer token-based authentication. In this method, the client first authenticates with a token server and receives a short-lived token. The client then passes this token in the HTTP Authorization header, specifying Bearer as the authentication scheme.

Configure bearer authentication in the zot configuration file as shown in this example.

"http": {
+...
+  "auth": {
+    "bearer": {
+      "realm": "https://auth.myreg.io/auth/token",
+        "service": "myauth",
+        "cert": "/etc/zot/auth.crt"
+    }
+  }
+

The following table lists the configurable attributes.

Attribute Description
realm A string typically related to the authentication scheme (BASIC and BEARER).
service The name of the authentication service.
cert The path and filename of the server’s SSL/TLS certificate.

Mutual TLS authentication

zot supports basic TLS and password-less mutual TLS authentication (mTLS). Specifying a cacert file in the TLS section of the zot configuration file enables mTLS. The cacert parameter is used to validate the client-side TLS certificates.

"http": {
+...
+  "tls": {
+    "cert": "/etc/zot/certs/server.cert",
+    "key": "/etc/zot/certs/server.key",
+    "cacert": "/etc/zot/certs/ca.cert"
+  }
+

The following table lists the configurable attributes.

Attribute Description
cert The path and filename of the server’s SSL/TLS certificate.
key The path and filename of the server’s registry key.
cacert The path and filename of the server’s cacerts file, which contains trusted certificate authority (CA) certificates.

Preventing automated attacks with failure delay

To help prevent automated attacks, you can add a delayed response to an authentication failure. Configure the failDelay attribute in the configuration file as shown in the following example.

"http": {
+  "auth": {
+    "failDelay": 5
+  }
+}
+

The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.

Server-side authentication

You can implement server-side authentication for zot using htpasswd or LDAP or both.

✏ When both htpasswd and LDAP configuration are specified, LDAP authentication is given preference. Because htpasswd authentication is strictly local and requires no remote service, htpasswd serves as a fail-safe authentication mechanism should LDAP become unavailable.

LDAP

zot supports integration with an LDAP-based authentication service such as Microsoft Windows Active Directory (AD). Enable and configure LDAP authentication in the zot configuration file, as shown in the following example.

"http": {
+...
+  "auth": {
+    "ldap": {
+      "credentialsFile": "examples/config-ldap-credentials.json",
+      "address": "ldap.example.org",
+      "port": 389,
+      "startTLS": false,
+      "baseDN": "ou=Users,dc=example,dc=org",
+      "userAttribute": "uid",
+      "userGroupAttribute": "memberOf",
+      "bindDN": "cn=ldap-searcher,ou=Users,dc=example,dc=org",
+      "bindPassword": "ldap-searcher-password",
+      "skipVerify": false,
+      "subtreeSearch": true
+    }
+  }
+}
+

The following table lists the configurable attributes for LDAP authentication.

Attribute Description
credentialsFile The path to a file containing the bind credentials for LDAP.
address The IP address or hostname of the LDAP server.
port The port number used by the LDAP service.
startTLS Set to true to enable TLS communication with the LDAP server.
baseDN Starting location within the LDAP directory for performing user searches.
userAttribute Attribute name used to obtain the username.
userGroupAttribute Attribute name used to obtain groups to which a user belongs.
skipVerify Skip TLS verification.
subtreeSearch Set to true to expand the scope for search to include subtrees of the base DN.

To allow for separation of configuration and credentials, the credentials for the LDAP server are specified in a separate file, as shown in the following example.

{
+  "bindDN":"cn=ldap-searcher,ou=Users,dc=example,dc=org",
+  "bindPassword":"ldap-searcher-password"
+}
+

The following table lists the configurable attributes of the LDAP credentials file.

Attribute Description
bindDN Base Distinguished Name for the LDAP search.
bindPassword Password of the bind LDAP user.

htpasswd

Enable and configure htpasswd authentication in the zot configuration file, as shown in the following example.

  1. Create and store an htpasswd file on the server.

    $ htpasswd -bBn <username> <password> >> /etc/zot/htpasswd
    +

    ✏ For strong security, make sure to use the -B option, specifying the bcrypt hashing algorithm. This is the only algorithm supported by zot for htpasswd.

  2. Enable htpasswd authentication and configure the path to the htpasswd authentication in the zot configuration file.

    "http": {
    +...
    +  "auth": {
    +      "htpasswd": {
    +        "path": "/etc/zot/htpasswd"
    +      },
    +

    The path attribute specifies the path and filename of the htpasswd file, which contains user names and hashed passwords.

Authorization

With an access scheme that relies solely on authentication, any authenticated user would be given complete access to the registry. To better control access, zot supports identity-based repository-level access control (authorization) policies. The access control policy is a function of repository, user, and the action being performed on that repository.

Access control policies

Five identity-based types of access control policies are supported:

Policy type Attribute Access allowed
Default defaultPolicy The default policy specifies what actions are allowed if a user is authenticated but does match any user-specific policy.
User-specific users, actions A user-specific policy specifies access and actions for explicitly named users.
Group-specific groups, actions A group-specific policy specifies access and actions for explicitly named groups.
Anonymous anonymousPolicy An anonymous policy specifies what an unauthenticated user is allowed to do. This is an appropriate policy when you want to grant open read-only access to one or more repositories.
Admin adminPolicy The admin policy is a global access control policy that grants privileges to perform actions on any repository.

Access control is organized by repositories, users, and their actions. Most users of a particular repository will have similar access control requirements and can be served by a repository-specific defaultPolicy. Should a user require an exception to the default policy, a user-specific or group-specific override policy can be configured.

With an anonymousPolicy, a repository can allow anonymous actions which do not require user authentication. Finally, one or more users can be designated as administrators, to whom the global adminPolicy applies.

A user's access to a particular repository is evaluated first by whether a user-specific policy exists, then by group-specific policies, and then (in order) by default and admin policies.

A group-specific policy can be applied within any type of access policy, including default or admin policies. The group policy name can also be used with LDAP.

Configuring access control

User identity or group identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific paths.

When you define policies for specific repository paths, the paths can be specified explicitly or by using glob patterns with simple or recursive wildcards. When a repository path matches more than one path description, authorization is granted based on the policy of the longest (most specific) path matched. For example, if policies are defined for path descriptions ** and repos2/repo, the repos2/repo path will match both ** and repos2/repo descriptions. In this case, the repos2/repo policy will be applied because it is longer.

Note that ** effectively defines the default policy, as it matches any path not matched by any other per-repository policy. To override all other policies, you can specify a global admin policy.

✏ Always include the read action in any policy that you define. The create, update, and delete actions cannot be used without the read action.

Example: Access control configuration

Use the accessControl attribute in the configuration file to define a set of identity-based authorization policies, as shown in the following example.

"http": {
+...
+  "accessControl": {
+    "groups": {
+      "group1": {
+        "users": ["bob", "mary"]
+      },
+      "group2": {
+        "users": ["alice", "mallory", "jim"]
+      }
+    },
+    "repositories": {
+      "**": {
+        "policies": [{
+          "users": ["charlie"],
+          "groups": ["group2"],
+          "actions": ["read", "create", "update"]
+        }],
+        "defaultPolicy": ["read", "create"]
+      },
+      "tmp/**": {
+        "anonymousPolicy": ["read"],
+        "defaultPolicy": ["read", "create", "update"]
+      },
+      "infra/*": {
+        "policies": [{
+            "users": ["alice", "bob"],
+            "actions": ["create", "read", "update", "delete"]
+          },
+          {
+            "users": ["mallory"],
+            "groups": ["group1"],
+            "actions": ["create", "read"]
+          }
+        ],
+        "defaultPolicy": ["read"]
+      },
+      "repos2/repo": {
+        "policies": [{
+            "users": ["bob"],
+            "actions": ["read", "create"]
+          },
+          {
+            "users": ["mallory"],
+            "actions": ["create", "read"]
+          }
+        ],
+        "defaultPolicy": ["read"]
+      }
+    },
+    "adminPolicy": {
+      "users": ["admin"],
+      "actions": ["read", "create", "update", "delete"]
+    }
+  }
+

In this example, five policies are defined:

  • The default policy (**) gives all authenticated users the ability to read or create content, while giving user "charlie" and those in "group2" the additional ability to update content.

  • The policy for tmp/** matches all repositories under tmp recursively and allows all authenticated users to read, create, or update content in those repositories. Unauthenticated users have read-only access to these repositories.

  • The policy for infra/* matches all repositories directly under infra. Separate policies are defined for specific users, along with a default read-only policy for all other users.

  • The policy for repos2/repo matches only that specific repository.

  • An admin policy (adminPolicy) gives the user "admin" global authorization to read, create, update, or delete content in any repository, overriding all other policies.

✏ In releases prior to zot v2.0.0, authorization policies were defined directly under the accessControl key in the zot configuration file. Beginning with v2.0.0, the set of authorization policies are now defined under a new repositories key.

Social login using OpenID/OAuth2

Social login is an authentication/authorization method in which your existing credentials for another site or service can be used to log in to a service such as zot. For example, you can log in to zot using your GitHub account credentials, and zot will contact GitHub to verify your identity using OAuth 2.0 and OpenID Connect (OIDC) protocols.

Several social login providers are supported by zot:

  • github
  • google
  • gitlab
  • oidc (for example, dex)

The following example shows the zot configuration for these providers:

{
+  "http": {
+    "auth": {
+      "openid": {
+        "providers": {
+          "github": {
+            "clientid": <client_id>,
+            "clientsecret": <client_secret>,
+            "scopes": ["read:org", "user", "repo"]
+          },
+          "google": {
+            "issuer": "https://accounts.google.com",
+            "clientid": <client_id>,
+            "clientsecret": <client_secret>,
+            "scopes": ["openid", "email"]
+          },
+          "gitlab": {
+            "issuer": "https://gitlab.com",
+            "clientid": <client_id>,
+            "clientsecret": <client_secret>,
+            "scopes": ["openid", "read_api", "read_user", "profile", "email"]
+          },
+          "oidc": {
+            "issuer": "http://<zot-server>:5556/dex",
+            "clientid": <client_id>,
+            "clientsecret": <client_secret>,
+            "keypath": "",
+            "scopes": ["openid", "profile", "email", "groups"]
+          }
+        }
+      }
+    }
+  }
+}
+

Using Google, GitHub, or GitLab

A client logging into zot by social login must specify a supported OpenID/OAuth2 provider as a URL query parameter. A client logging in using Google, GitHub, or GitLab must additionally specify a callback URL for redirection to a zot page after a successful authentication.

The login URL using Google, GitHub, or GitLab uses the following format:

http://<zot-server>/auth/login?provider=<provider>&callback_ui=<zot-server>/<page>
+

For example, a user logging in to the zot home page using GitHub as the authentication provider sends this URL:

http://zot.example.com:8080/auth/login?provider=github&callback_ui=http://zot.example.com:8080/home
+

Based on the specified provider, zot redirects the login to a provider service with the following URL:

http://<zot-server>/zot/auth/callback/<provider>
+

For the GitHub authentication example:

http://zot.example.com:8080/zot/auth/callback/github
+

✏ If your network policy doesn't allow inbound connections, the callback will not work and this authentication method will fail.

Using dex

dex is an identity service that uses OpenID Connect (OIDC) to drive authentication for client apps, such as zot. While this section shows how to use dex with zot, zot supports other OIDC services as well.

Like zot, dex uses a configuration file for setup. To specify zot as a client in dex, configure a staticClients entry in the dex configuration file with a zot callback, such as the following example in the dex configuration file:

staticClients:
+  - id: zot-client
+    redirectURIs:
+      - 'http://zot.example.com:8080/zot/auth/callback/oidc'
+    name: 'zot'
+    secret: ZXhhbXBsZS1hcHAtc2VjcmV0
+

In the zot configuration file, configure dex as an OpenID auth provider as in the following example:

  "http": {
+    "auth": {
+      "openid": {
+        "providers": {
+          "oidc": {
+            "name": "Corporate SSO",
+            "issuer": "http://<zot-server>:5556/dex",
+            "clientid": "zot-client",
+            "clientsecret": "ZXhhbXBsZS1hcHAtc2VjcmV0",
+            "keypath": "",
+            "scopes": ["openid", "profile", "email", "groups"]
+          }
+        }
+      }
+    }
+  }
+

A user logging in to zot using dex OpenID authentication sends a URL with dex as a URL query parameter, such as the following example:

http://zot.example.com:8080/auth/login?provider=oidc

For detailed information about configuring dex service, see the dex Getting Started documentation.

Using OpenID/OAuth2 when zot is behind a proxy or load balancer

When the zot registry is running behind a proxy or load balancer, you must provide an external URL for OpenID/OAuth2 clients to redirect back to zot. This externalUrl attribute is the URL of the registry, as shown in this example:

  "http": {
+    "address": "0.0.0.0",
+    "port": "8080",
+    "externalUrl": "https://zot.example.com",
+    "auth": {
+      "openid": {
+        "providers": {
+          "github": {
+            "clientid": <client_id>,
+            "clientsecret": <client_secret>,
+            "scopes": ["read:org", "user", "repo"]
+          }
+        }
+      }
+    }
+  }
+

Last update: February 5, 2024
\ No newline at end of file diff --git a/v2.0.2/articles/benchmarking-with-zb/index.html b/v2.0.2/articles/benchmarking-with-zb/index.html new file mode 100644 index 0000000..43db6dd --- /dev/null +++ b/v2.0.2/articles/benchmarking-with-zb/index.html @@ -0,0 +1,54 @@ + Benchmarking with zb - zotregistry.dev
Skip to content

Benchmarking zot with zb

👉 The zb tool is useful for benchmarking OCI registry workloads in scenarios such as the following:

  • comparing configuration changes
  • comparing software versions
  • comparing hardware/deployment environments
  • comparing with other registries

With the zb tool, you can benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification published by the Open Container Initiative (OCI).

💡 We recommend installing and benchmarking with zb when you install zot.

How to get zb

The zb project is hosted with zot on GitHub at project-zot. From GitHub, you can download the zb binary or you can build zb from the source. You can also directly run the released docker image.

Supported platforms and architectures

zb is supported for the following operating systems and platform architectures:

OS ARCH Platform
linux amd64 Intel-based Linux servers
linux arm64 ARM-based servers and Raspberry Pi4
darwin amd64 Intel-based MacOS
darwin arm64 ARM-based MacOS

Downloading zb binaries

Download the executable binary for your server platform and architecture under "Assets" on the GitHub zot releases page.

The binary image is named using the target platform and architecture from the Supported platforms and architectures table. For example, the binary for an Intel-based MacOS server is zb-darwin-amd64.

Building zb from source

To build the zb binary, copy or clone the zot project from GitHub and execute the make bench command in the zot directory. Use the same command options that you used to build zot, as shown:

make OS=os ARCH=architecture bench

For example, the following command builds zb for an Intel-based MacOS server:

make OS=darwin ARCH=amd64 bench

In this example, the resulting executable file is zb-darwin-amd64 in the zot/bin directory.

💡 A sample Dockerfile for zb is available at Dockerfile-zb.

Running zb

The original filename of the executable file will reflect the build options, such as zb-linux-amd64. For convenience, you can rename the executable to simply zb.

💡 The instructions and examples in this guide use zb as the name of the executable file.

Usage

To view the usage and options of zb, run the command with the --help option:

bin/zb --help

Command output:

    Usage:
+      zb <url> [flags]
+
+    Flags:
+      -A, --auth-creds string      Use colon-separated BASIC auth creds
+      -c, --concurrency int        Number of multiple requests to make at a time (default 1)
+      -h, --help                   help for zb
+      -o, --output-format string   Output format of test results: stdout (default), json, ci-cd
+      -r, --repo string            Use specified repo on remote registry for test data
+      -n, --requests int           Number of requests to perform (default 1)
+      -s, --src-cidr string        Use specified cidr to obtain ips to make requests from, src-ips and src-cidr are mutually exclusive
+      -i, --src-ips string         Use colon-separated ips to make requests from, src-ips and src-cidr are mutually exclusive
+      -v, --version                Show the version and exit
+      -d, --working-dir string     Use specified directory to store test data
+

Example

The following example executes a benchmark operation using zb.

bin/zb -c 10 -s 127.0.10.0/24 -n 1000 http://localhost:8080

You can also run the released docker image.

docker run --net=host -it ghcr.io/project-zot/zb-linux-amd64:latest -c 10 -n 1000 -s 127.0.10.0/24 http://localhost:8080

Command output:

    Registry URL: http://localhost:8080
+
+    Concurrency Level: 2
+    Total requests:    100
+    Working dir:
+
+    ========
+    Test name:            Get Catalog
+    Time taken for tests: 45.397205ms
+    Complete requests:    100
+    Failed requests:      0
+    Requests per second:  2202.7788
+
+    2xx responses: 100
+
+    min: 402.259µs
+    max: 3.295887ms
+    p50: 855.045µs
+    p75: 971.709µs
+    p90: 1.127389ms
+    p99: 3.295887ms
+
+    ========
+    Test name:            Push Monolith 1MB
+    Time taken for tests: 952.336383ms
+    Complete requests:    100
+    Failed requests:      0
+    Requests per second:  105.00491
+
+    2xx responses: 100
+
+    min: 11.125673ms
+    max: 26.375356ms
+    p50: 18.917253ms
+    p75: 21.753441ms
+    p90: 24.02137ms
+    p99: 26.375356ms
+
+    ...
+

Last update: December 21, 2022
\ No newline at end of file diff --git a/v2.0.2/articles/building-ci-cd-pipeline/index.html b/v2.0.2/articles/building-ci-cd-pipeline/index.html new file mode 100644 index 0000000..1bfae44 --- /dev/null +++ b/v2.0.2/articles/building-ci-cd-pipeline/index.html @@ -0,0 +1,27 @@ + CI/CD Pipeline - zotregistry.dev
Skip to content

Building an OCI-native Container Image CI/CD Pipeline

👉 An OCI-native secure container image build/delivery pipeline using the following tools:

  • stacker for building OCI images

  • zot as a vendor-neutral OCI image registry server

  • skopeo for performing repository interactions

  • cosign for container signing and verification

  • cri-o for deploying container images

  • cosigned for validating container images before deployment

The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.

This document describes a step-by-step procedure towards achieving an OCI-native secure software supply chain using zot in collaboration with other open source tools. The following diagram shows a portion of the CI/CD pipeline.

504568

Build images

stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout.

example: stacker build command

stacker build -f <stackerfile.yaml>
+

Image registry

zot is a production-ready vendor-neutral OCI image registry server purely based on the OCI Distribution Specification. If stacker is used to build the OCI image, it can also be used to publish the built image to an OCI registry.

example: stacker publish command

stacker publish --url <url> --username <user> --password <password>
+

Alternatively, you can use skopeo, a command line utility that performs various operations on container images and image repositories.

example: skopeo copies an image to a registry

skopeo copy --format=oci oci:<oci-dir>/image:tag \
+  docker://<zot-server>/image:tag
+
Click here to view an example of pushing and pulling an image using skopeo.

Signing images

cosign is a tool that performs container signing, verification, and storage in an OCI registry.

example: cosign generates keys and signs an image in the registry

cosign generate-key-pair
+
+cosign sign --key cosign.key <zot-server>/image:tag
+
Click here to view an example of cosign operations.

Deploying container images

cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes.

✏ zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.

example: kubelet configuration file

apiVersion: v1
+kind: Pod
+metadata:
+  name: example-pod
+spec:
+  containers:
+  - name: example-container
+    image: <zot-server>/image:tag
+

Container image verification

cosigned is an image admission controller that validates container images before deploying them.

example: install cosigned using Helm

kubectl create namespace cosign-system
+
+kubectl create secret generic mysecret -n \
+  cosign-system --from-file=cosign.pub=./cosign.pub
+
+helm repo add sigstore https://sigstore.github.io/helm-charts
+
+helm repo update
+
+helm install cosigned -n cosign-system sigstore/cosigned \
+  --devel --set cosign.secretKeyRef.name=mysecret
+

Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/clustering/index.html b/v2.0.2/articles/clustering/index.html new file mode 100644 index 0000000..53d40f7 --- /dev/null +++ b/v2.0.2/articles/clustering/index.html @@ -0,0 +1,76 @@ + Clustering - zotregistry.dev
Skip to content

zot Clustering

👉 High availability of the zot registry is supported by the following features:

  • Stateless zot instances to simplify scale out
  • Bare-metal and Kubernetes deployments

To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.

504569

Clustering is supported in both bare-metal and Kubernetes environments.

✏ The remote backend storage must be S3 API-compatible.

Bare-metal deployment

Prerequisites

  • A highly-available loadbalancer such as HAProxy configured to direct traffic to zot replicas.

  • Multiple zot replicas as systemd services hosted on multiple hosts or VMs.

  • AWS S3 API-compatible remote backend storage.

Kubernetes deployment

Prerequisites

  • A zot Kubernetes Deployment with required number of replicas.

  • AWS S3 API-compatible remote backend storage.

  • A zot Kubernetes Service.

  • A zot Kubernetes Ingress Gateway if the service needs to be exposed outside.

Implementing stateless zot

zot maintains two types of durable state:

  • the actual image data itself

  • the image metadata in the registry’s cache

In a stateless clustering scheme, the image data is stored in the remote storage backend and the registry cache is disabled by turning off both deduplication and garbage collection.

Ecosystem tools

The OCI Distribution Specification imposes certain rules about the HTTP URI paths to which various ecosystem tools must conform. Consider these rules when setting the HTTP prefixes during loadbalancing and ingress gateway configuration.

Examples

zot supports clustering by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load-balancing traffic to the replicas.

YAML configuration

Click here to view a sample haproxy configuration.
global
+        log /dev/log    local0
+        log /dev/log    local1 notice
+        chroot /var/lib/haproxy
+        maxconn 2000
+        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
+        stats timeout 30s
+        user haproxy
+        group haproxy
+        daemon
+
+        # Default SSL material locations
+        ca-base /etc/ssl/certs
+        crt-base /etc/ssl/private
+
+        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
+        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
+        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
+
+defaults
+        log     global
+        mode    http
+        option  httplog
+        option  dontlognull
+        timeout connect 5000
+        timeout client  50000
+        timeout server  50000
+        errorfile 400 /etc/haproxy/errors/400.http
+        errorfile 403 /etc/haproxy/errors/403.http
+        errorfile 408 /etc/haproxy/errors/408.http
+        errorfile 500 /etc/haproxy/errors/500.http
+        errorfile 502 /etc/haproxy/errors/502.http
+        errorfile 503 /etc/haproxy/errors/503.http
+        errorfile 504 /etc/haproxy/errors/504.http
+
+frontend zot
+    bind *:8080
+    mode http
+    default_backend zot-cluster
+
+backend zot-cluster
+    mode http
+    balance roundrobin
+    server zot1 127.0.0.1:8081 check
+    server zot2 127.0.0.1:8082 check
+    server zot3 127.0.0.1:8083 check
+

zot S3 configuration

Click here to view a sample zot configuration for S3.
{
+    "distSpecVersion": "1.0.1-dev",
+    "storage": {
+        "rootDirectory": "/tmp/zot",
+        "dedupe": true,
+        "storageDriver": {
+            "name": "s3",
+            "rootdirectory": "/zot",
+            "region": "us-east-2",
+            "bucket": "zot-storage",
+            "secure": true,
+            "skipverify": false
+        },
+        "cacheDriver": {
+            "name": "dynamodb",
+            "endpoint": "http://localhost:4566",
+            "region": "us-east-2",
+            "tableName": "MainTable"
+        }
+    },
+    "http": {
+        "address": "127.0.0.1",
+        "port": "8080"
+    },
+    "log": {
+        "level": "debug"
+    }
+}
+

Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/graphql/index.html b/v2.0.2/articles/graphql/index.html new file mode 100644 index 0000000..20b1f94 --- /dev/null +++ b/v2.0.2/articles/graphql/index.html @@ -0,0 +1,598 @@ + Using GraphQL for Enhanced Searches - zotregistry.dev
Skip to content

Using GraphQL for Enhanced Searches

👉 A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. You can submit a GraphQL structured query as an API call or you can use a browser to access the GraphQL Playground, an interactive graphical environment for GraphQL queries.

How to use GraphQL for search queries

GraphQL is a query language for APIs. A GraphQL server, as implemented in zot's registry search engine, executes GraphQL queries that match schema recognized by the server. In response, the server returns a structure containing the requested information. The schema currently recognized by zot are those that correspond to the queries listed in What GraphQL queries are supported.

💡 To learn more about GraphQL, see these resources:

To perform a search, compose a GraphQL structured query for a specific search and deliver it to zot using one of the methods described in the following sections.

For examples of GraphQL queries supported in zot, see Examples of zot searches using GraphQL.

Using the search API directly

You can submit a GraphQL structured query as the HTML data payload in a direct API call using a shell tool such as cURL or Postman. GraphQL queries are sent to the zot search extension API:

/v2/_zot/ext/search
+

The following example submits a zot GraphQL query using cURL:

curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageListForCVE (id:\"CVE-2002-1119\") { Results { Name Tags } } }" }' http://localhost:8080/v2/_zot/ext/search
+

The reply to your query is returned as a JSON payload in the HTML response.

Using the GraphQL Playground

✏ The GraphQL Playground feature is available only in a binary-debug zot build or when the zot registry was built with the debug extension label.

The GraphQL Playground is an interactive graphical web interface for GraphQL hosted by the zot registry server.

The GraphQL Playground is reachable by a browser at the following zot API:

/v2/_zot/debug/graphql-playground#
+

For example, if your zot server is located at http://localhost:8080, the GraphQL Playground can be accessed by your browser at this URL:

http://localhost:8080/v2/_zot/debug/graphql-playground#
+

In the GraphQL Playground, you can construct and submit a query structure and you can view the query response in a graphical environment in the browser. You can also inspect the schema.

What GraphQL queries are supported

Supported queries graphQL query Input Output Description
Search images by digest ImageListForDigest digest image list Searches all repositories in the registry and returns list of images that matches given digest (manifest, config or layers)
Search images affected by a given CVE id CVEListForImage CVE id image list Searches the entire registry and returns list of images affected by given CVE
List CVEs for a given image CVEListForImage image CVE list Scans given image and returns list of CVEs affecting the image
List images not affected by a given CVE id ImagesListWithCVEFixed repository, CVE id image list Scans all images in a given repository and returns list of latest (by date) images not affected by the given CVE
Latest image from all repos RepoListWithNewestImage none repo summary list Returns the latest image from all the repos in the registry
List all images with expanded information for a given repository ExpandedRepoInfo repository repo info List expanded repo information for all images in repo, alongside a repo summary
All images in repo ImageList repository image list Returns all images in the specified repo
Global search GlobalSearch query image summary / repo summary / layer summary Will return what's requested in the query argument
Derived image list DerivedImageList image image list Returns a list of images that depend on the image specified in the argument
Base image list BaseImageList image image list Returns a list of images that the specified image depends on
Get details of a specific image Image image image summary Returns details about a specific image
Get referrers of a specific image Referrers repo, digest, type artifact manifests Returns a list of artifacts of given type referring to a specific repo and digests

Examples of zot searches using GraphQL

✏ These examples show only the GraphQL query without details on how to send them to a server. See How to use GraphQL for search queries.

The query structures shown in these examples request all fields allowed by the schema for the particular query type. The schema allows you to request a subset of the data, if desired, omitting any fields that you don't need.

List CVEs of given image

Sample request

{
+  CVEListForImage(
+    image: "alpine:3.17"
+    requestedPage: {limit: 1, offset:1, sortBy: SEVERITY}
+  ) {
+    Tag
+    Page {
+      TotalCount
+      ItemCount
+    }
+    CVEList {
+      Id
+      Title
+      Description
+      Severity
+      PackageList {
+        Name
+        InstalledVersion
+        FixedVersion
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "CVEListForImage": {
+      "Tag": "3.17",
+      "Page": {
+        "TotalCount": 9,
+        "ItemCount": 1
+      },
+      "CVEList": [
+        {
+          "Id": "CVE-2023-5363",
+          "Title": "openssl: Incorrect cipher key and IV length processing",
+          "Description": "Issue summary: A bug has been identified in the processing of key and\ninitialisation vector (IV) lengths.  This can lead to potential truncation\nor overruns during the initialisation of some symmetric ciphers.\n\nImpact summary: A truncation in the IV can result in non-uniqueness,\nwhich could result in loss of confidentiality for some cipher modes.\n\nWhen calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or\nEVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after\nthe key and IV have been established.  Any alterations to the key length,\nvia the \"keylen\" parameter or the IV length, via the \"ivlen\" parameter,\nwithin the OSSL_PARAM array will not take effect as intended, potentially\ncausing truncation or overreading of these values.  The following ciphers\nand cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.\n\nFor the CCM, GCM and OCB cipher modes, truncation of the IV can result in\nloss of confidentiality.  For example, when following NIST's SP 800-38D\nsection 8.2.1 guidance for constructing a deterministic IV for AES in\nGCM mode, truncation of the counter portion could lead to IV reuse.\n\nBoth truncations and overruns of the key and overruns of the IV will\nproduce incorrect results and could, in some cases, trigger a memory\nexception.  However, these issues are not currently assessed as security\ncritical.\n\nChanging the key and/or IV lengths is not considered to be a common operation\nand the vulnerable API was recently introduced. Furthermore it is likely that\napplication developers will have spotted this problem during testing since\ndecryption would fail unless both peers in the communication were similarly\nvulnerable. For these reasons we expect the probability of an application being\nvulnerable to this to be quite low. However if an application is vulnerable then\nthis issue is considered very serious. For these reasons we have assessed this\nissue as Moderate severity overall.\n\nThe OpenSSL SSL/TLS implementation is not affected by this issue.\n\nThe OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because\nthe issue lies outside of the FIPS provider boundary.\n\nOpenSSL 3.1 and 3.0 are vulnerable to this issue.",
+          "Severity": "HIGH",
+          "PackageList": [
+            {
+              "Name": "libcrypto3",
+              "InstalledVersion": "3.0.8-r0",
+              "FixedVersion": "3.0.12-r0"
+            },
+            {
+              "Name": "libssl3",
+              "InstalledVersion": "3.0.8-r0",
+              "FixedVersion": "3.0.12-r0"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+

Search images affected by a given CVE id

Sample request

{
+  ImageListForCVE(id: "CVE-2023-0464") {
+    Results{
+      RepoName
+      Tag
+      Digest
+      LastUpdated
+      IsSigned
+      Size
+      Vendor
+      DownloadCount
+      Licenses
+      Title
+      Manifests {
+        Digest
+        ConfigDigest
+        Platform {
+          Os
+          Arch
+        }
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "ImageListForCVE": {
+      "Results": [
+        {
+          "RepoName": "alpine",
+          "Tag": "3.17",
+          "Digest": "sha256:75bfe77c8d5a76b4421cfcebbd62a28ae70d10147578d0cda45820e99b0ef1d8",
+          "LastUpdated": "2023-02-11T04:46:42.558343068Z",
+          "IsSigned": true,
+          "Size": "3375436",
+          "Vendor": "",
+          "DownloadCount": 0,
+          "Licenses": "",
+          "Title": "",
+          "Manifests": [
+            {
+              "Digest": "sha256:75bfe77c8d5a76b4421cfcebbd62a28ae70d10147578d0cda45820e99b0ef1d8",
+              "ConfigDigest": "sha256:6a2bcc1c7b4c9207f791a4512d7f2fa8fc2daeae58dbc51cb2797b05415f082a",
+              "Platform": {
+                "Os": "linux",
+                "Arch": "amd64"
+              }
+            }
+          ]
+        },
+      ]
+    }
+  }
+}
+

List images not affected by a given CVE id

Sample request

{
+  ImageListWithCVEFixed(id: "CVE-2023-0464", image: "ubuntu") {
+    Results {
+      RepoName
+      Tag
+      Digest
+      LastUpdated
+      Manifests {
+        Digest
+        ConfigDigest
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "ImageListWithCVEFixed": {
+      "Results": [
+        {
+          "RepoName": "ubuntu",
+          "Tag": "kinetic",
+          "Digest": "sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f",
+          "LastUpdated": "2022-10-14T15:28:55.0263968Z",
+          "Manifests": [
+            {
+              "Digest": "sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f",
+              "ConfigDigest": "sha256:824c0269745923afceb9765ae24f5b331bb6fcf2a82f7eba98b3cfd543afb41e"
+            }
+          ]
+        },
+        {
+          "RepoName": "ubuntu",
+          "Tag": "kinetic-20220922",
+          "Digest": "sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff",
+          "LastUpdated": "2022-10-14T15:27:41.2144454Z",
+          "Manifests": [
+            {
+              "Digest": "sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff",
+              "ConfigDigest": "sha256:15c8dcf63970bb14ea36e41aa001b87d8d31e25a082bf6f659d12489d3e53d90"
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+

Search images by digest

Sample request

{
+  ImageListForDigest(
+    id: "79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff"
+  ) {
+    Results{
+      RepoName
+      Tag
+      Title
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "ImageListForDigest": {
+      "Results": [
+        {
+          "RepoName": "ubuntu",
+          "Tag": "kinetic-20220922",
+          "Title": "ubuntu"
+        }
+      ]
+    }
+  }
+}
+

List the latest image across every repository

Sample request

{
+  RepoListWithNewestImage(requestedPage: {limit: 2, offset:0, sortBy: ALPHABETIC_ASC}) {
+    Page {
+      TotalCount
+      ItemCount
+    }
+    Results {
+      Name
+      LastUpdated
+      Size
+      Platforms {
+        Os
+        Arch
+      }
+      NewestImage {
+        Digest
+        Tag
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "RepoListWithNewestImage": {
+      "Page": {
+        "TotalCount": 30,
+        "ItemCount": 2
+      },
+      "Results": [
+        {
+          "Name": "mariadb",
+          "LastUpdated": "2022-10-18T14:56:33.1993083+03:00",
+          "Size": "124116964",
+          "Platforms": [
+            {
+              "Os": "linux",
+              "Arch": "amd64"
+            }
+          ],
+          "NewestImage": {
+            "Digest": "sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0",
+            "Tag": "latest"
+          }
+        },
+        {
+          "Name": "tomcat",
+          "LastUpdated": "2022-10-18T14:55:13.8303866+03:00",
+          "Size": "311658063",
+          "Platforms": [
+            {
+              "Os": "linux",
+              "Arch": "amd64"
+            }
+          ],
+          "NewestImage": {
+            "Digest": "sha256:bbc5a3912b568fbfb5912beaf25054f1f407c32a53acae29f19ad97485731a78",
+            "Tag": "jre17"
+          }
+        }
+      ]
+    }
+  }
+}
+

All images in repo

Sample request

{
+  ImageList (repo: "ubuntu") {
+    Results {
+      Tag
+      Digest
+      LastUpdated
+      Size
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "ImageList": {
+      "Results": [
+        {
+          "Tag": "jammy",
+          "Digest": "sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27",
+          "LastUpdated": "2022-10-14T15:29:18.0325322Z",
+          "Size": "30472739"
+        },
+        {
+          "Tag": "jammy-20221003",
+          "Digest": "sha256:86681debca1719dff33f426a0f5c41792ebc52496c5d78a93b655b8b48fb71b2",
+          "LastUpdated": "2022-10-14T15:29:07.0004587Z",
+          "Size": "30472748"
+        },
+        {
+          "Tag": "kinetic",
+          "Digest": "sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f",
+          "LastUpdated": "2022-10-14T15:28:55.0263968Z",
+          "Size": "27498890"
+        },
+        {
+          "Tag": "kinetic-20220922",
+          "Digest": "sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff",
+          "LastUpdated": "2022-10-14T15:27:41.2144454Z",
+          "Size": "27498899"
+        },
+        {
+          "Tag": "latest",
+          "Digest": "sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c",
+          "LastUpdated": "2022-10-14T15:26:59.6707939Z",
+          "Size": "30472740"
+        },
+        {
+          "Tag": "rolling",
+          "Digest": "sha256:72e75626c5068b9d9a462c4fc80a29787d0cf61c8abc81bfd5ea69f6248d56fc",
+          "LastUpdated": "2022-10-14T15:27:21.2441356Z",
+          "Size": "30472741"
+        }
+      ]
+    }
+  }
+}
+

List all images with expanded information for a given repository

Sample request

{
+  ExpandedRepoInfo(repo: "ubuntu") {
+    Images {
+      Tag
+      Digest
+    }
+    Summary {
+      LastUpdated
+      Size
+      NewestImage {
+        Tag
+        LastUpdated
+        Digest
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "ExpandedRepoInfo": {
+      "Images": [
+        {
+          "Tag": "jammy",
+          "Digest": "sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27"
+        },
+        {
+          "Tag": "jammy-20221003",
+          "Digest": "sha256:86681debca1719dff33f426a0f5c41792ebc52496c5d78a93b655b8b48fb71b2"
+        },
+        {
+          "Tag": "kinetic",
+          "Digest": "sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f"
+        },
+        {
+          "Tag": "kinetic-20220922",
+          "Digest": "sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff"
+        },
+        {
+          "Tag": "rolling",
+          "Digest": "sha256:72e75626c5068b9d9a462c4fc80a29787d0cf61c8abc81bfd5ea69f6248d56fc"
+        },
+        {
+          "Tag": "latest",
+          "Digest": "sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c"
+        }
+      ],
+      "Summary": {
+        "LastUpdated": "2022-10-14T15:29:18.0325322Z",
+        "Size": "58146896",
+        "NewestImage": {
+          "Tag": "jammy",
+          "LastUpdated": "2022-10-14T15:29:18.0325322Z",
+          "Digest": "sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27"
+        }
+      }
+    }
+  }
+}
+

Sample request

{
+  GlobalSearch(query: "ubuntu:latest") {
+    Page {
+      ItemCount
+      TotalCount
+    }
+    Images {
+      RepoName
+      Tag
+      LastUpdated
+      Manifests {
+        Digest
+        Layers {
+          Size
+          Digest
+        }
+      }
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "GlobalSearch": {
+      "Page": {
+        "ItemCount": 1,
+        "TotalCount": 1
+      },
+      "Images": [
+        {
+          "RepoName": "ubuntu",
+          "Tag": "latest",
+          "LastUpdated": "2022-10-14T15:26:59.6707939Z",
+          "Manifests": [
+            {
+              "Digest": "sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c",
+              "Layers": [
+                {
+                  "Size": "30428928",
+                  "Digest": "sha256:cf92e523b49ea3d1fae59f5f082437a5f96c244fda6697995920142ff31d59cf"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+

Sample request

{
+  GlobalSearch(query: "") {
+    Repos {
+      Name
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "GlobalSearch": {
+      "Repos": [
+        {
+          "Name": "centos"
+        },
+        {
+          "Name": "ubuntu"
+        }
+      ]
+    }
+  }
+}
+

Search derived images

Sample query

{
+  DerivedImageList(image: "ubuntu:latest", requestedPage: {offset: 0, limit: 10}) {
+    Page {
+      TotalCount
+      ItemCount
+    }
+    Results {
+      RepoName
+      Tag
+      LastUpdated
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "DerivedImageList": {
+      "Page": {
+        "TotalCount": 9,
+        "ItemCount": 9
+      },
+      "Results": [
+        {
+          "RepoName": "mariadb",
+          "Tag": "latest",
+          "LastUpdated": "2022-10-18T14:56:33.1993083+03:00"
+        },
+        {
+          "RepoName": "maven",
+          "Tag": "latest",
+          "LastUpdated": "2022-10-14T18:30:12.0929807+03:00"
+        },
+        {
+          "RepoName": "tomcat",
+          "Tag": "latest",
+          "LastUpdated": "2022-10-18T14:50:09.7229959+03:00"
+        },
+        {
+          "RepoName": "tomcat",
+          "Tag": "jre17",
+          "LastUpdated": "2022-10-18T14:55:13.8303866+03:00"
+        },
+        {
+          "RepoName": "tomcat",
+          "Tag": "jre17-temurin",
+          "LastUpdated": "2022-10-18T14:54:46.4133521+03:00"
+        },
+        {
+          "RepoName": "tomcat",
+          "Tag": "jre17-temurin-jammy",
+          "LastUpdated": "2022-10-18T14:51:12.235475+03:00"
+        }
+      ]
+    }
+  }
+}
+

Search base images

Sample query

{
+  BaseImageList(image: "mariadb:latest", requestedPage: {offset: 0, limit: 10}) {
+    Page {
+      TotalCount
+      ItemCount
+    }
+    Results {
+      RepoName
+      Tag
+      LastUpdated
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "BaseImageList": {
+      "Page": {
+        "TotalCount": 4,
+        "ItemCount": 4
+      },
+      "Results": [
+        {
+          "RepoName": "ubuntu",
+          "Tag": "jammy",
+          "LastUpdated": "2022-10-14T18:29:18.0325322+03:00"
+        },
+        {
+          "RepoName": "ubuntu",
+          "Tag": "jammy-20221003",
+          "LastUpdated": "2022-10-14T18:29:07.0004587+03:00"
+        },
+        {
+          "RepoName": "ubuntu",
+          "Tag": "latest",
+          "LastUpdated": "2022-10-14T18:26:59.6707939+03:00"
+        },
+        {
+          "RepoName": "ubuntu",
+          "Tag": "rolling",
+          "LastUpdated": "2022-10-14T18:27:21.2441356+03:00"
+        }
+      ]
+    }
+  }
+}
+

Get details of a specific image

Sample query

{
+  Image(image: "mariadb:latest") {
+    RepoName
+    Tag
+    LastUpdated
+    Digest
+    Description
+  }
+}
+

Sample response

{
+  "data": {
+    "Image": {
+      "RepoName": "mariadb",
+      "Tag": "latest",
+      "LastUpdated": "2022-10-18T14:56:33.1993083+03:00",
+      "Digest": "sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0",
+      "Description": "MariaDB Server is a high performing open source relational database, forked from MySQL."
+    }
+  }
+}
+

Get referrers of a specific image

Sample query

{
+  Referrers(
+    repo: "golang"
+    digest: "sha256:fed08b0eaea00aab17f82ecbb78675919d216c72eea985581758191f694aeaf7"
+    type: "application/vnd.example.icecream.v1"
+  ) {
+    MediaType
+    ArtifactType
+    Digest
+    Annotations {
+      Key
+      Value
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "Referrers": [
+      {
+        "MediaType": "application/vnd.oci.artifact.manifest.v1+json",
+        "ArtifactType": "application/vnd.example.icecream.v1",
+        "Digest": "sha256:be7a3d01c35a2cf53c502e9dc50cdf36b15d9361c81c63bf319f1d5cbe44ab7c",
+        "Annotations": [
+          {
+            "Key": "format",
+            "Value": "oci"
+          },
+          {
+            "Key": "demo",
+            "Value": "true"
+          }
+        ]
+      },
+      {
+        "MediaType": "application/vnd.oci.artifact.manifest.v1+json",
+        "ArtifactType": "application/vnd.example.icecream.v1",
+        "Digest": "sha256:d9ad22f41d9cb9797c134401416eee2a70446cee1a8eb76fc6b191f4320dade2",
+        "Annotations": [
+          {
+            "Key": "demo",
+            "Value": "true"
+          },
+          {
+            "Key": "format",
+            "Value": "oci"
+          }
+        ]
+      }
+    ]
+  }
+}
+

Last update: November 15, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/immutable-tags/index.html b/v2.0.2/articles/immutable-tags/index.html new file mode 100644 index 0000000..b030e74 --- /dev/null +++ b/v2.0.2/articles/immutable-tags/index.html @@ -0,0 +1,23 @@ + Immutable Image Tags - zotregistry.dev
Skip to content

Immutable Image Tags

👉 Immutable image tag support is achieved by leveraging authorization policies.

It is considered best practice to avoid changing the content once a software version has been released. While zot does not have an explicit configuration flag to make image tags immutable, the same effect can be achieved with authorization as follows.

Immutable For All Users

By setting the defaultPolicy to "read" and "create" for a particular repository, images can be pushed (once) and pulled but further updates are rejected.

{
+...
+  "repositories": {
+    "**": {
+      "defaultPolicy": ["read", "create"]
+    }
+  }
+...
+}
+

Immutable With Overrides

As in the example above, with defaultPolicy set to "read" and "create" for a particular repository, images can be pushed (once) and pulled, but further updates are rejected. Exceptions can be made for some users, and user-specific policies can be added to allow "update" operations as shown below.

{
+...
+  "repositories": {
+    "**": {
+      "policies": [{
+        "users": ["alice", "bob"],
+        "actions": ["read", "create", "update"]
+      }],
+      "defaultPolicy": ["read", "create"]
+    }
+  }
+...
+}
+

Last update: March 13, 2024
\ No newline at end of file diff --git a/v2.0.2/articles/kind-deploy/index.html b/v2.0.2/articles/kind-deploy/index.html new file mode 100644 index 0000000..79d12ea --- /dev/null +++ b/v2.0.2/articles/kind-deploy/index.html @@ -0,0 +1,124 @@ + Using kind for Deployment Testing - zotregistry.dev
Skip to content

Using kind for Deployment Testing

👉 Use kind to try out zot deployment with Kubernetes.

This article describes how to create a kind cluster that includes a local zot registry.

Deploying the cluster and registry

The procedure described installs a kind cluster with a zot registry at localhost:5001 and then loads and runs a "hello" app to test the installation. Although the procedure is given as a series of steps, you can find a complete shell script to perform these steps at the end of this article.

✏ This article is based on Create A Cluster And Registry, which you can find on the kind website.

Step 1: Prepare the environment

The following packages must be installed:

  • docker
  • kubernetes
  • kind
  • containerd
  • skopeo

Execute the following shell commands to set environment variables.

set -o errexit
+
+# set no_proxy if applicable
+if [ ! -z "${no_proxy}" ]; then 
+  echo "Updating no_proxy environment variables";
+  export no_proxy=${no_proxy},kind-registry;
+  export NO_PROXY=${no_proxy};
+fi
+

Step 2: Create a registry container

Create a kind-registry container, pulling a zot binary from the GitHub Container Registry (ghcr.io).

✏ This example pulls zot-minimal-linux-amd64:latest,
a minimal (no extensions) zot image for an AMD-based linux server.

Other available images are described at the zot releases page in GitHub.
You can also specify a release by replacing latest with an available release number.

# create registry container unless it already exists
+reg_name='kind-registry'
+reg_port='5001'
+if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
+  docker run \
+    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
+    ghcr.io/project-zot/zot-minimal-linux-amd64:latest
+fi
+

Step 3: Create the kind cluster

Create a cluster with the local registry enabled.

# enable the local registry in containerd
+cat <<EOF | kind create cluster --config=-
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+containerdConfigPatches:
+- |-
+  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
+    endpoint = ["http://${reg_name}:5000"]
+EOF
+

Step 4: Connect the registry to the cluster network

Connect the registry to the "kind" network so that it can communicate with other resources in the same network.

# check whether already connected to the network
+if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' \
+"${reg_name}")" = 'null' ]; then
+  docker network connect "kind" "${reg_name}"
+fi
+

Step 5: Document the local registry

Create a ConfigMap that specifies how to interact with the local registry. This ConfigMap follows the KEP-1755 Standard for communicating a local registry.

cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: local-registry-hosting
+  namespace: kube-public
+data:
+  localRegistryHosting.v1: |
+    host: "localhost:${reg_port}"
+    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
+EOF
+

Step 6: Deploy and test

Use skopeo to copy (pull) a "hello" app from the Google Container Registry (gcr.io) into the new zot registry. Using kubectl, deploy the app from the new local zot registry as "hello-server" and monitor the deployment for initial availability.

# copy an image
+skopeo copy --format=oci --dest-tls-verify=false \
+docker://gcr.io/google-samples/hello-app:1.0 \
+docker://localhost:5001/hello-app:1.0
+
+# deploy the image
+kubectl create deployment hello-server --image=localhost:5001/hello-app:1.0
+
+# check for availability
+echo "Waiting for deployment/hello-server to be ready ..."
+kubectl wait deployment -n default hello-server \
+  --for condition=Available=True --timeout=90s
+

Clean up

To clean up after testing, run the following commands to delete the kind cluster and registry.

kind delete cluster
+docker stop kind-registry
+docker rm kind-registry
+

Reference: A complete script

The following script executes all of the preceding steps.

Click here to view the entire script
#!/bin/sh
+set -o errexit
+
+# Reference: https://kind.sigs.k8s.io/docs/user/local-registry/
+
+# set no_proxy if applicable
+if [ ! -z "${no_proxy}" ]; then 
+  echo "Updating no_proxy env var";
+  export no_proxy=${no_proxy},kind-registry;
+  export NO_PROXY=${no_proxy};
+fi
+
+# create registry container unless it already exists
+reg_name='kind-registry'
+reg_port='5001'
+if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
+  docker run \
+    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
+    ghcr.io/project-zot/zot-minimal-linux-amd64:latest
+fi
+
+# create a cluster with the local registry enabled in containerd
+cat <<EOF | kind create cluster --config=-
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+containerdConfigPatches:
+- |-
+  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
+    endpoint = ["http://${reg_name}:5000"]
+EOF
+
+# connect the registry to the cluster network if not already connected
+if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
+  docker network connect "kind" "${reg_name}"
+fi
+
+# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
+#
+# document the local registry
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: local-registry-hosting
+  namespace: kube-public
+data:
+  localRegistryHosting.v1: |
+    host: "localhost:${reg_port}"
+    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
+EOF
+
+# copy an image
+skopeo copy --format=oci --dest-tls-verify=false docker://gcr.io/google-samples/hello-app:1.0 docker://localhost:5001/hello-app:1.0
+
+# deploy the image
+kubectl create deployment hello-server --image=localhost:5001/hello-app:1.0
+
+# check for availability
+echo "Waiting for deployment/hello-server to be ready ..."
+kubectl wait deployment -n default hello-server --for condition=Available=True --timeout=90s
+
+# cleanup
+echo "Press a key to begin cleanup ..."
+read KEYPRESS
+kind delete cluster
+docker stop kind-registry
+docker rm kind-registry
+

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/mirroring/index.html b/v2.0.2/articles/mirroring/index.html new file mode 100644 index 0000000..1f386f4 --- /dev/null +++ b/v2.0.2/articles/mirroring/index.html @@ -0,0 +1,248 @@ + Mirroring - zotregistry.dev
Skip to content

OCI Registry Mirroring With zot

👉 A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry (gcr.io).

A key use case for zot is to act as a mirror for upstream registries. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Because synchronized images are stored in zot's local storage, registry mirroring allows for a fully distributed disconnected container image build pipeline. Container image operations terminate in local zot storage, which may reduce network latency and costs.

⚠ Because zot is a OCI-only registry, any upstream image stored in the Docker image format is converted to OCI format when downloading to zot. In the conversion, some non-OCI attributes may be lost. Signatures, for example, are removed due to the incompatibility between formats.

Mirroring modes

For mirroring an upstream registry, two common use cases are a fully mirrored or a pull through (on-demand) cache registry.

As with git, wherein every clone is a full repository, you can configure your local zot instance to be a fully mirrored OCI registry. For this mode, configure zot for synchronization by periodic polling, not on-demand. Zot copies and caches a full copy of every image on the upstream registry, updating the cache whenever polling discovers a change in content or image version at the upstream registry.

For a pull through cache mirrored registry, configure zot for on-demand synchronization. When an image is first requested from the local zot registry, the image is downloaded from the upstream registry and cached in local storage. Subsequent requests for the same image are served from zot's cache. Images that have not been requested are not downloaded. If a polling interval is also configured, zot periodically polls the upstream registry for changes, updating any cached images if changes are detected.

✏ Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only on-demand mirroring with Docker Hub.

Migrating or updating a registry using mirroring

Mirroring zot using the sync feature allows you to easily migrate a registry. In situations such as the following, zot mirroring provides an easy solution.

  • Migrating an existing zot or non-zot registry to a new location.

    Provided that the source registry is OCI-compliant for image pulls, you can mirror the registry to a new zot registry, delete the old registry, and reroute network traffic to the new registry.

  • Updating (or downgrading) a zot registry.

    To minimize downtime during an update, or to avoid any incompatibilities between zot releases that would preclude an in-place update, you can bring up a new zot registry with the desired release and then migrate from the existing registry.

To ensure a complete migration of the registry contents, set a polling interval in the configuration of the new zot registry and set prefix to **, as shown in this example:

  {
+    "urls": [
+        "https://registry1:5000"
+    ],
+    "pollInterval": "12h",
+    "onDemand": true,
+    "content": [
+        {
+            "prefix": "**"
+        }
+    ]
+  }
+

Basic configuration for mirroring with sync

The sync feature of zot is an extension of the OCI-compliant registry implementation. You can configure the sync feature under the extensions section of the zot configuration file, as shown in this example:

  "extensions": {
+    "sync": {
+      "credentialsFile": "./examples/sync-auth-filepath.json",
+      "registries": [
+        {
+          "urls": [
+            "https://registry1:5000"
+          ],
+          "onDemand": false,
+          "pollInterval": "6h",
+          "tlsVerify": true,
+          "certDir": "/home/user/certs",
+          "maxRetries": 3,
+          "retryDelay": "5m", 
+          "onlySigned": true,
+          "content": [
+            {
+              "prefix": "/repo2/repo",
+              "tags": {
+                "regex": "4.*",
+                "semver": true
+              }
+              "destination": "/repo2",
+              "stripPrefix": true
+            }
+          ]
+        }
+      ]
+    }
+  }
+

The following table lists the configurable attributes for the sync feature:

Attribute Description

credentialsFile

The location of a local file containing credentials for other registries, as in the following example:

{
  "127.0.0.1:8080": {
    "username": "user",
    "password": "pass"
  },
    "registry2:5000": {
    "username": "user2",
    "password": "pass2"
  }
}

urls

A list of one or more URLs to an upstream image registry. If the main URL fails, the sync process will try the next URLs in the listed order.

onDemand

  • false: Pull all images not found in the local registry.

  • true: Pull any image not found in the local registry only when the image is requested by a user.

pollInterval

The period in seconds between polling of a remote registry. If no value is specified, no periodic polling will occur. If a value is set and the content attributes are configured, periodic synchronization is enabled and will run at the specified value.

Note: Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only onDemand mirroring with Docker Hub.

tlsVerify

  • false: TLS will not be verified.

  • true: (Default) The TLS connection to the destination registry will be verified.

certDir

If a path is specified, use certificates (*.crt, *.cert, *.key files) at this path when connecting to the destination registry or daemon. If no path is specified, use the default certificates directory.

maxRetries

The maximum number of retries if an error occurs during either an on-demand or periodic synchronization. If no value is specified, no retries will occur.

retryDelay

The interval in seconds between retries. This attribute is mandatory when maxRetries is configured.

onlySigned

  • false: Synchronize signed or unsigned images.

  • true: Synchronize only signed images (either notary or cosign).

content

The included attributes in this section specify which content will be pulled. If this section is not populated, periodic polling will not occur. The included attributes can also filter which on-demand images are pulled.

  prefix

On the remote registry, the path from which images will be pulled. This path can be a string that exactly matches the remote path, or it can be a glob pattern. For example, the path can include a wildcard (*) or a recursive wildcard (**).

  tags

The included attributes in this optional section specify how remote images will be selected for synchronization based on image tags.

  tags.regex

Specifies a regular expression for matching image tags. Images whose tags do not match the expression are not pulled.

  tags.semver

Specifies whether image tags are to be filtered by semantic versioning (semver) compliance.

  • false: Do not filter by semantic versioning.

  • true: Filter by semantic versioning.

  destination

Specifies the local path in which pulled images are to be stored.

  stripPrefix

Specifies whether the prefix path from the remote registry will be retained or replaced when the image is stored in the zot registry.

  • false: Retain the source prefix, append it to the destination path.

  • true: Remove the source prefix.

    Note: If the source prefix was specified with meta-characters (such as **), only the prefix segments that precede the meta-characters are removed. Any remaining path segments are appended to the destination path.

Configuration examples for mirroring

Example: Multiple repositories with polled mirroring

The following is an example of sync configuration for mirroring multiple repositories with polled mirroring.

"sync": {
+  "enable": true,
+  "credentialsFile": "./examples/sync-auth-filepath.json",
+  "registries": [
+    {
+      "urls": ["https://registry1:5000"],
+      "onDemand": false,
+      "pollInterval": "6h",
+      "tlsVerify": true,
+      "certDir": "/home/user/certs",
+      "maxRetries": 3,
+      "retryDelay": "5m",
+      "onlySigned": true,
+      "content": [
+        {
+          "prefix": "/repo1/repo",
+          "tags": {
+            "regex": "4.*",
+            "semver": true
+          }
+        },
+        {
+          "prefix": "/repo2/repo",
+          "destination": "/repo2",
+          "stripPrefix": true
+        },
+        {
+          "prefix": "/repo3/repo"
+        }
+      ]
+    }
+  }
+

The configuration in this example will result in the following behavior:

  • Only signed images (notation and cosign) are synchronized.
  • The sync communication is secured using certificates in certDir.
  • This registry synchronizes with upstream registry every 6 hours.
  • On-demand mirroring is disabled.
  • Based on the content filtering options, this registry synchronizes these images:
    • From /repo1/repo, images with tags that begin with "4." and are semver compliant.
      Files are stored locally in /repo1/repo on localhost.
    • From /repo2/repo, images with all tags.
      Because stripPrefix is enabled, files are stored locally in /repo2. For example, docker://upstream/repo2/repo:v1 is stored as docker://local/repo2:v1.
    • From /repo3/repo, images with all tags.
      Files are stored locally in /repo3/repo.

Example: Multiple registries with on-demand mirroring

The following is an example of sync configuration for mirroring multiple registries with on-demand mirroring.

{
+  "distSpecVersion": "1.0.1",
+  "storage": {
+    "rootDirectory": "/tmp/zot",
+    "gc": true
+  },
+  "http": {
+    "address": "0.0.0.0",
+    "port": "8080"
+  },
+  "log": {
+    "level": "debug"
+  },
+  "extensions": {
+    "sync": {
+      "enable": true,
+      "registries": [
+        {
+          "urls": ["https://k8s.gcr.io"],
+          "content": [
+            {
+              "prefix": "**", 
+              "destination": "/k8s-images"
+            }
+          ],
+          "onDemand": true,
+          "tlsVerify": true
+        },
+        {
+          "urls": ["https://docker.io/library"],
+          "content": [
+            {
+              "prefix": "**", 
+              "destination": "/docker-images"
+            }
+          ],
+          "onDemand": true,
+          "tlsVerify": true
+        }
+      ]
+    }
+  }
+}
+

With this zot configuration, the sync behavior is as follows:

  1. This initial user request for content from the zot registry:
    skopeo copy --src-tls-verify=false docker://localhost:8080/docker-images/alpine <dest>
    causes zot to synchronize the content with the docker.io registry:
        docker.io/library/alpine:latest
    to the zot registry:
        localhost:8080/docker-images/alpine:latest
    before delivering the content to the requestor at <dest>.

  2. This initial user request for content from the zot registry:
    skopeo copy --src-tls-verify=false docker://localhost:8080/k8s-images/kube-proxy:v1.19.2 <dest>
    causes zot to synchronize the content with the gcr.io registry:
        k8s.gcr.io/kube-proxy:v1.19.2
    to the zot registry:
        localhost:8080/k8s-images/kube-proxy:v1.19.2
    before delivering the content to the requestor at <dest>.

You can use this command:
     curl http://localhost:8080/v2/_catalog
to display the local repositories:

  {
+    "repositories":[
+      "docker-images/alpine",
+      "k8s-images/kube-proxy"
+    ]
+  }
+

Example: Multiple registries with mixed mirroring modes

The following is an example of a zot configuration file for mirroring multiple upstream registries.

{
+  "distSpecVersion": "1.1.0-dev",
+  "storage": {
+    "rootDirectory": "/tmp/zot"
+  },
+  "http": {
+    "address": "127.0.0.1",
+    "port": "8080"
+  },
+  "log": {
+    "level": "debug"
+  },
+  "extensions": {
+    "sync": {
+      "enable": true,
+      "credentialsFile": "./examples/sync-auth-filepath.json",
+      "registries": [
+        {
+          "urls": [
+            "https://registry1:5000"
+          ],
+          "onDemand": false,
+          "pollInterval": "6h",
+          "tlsVerify": true,
+          "certDir": "/home/user/certs",
+          "maxRetries": 3,
+          "retryDelay": "5m",
+          "onlySigned": true,
+          "content": [
+            {
+              "prefix": "/repo1/repo",
+              "tags": {
+                "regex": "4.*",
+                "semver": true
+              }
+            },
+            {
+              "prefix": "/repo1/repo",
+              "destination": "/repo",
+              "stripPrefix": true
+            },
+            {
+              "prefix": "/repo2/repo"
+            }
+          ]
+        },
+        {
+          "urls": [
+            "https://registry2:5000",
+            "https://registry3:5000"
+          ],
+          "pollInterval": "12h",
+          "tlsVerify": false,
+          "onDemand": false,
+          "content": [
+            {
+              "prefix": "/repo2",
+              "tags": {
+                "semver": true
+              }
+            }
+          ]
+        },
+        {
+          "urls": [
+            "https://docker.io/library"
+          ],
+          "onDemand": true,
+          "tlsVerify": true,
+          "maxRetries": 6,
+          "retryDelay": "5m"
+        }
+      ]
+    }
+  }
+}
+

Example: Support for subpaths in local storage

{
+  "distSpecVersion": "1.0.1",
+  "storage": {
+    "subPaths":{
+      "/kube-proxy":{
+        "rootDirectory": "/tmp/kube-proxy",
+        "dedupe": true,
+        "gc": true
+       }
+     },
+    "rootDirectory": "/tmp/zot",
+    "gc": true
+  },
+  "http": {
+    "address": "0.0.0.0",
+    "port": "8080"
+  },
+  "log": {
+    "level": "debug"
+  },
+  "extensions": {
+    "sync": {
+      "enable": true,
+      "registries": [
+        {
+          "urls": ["https://k8s.gcr.io"],
+          "content": [
+            {
+              "destination": "/kube-proxy", 
+              "prefix": "**"
+            }
+          ],
+          "onDemand": true,
+          "tlsVerify": true,
+          "maxRetries": 2,
+          "retryDelay": "5m"
+        }
+      ]
+    }
+  }
+}
+
With this zot configuration, the sync behavior is as follows:

  • This user request for content from the zot registry:
    skopeo copy --src-tls-verify=false docker://localhost:8080/kube-proxy/kube-proxy:v1.19.2 <dest>
    causes zot to synchronize the content with this remote registry:
        k8s.gcr.io/kube-proxy:v1.19.2
    to the zot registry:
        localhost:8080/kube-proxy/kube-proxy:v1.19.2
    before delivering the content to the requestor at <dest>.

You can use this command:
     curl http://localhost:8080/v2/_catalog
to display the local repositories:

  {
+    "repositories":[
+      "docker-images/alpine",
+      "k8s-images/kube-proxy",
+      "kube-proxy/kube-proxy"
+    ]
+  }
+

In zot storage, the requested content is located here:
    /tmp/zot/kube-proxy/kube-proxy/kube-proxy/
This subpath is created from the following path components:

  • /tmp/zot is the rootDirectory of the zot registry
  • kube-proxy is the rootDirectory of the storage subpath
  • kube-proxy is the sync destination parameter
  • kube-proxy is the repository name

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/monitoring/index.html b/v2.0.2/articles/monitoring/index.html new file mode 100644 index 0000000..65cfd35 --- /dev/null +++ b/v2.0.2/articles/monitoring/index.html @@ -0,0 +1,27 @@ + Monitoring - zotregistry.dev
Skip to content

Monitoring the registry

👉 zot supports a range of monitoring tools including logging, metrics, and benchmarking.

The following sections describe how to configure logging and monitoring with zot. You can use zot's benchmarking tool to test your configuration and deployment, as described in Benchmarking zot with zb.

Logging

Logging for zot operations is configured with the log attribute in the configuration file, as shown in the following example.

"log":{
+  "level":"debug",
+  "output":"/tmp/zot.log",
+  "audit": "/tmp/zot-audit.log"
+}
+

The following table lists the configurable attributes.

Attribute Description

level

The minimum level for logged events. The levels are:
panic, fatal, error, warn, info, debug, and trace.

output

The filesystem path for the log output file. The default is stdout.

audit

(Optional) If a filesystem path is specified for audit logging, an audit log is enabled and will be stored at the specified path.

Metrics

The available methods for collecting metrics varies depending on whether your zot installation is a minimal (distribution-spec-only) image or a full image including extensions.

Enabling metrics for a full zot image with extensions

Add the metrics attribute under extensions in the configuration file to enable and configure metrics, as shown in the following example.

"extensions": {
+    "metrics": {
+        "enable": true,
+        "prometheus": {
+            "path": "/metrics"
+        }
+    }
+}
+

The following table lists the configurable attributes for metrics collection.

Attribute Description
enable If this attribute is missing, metrics collection is enabled by default. Metrics collection can be disabled by setting this attribute to false.
prometheus Attributes under prometheus contain configuration settings for the Prometheus node exporter.
path The server path on which metrics will be exposed.

Collecting metrics from a minimal zot image using a node exporter

Although a minimal zot image does not contain a node exporter, it exposes internal metrics in a Prometheus format for collection by a separate node exporter tool such as zxp. The zot companion binary zxp is a node exporter that can be deployed with a minimal zot image in order to scrape metrics from the zot server.

Metrics are automatically enabled in the zot server upon first scrape from the node exporter and the metrics are automatically disabled when the node exporter has not performed any scraping for some period. No extra zot configuration is needed for this behavior.

You can download the zxp executable binary for your server platform and architecture under "Assets" on the GitHub zot releases page.

The binary image is named using the target platform and architecture. For example, the binary for an Intel-based MacOS server is zxp-darwin-amd64. To configure the zxp example image, run this command:

zxp-darwin-amd64 config zxp-config-file

💡 For convenience, you can rename the binary image file to simply zxp.

💡 A sample Dockerfile for zxp is available at Dockerfile-zxp.

The configuration file of zxp contains connection details for the zot server from which it will scrape metrics. The following JSON structure is an example of the zxp-config-file contents:

{
+    "Server": {
+        "protocol": "http",
+        "host": "127.0.0.1",
+        "port": "8080"
+    },
+    "Exporter": {
+        "port": "8081",
+        "log": {
+            "level": "debug"
+        }
+    }
+}
+

💡 The zxp module does not have Prometheus integration.

The zxp module is not needed with a full zot image.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/pprofiling/index.html b/v2.0.2/articles/pprofiling/index.html new file mode 100644 index 0000000..8528af5 --- /dev/null +++ b/v2.0.2/articles/pprofiling/index.html @@ -0,0 +1,32 @@ + Performance Profiling - zotregistry.dev
Skip to content

Performance Profiling in zot

👉 Use zot's built-in profiling tools to collect and analyze runtime performance.

The profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

✏ If authentication is enabled, only a zot admin user can access the APIs for profiling.

✏ All examples in this article assume that the zot registry is running at localhost:8080.

What data is available?

The zot source code incorporates golang's pprof package of runtime analysis tools to collect data for the following performance-related profiles:

Profile Description
allocs A sampling of all past memory allocations.
block Stack traces that led to blocking on synchronization primitives.
cmdline The command line invocation of the current program.
goroutine Stack traces of all current goroutines. Use debug=2 as a URL query parameter to export in the same format as an unrecovered panic.
heap A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.
mutex Stack traces of holders of contended mutexes.
profile CPU usage profile. You can specify the duration in the seconds URL query parameter. After receiving the profile file, use the go tool pprof command to investigate the profile.
threadcreate Stack traces that led to the creation of new OS threads.
trace A trace of execution of the current program. You can specify the duration in the seconds URL query parameter. After you get the trace file, use the go tool trace command to investigate the trace.

To return a current HTML-format profile list along with a count of currently available records for each profile, use the following API command:

/v2/_zot/pprof/
+

✏ If authentication is enabled, only an admin user can access this API.

How do I export profile data?

To collect and export any available profile, use the following API command format:

/v2/_zot/pprof/<profile-type>[?<query-parameters>]
+

The following example shows an API request for the CPU usage profile named profile using a collection window of 30 seconds:

$ curl -s http://localhost:8080/v2/_zot/pprof/profile?seconds=30 > cpu.prof
+

This command example creates an output data file named "cpu.prof".

  • The query parameter ?seconds=<number> specifies the number of seconds to gather the profile data. If this parameter is not specified, the default is 30 seconds.
  • In this example, the raw output data is redirected to a file named "cpu.prof". Alternatively, you can use curl -O to create a file with the default profile name (in this case, "profile"). If no output file is specified by either a cURL flag or an output redirection, the cURL command fails with "Failure writing output to destination".
  • The command output file is in a machine-readable format that can be interpreted by performance analyzers.

Analyzing the CPU usage profile using go tool pprof

Go's pprof package provides a variety of presentation formats for analyzing runtime performance.

For detailed information, see the pprof documentation.

Generating a pprof web presentation

When an HTTP port is specified as a command flag, the go tool pprof command installs and opens a local web server that provides a web interface for viewing and analyzing the profile data. This example opens a localhost page at port 9090 for viewing the CPU usage data captured in the profile file named "cpu.prof".

$ go tool pprof -http=:9090 cpu.prof
+Serving web UI on http://localhost:9090
+

The pprof web view offers several options for viewing and interpreting the collected performance data. Select VIEW to see the available options:

pprof-view.jpg

A Flame Graph can be very useful for analyzing CPU usage:

profiling-flame.svg

Generating a graphic image

The pprof package can generate graphic representations of profile data in many formats. This example generates a PNG file representing the CPU usage in the "cpu.prof" file.

$ go tool pprof -png cpu.prof
+Generating report in profile001.png
+

profile001.png

Opening a pprof interactive session

This example opens an interactive session with pprof and executes the pprof top command, which displays the top ten modules by CPU usage during the profiling capture window.

$ go tool pprof cpu.prof
+Type: cpu
+Time: Sep 26, 2023 at 10:01am (PDT)
+Duration: 30s, Total samples = 10ms (  0.1%)
+Entering interactive mode (type "help" for commands, "o" for options)
+(pprof) top
+Showing nodes accounting for 10ms, 100% of 10ms total
+    flat  flat%   sum%        cum   cum%
+    10ms   100%   100%       10ms   100%  runtime.pthread_cond_signal
+        0     0%   100%       10ms   100%  runtime.findRunnable
+        0     0%   100%       10ms   100%  runtime.mcall
+        0     0%   100%       10ms   100%  runtime.notewakeup
+        0     0%   100%       10ms   100%  runtime.park_m
+        0     0%   100%       10ms   100%  runtime.runSafePointFn
+        0     0%   100%       10ms   100%  runtime.schedule
+        0     0%   100%       10ms   100%  runtime.semawakeup
+(pprof)
+

Analyzing the trace profile using go tool trace

You can collect trace data with the trace profile, as in this example:

  $ curl -s -v http://localhost:8080/v2/_zot/pprof/trace?seconds=30 > trace.prof
+

Using the go tool trace package, you can analyze the trace data captured in the "trace.prof" example file:

$ go tool trace trace.prof
+2023/09/21 16:58:58 Parsing trace...
+2023/09/21 16:58:58 Splitting trace...
+2023/09/21 16:58:58 Opening browser. Trace viewer is listening on http://127.0.0.1:62606
+

The go tool trace command installs and opens a local web server that provides a web interface for viewing and analyzing the trace data.

As an alternative, you can generate a pprof-like profile from the trace file using the following command:

$ go tool trace -pprof=[net|sync|syscall|sched] <filename>
+

For example:

$ go tool trace -pprof=net trace.prof
+

Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/retention/index.html b/v2.0.2/articles/retention/index.html new file mode 100644 index 0000000..99d52a3 --- /dev/null +++ b/v2.0.2/articles/retention/index.html @@ -0,0 +1,99 @@ + Retention Policies - zotregistry.dev
Skip to content

Configuring zot Tag Retention Policies

👉 To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.

Tag retention policies in zot can specify how many tags of a given repository to retain or how long to retain certain tags.

You can define tag retention policies that apply one or more of the following rules:

  • Top <n> tags most recently pushed
  • Top <n> tags most recently pulled
  • Tags pushed in the past <n> hours
  • Tags pulled in the past <n> hours
  • Tags matching a regular expression (regex) pattern

Configuring retention policies

Retention policies are configured in the storage section of the zot configuration file under the retention attribute. One or more policies can be grouped under the policies attribute.

By default, if no retention policies are defined, all tags are retained.

⚠ If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed. To avoid unintended removals, we recommend defining a default policy, as described in Configuration notes.

Configuration example

The following example is a simple retention configuration with two policies:

  • The first includes all available configuration attributes.
  • The second acts as a default policy.

simple policy example

  "storage": {
+    "retention": {
+      "dryRun": false,
+      "delay": "24h",
+      "policies": [
+        {
+          "repoNames": ["infra/*", "tmp/**"],
+          "deleteReferrers": false,
+          "deleteUntagged": true,
+          "KeepTags": [{
+            "patterns": ["v2.*", ".*-prod"],
+            "mostRecentlyPushedCount": 10,
+            "mostRecentlyPulledCount": 10,
+            "pulledWithin": "720h",
+            "pushedWithin": "720h"
+          }]  
+        },
+        {
+          "keepTags": [{
+            "patterns": [".*"]
+          }]
+        }
+      ]
+    }
+  }
+

Configurable attributes

The following table lists the attributes available in the retention policy configuration.

Attribute Value Description
dryRun boolean If true, will log a removal action without actually removing the image. Default is false.
delay time Remove untagged and referrers only if they are older than the specified <time> hours, such as 24h.
policies list A list of policies.
repositories list A list of glob patterns to match repositories.
deleteReferrers boolean If true, delete manifests with a missing Subject. Default is false.
deleteUntagged boolean If true, delete untagged manifests. Default is true.
keepTags list Criteria for tags to retain always.
mostRecentlyPushedCount count Retains the top <count> most recently pushed tags.
mostRecentlyPulledCount count Retains the top <count> most recently pulled tags.
pushedWithin time Retains the tags pushed during the last <time> hours, such as 24h.
pulledWithin time Retains the tags pulled during the last <time> hours, such as 24h.
patterns regex See Notes.

Configuration notes

  • A repository will apply the first policy it matches.
  • If a repository matches no policy, the repository and all its tags are retained.
  • If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed.
  • If keepTags is present but empty, all tags are retained.
  • When multiple rules are configured, a tag is retained if it meets at least one rule.
  • When you specify a regex pattern combined with one or more rules, the rules are applied only to those tags matching the regex.
  • When you specify a regex pattern with no rules other than the default, all tags matching the pattern are retained.
  • In the repositories list, a single asterisk (/*) matches all first-level items in the repository. A double asterisk (/**) matches all recursively.

⚠ We recommend defining a default keepTags policy, such as the following example, as the last policy in the policy list. All tags that don't match the preceding policies will be retained by this default policy:

default policy example

  {
+    "keepTags": [{                               
+        "patterns": [".*"]
+      }]
+  }
+

Complete configuration file example

The following example shows the configuration of multiple retention policies in the context of a complete configuration file.

{
+  "distSpecVersion": "1.1.0-dev",
+  "storage": {
+    "rootDirectory": "/tmp/zot",
+    "gc": true,
+    "gcDelay": "2h",
+    "gcInterval": "1h",
+    "retention": {
+      "dryRun": false,
+      "delay": "24h",
+      "policies": [
+        {
+          "repositories": ["infra/*", "prod/*"],
+          "deleteReferrers": false,
+          "keepTags": [{
+            "patterns": ["v2.*", ".*-prod"]
+          },
+          {
+            "patterns": ["v3.*", ".*-prod"],
+            "pulledWithin": "168h"
+          }]
+        },
+        {
+          "repositories": ["tmp/**"],
+          "deleteReferrers": true,
+          "deleteUntagged": true,
+          "keepTags": [{
+            "patterns": ["v1.*"],
+            "pulledWithin": "168h",
+            "pushedWithin": "168h"
+          }]
+        },
+        {
+          "repositories": ["**"],
+          "deleteReferrers": true,
+          "deleteUntagged": true,
+          "keepTags": [{
+            "mostRecentlyPushedCount": 10,
+            "mostRecentlyPulledCount": 10,
+            "pulledWithin": "720h",
+            "pushedWithin": "720h"
+          }]
+        }
+      ]
+    },
+    "subPaths": {
+      "/a": {
+        "rootDirectory": "/tmp/zot1",
+        "dedupe": true,
+        "retention": {
+          "policies": [
+            {
+              "repositories": ["infra/*", "prod/*"],
+              "deleteReferrers": false
+            }
+          ]
+        }
+      }
+    }
+  },
+  "http": {
+    "address": "127.0.0.1",
+    "port": "8080"
+  },
+  "log": {
+    "level": "debug"
+  }
+}
+

Last update: November 1, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/security-posture/index.html b/v2.0.2/articles/security-posture/index.html new file mode 100644 index 0000000..a6f6404 --- /dev/null +++ b/v2.0.2/articles/security-posture/index.html @@ -0,0 +1 @@ + Security Posture - zotregistry.dev
Skip to content

zot Security Posture

👉 An overview of zot build-time and runtime security hardening features, including:

  • Build-time hardening such as PIE-mode builds
  • Minimal-build option for smaller attack surface
  • Open Source Security Foundation best practices for CI/CD
  • Non-root deployment
  • Robust authentication/authorization options

The zot project takes a defense-in-depth approach to security, applying industry-standard best practices at various stages. Recognizing that security hardening and product features are sometimes in conflict with each other, we also provide flexibility both at build and deployment time.

Build-time hardening

The following are the steps taken during build-time.

PIE build-mode

The zot binary is built with PIE build-mode enabled to take advantage of ASLR support in modern operating systems such as Linux ASLR. While zot is intended to be a long-running service (without frequent restarts), it prevents attackers from developing a generic attack that depends on predictable memory addresses across multiple zot deployments.

Conditional builds

Functionality in zot is broadly organized as a core Distribution Specification implementation and additional features as extensions. The rationale behind this approach is to minimize or control library dependencies that get included in the binary and consequently the attack surface.

We currently build and release two image flavors:

  • minimal, which is a minimal Distribution Specification conformant registry, and

  • full, which incorporates the minimal build and all extensions

The minimal flavor is for the security-minded and minimizes the number of dependencies and libraries. The full flavor is for the functionality-minded with the caveat that the attack surface of the binary is potentially broader. However by no means are these the only options. Our build (via the Makefile) provides the flexibility to pick and choose extensions in order to build a binary between minimal and full. For example,

make EXTENSIONS=search binary

produces a zot binary with only the search feature enabled.

CI/CD pipeline

zot CI/CD process attempts to align with the Open Source Security Foundation (OSSF) best practices guidelines to achieve high code quality.

Code reviews

zot is an open source project and all code submissions are open and transparent. Every pull request (PR) submitted to the project repository must be reviewed by the code owners. We have additional CI/CD workflows monitoring for unreviewed commits.

CI/CD checks

All PRs must pass the full CI/CD pipeline checks including unit, functional, and integration tests, code quality and style checks, and performance regressions. In addition, all binaries produced are subjected to further security scans to detect any known vulnerabilities.

Runtime hardening

The following steps can be taken to harden a zot deployment.

Unprivileged runtime process

Running zot doesn’t require root privileges. In fact, the recommended approach is to create a separate user/group ID for the zot process.

Authentication

All interactions with zot are over HTTP APIs, and htpasswd-based local authentication, LDAP, mutual TLS, and token-based authentication mechanisms are supported. We strongly recommend enabling a suitable mechanism for your deployment use case in order to prevent unauthorized access. See the provided authentication examples.

Access control

Following authentication, it is further possible to allow or deny actions by a user on a particular repository stored on the zot registry. See the provided access control examples.

Vulnerability scans

Apart from hardening the deployment itself, zot also supports security scanning of stored container images.

Reporting security issues

We understand that no software is perfect and in spite of our best efforts, security bugs may be found. Refer to our security policy for taking a responsible course of action when reporting security bugs.


Last update: December 21, 2022
\ No newline at end of file diff --git a/v2.0.2/articles/storage/index.html b/v2.0.2/articles/storage/index.html new file mode 100644 index 0000000..3760231 --- /dev/null +++ b/v2.0.2/articles/storage/index.html @@ -0,0 +1,165 @@ + Storage Planning - zotregistry.dev
Skip to content

Storage Planning with zot

👉 zot supports the following features to provide OCI standards-based, vendor-agnostic image storage:

  • Local and remote file storage
  • Inline deduplication and garbage collection
  • Data scrubbing in background

Storage model

Data handling in zot revolves around two main principles: that data and APIs on the wire conform to the OCI Distribution Specification and that data on the disk conforms to the OCI Image Layout Specification. As a result, any client that is compliant with the Distribution Specification can read from or write to a zot registry. Furthermore, the actual storage is simply an OCI Image Layout. With only these two specification documents in hand, the entire data flow inside can be easily understood.

✏ zot does not implement, support, or require any vendor-specific protocols, including that of Docker.

Hosting an OCI image layout

Because zot supports the OCI image layout, it can readily host and serve any directories holding a valid OCI image layout even when those directories have been created elsewhere. This property of zot is suitable for use cases in which container images are independently built, stored, and transferred, but later need to be served over the network.

Storage features

Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.

Commit

Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.

Deduplication

Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.

Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.

Garbage collection

After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. See Configuring garbage collection for details.

Scrub

The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.

Storage backends

The following types of storage backends are supported.

Local filesystem

zot can store and serve files from one or more local directories. A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.

✏ Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.

Remote filesystem

zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS s3 storage service.

Example: configuration for remote (s3) storage

Click here to view a sample zot configuration for remote storage.
{
+    "distSpecVersion": "1.0.1-dev",
+    "storage": {
+        "rootDirectory": "/tmp/zot",
+        "dedupe": true,
+        "storageDriver": {
+            "name": "s3",
+            "rootdirectory": "/zot",
+            "region": "us-east-2",
+            "bucket": "zot-storage",
+            "secure": true,
+            "skipverify": false
+        },
+        "cacheDriver": {
+            "name": "dynamodb",
+            "endpoint": "http://localhost:4566",
+            "region": "us-east-2",
+            "tableName": "MainTable"
+        },
+    },
+    "http": {
+        "address": "127.0.0.1",
+        "port": "8080"
+    },
+    "log": {
+        "level": "debug"
+    }
+}
+

Configuring zot storage

Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following example.

    "storage":{
+        "rootDirectory":"/tmp/zot",
+        "commit": true,
+        "dedupe": true,
+        "gc": true,
+        "gcDelay": "1h",
+        "gcInterval": "24h"
+    }
+

Configurable attributes

The following table lists the attributes of the storage configuration.

Attribute Description

rootDirectory

Location of the images stored in the server file system.

commit

For faster performance, data written by zot is retained in memory before being periodically committed to disk by the operating system. To eliminate this retention time and cause data to be written to disk immediately, set to true. This prevents data loss but reduces performance.

dedupe

If the server filesystem supports hard links, you can optimize storage space by enabling inline deduplication of layers and blobs that are shared among multiple container images. Deduplication is enabled by default. Set to false to disable deduplication.

gc

When an image is deleted, either by tag or by reference, orphaned blobs can lead to wasted storage. Garbage collection (gc) is enabled by default to reclaim this space. Set to false to disable garbage collection.

gcDelay

(Optional) If garbage collection is enabled, causes it to run once after the specified delay time. The default is 1 hour. Requires the gc attribute to be true.

gcInterval

(Optional) If garbage collection is enabled, causes periodic collection at the specified interval. Must be set based on use cases and user workloads. If no value is specified, there is no periodic collection. Requires the gc attribute to be true.

subpaths

You can store and serve images from multiple filesystems, each with their own repository paths and settings. The following example shows three subpaths.

"storage":{
+  "subPaths": {
+    "/a": {
+      "rootDirectory": "/tmp/zot1",
+      "dedupe": true,
+      "gc": true
+    },
+    "/b": {
+      "rootDirectory": "/tmp/zot2",
+      "dedupe": true
+    },
+    "/c": {
+      "rootDirectory": "/tmp/zot3",
+      "dedupe": false
+    }
+  }
+}

storageDriver

(Remote storage only) Contains settings for a remote storage service. See Configuring remote storage with s3 for details.

cacheDriver

Specifies which database is used to store duplicate blobs when deduplication is enabled. See Cache drivers for details.

Configuring garbage collection

The zot configuration model allows for enabling and disabling garbage collection (gc) and specifying a periodic interval (gcInterval) for collection.

gc gcInterval Result
false n/a GC disabled
omitted n/a GC enabled with 1 hour interval (default)
true omitted GC enabled with 1 hour interval
true 0 GC runs only once
true >0 GC enabled with specified interval

The configuration model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs. The gcDelay attribute causes collection to run once after the specified delay time. This attribute has a default value of one hour (1h).

Configuring remote storage with s3

To configure an Amazon Simple Storage Service (s3) bucket for zot, use the storageDriver attribute in the zot configuration file, as shown in the following example:

    "storage": {
+        "rootDirectory": "/tmp/zot",
+        "storageDriver": {
+            "name": "s3",
+            "region": "us-east-2",
+            "bucket": "zot-storage",
+            "secure": true,
+            "skipverify": false,
+            "accesskey": "<YOUR_ACCESS_KEY_ID>",
+            "secretkey": "<YOUR_SECRET_ACCESS_KEY>"
+        }
+    }
+

For descriptions of the configurable attributes for storageDriver, see the s3 storage driver project in GitHub.

s3 Credentials

In the s3 configuration file example, the s3 credentials were configured with the attributes accesskey and secretkey. As an alternative, you can omit these attributes from the configuration file and you can configure them using environment variables or a credential file.

  • Environment variables

    zot looks for credentials in the following environment variables:

    AWS_ACCESS_KEY_ID
    +AWS_SECRET_ACCESS_KEY
    +AWS_SESSION_TOKEN (optional)
    +
  • Credential file

    A credential file is a plaintext file that contains your access keys, as shown in the following example.

    [default]
    +aws_access_key_id = <YOUR_DEFAULT_ACCESS_KEY_ID>
    +aws_secret_access_key = <YOUR_DEFAULT_SECRET_ACCESS_KEY>
    +
    +[test-account]
    +aws_access_key_id = <YOUR_TEST_ACCESS_KEY_ID>
    +aws_secret_access_key = <YOUR_TEST_SECRET_ACCESS_KEY>
    +
    +[prod-account]
    +; work profile
    +aws_access_key_id = <YOUR_PROD_ACCESS_KEY_ID>
    +aws_secret_access_key = <YOUR_PROD_SECRET_ACCESS_KEY>
    +

    The [default] heading defines credentials for the default profile, which zot will use unless you configure it to use another profile. You can specify a profile using the AWS_PROFILE environment variable as in this example:

    AWS_PROFILE=test-account
    +

    The credential file must be named credentials. The file must be located in the .aws/ subdirectory in the home directory of the same server that is running your zot application.

For more details about specifying s3 credentials, see the AWS documentation.

S3 permissions scopes

The following AWS policy is required by zot for push and pull.

✏ Replace S3_BUCKET_NAME with the name of your s3 bucket.

[AWS CONFIGURATION]
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": [
+        "s3:ListBucket",
+        "s3:GetBucketLocation",
+        "s3:ListBucketMultipartUploads"
+      ],
+      "Resource": "arn:aws:s3:::<S3_BUCKET_NAME>"
+    },
+    {
+      "Effect": "Allow",
+      "Action": [
+        "s3:PutObject",
+        "s3:GetObject",
+        "s3:DeleteObject",
+        "s3:ListMultipartUploadParts",
+        "s3:AbortMultipartUpload"
+      ],
+      "Resource": "arn:aws:s3:::<S3_BUCKET_NAME>/*"
+    }
+  ]
+}
+

For more details about configuring AWS policies, see the AWS documentation.

Cache drivers

A cache driver is used to store duplicate blobs when dedupe is enabled. zot supports database caching using BoltDB as the cache driver for local filesystems and DynamoDB for remote filesystems.

BoltDB

If you don't specify a cache driver, zot defaults to BoltDB. BoltDB is stored either in zot's root directory or in the subpath root directory.

    "storage": {
+        "rootDirectory": "/tmp/zot",
+        "dedupe": true
+    }
+

In this example, BoltDB can be found at /tmp/zot/cache.db.

DynamoDB

To use DynamoDB as the cache driver, the following storage configuration must be present:

  • dedupe is enabled
  • remoteCache is enabled
  • cacheDriver attribute is configured as in the following example:
    "storage": {
+        "rootDirectory": "/tmp/zot",
+        "dedupe": true,
+        "remoteCache": true,
+        "cacheDriver": {
+            "name": "dynamodb",                  // driver name
+            "endpoint": "http://localhost:4566", // aws endpoint
+            "region": "us-east-2"                // aws region
+            "cacheTablename": "ZotBlobTable"     // table to store deduped blobs
+        }
+    },
+

The AWS GO SDK loads additional configuration and credentials values from your environment variables, shared credentials, and shared configuration files.

If the search extension is enabled, additional parameters are required:

        "cacheDriver": {
+            "name": "dynamodb",
+            "endpoint": "http://localhost:4566",
+            "region": "us-east-2",
+            "cacheTablename": "ZotBlobTable",
+            // used by search extensions
+            "repoMetaTablename": "ZotRepoMetadataTable",
+            "manifestDataTablename": "ZotManifestDataTable",
+            "versionTablename": "ZotVersion"
+        }
+

DynamoDB permission scopes

The following AWS policy is required by zot for caching blobs.

✏ Replace DYNAMODB_TABLE with the name of your table, which should be the value of cacheTablename in the zot configuration.

In this case, the AWS Resource value would be arn:aws:dynamodb:*:*:table/ZotBlobTable

[AWS CONFIGURATION]
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Action": [
+        "dynamodb:CreateTable",
+        "dynamodb:GetItem",
+        "dynamodb:UpdateItem",
+        "dynamodb:DeleteItem"
+      ],
+      "Resource": "arn:aws:dynamodb:*:*:table/<DYNAMODB_TABLE>"
+    }
+  ]
+}
+

For more details about configuring AWS DynamoDB, see the AWS documentation.

Remote storage subpaths

As in the case with local filesystem storage, you can use multiple remote storage locations using the subpath attribute, as in the following example.

"subPaths": {
+    "/a": {
+        "rootDirectory": "/zot-a",
+        "storageDriver": {
+            "name": "s3",
+            "region": "us-east-2",
+            "bucket": "zot-storage",
+            "secure": true,
+            "skipverify": false
+        }
+    },
+    "/b": {
+       .
+       .
+       .
+    }
+}
+

The subPaths feature ties together several separate storage filesystems and backends behind the same HTTP API interface. In the example above, both repository paths "/a" and "/b" are exposed to clients. Content on these two paths can be hosted completely separately by different storage services, locations, or filesystems, with no difference to the user interface and no perceptible difference to the user experience. This is useful if one wants to serve existing OCI images from different backends or if storage can be expanded only by using different backing stores.

💡 zot also supports different storage drivers for each subpath.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/verifying-signatures/index.html b/v2.0.2/articles/verifying-signatures/index.html new file mode 100644 index 0000000..4ae19d2 --- /dev/null +++ b/v2.0.2/articles/verifying-signatures/index.html @@ -0,0 +1,86 @@ + Verifying Image Signatures - zotregistry.dev
Skip to content

Verifying image signatures

Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user.

To verify image signatures, zot supports the following tools:

Enabling image signature verification

To enable image signature verification, add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:

"extensions": {
+  "trust": {
+    "enable": true,
+    "cosign": true,
+    "notation": true
+  }
+}
+

The following table lists the configurable attributes of the trust extension.

Attribute Description
enable If this attribute is missing, signature verification is disabled by default. Signature verification is enabled by including this attribute and setting it to true. You must also enable at least one of the verification tools.
cosign Set to true to enable signature verification using the cosign tool.
notation Set to true to enable signature verification using the notation tool.

What is needed for verifying signatures

To verify the validity of a signature for an image, zot makes use of two types of files:

  • A public key file that pairs with the private key used to sign an image with cosign

  • A certificate file that is used to sign an image with notation

Upload these files using an extension of the zot API, as shown in the following examples:

  • To upload a public key for cosign:

    API path

    /v2/_zot/ext/cosign"
    +
    Example request
    curl --data-binary @file.pub -X POST "http://localhost:8080/v2/_zot/ext/cosign"
    +
    Result

    The uploaded file is stored in the _cosign directory under the rootDir specified in the zot configuration file or in the Secrets Manager.

  • To upload a certificate for notation:

    API path

    /v2/_zot/ext/notation?truststoreType=ca
    +

    When uploading a certificate, you should specify the truststoreType. If the truststore is a certificate authority, the value is ca. This is the default if this attribute is omitted.

    Example request

    curl --data-binary @certificate.crt -X POST "http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca"
    +
    Result

    The uploaded file is stored in the _notation/truststore/x509/{truststoreType}/default directory under the rootDir specified in the zot configuration file or in the Secrets Manager.

Where needed files are stored

Uploaded public keys and certificates are stored in the local filesystem, in specific directories named _cosign and _notation under $rootDir, or in the Secrets Manager.

  • The _cosign directory contains uploaded public key files in the following structure:

    _cosign
    +├── $publicKey1
    +└── $publicKey2
    +
  • The _notation directory contains a set of files in the following structure:

    _notation
    +├── trustpolicy.json
    +└── truststore
    +    └── x509
    +        └── $truststoreType
    +            └── default
    +                └── $certificate
    +

    In this directory, the trustpolicy.json file contains content that is updated automatically whenever a new certificate is added to a new truststore. This content cannot be changed by the user. An example of the trustpolicy.json file content is shown below:

    {
    + "version": "1.0",
    +  "trustPolicies": [
    +    {
    +      "name": "default-config",
    +      "registryScopes": [ "*" ],
    +      "signatureVerification": {
    +        "level" : "strict" 
    +      },
    +      "trustStores": ["ca:default","signingAuthority:default"],
    +      "trustedIdentities": [
    +        "*"
    +      ]
    +    }
    +  ]
    +}
    +
    • By default, the trustpolicy.json file sets the signatureVerification.level property to strict, which enforces all validations. For example, a signature is not trusted if its certificate has expired, even if the certificate verifies the signature.

    • The trustpolicy.json file contains two default truststores, ca:default and signingAuthority:default. This list of truststores is not updated when a new certificate is uploaded.

    • The content of the trustStores field will match the content of the _notation/truststore directory.

How signature verification works

Based on the uploaded files and the information about images stored in zot's database, signature verification is performed for all signed images. The verification result for each signed image is stored in the database and is visible from GraphQL. The stored information about a signature includes:

  • The tool that was used to generate the signature, such as cosign or notation
  • The trustworthiness of the signature, such as whether a certificate or public key exists that can successfully verify the signature
  • The author of the signature, which can be either:

    • The public key, for signatures generated using cosign
    • The subject of the certificate, for signatures generated using notation

Example of GraphQL output

Sample request

{
+  Image(image: "busybox:latest") {
+    Digest
+    IsSigned
+    Tag
+    SignatureInfo {
+        Tool
+        IsTrusted
+        Author
+    }
+  }
+}
+

Sample response

{
+  "data": {
+    "Image": {
+      "Digest":"sha256:6c19fba547b87bde9a45df2f8563e0c61826d098dd30192a2c8b86da1e1a6360",
+      "IsSigned": true,
+      "Tag": "latest",
+      "SignatureInfo":[
+        {
+          "Tool":"cosign",
+          "IsTrusted":false,
+          "Author":""
+        },
+        {
+          "Tool":"cosign",
+          "IsTrusted":false,
+          "Author":""
+        },
+        {
+          "Tool":"cosign",
+          "IsTrusted": true,
+          "Author":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9pN+/hGcFlh4YYaNvZxNvuh8Qyhl\npURz77qScOHe3DqdmiWiuqIseyhEdjEDwpL6fHRwu3a2Nd9wbKqm0la76w==\n-----END PUBLIC KEY-----\n"
+        },
+        {
+          "Tool":"notation",
+          "IsTrusted": false,
+          "Author":"CN=v4-test,O=Notary,L=Seattle,ST=WA,C=US"
+        },
+        {
+          "Tool":"notation",
+          "IsTrusted": true,
+          "Author":"CN=multipleSig,O=Notary,L=Seattle,ST=WA,C=US"
+        }
+      ]
+    }
+  }
+}
+

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/articles/workflow/index.html b/v2.0.2/articles/workflow/index.html new file mode 100644 index 0000000..3109c6c --- /dev/null +++ b/v2.0.2/articles/workflow/index.html @@ -0,0 +1,207 @@ + Software Provenance Workflow Using OCI Artifacts - zotregistry.dev
Skip to content

Software Provenance Workflow Using OCI Artifacts

👉 This article demonstrates an end-to-end workflow for installing a zot registry, then pushing and signing an image and a related artifact, such as an SBOM.

Workflow

The following sections describe the step-by-step workflow. To view the steps combined into a single script, see Reference: Full workflow script.

For the workflow examples, the zot registry is assumed to be installed and running at localhost:8080.

Step 1: Download the client tools

This workflow uses the regctl registry client and the cosign image signing tool. As a first step, we download binaries for these tools in a tools directory.

TEST_TMPDIR=$(mktemp -d "${PWD}/artifact-test-${1:+-$1}.XXXXXX")
+
+TOOLSDIR=$(pwd)/hack/tools
+mkdir -p ${TOOLSDIR}/bin
+
+REGCLIENT=${TOOLSDIR}/bin/regctl
+REGCLIENT_VERSION=v0.5.1
+curl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64
+chmod +x ${REGCLIENT}
+
+COSIGN=${TOOLSDIR}/bin/cosign
+COSIGN_VERSION=2.1.1
+curl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 
+chmod +x ${COSIGN}
+

Step 2: Deploy an OCI registry with referrers support (zot)

Next, we execute the following tasks to deploy an OCI registry:

  • Copy a zot executable binary to the server.
  • Create a basic configuration file for the zot server, specifying the local root directory, the network location, and the port number.
  • Launch zot with the newly-created configuration file.
  • Looping with a periodic cURL query, detect when zot is up and running.
ZOT=${TOOLSDIR}/bin/zot
+ZOT_VERSION=2.0.0-rc6
+curl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal
+chmod +x ${ZOT}
+
+ZOT_HOST=localhost
+ZOT_PORT=8080
+
+# function to start zot and test for readiness
+function zot_setup() {
+cat > $TEST_TMPDIR/zot-config.json << EOF
+{
+  "distSpecVersion": "1.1.0-dev",
+  "storage": {
+      "rootDirectory": "$TEST_TMPDIR/zot"
+  },
+  "http": {
+      "address": "$ZOT_HOST",
+      "port": "$ZOT_PORT"
+  },
+  "log": {
+      "level": "error"
+  }
+}
+EOF
+  # start zot as a background task
+  ${ZOT} serve $TEST_TMPDIR/zot-config.json &
+  pid=$!
+        # wait until service is up
+  count=5
+  up=0
+  while [[ $count -gt 0 ]]; do
+    if [ ! -d /proc/$pid ]; then
+      echo "zot failed to start or died"
+      exit 1
+    fi
+    up=1
+    curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0
+    if [ $up -eq 1 ]; then break; fi
+    sleep 1
+    count=$((count - 1))
+  done
+  if [ $up -eq 0 ]; then
+    echo "Timed out waiting for zot"
+    exit 1
+  fi
+  # setup an OCI client
+  ${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT
+}
+
+# call the function to start zot
+zot_setup
+

Step 3: Copy an image to the OCI registry

This step copies a busybox container image into the registry.

skopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+

This step creates a simple artifact file and associates it with the busybox image in the registry.

cat > ${TEST_TMPDIR}/artifact.yaml << EOF
+key:
+  val: artifact
+EOF
+${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+

The --subject command flag associates the artifact file with the specified subject (in this case, the busybox image). If no subject is specified by the command, the artifact is considered independent and not associated with any existing image.

Step 5: Display the artifact tree

This step prints the artifact tree of the busybox image. The tree includes the artifact yaml file, showing the association of the artifact to the busybox image.

These script commands define REF0 as the artifact that was uploaded referring to the first container image.

REF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)
+REF0="${REF0:1:-1}"
+

The following example shows the command and its output:

$ regctl artifact tree localhost:8080/busybox:latest
+
+Ref: localhost:8080/busybox:latest  
+Digest: sha256:9172c5f692f2c65e4f773448503b21dba2de6454bd159905c4bf6d83176e4ea3
+Referrers:  
+   - sha256:9c0655368b10ca4b2ffe39e4dd261fb89df25a46ae92d6eb4e6e1792a451883e: application/yaml
+

The displayed artifact tree shows that the original image (localhost:8080/busybox:latest) has one direct referrer (sha256:9c06...883e: application/yaml), the artifact yaml file.

Step 6: Sign the image and artifact

This step creates a key pair for cosign in a separate directory, then uses cosign to sign both the image and the artifact file. Both signatures, like the artifact file itself, are associated with the busybox image.

# create a key pair in a different directory
+pushd ${TEST_TMPDIR}
+COSIGN_PASSWORD= ${COSIGN} generate-key-pair
+popd
+# sign the image
+COSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+# sign the artifact referring to the image
+COSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}
+

Step 7: Display the artifact tree

This step again prints the artifact tree, which should now show the artifact and the two signatures, all associated to the busybox image.

${REGCLIENT} artifact tree localhost:8080/busybox:latest
+

The following example shows the command and its output:

$ regctl artifact tree localhost:8080/busybox:latest
+
+Ref: localhost:8080/busybox:latest
+Digest: sha256:9172c5f692f2c65e4f773448503b21dba2de6454bd159905c4bf6d83176e4ea3
+Referrers:
+  - sha256:9c0655368b10ca4b2ffe39e4dd261fb89df25a46ae92d6eb4e6e1792a451883e: application/yaml
+    Referrers:
+      - sha256:06792b209137486442a2b804b2225c0014e3e238d363cdbea088bbd73207fb34: application/vnd.dev.cosign.artifact.sig.v1+json
+  - sha256:995b6a78bf04a7a9676dac76b4598ccb645c17e30b02f294de9fdfa2f28eb7b2: application/vnd.dev.cosign.artifact.sig.v1+json
+

The displayed artifact tree shows that the original image now has two direct referrers — the artifact and the cosign signature of the original image. In addition, there is a second-level referrer — the cosign signature of the artifact, which is a referrer of the artifact file.

Step 8: End of demonstration

This step halts the zot registry server, ending the workflow demonstration.

# function for stopping zot after demonstration
+function zot_teardown() {
+  killall zot
+}
+
+# stop zot
+zot_teardown
+

Reference: Full workflow script

Expand the text box below to view the entire workflow as a single executable shell script.

💡 To copy the script to the clipboard, click the copy icon that appears in the upper right corner of the expanded text box.

Click here to view the all-in-one script
#!/bin/bash -xe
+
+TEST_TMPDIR=$(mktemp -d "${PWD}/artifact-test-${1:+-$1}.XXXXXX")
+
+TOOLSDIR=$(pwd)/hack/tools
+mkdir -p ${TOOLSDIR}/bin
+
+REGCLIENT=${TOOLSDIR}/bin/regctl
+REGCLIENT_VERSION=v0.5.1
+curl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64
+chmod +x ${REGCLIENT}
+
+COSIGN=${TOOLSDIR}/bin/cosign
+COSIGN_VERSION=2.1.1
+curl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 
+chmod +x ${COSIGN}
+
+# OCI registry
+ZOT=${TOOLSDIR}/bin/zot
+ZOT_VERSION=2.0.0-rc6
+curl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal
+chmod +x ${ZOT}
+
+ZOT_HOST=localhost
+ZOT_PORT=8080
+
+function zot_setup() {
+cat > $TEST_TMPDIR/zot-config.json << EOF
+{
+  "distSpecVersion": "1.1.0-dev",
+  "storage": {
+      "rootDirectory": "$TEST_TMPDIR/zot"
+  },
+  "http": {
+      "address": "$ZOT_HOST",
+      "port": "$ZOT_PORT"
+  },
+  "log": {
+      "level": "error"
+  }
+}
+EOF
+# start as a background task
+${ZOT} serve $TEST_TMPDIR/zot-config.json &
+pid=$!
+        # wait until service is up
+count=5
+up=0
+while [[ $count -gt 0 ]]; do
+    if [ ! -d /proc/$pid ]; then
+    echo "zot failed to start or died"
+    exit 1
+    fi
+    up=1
+    curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0
+    if [ $up -eq 1 ]; then break; fi
+    sleep 1
+    count=$((count - 1))
+done
+if [ $up -eq 0 ]; then
+    echo "Timed out waiting for zot"
+    exit 1
+fi
+# setup a OCI client
+${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT
+}
+
+# function for stopping zot after demonstration
+function zot_teardown() {
+killall zot
+}
+
+# call the function to start zot
+zot_setup
+
+# copy an image
+skopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+
+# copy an artifact referring to the above image
+cat > ${TEST_TMPDIR}/artifact.yaml << EOF
+key:
+val: artifact
+EOF
+${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+REF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)
+REF0="${REF0:1:-1}"
+
+# create a key pair in a different directory
+pushd ${TEST_TMPDIR}
+COSIGN_PASSWORD= ${COSIGN} generate-key-pair
+popd
+# sign the image
+COSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest
+# sign the artifact referring to the image
+COSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}
+
+# list the reference tree
+${REGCLIENT} artifact tree localhost:8080/busybox:latest
+
+# stop zot
+zot_teardown
+

Last update: October 6, 2023
\ No newline at end of file diff --git a/v2.0.2/assets/images/504566.jpg b/v2.0.2/assets/images/504566.jpg new file mode 100644 index 0000000..621abf6 Binary files /dev/null and b/v2.0.2/assets/images/504566.jpg differ diff --git a/v2.0.2/assets/images/504567.jpg b/v2.0.2/assets/images/504567.jpg new file mode 100644 index 0000000..919bcf9 Binary files /dev/null and b/v2.0.2/assets/images/504567.jpg differ diff --git a/v2.0.2/assets/images/504568.jpg b/v2.0.2/assets/images/504568.jpg new file mode 100644 index 0000000..3723954 Binary files /dev/null and b/v2.0.2/assets/images/504568.jpg differ diff --git a/v2.0.2/assets/images/504569.jpg b/v2.0.2/assets/images/504569.jpg new file mode 100644 index 0000000..9ae98b2 Binary files /dev/null and b/v2.0.2/assets/images/504569.jpg differ diff --git a/v2.0.2/assets/images/alpine_bookmarked.png b/v2.0.2/assets/images/alpine_bookmarked.png new file mode 100644 index 0000000..52fbaa1 Binary files /dev/null and b/v2.0.2/assets/images/alpine_bookmarked.png differ diff --git a/v2.0.2/assets/images/alpine_not_bookmarked.png b/v2.0.2/assets/images/alpine_not_bookmarked.png new file mode 100644 index 0000000..6b955a2 Binary files /dev/null and b/v2.0.2/assets/images/alpine_not_bookmarked.png differ diff --git a/v2.0.2/assets/images/bookmarked_off.png b/v2.0.2/assets/images/bookmarked_off.png new file mode 100644 index 0000000..e08fa0b Binary files /dev/null and b/v2.0.2/assets/images/bookmarked_off.png differ diff --git a/v2.0.2/assets/images/bookmarked_on.png b/v2.0.2/assets/images/bookmarked_on.png new file mode 100644 index 0000000..1b8d475 Binary files /dev/null and b/v2.0.2/assets/images/bookmarked_on.png differ diff --git a/v2.0.2/assets/images/cosign.svg b/v2.0.2/assets/images/cosign.svg new file mode 100644 index 0000000..c66fe6d --- /dev/null +++ b/v2.0.2/assets/images/cosign.svg @@ -0,0 +1 @@ +$0 podman launching zot$1 bash$podmanrun-p5000:5000ghcr.io/project-zot/zot-linux-amd64:latest{"level":"info","params":{"Version":"1.0.0-dev","GoVersion":"go1.17.5","Commit":"v1.3.8-rc3-38a110314ba3af67f970ed0ac909102edf7208d3","BinaryType":"extended","AccessControl":null,"Storage":{"Dedupe":true,"GC":true,"Commit":false,"GCDelay":3600000000000,"RootDirectory":"/var/lib/registry","StorageDriver":null,"SubPaths":null},"HTTP":{"Address":"0.0.0.0","Port":"5000","TLS":null,"Auth":null,"RawAccessControl":null,"Realm":"","AllowReadAccess":false,"ReadOnly":false,"Ratelimit":null},"Log":{"Level":"debug","Output":"","Audit":""},"Extensions":null},"goroutine":1,"caller":"zotregistry.io/zot/pkg/api/controller.go:103","time":"2022-04-11T07:52:53.967114224Z","message":"configurationsettings"}{"level":"info","cpus":8,"max.openfiles":1048576,"max.inotifywatches":"2147483647","goroutine":1,"caller":"zotregistry.io/zot/pkg/api/controller.go:91","time":"2022-04-11T07:52:53.967201658Z","message":"runtimeparams"}$skopeo--insecure-policycopy--format=oci--dest-tls-verify=falsedocker://busybox:latestdocker://localhost:5000/busybox:latestGettingimagesourcesignatures{"level":"error","error":"stat/var/lib/registry/busybox/blobs/sha256/554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df:nosuchfileordirectory","blob":"/var/lib/registry/busybox/blobs/sha256/554879bb300427c7301c1cbdf266atblob"}{"level":"error","error":"cache:miss","digest":"sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":65,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","time":"2022-04-11T07:53:01.250247114Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","message":"cache:notfound"}PAPI"}f","goroutine":67,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","time":"2022-04-11T07:53:01.756012536Z",{"level":"info","module":"http","clientIP":"10.0.2.100:34750","method":"HEAD","path":"/v2/busybox/blobs/sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","statusCode":404,"latency":"280.768µs","bodySize":407,"headers":{"Connection":["close"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":67,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.756148592Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34754","method":"POST","path":"/v2/busybox/blobs/uploads/","statusCode":202,"latency":"1.086855ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["0"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":69,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.758698279Z","message":"HTTPAPI"}Copyingblob554879bb3004done{"level":"info","module":"http","clientIP":"10.0.2.100:34756","method":"PATCH","path":"/v2/busybox/blobs/uploads/3dcddca9-e320-4c48-aa26-a996487171d4","statusCode":202,"latency":"81.964986ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["772806"],"Content-Type":["application/octet-stream"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":71,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.842347694Z","message":"HTTPAPI"}{"level":"info","r.ContentLength":0,"goroutine":25,"caller":"zotregistry.io/zot/pkg/api/routes.go:1040","time":"2022-04-11T07:53:01.844397079Z","message":"DEBUG"}4879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","dst":"/var/lib/registry/busybox/blobs/sha256/554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":25,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","time":"2022-04-11T07:53:01.846033457Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","message":"dedupe:enter"}{"level":"debug","src":"/var/lib/registry/busybox/.uploads/3dcddca9-e320-4c48-aa26-a996487171d4","dst":"/var/lib/registry/busybox/blobs/sha256/554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":25,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1171","time":"2022-04-11T07:5egistry.io/zot/pkg/storage/storage_fs.go:1171","time":"2022-04-11T07:53:01.848178432Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1171","message":"dedupe:rename"}{"level":"info","module":"http","clientIP":"10.0.2.100:34758","method":"PUT","path":"/v2/busybox/blobs/uploads/3dcddca9-e320-4c48-aa26-a996487171d4?digest=sha256%3A554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","statusCode":201,"latency":"4.054838ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["0"],"Content-Type":["application/octh":["0"],"Content-Type":["application/octet-stream"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":25,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.{"level":"error","error":"cache:miss","digest":"sha256:02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":72,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","time":"2022-04-11T07:53:02.285817834Z",4a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","statusCode":404,"latency":"692.213µs","bodySize":407,"headeroutine":72,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:02.286318115Z","message":"HTTP{"level":"info","module":"http","clientIP":"10.0.2.100:34762","method":"POST","path":"/v2/busybox/blobs/uploads/","statusCode":202,"latency":"188.595µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["0"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":74,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:02.288571194Z","message":"HTTPAPI"}Copyingconfig02611b034adone{"level":"info","module":"http","clientIP":"10.0.2.100:34766","method":"PATCH","path":"/v2/busybox/blobs/uploads/172e7487-2eb8-4018-9e74-e2717ca0438c","statusCode":202,"latency":"211.237µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["575"],"Content-Type":["application/octet-stream"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":41,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:02.290314854Z","message":"HTTPAPI"}{"level":"info","r.ContentLength":0,"goroutine":43,"caller":"zotregistry.io/zot/pkg/api/routes.go:1040","time":"2022-04-11T07:53:02.291704639Z","message":"DEBUG"}611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","dst":"/var/lib/registry/busybox/blobs/sha256/02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":43,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","time":"2022-04-11T07:53:02.291886121Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","mesegistry.io/zot/pkg/storage/storage_fs.go:1171","time":"2022-04-11T07:53:02.295545014Z","caller":"zotregistry.io/zot/pkg{"level":"info","module":"http","clientIP":"10.0.2.100:34768","method":"PUT","path":"/v2/busybox/blobs/uploads/172e7487-2eb8-4018-9e74-e2717ca0438c?digest=sha256%3A02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","statusCode":201,"latency":"3.988163ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Leng"Go-http-client/1.1"]},"goroutine":43,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:02.295663186Z","message":"HTTPAPI"}Writingmanifesttoimagedestination{"level":"info","blobPath":"/var/lib/registry/busybox/blobs/sha256/554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d3ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.298946022Z","message":"GC:gotreference"}{"level":"debug","digest":"sha256:d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182","goroutine":51,"cal022-04-11T07:53:02.298682766Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:516","message":"manifestlayers"}fromroot"}image-spec/specs-go/v1","goroutine":51,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.29907803Z","message":"detectedjumpoutsidepermittedpackages"}{"level":"debug","digest":"sha256:02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":51,"cale"}ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.299111583Z","message":"->ws.recurs{"level":"debug","v1path":"github.com/opencontainers/image-spec/specs-go/v1","name":"time::Time","goroutine":51,"callerler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.299181184Z","message":"detectedjumpoutsidepermittedpackages"}{"level":"debug","goroutine":51,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df"}.299476219Z","message":"garbagecollected0blobs"}{"level":"info","module":"http","clientIP":"10.0.2.100:34770","method":"PUT","path":"/v2/busybox/manifests/latest","statusCode":201,"latency":"1.151546ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Content-Length":["347"],"Content-Type":["application/vnd.oci.image.manifest.v1+json"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":51,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:02.299504703Z","message":"HTTPAPI"}Storingsignatures$cosigngenerate-key-pairEnterpasswordforprivatekey:Enterpasswordforprivatekeyagain:Privatekeywrittentocosign.keyPublickeywrittentocosign.pub$cosignverify--keycosign.publocalhost:5000/busybox:latest{"level":"info","module":"http","clientIP":"10.0.2.100:34774","method":"GET","path":"/v2/","statusCode":200,"latency":"e":"2022-04-11T07:53:14.82411121Z","message":"HTTPAPI"}+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json"],"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":54,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:14.824932815Z","message":"HTTPAPI"}":"2022-04-11T07:53:14.826410906Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34774","method":"GET","path":"/v2/busybox/manifests/sha256-d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182.sig","statusCode":404,"latency":"106.38µs","bodySize":294,"headers":{"Accept":["application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json"],"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":54,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:14.826914864Z","message":"HTTPAPI"}Error:nomatchingsignatures:main.go:46:errorduringcommandexecution:nomatchingsignatures:$cosignsign--keycosign.keylocalhost:5000/busybox:latest{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"GET","path":"/v2/","statusCode":200,"latency":"e":"2022-04-11T07:53:21.543440645Z","message":"HTTPAPI"}1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.544303959Z","message":"HTTPAPI"}Pushingsignatureto:localhost:5000/busybox:"2022-04-11T07:53:21.545961377Z","message":"HTTPAPI"}ser-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.546566045Z","message":"HTTPAPI"}5.049µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.549112596Z","message":"HTTPAPI"}{"level":"error","error":"stat/var/lib/registry/busybox/blobs/sha256/a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a6{"level":"error","error":"cache:miss","digest":"sha256:a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","time":"2022-04-11T07:53:21.550712155Z",9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","statusCode":404,"latency":"112.392µs","bodySize":407,"headers":{"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine{"level":"error","error":"cache:miss","digest":"sha256:e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","time":"2022-04-11T07:53:21.551368089Z",41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","statusCode":404,"latency":"212.029µs","bodySize":407,"header":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.551500288Z","message":"HTTPAPI"}pe":["application/json"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":82,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.552216174Z","message":"HTTPAPI"}e":["application/json"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.552667654Z","message":"HTTPAPI"}],"Content-Type":["application/octet-stream"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":82,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.552938212Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"PATCH","path":"/v2/busybox/blobs/uploads/cac8b7fc-e962-4741-9bb3-7ecfc04b8b4a","statusCode":202,"latency":"90.511µs","bodySize":0,"headers":{"Accept-Encoding":["gzip".20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.553215374Z","message":"HTTPAPI"}-11T07:53:21.553367049Z","message":"DEBUG"}f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","time":"2022-04-11T07:53:21.553480653Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","mes{"level":"info","r.ContentLength":0,"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/routes.go:1040","time":"2022-04-11T07:53:21.553490221Z","message":"DEBUG"}1220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","dst":"/var/lib/registry/busybox/blobs/sha256/e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","time":"2022-04-11T07:53:21.554681021Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1146","mes{"level":"debug","src":"/var/lib/registry/busybox/.uploads/cac8b7fc-e962-4741-9bb3-7ecfc04b8b4a","dst":"/var/lib/registry/busybox/blobs/sha256/e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1171","time":"2022-04-11T07:53:21.555648381Z","caller":"zotregistry.io/zot/pkg{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"PUT","path":"/v2/busybox/blobs/uploads/cac8b7fcode":201,"latency":"2.20057ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Content-Length":["0"],"Content-Type":["application/octet-stream"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.55568514Z","message":"HTTPAPI"}{"level":"info","blobPath":"/var/lib/registry/busybox/blobs/sha256/e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","reference":"sha256-d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182.sig","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:516","time":"2022-04-11T07:53:21.556726239Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:516","message":"manifestlayers"}{"level":"debug","digest":"sha256:d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557051441Z","message":"GC:gotrefe{"level":"debug","digest":"sha256:05f65cfd444a4ba3b0557f6fef7f59175ee355990a5db03d79bfa038e6e87aed","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557112746Z","message":"GC:gotrefeler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557167619Z","message":"GC:markingler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557229406Z","message":"->ws.recurs{"level":"debug","name":"github.com/opencontainers/image-spec/specs-go::Versioned","v1path":"github.com/opencontainers/image-spec/specs-go/v1","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557372134Z","message":"detectedjumpoutsidepermittedpackages"}{"level":"debug","digest":"sha256:02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557445612Z","message":"->ws.recurs{"level":"debug","name":"time::Time","v1path":"github.com/opencontainers/image-spec/specs-go/v1","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557604501Z","message":"detectedjumpo":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557688459Z","message":"detectedjumpo{"level":"debug","v1path":"github.com/opencontainers/image-spec/specs-go/v1","name":"time::Time","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557793006Z","message":"detectedjumpoler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.55786428Z","message":"<-ws.recurse"}{"level":"debug","digest":"sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.557926748Z","message":"->ws.recurs.557996258Z","message":"skippingwalkintonon-parseablemedia-typeapplication/vnd.oci.image.layer.v1.tar+gzipofblob{"level":"debug","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558059277Z","message":"<-ws.recursler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558120011Z","message":"<-ws.recursler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558174323Z","message":"GC:markingler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558233515Z","message":"->ws.recurs7:53:21.558375331Z","message":"detectedjumpoutsidepermittedpackages"}{"level":"debug","digest":"sha256:a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558448008Z","message":"->ws.recurs":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.55857632Z","message":"detectedjumpoutsidepermittedpackages"}":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558659676Z","message":"detectedjumpoler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558722885Z","message":"<-ws.recurs{"level":"debug","digest":"sha256:e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558786665Z","message":"->ws.recurs.558851818Z","message":"skippingwalkintonon-parseablemedia-typeapplication/vnd.dev.cosign.simplesigning.v1+jsonofblobsha256:e31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2"}ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558913554Z","message":"<-ws.recursler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558972264Z","message":"<-ws.recurs.559116365Z","message":"garbagecollected0blobs"}{"level":"info","module":"http","clientIP":"10.0.2.100:34786","method":"PUT","path":"/v2/busybox/manifests/sha256-d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182.sig","statusCode":201,"latency":"2.594891ms","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Content-Length":["558"],"Content-Type":["application/vnd.oci.image.manifest.v1+json"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":82,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.559168624Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34792","method":"GET","path":"/v2/","statusCode":200,"latency":"me":"2022-04-11T07:53:27.025974807Z","message":"HTTPAPI"}1-0.20220209165246-a44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:27.026555329Z","message":"HTTPAPI"}":"2022-04-11T07:53:27.027792827Z","message":"HTTPAPI"}/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json"],"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:27.028098192Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34792","method":"GET","path":"/v2/busybox/blobs/sha256:e31220af4:{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:27.028476543Z","message":"HTTPAPI"}1ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","statusCode":200,"latency":"20.589µs","bodySize":238,"headers"44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:27.028771849Z","message":"HTTPAPI"}Verificationforlocalhost:5000/busybox:latest--Thefollowingcheckswereperformedoneachofthesesignatures:-Thecosignclaimswerevalidated-Thesignatureswereverifiedagainstthespecifiedpublickey1ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","statusCode":200,"latency":"19.577µs","bodySize":238,"headers"44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:27.029114724Z","message":"HTTPAPI"}[{"critical":{"identity":{"docker-reference":"localhost:5000/busybox"},"image":{"docker-manifest-digest":"sha256:d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182"},"type":"cosigncontainerimagesignature"},"optional":null}]{"level":"info","module":"http","clientIP":"10.0.2.100:34746","method":"GET","path":"/v2/","statusCode":200,"latency":"8.246µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":15,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.24804926Z","message":"HTTPAPI"}a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":65,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","time":"2022-04-11T07:53:01.250149941Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","message":"failedtost{"level":"info","module":"http","clientIP":"10.0.2.100:34748","method":"HEAD","path":"/v2/busybox/blobs/sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","statusCode":404,"latency":"1.469364ms","bodySize":407,"headers":{"Connection":["close"],"Docker-Distribution-Api-Version":["registry/2.0"],"User-Agent":["Go-http-client/1.1"]},"goroutine":65,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.250991895Z","message":"HTTa7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":67,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","time":"2022-04-11T07:53:01.755927777Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","message":"failedtostf","goroutine":67,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","timoutine":67,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:01.756148592Z","mesa{"level":"debug","src":"/var/lib/registry/busybox/.uploads/3dcddca9-e320-4c48-aa26-a996487171d4","dstDigest":"sha256:55-e320-4c48-aa26-a996487171d4?digest=sha256%3A554879848290212Z","message":"HTTPAPI848290212Z","message":"HTTPAPI"}{"level":"error","error":"stat/var/lib/registry/busybox/blobs/sha256/02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b:nosuchfileordirectory","blob":"/var/lib/registry/busybox/blobs/sha256/02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":72,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","time":"2022-04-11T07:53:02.285682529Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","message":"failedtost{"level":"info","module":"http","clientIP":"10.0.2.100:34760","method":"HEAD","path":"/v2/busybox/blobs/sha256:02611b03{"level":"info","r.ContentLength":0{"level":"info","r.Co{"level":"debug","src":"/var/lib/registry/busybox/.uploads/172e7487-2eb8-4018-9e74-e2717ca0438c","dstDigest":"sha256:02{"level":"debug","src":"/var/lib/registry/busybox/.uploads/172e7487-2eb8-4018-9e74-e2717ca0438c","dst":"/var/lib/registry/busybox/blobs/sha256/02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdc8b","goroutine":43,"caller":"zotr48b9eb9ca7df","reference":"latest","goroutine":51,"caller":ler":"zotregistry.io/zot/48b9eb9ca7df","reference":"latest","goroutine":51,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:516","time":"2ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.298974525Z","message":"GC:markingler":"zotregistrler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.299004091Z","message":"->ws.recursler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.299319655Z","message":"->ws.recurs.299354019Z","message":"skippingwalkintonon-parseablemedia-typeapplication/vnd.oci.image.layer.v1.tar+gzipofblob{"level":"debug","digest":"sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","gort{"level":"debug","digest":"sha256:554879bb300427c7301c1cbdf266a7eba24a85b10d19f270b3d348b9eb9ca7df","goroutine":51,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:02.299382723Z","message":"<-ws.recurs39.203µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":54,"caller":"zotregistry.io/zot/pkg/api/session.go:132","tim{"level":"info","module":"http","clientIP":"10.0.2.100:34774","method":"GET","path":"/v2/busybox/manifests/latest","statusCode":200,"latency":"222.038µs","bodySize":347,"headers":{"Accept":["application/vnd.docker.distribution.manifest.v1{"level":"info","module":"http","clientIP":"10.0.2.100:346.432µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":54,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time29.075µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","tim{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"GET","path":"/v2/busybox/manifests/latest","statusCode":200,"latency":"126.839µs","bodySize":347,"headers":{"Accept":["application/vnd.docker.distribution.manifest.v15.62µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time"{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"GET","path":"/v2/busybox/manifests/sha256-d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182.sig","statusCode":404,"latency":"72.907µs","bodySize":294,"58c64a13ad5ae72:nosuchfileordirectory","blob":"/var/lib/registry/busybox/blobs/sha256/a56e054a9f5c5db6ce3be0b0dd58c64a13ad5ae72:nosuchfileordirectory","blob":"/var/lib/registry/busybox/blobs/sha256/a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","time":"2022-04-11T07:53:21.550682299Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1272","message":"failedtost2","goroutine":57,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","tim"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1277","message":"cach{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"HEAD","path":"/v2/busybox/blobs/sha256:a56e054a":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.5507543{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"HEAD","path":"/v2/busyb":57,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.550754374Z","message":"HTTPAPI"}{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"HEAD","path":"/v2/busybox/blobs/sha256:e31220af{"level":"info","module":"http","clientIP":"10.0.2.100:34786","method":"POST","path":"/v2/busybox/blobs/uploads/","statusCode":202,"latency":"165.091µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Content-Length":["0"],"Content-Ty{"level":"info","module":"http","clientIP":"10.0.2.100:34780","method":"POST","path":"/v2/busybox/blobs/uploads/","statusCode":202,"latency":"66.044µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"Content-Length":["0"],"Content-Typfc-e962-4741-9bb3-7ecfc04b8b4a","statusCode":202,"latency":".20220209165246-a44adc326839"]},"goroutine":57,"c{"level":"info","module":"http","clientIP":"10.0.2.100:34780","meth],"Content-Type":["application/octet-stream"],"User-Agen{"level":"debug{"level":"info","r.ContentLength":0,"goroutine":82,"caller":"zotregistry.io/zot/pkg/api/routes.go:1040","time":"2022-04{"level":"debug","src":"/var/lib/registry/busybox/.uploads/7aead363-06cf-4d7e-95ca-298f10f39d8a","dstDigest":"sha256:a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","dst":"/var/lib/registry/busybox/blobs/sha256/a56e054a9{"level":"info","r.ContentLength":0,"goroutine":57,"caller":"zotregistry.io/zot/pkg/api/ro{"level":"debug","src":"/var/lib/registry/busybox/.uploads/7aead363-06cf-4d7e-95ca-298f10f39d8a","dst":"/var/lib/registry/busybox/blobs/sha256/a56e054a9f5c5db6ce3be0b0ddd1da2dff77b3396445c12a658c64a13ad5ae72","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:1171","time":"2022-04-11T07:53:21.554536359Z","caller":"zotregistry.io/zot/pkg/storage/storage_fs.go":["application/octet-stream"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":82,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time":"2022-04-11T07:53:21.554604768Z","message":"HTTPAPI"}{"level":"debug","src":"/var/lib/registry/busybox/.uploads/cac8b7fc-e962-4741-9bb3-7ecfc04b8b4a","dstDigest":"sha256:e3-e962-4741-9bb3-7ecfc04b8b4a?digest=sha256%3Ae3122-e962-4741-9bb3-7ecfc04b8b4a?digest=sha256%3Ae31220af41ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","statusC{"l{"level":"debug","digest":"sha256:d11abb379758784ce3c263c2fler":"zotregistry.io/z{"level":"debug","digest":"sha256:d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182","goroutimage-spec/specs-go/v1","goroutine{"level":"debug","digest":"sha256:02611b034a2eaf78ac6fca8f91b88cd4c83794e3713e547a096cda667e5fdutsideperm{"level":"debug","name":"time::Time","v1path":"github.com/opencontainers/image-spec{"level":"debug","v1path":"github.com{"level":"debug","digest":"sha256{"level":"debug","goroutine":82,"caller":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"202{"level":"debug","digest":"sha256:554879bb30042{"level":"debug","digest":"sh{"level":"debug","digest":"sha256:05f65cfd444a4ba3b0557f6fef7f59175ee355990a5db03d79bfa038e6e87aed","goroutine":82,{"level":"debug","name":"github.com/opencontainers/image-spec/specs-go::Versioned",ler":"zotregistry.io/zot/pkg/storage/storage_fs.go:143","time":"2022-04-11T07:53:21.558972264Z","me{"level":"info","module":"http","clientIP":"10.0.2.100:34786","method":"PUT","pat28.524µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","ti{"level":"info","module":"http","clientIP":"10.0.2.100:34792","method":"GET","path":"/v2/busybox/manifests/latest","statusCode":200,"latency":"185.168µs","bodySize":347,"headers":{"Accept":["application/vnd.docker.distribution.manifest.v15.42µs","bodySize":0,"headers":{"Accept-Encoding":["gzip"],"User-Agent":["cosign/v1.6.0(linux;amd64)go-containerregistry/v0.8.1-0.20220209165246-a44adc326839"]},"goroutine":101,"caller":"zotregistry.io/zot/pkg/api/session.go:132","time{"level":"info","module":"http","clientIP":"10.0.2.100:34792","method":"GET","path":"/v2/busybox/manifests/sha256-d11abb379758784ce3c263c2fe3eabe6baf629335037baeb12fa2c5acb960182.sig","statusCode":200,"latency":"84.89µs","bodySize":558,"headers":{"Accept":["application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application1ba68ddcb2986895b783d5082c1ced7d34d69d0c22284641b4d5fd2","statusCode":200,"latency":"42.891µs","bodySize":238,"headers"$cosignverify--keycosign.publocalhost:5000/b-ThPushingsignatureto:l[detachedfrom51944.devto] \ No newline at end of file diff --git a/v2.0.2/assets/images/critical.jpg b/v2.0.2/assets/images/critical.jpg new file mode 100644 index 0000000..265bf84 Binary files /dev/null and b/v2.0.2/assets/images/critical.jpg differ diff --git a/v2.0.2/assets/images/favicon.png b/v2.0.2/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/v2.0.2/assets/images/favicon.png differ diff --git a/v2.0.2/assets/images/high.jpg b/v2.0.2/assets/images/high.jpg new file mode 100644 index 0000000..ccbaf52 Binary files /dev/null and b/v2.0.2/assets/images/high.jpg differ diff --git a/v2.0.2/assets/images/icon-failed-to-scan.jpg b/v2.0.2/assets/images/icon-failed-to-scan.jpg new file mode 100644 index 0000000..e7ecdf0 Binary files /dev/null and b/v2.0.2/assets/images/icon-failed-to-scan.jpg differ diff --git a/v2.0.2/assets/images/icon-no-vulnerability.jpg b/v2.0.2/assets/images/icon-no-vulnerability.jpg new file mode 100644 index 0000000..2ac242f Binary files /dev/null and b/v2.0.2/assets/images/icon-no-vulnerability.jpg differ diff --git a/v2.0.2/assets/images/icon-unverified-signature.jpg b/v2.0.2/assets/images/icon-unverified-signature.jpg new file mode 100644 index 0000000..a4e7dc0 Binary files /dev/null and b/v2.0.2/assets/images/icon-unverified-signature.jpg differ diff --git a/v2.0.2/assets/images/icon-verified-signature.jpg b/v2.0.2/assets/images/icon-verified-signature.jpg new file mode 100644 index 0000000..e75f638 Binary files /dev/null and b/v2.0.2/assets/images/icon-verified-signature.jpg differ diff --git a/v2.0.2/assets/images/illustrations/arch.jpg b/v2.0.2/assets/images/illustrations/arch.jpg new file mode 100644 index 0000000..919bcf9 Binary files /dev/null and b/v2.0.2/assets/images/illustrations/arch.jpg differ diff --git a/v2.0.2/assets/images/illustrations/home.png b/v2.0.2/assets/images/illustrations/home.png new file mode 100644 index 0000000..7eacc0a Binary files /dev/null and b/v2.0.2/assets/images/illustrations/home.png differ diff --git a/v2.0.2/assets/images/layers-details.jpg b/v2.0.2/assets/images/layers-details.jpg new file mode 100644 index 0000000..c21bfe1 Binary files /dev/null and b/v2.0.2/assets/images/layers-details.jpg differ diff --git a/v2.0.2/assets/images/logo.png b/v2.0.2/assets/images/logo.png new file mode 100644 index 0000000..92ab98b Binary files /dev/null and b/v2.0.2/assets/images/logo.png differ diff --git a/v2.0.2/assets/images/logo.svg b/v2.0.2/assets/images/logo.svg new file mode 100644 index 0000000..f38e266 --- /dev/null +++ b/v2.0.2/assets/images/logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/v2.0.2/assets/images/low.jpg b/v2.0.2/assets/images/low.jpg new file mode 100644 index 0000000..ac766a3 Binary files /dev/null and b/v2.0.2/assets/images/low.jpg differ diff --git a/v2.0.2/assets/images/medium.jpg b/v2.0.2/assets/images/medium.jpg new file mode 100644 index 0000000..b2499fb Binary files /dev/null and b/v2.0.2/assets/images/medium.jpg differ diff --git a/v2.0.2/assets/images/pprof-view.jpg b/v2.0.2/assets/images/pprof-view.jpg new file mode 100644 index 0000000..79d1106 Binary files /dev/null and b/v2.0.2/assets/images/pprof-view.jpg differ diff --git a/v2.0.2/assets/images/profile001.png b/v2.0.2/assets/images/profile001.png new file mode 100644 index 0000000..094d72f Binary files /dev/null and b/v2.0.2/assets/images/profile001.png differ diff --git a/v2.0.2/assets/images/profiling-flame.svg b/v2.0.2/assets/images/profiling-flame.svg new file mode 100644 index 0000000..ef8eb49 --- /dev/null +++ b/v2.0.2/assets/images/profiling-flame.svg @@ -0,0 +1,15285 @@ + + + + + + + + + + + + + + +Flame Graph + +Reset Zoom +Search +ic + + + +os.statNolog.func1 (60 samples, 0.60%) + + + +runtime.slicebytetostring (4 samples, 0.04%) + + + +reflect.Value.Interface (2 samples, 0.02%) + + + +encoding/json.(*decodeState).literalStore (222 samples, 2.22%) +e.. + + +reflect.Value.Addr (1 samples, 0.01%) + + + +path.(*lazybuf).append (42 samples, 0.42%) + + + +github.com/aquasecurity/trivy-db/pkg/types.(*Advisory).UnmarshalJSON (1 samples, 0.01%) + + + +runtime.newobject (26 samples, 0.26%) + + + +runtime.unlockWithRank (3 samples, 0.03%) + + + +runtime.arenaIdx.l2 (1 samples, 0.01%) + + + +runtime.slicebytetostring (9 samples, 0.09%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.PaginatedRepoMeta2RepoSummaries (2,705 samples, 27.10%) +zotregistry.io/zot/pkg/extensions/search/co.. + + +cmpbody (1 samples, 0.01%) + + + +runtime.evacuate_faststr (7 samples, 0.07%) + + + +cmpbody (3 samples, 0.03%) + + + +reflect.MakeMapWithSize (6 samples, 0.06%) + + + +runtime.mcall (115 samples, 1.15%) + + + +runtime.growslice (2 samples, 0.02%) + + + +internal/poll.(*FD).decref (1 samples, 0.01%) + + + +internal/poll.ignoringEINTRIO (10 samples, 0.10%) + + + +memeqbody (2 samples, 0.02%) + + + +runtime.spanOfHeap (1 samples, 0.01%) + + + +runtime.getLockRank (1 samples, 0.01%) + + + +regexp.(*inputString).step (7 samples, 0.07%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +reflect.(*rtype).Name (1 samples, 0.01%) + + + +time.norm (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (107 samples, 1.07%) + + + +runtime.forEachG (1 samples, 0.01%) + + + +reflect.resolveTypeOff (2 samples, 0.02%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +runtime.mallocgc (24 samples, 0.24%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +sync.(*Pool).Get (14 samples, 0.14%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func24 (1 samples, 0.01%) + + + +syscall.ByteSliceFromString (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.getitab (1 samples, 0.01%) + + + +net/http.serveContent (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +reflect.(*rtype).Elem (1 samples, 0.01%) + + + +runtime.mallocgc (19 samples, 0.19%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.heapBitsSetType (7 samples, 0.07%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.growslice (2 samples, 0.02%) + + + +reflect.(*rtype).NumMethod (1 samples, 0.01%) + + + +runtime.exitsyscall (1 samples, 0.01%) + + + +os.(*File).Readdirnames (1 samples, 0.01%) + + + +memeqbody (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.writeHeapBits.write (2 samples, 0.02%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotationValue (3 samples, 0.03%) + + + +reflect.unsafe_New (3 samples, 0.03%) + + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +runtime.callers (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +reflect.Value.Set (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.(*gcControllerState).removeIdleMarkWorker (4 samples, 0.04%) + + + +runtime.gcWriteBarrierBX (1 samples, 0.01%) + + + +runtime.(*itabTableType).find (3 samples, 0.03%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +runtime.(*sysMemStat).add (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.futex (2 samples, 0.02%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +reflect.(*rtype).nameOff (2 samples, 0.02%) + + + +runtime.(*mcentral).cacheSpan (2 samples, 0.02%) + + + +runtime.mapaccess1_faststr (7 samples, 0.07%) + + + +runtime.pcvalue (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec.func1 (3 samples, 0.03%) + + + +runtime.mallocgc (41 samples, 0.41%) + + + +reflect.flag.mustBeExported (3 samples, 0.03%) + + + +reflect.directlyAssignable (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (4 samples, 0.04%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 + + +fmt.(*fmt).init (1 samples, 0.01%) + + + +runtime.(*stkframe).getStackMap (7 samples, 0.07%) + + + +runtime.memmove (6 samples, 0.06%) + + + +runtime.(*gcWork).put (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).allocate (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.getBlob (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.notesleep (1 samples, 0.01%) + + + +runtime.(*gcControllerState).findRunnableGCWorker.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.scanManifest (8 samples, 0.08%) + + + +sync.(*Pool).pin (4 samples, 0.04%) + + + +encoding/json.stateBeginString (2 samples, 0.02%) + + + +sort.symMerge (4 samples, 0.04%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetLicenses (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.ScanImage (3 samples, 0.03%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +reflect.Value.SetMapIndex (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +regexp.(*Regexp).MatchString (66 samples, 0.66%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +reflect.(*rtype).nameOff (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (450 samples, 4.51%) +encod.. + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs.func1 (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint64).Load (1 samples, 0.01%) + + + +runtime.unlockWithRank (1 samples, 0.01%) + + + +strconv.FormatInt (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia (2 samples, 0.02%) + + + +runtime.(*sysMemStat).add (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (3 samples, 0.03%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +runtime.(*gcControllerState).findRunnableGCWorker (6 samples, 0.06%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +syscall.Syscall (3 samples, 0.03%) + + + +runtime.systemstack (2 samples, 0.02%) + + + +sort.StringSlice.Swap (4 samples, 0.04%) + + + +runtime.resetspinning (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch + + +runtime.makeslice (2 samples, 0.02%) + + + +runtime.unlockWithRank (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +sort.Search (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 (3 samples, 0.03%) + + + +runtime.(*gcBits).bitp (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.forEach.func1 (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.lock2 (2 samples, 0.02%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +fmt.Sprintf (146 samples, 1.46%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +sort.StringSlice.Less (6 samples, 0.06%) + + + +sync.(*Map).loadReadOnly (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanNext (2 samples, 0.02%) + + + +runtime.getitab (3 samples, 0.03%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +sort.Search (9 samples, 0.09%) + + + +github.com/opencontainers/go-digest.Algorithm.Validate (2 samples, 0.02%) + + + +reflect.unpackEface (2 samples, 0.02%) + + + +runtime.writeHeapBits.write (2 samples, 0.02%) + + + +encoding/json.checkValid (524 samples, 5.25%) +encodi.. + + +runtime.mapaccess1_faststr (13 samples, 0.13%) + + + +encoding/json.isSpace (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.ifaceeq (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.futexsleep (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.makeslice (15 samples, 0.15%) + + + +reflect.ifaceIndir (1 samples, 0.01%) + + + +runtime.putempty (1 samples, 0.01%) + + + +reflect.PointerTo (1 samples, 0.01%) + + + +runtime.releasem (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2,906 samples, 29.12%) +zotregistry.io/zot/pkg/storage/local.(*Driver).. + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +sync.(*Map).loadReadOnly (6 samples, 0.06%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.scanVulnerabilities (1 samples, 0.01%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +runtime.gcDrainN (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (2 samples, 0.02%) + + + +fmt.(*pp).printArg (8 samples, 0.08%) + + + +syscall.fcntl (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +reflect.(*rtype).String (4 samples, 0.04%) + + + +encoding/json.(*decodeState).readIndex (2 samples, 0.02%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.(*rtype).nameOff (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +syscall.ReadDirent (7 samples, 0.07%) + + + +reflect.(*rtype).Name (2 samples, 0.02%) + + + +fmt.(*pp).fmtString (5 samples, 0.05%) + + + +encoding/json.(*decodeState).value (877 samples, 8.79%) +encoding/jso.. + + +encoding/json.stateBeginValue (3 samples, 0.03%) + + + +regexp.lazyFlag.match (4 samples, 0.04%) + + + +reflect.Value.assignTo (1 samples, 0.01%) + + + +runtime.slicebytetostring (23 samples, 0.23%) + + + +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +os.direntNamlen (1 samples, 0.01%) + + + +runtime.writeHeapBits.write (1 samples, 0.01%) + + + +sort.symMerge (5 samples, 0.05%) + + + +reflect.Value.IsValid (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).spill (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.(*gcBits).bitp (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (6 samples, 0.06%) + + + +aeshashbody (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (13 samples, 0.13%) + + + +runtime.add (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (2 samples, 0.02%) + + + +os.readInt (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner.Scanner.ScanArtifact (2 samples, 0.02%) + + + +regexp.(*Regexp).doExecute (629 samples, 6.30%) +regexp.(.. + + +runtime.(*mspan).initHeapBits (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*mspan).objIndex (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (9 samples, 0.09%) + + + +runtime.pcdatavalue (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 + + +runtime.(*mcentral).grow (3 samples, 0.03%) + + + +syscall.SetNonblock (2 samples, 0.02%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanNext (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +syscall.fcntl (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (3 samples, 0.03%) + + + +runtime.readUintptr (4 samples, 0.04%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 (3 samples, 0.03%) + + + +runtime.(*mcache).refill (3 samples, 0.03%) + + + +sync.(*Pool).Get (1 samples, 0.01%) + + + +reflect.New (6 samples, 0.06%) + + + +runtime.unlock2 (2 samples, 0.02%) + + + +time.leadingInt[...] (6 samples, 0.06%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +cmpbody (2 samples, 0.02%) + + + +syscall.RawSyscall6 (4 samples, 0.04%) + + + +encoding/json.stateBeginString (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +sort.symMerge (24 samples, 0.24%) + + + +encoding/json.(*decodeState).readIndex (1 samples, 0.01%) + + + +syscall.Write (1 samples, 0.01%) + + + +syscall.RawSyscall6 (1 samples, 0.01%) + + + +reflect.Value.CanAddr (1 samples, 0.01%) + + + +runtime.newobject (3 samples, 0.03%) + + + +runtime.mallocgc (17 samples, 0.17%) + + + +encoding/json.(*decodeState).object (254 samples, 2.55%) +en.. + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.growslice (1 samples, 0.01%) + + + +encoding/json.indirect (20 samples, 0.20%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.gentraceback (20 samples, 0.20%) + + + +runtime.growWork_faststr (9 samples, 0.09%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.scan (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.getOCIImage (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (3 samples, 0.03%) + + + +runtime.nilinterhash (6 samples, 0.06%) + + + +sync.runtime_procPin (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +runtime.deferprocStack (2 samples, 0.02%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +encoding/json.(*decodeState).value (1,292 samples, 12.95%) +encoding/json.(*dec.. + + +runtime.(*moduledata).textAddr (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (2 samples, 0.02%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).Update (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (2 samples, 0.02%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +os.openFileNolog (7 samples, 0.07%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 + + +os.Open (8 samples, 0.08%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).Cursor (4 samples, 0.04%) + + + +runtime.step (1 samples, 0.01%) + + + +os.newFile (4 samples, 0.04%) + + + +syscall.Stat (60 samples, 0.60%) + + + +github.com/opencontainers/go-digest.NewDigestFromEncoded (3 samples, 0.03%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (2 samples, 0.02%) + + + +runtime.markBits.setMarked (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +runtime.(*lfstack).push (1 samples, 0.01%) + + + +runtime.roundupsize (3 samples, 0.03%) + + + +runtime/internal/syscall.EpollCtl (1 samples, 0.01%) + + + +internal/poll.(*FD).destroy (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.gcWriteBarrierDX (1 samples, 0.01%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +github.com/gorilla/mux.(*Router).ServeHTTP (3 samples, 0.03%) + + + +reflect.Value.Kind (8 samples, 0.08%) + + + +runtime.arenaIdx.l2 (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.makemap (2 samples, 0.02%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (1 samples, 0.01%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +fmt.(*pp).free (1 samples, 0.01%) + + + +runtime.removefinalizer (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (2 samples, 0.02%) + + + +runtime/internal/syscall.Syscall6 (4 samples, 0.04%) + + + +runtime.mallocgc (41 samples, 0.41%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.Scan (2 samples, 0.02%) + + + +encoding/json.indirect (5 samples, 0.05%) + + + +runtime.profilealloc (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage.func1 (7 samples, 0.07%) + + + +runtime.(*gcControllerState).memoryLimitHeapGoal (2 samples, 0.02%) + + + +runtime.reentersyscall (22 samples, 0.22%) + + + +sync.(*Pool).Get (2 samples, 0.02%) + + + +encoding/json.stateInString (222 samples, 2.22%) +e.. + + +syscall.RawSyscall6 (4 samples, 0.04%) + + + +runtime.writeHeapBits.write (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +sort.swapRange (6 samples, 0.06%) + + + +runtime.(*gcWork).empty (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Cursor).search (1 samples, 0.01%) + + + +os.basename (43 samples, 0.43%) + + + +os.basename (1 samples, 0.01%) + + + +runtime.(*gcControllerState).memoryLimitHeapGoal (1 samples, 0.01%) + + + +fmt.(*fmt).fmtS (5 samples, 0.05%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (357 samples, 3.58%) +enc.. + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (666 samples, 6.67%) +zotregist.. + + +runtime.gcStart (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/fanal/applier.(*applier).ApplyLayers (1 samples, 0.01%) + + + +runtime.newobject (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (846 samples, 8.48%) +encoding/jso.. + + +runtime.unlock2 (1 samples, 0.01%) + + + +fmt.newPrinter (6 samples, 0.06%) + + + +os.Open (2 samples, 0.02%) + + + +reflect.(*rtype).NumMethod (4 samples, 0.04%) + + + +os.OpenFile (9 samples, 0.09%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec.func1 (3 samples, 0.03%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.newobject (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).dedupeBlobs (2 samples, 0.02%) + + + +runtime.funcInfo.entry (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +reflect.typesMustMatch (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (4 samples, 0.04%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Algorithm.String (4 samples, 0.04%) + + + +runtime.greyobject (2 samples, 0.02%) + + + +reflect.(*rtype).Name (12 samples, 0.12%) + + + +runtime.(*mcentral).cacheSpan (3 samples, 0.03%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +reflect.Copy (9 samples, 0.09%) + + + +runtime.mapassign_faststr (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (282 samples, 2.83%) +en.. + + +bytes.Compare (5 samples, 0.05%) + + + +runtime.(*activeSweep).end (3 samples, 0.03%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +os.ignoringEINTR (525 samples, 5.26%) +os.ign.. + + +sort.symMerge (8 samples, 0.08%) + + + +encoding/json.unquoteBytes (6 samples, 0.06%) + + + +memeqbody (2 samples, 0.02%) + + + +runtime.(*gcBitsArena).tryAlloc (1 samples, 0.01%) + + + +crypto/tls.(*Conn).readRecordOrCCS (1 samples, 0.01%) + + + +runtime.getempty (193 samples, 1.93%) +r.. + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +os.(*File).Close (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Tx).CreateBucketIfNotExists (1 samples, 0.01%) + + + +runtime.duffzero (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateImageSummaryVulnerabilities (1 samples, 0.01%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +reflect.Value.Interface (4 samples, 0.04%) + + + +runtime.lock2 (4 samples, 0.04%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.archiveStandaloneScanner (1 samples, 0.01%) + + + +fmt.(*pp).doPrintf (87 samples, 0.87%) + + + +sort.symMerge (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +sort.Stable (18 samples, 0.18%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 (3 samples, 0.03%) + + + +reflect.(*rtype).nameOff (1 samples, 0.01%) + + + +runtime.newobject (46 samples, 0.46%) + + + +reflect.(*rtype).String (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.wbBufFlush (2 samples, 0.02%) + + + +runtime.(*mspan).divideByElemSize (1 samples, 0.01%) + + + +runtime.profilealloc (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (7 samples, 0.07%) + + + +net/http.initALPNRequest.ServeHTTP (3 samples, 0.03%) + + + +sort.rotate (10 samples, 0.10%) + + + +runtime.(*mcentral).grow (2 samples, 0.02%) + + + +runtime.(*mspan).objIndex (1 samples, 0.01%) + + + +net/http.(*http2serverConn).runHandler (4,932 samples, 49.42%) +net/http.(*http2serverConn).runHandler + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.lock (1 samples, 0.01%) + + + +reflect.Value.Set (1 samples, 0.01%) + + + +encoding/json.stateEndValue (3 samples, 0.03%) + + + +reflect.resolveTypeOff (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).ScanImage (3 samples, 0.03%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +syscall.Syscall (7 samples, 0.07%) + + + +runtime.releasem (1 samples, 0.01%) + + + +reflect.unsafe_NewArray (17 samples, 0.17%) + + + +runtime.(*mspan).divideByElemSize (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +internal/poll.(*FD).Read (1 samples, 0.01%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanWhile (6 samples, 0.06%) + + + +runtime.funcInfo.entry (1 samples, 0.01%) + + + +indexbytebody (3 samples, 0.03%) + + + +syscall.Syscall6 (460 samples, 4.61%) +sysca.. + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +os.readInt (3 samples, 0.03%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.memmove (2 samples, 0.02%) + + + +runtime.(*mcache).nextFree (2 samples, 0.02%) + + + +crypto/tls.(*Conn).Read (1 samples, 0.01%) + + + +runtime.systemstack (6 samples, 0.06%) + + + +encoding/json.(*decodeState).literalStore (1 samples, 0.01%) + + + +syscall.Syscall6 (4 samples, 0.04%) + + + +os.(*fileStat).IsDir (1 samples, 0.01%) + + + +runtime.convTslice (4 samples, 0.04%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch.func2 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.PaginatedRepoMeta2RepoSummaries (1 samples, 0.01%) + + + +reflect.Value.Addr (1 samples, 0.01%) + + + +runtime.(*gcBits).bitp (1 samples, 0.01%) + + + +reflect.Value.Type (4 samples, 0.04%) + + + +fmt.(*buffer).writeString (3 samples, 0.03%) + + + +github.com/opencontainers/go-digest.Algorithm.Validate (645 samples, 6.46%) +github.c.. + + +runtime.newstack (6 samples, 0.06%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +reflect.Value.Kind (2 samples, 0.02%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +syscall.ReadDirent (10 samples, 0.10%) + + + +runtime.(*gcControllerState).memoryLimitHeapGoal (1 samples, 0.01%) + + + +runtime.futex (4 samples, 0.04%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (2 samples, 0.02%) + + + +runtime.lockRankMayQueueFinalizer (2 samples, 0.02%) + + + +runtime.findRunnable (4 samples, 0.04%) + + + +runtime/internal/atomic.(*Uint32).Add (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*elemRef).isLeaf (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +runtime.memclrHasPointers (1 samples, 0.01%) + + + +reflect.(*rtype).Key (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +sort.Stable (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.exitsyscallfast (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.putempty (83 samples, 0.83%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +runtime.stealWork (72 samples, 0.72%) + + + +reflect.unpackEface (1 samples, 0.01%) + + + +runtime.(*gcControllerState).trigger (1 samples, 0.01%) + + + +strconv.formatBits (6 samples, 0.06%) + + + +path.Join (408 samples, 4.09%) +path.. + + +runtime.mallocgc (3 samples, 0.03%) + + + +os.basename (1 samples, 0.01%) + + + +internal/poll.(*pollDesc).init (1 samples, 0.01%) + + + +runtime.arenaIdx.l1 (1 samples, 0.01%) + + + +reflect.(*rtype).PkgPath (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (12 samples, 0.12%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage (49 samples, 0.49%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.growslice (2 samples, 0.02%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +github.com/gorilla/mux.(*routeRegexp).Match (1 samples, 0.01%) + + + +runtime.getempty (2 samples, 0.02%) + + + +encoding/json.checkValid (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +time.isDigit[...] (1 samples, 0.01%) + + + +crypto.Hash.Available (4 samples, 0.04%) + + + +github.com/gorilla/mux.(*Router).Match (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.releasem (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.Descriptor2ImageSummary (1 samples, 0.01%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +sync.(*Pool).Put (1 samples, 0.01%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +time.(*Time).UnmarshalJSON (72 samples, 0.72%) + + + +reflect.makemap (3 samples, 0.03%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.gcWriteBarrierCX (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (4 samples, 0.04%) + + + +reflect.name.name (6 samples, 0.06%) + + + +runtime.(*mcentral).cacheSpan (2 samples, 0.02%) + + + +runtime.(*gcBits).bitp (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (33 samples, 0.33%) + + + +sync.indexLocal (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (2 samples, 0.02%) + + + +go.etcd.io/bbolt.unsafeSlice (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateRepoSummaryVulnerabilities (2 samples, 0.02%) + + + +runtime.makeBucketArray (3 samples, 0.03%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +time.FixedZone (1 samples, 0.01%) + + + +runtime.(*sweepLocker).tryAcquire (1 samples, 0.01%) + + + +github.com/gorilla/mux.(*Router).Match (1 samples, 0.01%) + + + +runtime.heapBitsForAddr (17 samples, 0.17%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +reflect.name.data (4 samples, 0.04%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +io.ReadAtLeast (1 samples, 0.01%) + + + +reflect.unpackEface (1 samples, 0.01%) + + + +syscall.ByteSliceFromString (2 samples, 0.02%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec.func1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec... + + +sort.StringSlice.Swap (2 samples, 0.02%) + + + +time.atoi[...] (7 samples, 0.07%) + + + +runtime.resolveTypeOff (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +runtime.publicationBarrier (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +reflect.flag.mustBeAssignable (1 samples, 0.01%) + + + +runtime.memmove (6 samples, 0.06%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.getAllHistory (78 samples, 0.78%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +time.parseRFC3339[...] (70 samples, 0.70%) + + + +runtime.(*mheap).alloc.func1 (3 samples, 0.03%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/storage/local.(*Driver)... + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 (3 samples, 0.03%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage.func1 (7 samples, 0.07%) + + + +reflect.(*rtype).ptrTo (3 samples, 0.03%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +runtime.newMarkBits (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/common.RankRepoName (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +reflect.(*rtype).Name (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (3 samples, 0.03%) + + + +net/http.HandlerFunc.ServeHTTP (4,931 samples, 49.41%) +net/http.HandlerFunc.ServeHTTP + + +runtime.cmpstring (1 samples, 0.01%) + + + +runtime.newobject (8 samples, 0.08%) + + + +syscall.Syscall (3 samples, 0.03%) + + + +runtime.systemstack (3 samples, 0.03%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.exitsyscall (1 samples, 0.01%) + + + +regexp.(*Regexp).FindAllString (1 samples, 0.01%) + + + +reflect.(*rtype).Elem (1 samples, 0.01%) + + + +runtime.procyield (3 samples, 0.03%) + + + +runtime.(*pageAlloc).allocRange (2 samples, 0.02%) + + + +path.lastSlash (85 samples, 0.85%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +os.(*File).readdir (30 samples, 0.30%) + + + +runtime.fastexprand (1 samples, 0.01%) + + + +runtime.mapiternext (4 samples, 0.04%) + + + +cmpbody (14 samples, 0.14%) + + + +runtime.scanblock (7 samples, 0.07%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.growslice (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (114 samples, 1.14%) + + + +runtime.gcWriteBarrierR8 (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (3 samples, 0.03%) + + + +runtime.reentersyscall (1 samples, 0.01%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +syscall.read (3 samples, 0.03%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23.1 (1 samples, 0.01%) + + + +runtime.divRoundUp (7 samples, 0.07%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (2 samples, 0.02%) + + + +runtime.gcWriteBarrierR8 (1 samples, 0.01%) + + + +reflect.Value.IsValid (2 samples, 0.02%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +regexp.(*Regexp).doExecute (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*mspan).markBitsForIndex (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotations (15 samples, 0.15%) + + + +sync.(*Map).loadReadOnly (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +reflect.ifaceIndir (1 samples, 0.01%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.mallocgc (22 samples, 0.22%) + + + +fmt.(*fmt).padString (4 samples, 0.04%) + + + +runtime.gcResetMarkState (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 (3 samples, 0.03%) + + + +runtime/internal/atomic.(*Uint8).Store (1 samples, 0.01%) + + + +runtime.heapBitsSetType (11 samples, 0.11%) + + + +internal/poll.(*FD).Close (3 samples, 0.03%) + + + +runtime.divRoundUp (3 samples, 0.03%) + + + +runtime.arenaIndex (6 samples, 0.06%) + + + +runtime.(*mcentral).cacheSpan (4 samples, 0.04%) + + + +sort.swapRange (1 samples, 0.01%) + + + +reflect.directlyAssignable (1 samples, 0.01%) + + + +runtime.makeBucketArray (6 samples, 0.06%) + + + +internal/testlog.Stat (2 samples, 0.02%) + + + +runtime.(*hmap).growing (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +reflect.unsafe_New (12 samples, 0.12%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23.1 (3 samples, 0.03%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*sweepLocked).sweep (1 samples, 0.01%) + + + +reflect.(*rtype).NumMethod (1 samples, 0.01%) + + + +reflect.makeString (1 samples, 0.01%) + + + +runtime.(*mspan).initHeapBits (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.newobject (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Tx).allocate (1 samples, 0.01%) + + + +runtime.(*gcBitsArena).tryAlloc (8 samples, 0.08%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +os.fillFileStatFromSys (2 samples, 0.02%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +reflect.(*rtype).String (8 samples, 0.08%) + + + +internal/poll.(*FD).Init (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*elemRef).isLeaf (2 samples, 0.02%) + + + +runtime.gopreempt_m (6 samples, 0.06%) + + + +reflect.(*rtype).exportedMethods (2 samples, 0.02%) + + + +reflect.(*rtype).exportedMethods (1 samples, 0.01%) + + + +sort.insertionSort (51 samples, 0.51%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +reflect.add (1 samples, 0.01%) + + + +encoding/json.indirect (35 samples, 0.35%) + + + +aeshashbody (2 samples, 0.02%) + + + +memeqbody (3 samples, 0.03%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (4 samples, 0.04%) + + + +strings.Split (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (2 samples, 0.02%) + + + +encoding/json.(*decodeState).object (42 samples, 0.42%) + + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (2 samples, 0.02%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.arenaIdx.l1 (2 samples, 0.02%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (3 samples, 0.03%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +runtime.pageIndexOf (27 samples, 0.27%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.(*pallocData).findScavengeCandidate (1 samples, 0.01%) + + + +runtime.getMCache (2 samples, 0.02%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +io.ReadFull (1 samples, 0.01%) + + + +runtime.traceback1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +syscall.openat (4 samples, 0.04%) + + + +runtime.(*mheap).alloc (2 samples, 0.02%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +reflect.Value.assignTo (1 samples, 0.01%) + + + +reflect.Value.CanAddr (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.runSafePointFn (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*page).branchPageElements (1 samples, 0.01%) + + + +regexp.newLazyFlag (38 samples, 0.38%) + + + +os.readInt (1 samples, 0.01%) + + + +sort.StringSlice.Less (2 samples, 0.02%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.duffzero (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +reflect.ValueOf (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +reflect.Value.IsNil (1 samples, 0.01%) + + + +runtime.findObject (231 samples, 2.31%) +r.. + + +go.etcd.io/bbolt.(*DB).View (2,225 samples, 22.29%) +go.etcd.io/bbolt.(*DB).View + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +reflect.name.name (1 samples, 0.01%) + + + +syscall.openat (3 samples, 0.03%) + + + +reflect.(*rtype).ptrTo (3 samples, 0.03%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.typedslicecopy (3 samples, 0.03%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +os.direntReclen (5 samples, 0.05%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (2 samples, 0.02%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +fmt.(*pp).printValue (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).seek (52 samples, 0.52%) + + + +sync.(*Pool).Get (1 samples, 0.01%) + + + +runtime.mapassign_faststr (4 samples, 0.04%) + + + +internal/reflectlite.TypeOf (2 samples, 0.02%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).next (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.bgsweep (106 samples, 1.06%) + + + +runtime.makeslice (4 samples, 0.04%) + + + +time.daysSinceEpoch (4 samples, 0.04%) + + + +encoding/json.(*decodeState).init (2 samples, 0.02%) + + + +reflect.name.readVarint (1 samples, 0.01%) + + + +regexp.newOnePassMachine (8 samples, 0.08%) + + + +runtime.(*mcache).nextFree (3 samples, 0.03%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.scanblock (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (2 samples, 0.02%) + + + +reflect.name.readVarint (3 samples, 0.03%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.getempty (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +runtime.(*mcentral).grow (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.Scan (5 samples, 0.05%) + + + +time.unixTime (2 samples, 0.02%) + + + +encoding/json.(*decodeState).object (246 samples, 2.46%) +en.. + + +runtime.(*gcControllerState).heapGoalInternal (1 samples, 0.01%) + + + +reflect.(*rtype).NumMethod (1 samples, 0.01%) + + + +runtime.duffzero (5 samples, 0.05%) + + + +encoding/json.(*decodeState).scanWhile (9 samples, 0.09%) + + + +runtime.newobject (3 samples, 0.03%) + + + +path.(*lazybuf).append (185 samples, 1.85%) +p.. + + +runtime.gcMarkTermination (5 samples, 0.05%) + + + +internal/reflectlite.(*rtype).Comparable (2 samples, 0.02%) + + + +runtime.evacuate_faststr (1 samples, 0.01%) + + + +syscall.Syscall (10 samples, 0.10%) + + + +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 + + +syscall.write (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (10 samples, 0.10%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.(*mspan).nextFreeIndex (1 samples, 0.01%) + + + +runtime.(*lfstack).push (1 samples, 0.01%) + + + +sort.symMerge (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +sync.(*Pool).Put (6 samples, 0.06%) + + + +encoding/json.stateT (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (9 samples, 0.09%) + + + +reflect.Value.Addr (7 samples, 0.07%) + + + +syscall.RawSyscall6 (422 samples, 4.23%) +sysca.. + + +runtime.funcdata (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +sync.runtime_procPin (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1 (3 samples, 0.03%) + + + +os.ignoringEINTR (13 samples, 0.13%) + + + +sort.StringSlice.Less (4 samples, 0.04%) + + + +encoding/json.(*decodeState).literalStore (77 samples, 0.77%) + + + +syscall.ReadDirent (1 samples, 0.01%) + + + +reflect.(*rtype).String (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).ScanImage (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +reflect.Value.Addr (12 samples, 0.12%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +sort.symMerge (101 samples, 1.01%) + + + +github.com/rs/zerolog.(*Event).msg (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (3 samples, 0.03%) + + + +reflect.(*rtype).uncommon (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.mapassign_faststr (22 samples, 0.22%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +runtime.assertE2I2 (1 samples, 0.01%) + + + +runtime.(*stackScanState).putPtr (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.stringtoslicebyte (5 samples, 0.05%) + + + +runtime.newobject (1 samples, 0.01%) + + + +internal/poll.(*FD).incref (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.fileInfo.IsDir (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).Next (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (2 samples, 0.02%) + + + +runtime.reentersyscall (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.scan (3 samples, 0.03%) + + + +runtime.mallocgc (8 samples, 0.08%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +runtime.memequal (1 samples, 0.01%) + + + +runtime.memmove (2 samples, 0.02%) + + + +encoding/json.Unmarshal (1,824 samples, 18.28%) +encoding/json.Unmarshal + + +runtime/internal/atomic.(*Uint32).Add (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.convT64 (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +reflect.MakeMap (1 samples, 0.01%) + + + +os.(*fileStat).IsDir (1 samples, 0.01%) + + + +runtime.pageIndexOf (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/detector/ospkg.Detect (2 samples, 0.02%) + + + +runtime.newarray (1 samples, 0.01%) + + + +runtime.getitab (4 samples, 0.04%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +all (9,980 samples, 100%) + + + +reflect.flag.mustBeAssignable (1 samples, 0.01%) + + + +runtime.mallocgc (18 samples, 0.18%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +runtime.divRoundUp (3 samples, 0.03%) + + + +runtime.(*bmap).overflow (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +syscall.Close (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.NewFSCache (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func24 (3 samples, 0.03%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.NewFSCache.func1 (1 samples, 0.01%) + + + +runtime.spanSetSpinePointer.lookup (1 samples, 0.01%) + + + +reflect.(*rtype).exportedMethods (5 samples, 0.05%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +os.(*File).readdir (1 samples, 0.01%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +runtime.(*_type).typeOff (2 samples, 0.02%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +time.(*Time).UnmarshalJSON (14 samples, 0.14%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.(*sweepLocker).tryAcquire (1 samples, 0.01%) + + + +runtime.lockWithRank (2 samples, 0.02%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +memeqbody (1 samples, 0.01%) + + + +runtime.mapassign_faststr (10 samples, 0.10%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +os.(*File).Read (3 samples, 0.03%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +cmpbody (2 samples, 0.02%) + + + +runtime.read (1 samples, 0.01%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +memeqbody (1 samples, 0.01%) + + + +sort.rotate (14 samples, 0.14%) + + + +reflect.(*rtype).hasName (1 samples, 0.01%) + + + +regexp.(*inputs).clear (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 (3 samples, 0.03%) + + + +cmpbody (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +internal/reflectlite.toType (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia (3 samples, 0.03%) + + + +internal/poll.(*FD).Close (1 samples, 0.01%) + + + +io.copyBuffer (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +aeshashbody (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).get (51 samples, 0.51%) + + + +runtime.bucketMask (1 samples, 0.01%) + + + +runtime.(*gcWork).tryGetFast (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.ImageManifest2ImageSummary (2,628 samples, 26.33%) +zotregistry.io/zot/pkg/extensions/search/.. + + +github.com/google/go-containerregistry/pkg/v1/layout.(*layoutIndex).IndexManifest (1 samples, 0.01%) + + + +runtime.(*scavengerState).run (34 samples, 0.34%) + + + +github.com/aquasecurity/trivy/pkg/detector/ospkg/ubuntu.(*Scanner).Detect (2 samples, 0.02%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.(*gcWork).balance (2 samples, 0.02%) + + + +internal/poll.ignoringEINTRIO (1 samples, 0.01%) + + + +regexp.(*Regexp).MatchString (1 samples, 0.01%) + + + +runtime.(*mheap).allocMSpanLocked (2 samples, 0.02%) + + + +reflect.name.readVarint (2 samples, 0.02%) + + + +sync.(*Pool).pin (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*DB).Update (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch (3 samples, 0.03%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1 (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.. + + +runtime.systemstack (1 samples, 0.01%) + + + +sort.rotate (2 samples, 0.02%) + + + +encoding/json.indirect (20 samples, 0.20%) + + + +encoding/json.indirect (4 samples, 0.04%) + + + +internal/poll.(*fdMutex).decref (1 samples, 0.01%) + + + +strings.Index (4 samples, 0.04%) + + + +runtime.makeslice (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.ScanImage (8 samples, 0.08%) + + + +runtime.mapaccess2_faststr (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.runTrivy (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/storage/local.(*fileWriter).Close (1 samples, 0.01%) + + + +fmt.(*fmt).padString (4 samples, 0.04%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +reflect.(*rtype).Elem (2 samples, 0.02%) + + + +runtime.scanobject (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (5 samples, 0.05%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.getDataSource (1 samples, 0.01%) + + + +syscall.BytePtrFromString (8 samples, 0.08%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.SetFinalizer.func1 (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (3 samples, 0.03%) + + + +runtime.add (1 samples, 0.01%) + + + +runtime.bulkBarrierPreWrite (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +reflect.unpackEface (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +time.Date (16 samples, 0.16%) + + + +internal/poll.(*FD).decref (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*node).spill (1 samples, 0.01%) + + + +runtime.(*mspan).base (1 samples, 0.01%) + + + +runtime.(*gcWork).putFast (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 (3 samples, 0.03%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +reflect.Value.Interface (7 samples, 0.07%) + + + +runtime.gcTrigger.test (1 samples, 0.01%) + + + +reflect.(*uncommonType).exportedMethods (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 (4,931 samples, 49.41%) +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.gcBgMarkWorker.func2 (1,665 samples, 16.68%) +runtime.gcBgMarkWorker.fu.. + + +encoding/json.stateEndValue (3 samples, 0.03%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +reflect.toType (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (4 samples, 0.04%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.(*Driver).DetectVulnerabilities (1 samples, 0.01%) + + + +os.statNolog.func1 (519 samples, 5.20%) +os.sta.. + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/common.InitializeImageConfig (1,166 samples, 11.68%) +zotregistry.io/zo.. + + +runtime.newMarkBits (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.(*mspan).base (17 samples, 0.17%) + + + +indexbytebody (17 samples, 0.17%) + + + +reflect.ValueOf (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (33 samples, 0.33%) + + + +runtime.(*mcache).refill (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.PaginatedRepoMeta2RepoSummaries (3 samples, 0.03%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +reflect.Value.Set (1 samples, 0.01%) + + + +runtime.SetFinalizer (1 samples, 0.01%) + + + +sort.rotate (18 samples, 0.18%) + + + +go.etcd.io/bbolt.(*Cursor).nsearch.func2 (5 samples, 0.05%) + + + +aeshashbody (1 samples, 0.01%) + + + +reflect.add (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateRepoSummaryVulnerabilities (3 samples, 0.03%) + + + +strconv.ParseUint (10 samples, 0.10%) + + + +encoding/json.indirect (26 samples, 0.26%) + + + +os.openFileNolog (9 samples, 0.09%) + + + +reflect.Value.Convert (2 samples, 0.02%) + + + +net/http.HandlerFunc.ServeHTTP (4,930 samples, 49.40%) +net/http.HandlerFunc.ServeHTTP + + +runtime.bucketMask (1 samples, 0.01%) + + + +regexp.(*Regexp).doExecute (1 samples, 0.01%) + + + +reflect.Value.SetString (1 samples, 0.01%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (3 samples, 0.03%) + + + +time.tzsetOffset (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (1 samples, 0.01%) + + + +sync.(*entry).load (3 samples, 0.03%) + + + +reflect.Value.assignTo (2 samples, 0.02%) + + + +reflect.(*rtype).nameOff (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +syscall.Syscall (2 samples, 0.02%) + + + +encoding/json.unquoteBytes (32 samples, 0.32%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanWhile (11 samples, 0.11%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*BaseService).SyncRepo.func2 (119 samples, 1.19%) + + + +reflect.Value.Field (3 samples, 0.03%) + + + +runtime.bool2int (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Bool).Load (3 samples, 0.03%) + + + +regexp.(*Regexp).backtrack (1 samples, 0.01%) + + + +syscall.Syscall (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.(*mspan).markBitsForIndex (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetDocumentation (2 samples, 0.02%) + + + +fmt.Sprintf (15 samples, 0.15%) + + + +os.direntIno (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (177 samples, 1.77%) + + + +runtime.findObject (3 samples, 0.03%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.(*gcControllerState).trigger (1 samples, 0.01%) + + + +runtime.newobject (2 samples, 0.02%) + + + +runtime.evacuate_faststr (13 samples, 0.13%) + + + +path.(*lazybuf).append (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).scanArtifact (2 samples, 0.02%) + + + +github.com/gorilla/mux.(*Route).Match (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).pageNode (3 samples, 0.03%) + + + +encoding/json.(*decodeState).literalStore (17 samples, 0.17%) + + + +encoding/json.(*scanner).pushParseState (1 samples, 0.01%) + + + +time.parseRFC3339[...].func1 (4 samples, 0.04%) + + + +sort.Search (8 samples, 0.08%) + + + +reflect.(*rtype).typeOff (4 samples, 0.04%) + + + +runtime.(*gcWork).balance (296 samples, 2.97%) +ru.. + + +reflect.resolveNameOff (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).GetNextDigestWithBlobPaths.func1 (980 samples, 9.82%) +zotregistry.io.. + + +runtime.mapassign_faststr (20 samples, 0.20%) + + + +runtime.convTstring (43 samples, 0.43%) + + + +runtime.getMCache (3 samples, 0.03%) + + + +sync/atomic.(*Value).Load (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.scanManifest (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.scan (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).initCache (1 samples, 0.01%) + + + +runtime.(*mheap).freeSpan (27 samples, 0.27%) + + + +runtime.(*gcControllerState).trigger (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.makeSpanClass (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +os.statNolog (13 samples, 0.13%) + + + +reflect.name.isExported (2 samples, 0.02%) + + + +runtime.(*mheap).freeSpan.func1 (26 samples, 0.26%) + + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.lock (2 samples, 0.02%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +reflect.(*rtype).Name (12 samples, 0.12%) + + + +sync.(*Pool).pin (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/storage/cache.(*BoltDBDriver).PutBlob (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.memmove (31 samples, 0.31%) + + + +runtime.mallocgc (41 samples, 0.41%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.(*mcache).nextFree (2 samples, 0.02%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +reflect.(*rtype).uncommon (2 samples, 0.02%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +memeqbody (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).scanArtifact (2 samples, 0.02%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +encoding/json.stateBeginString (2 samples, 0.02%) + + + +runtime.memmove (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).Add (2 samples, 0.02%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.SetFinalizer (1 samples, 0.01%) + + + +runtime.(*activeSweep).markDrained (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +internal/poll.(*FD).ReadDirent (11 samples, 0.11%) + + + +encoding/json.stateInString (100 samples, 1.00%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs (1 samples, 0.01%) + + + +runtime.markBits.isMarked (7 samples, 0.07%) + + + +runtime.arenaIndex (3 samples, 0.03%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.(*mspan).initHeapBits (2 samples, 0.02%) + + + +regexp.newLazyFlag (1 samples, 0.01%) + + + +runtime.mallocgc (9 samples, 0.09%) + + + +sort.swapRange (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.futexsleep (4 samples, 0.04%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +fmt.(*pp).doPrintf (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/common.(*DedupeTaskGenerator).Next (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/storage/common.(*DedupeT.. + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*sweepLocked).sweep (68 samples, 0.68%) + + + +sync.(*entry).load (1 samples, 0.01%) + + + +runtime.slicebytetostring (22 samples, 0.22%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetVulnerability (2 samples, 0.02%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 (3 samples, 0.03%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +reflect.(*rtype).uncommon (2 samples, 0.02%) + + + +fmt.(*fmt).fmtS (7 samples, 0.07%) + + + +fmt.(*pp).doPrintf (10 samples, 0.10%) + + + +runtime.gcWriteBarrierBX (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*page).fastCheck (2 samples, 0.02%) + + + +reflect.(*rtype).Elem (5 samples, 0.05%) + + + +sort.symMerge (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query (3 samples, 0.03%) + + + +runtime.pollWork (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (40 samples, 0.40%) + + + +reflect.New (3 samples, 0.03%) + + + +runtime.mapaccess2_faststr (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*node).spill (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +cmpbody (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +reflect.mapassign_faststr (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*syncRepoTask).DoWork (119 samples, 1.19%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.convT (19 samples, 0.19%) + + + +encoding/json.indirect (12 samples, 0.12%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (34 samples, 0.34%) + + + +runtime.(*mheap).allocNeedsZero (1 samples, 0.01%) + + + +runtime.netpoll (2 samples, 0.02%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +os.newFile (5 samples, 0.05%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +syscall.Getdents (7 samples, 0.07%) + + + +runtime.(*hmap).noldbuckets (2 samples, 0.02%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +internal/poll.(*FD).ReadDirent (99 samples, 0.99%) + + + +os.Stat (8 samples, 0.08%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func22 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +github.com/aquasecurity/trivy/pkg/fanal/image.NewArchiveImage (1 samples, 0.01%) + + + +time.parseRFC3339[...].func1 (15 samples, 0.15%) + + + +reflect.name.name (1 samples, 0.01%) + + + +runtime.lock (4 samples, 0.04%) + + + +reflect.Value.Addr (1 samples, 0.01%) + + + +syscall.Syscall (1 samples, 0.01%) + + + +memeqbody (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Digest.Validate (665 samples, 6.66%) +github.co.. + + +reflect.name.data (2 samples, 0.02%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +strconv.ParseUint (2 samples, 0.02%) + + + +net/http.ioFile.Read (1 samples, 0.01%) + + + +runtime.systemstack (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.(*rtype).String (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (5 samples, 0.05%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.hashGrow (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/artifact/image.Artifact.Inspect (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +github.com/gorilla/mux.(*Route).Match (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +internal/poll.(*pollDesc).prepare (1 samples, 0.01%) + + + +aeshashbody (1 samples, 0.01%) + + + +encoding/json.stateEndValue (4 samples, 0.04%) + + + +encoding/base64.(*Encoding).decodeQuantum (2 samples, 0.02%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.trygetfull (137 samples, 1.37%) + + + +runtime.memclrNoHeapPointers (4 samples, 0.04%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +reflect.(*rtype).Elem (3 samples, 0.03%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +time.(*Location).lookup (2 samples, 0.02%) + + + +reflect.resolveNameOff (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.Value.Kind (5 samples, 0.05%) + + + +runtime.memmove (3 samples, 0.03%) + + + +reflect.Value.Convert (27 samples, 0.27%) + + + +sort.symMerge (131 samples, 1.31%) + + + +runtime.memclrNoHeapPointers (5 samples, 0.05%) + + + +encoding/json.stateBeginValueOrEmpty (2 samples, 0.02%) + + + +runtime.makemap (5 samples, 0.05%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 (3 samples, 0.03%) + + + +runtime.slicebytetostring (3 samples, 0.03%) + + + +runtime.(*_type).typeOff (2 samples, 0.02%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).get (5 samples, 0.05%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.(*consistentHeapStats).acquire (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.resolveTypeOff (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +reflect.Value.Interface (9 samples, 0.09%) + + + +runtime.gcAssistAlloc.func1 (1 samples, 0.01%) + + + +syscall.SetNonblock (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1 (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (9 samples, 0.09%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +syscall.fstatat (13 samples, 0.13%) + + + +syscall.fcntl (3 samples, 0.03%) + + + +runtime.(*mheap).alloc.func1 (2 samples, 0.02%) + + + +syscall.Getdents (10 samples, 0.10%) + + + +encoding/json.(*decodeState).rescanLiteral (13 samples, 0.13%) + + + +os.(*File).Readdirnames (13 samples, 0.13%) + + + +encoding/json.stateBeginValue (4 samples, 0.04%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +os.ignoringEINTR (10 samples, 0.10%) + + + +runtime/internal/atomic.(*Uint8).Load (1 samples, 0.01%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +runtime.casgstatus (9 samples, 0.09%) + + + +runtime.(*mspan).nextFreeIndex (1 samples, 0.01%) + + + +reflect.name.name (2 samples, 0.02%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (6 samples, 0.06%) + + + +github.com/gorilla/mux.(*Router).Match (1 samples, 0.01%) + + + +strconv.ParseInt (10 samples, 0.10%) + + + +strconv.FormatInt (6 samples, 0.06%) + + + +github.com/gorilla/handlers.recoveryHandler.ServeHTTP (3 samples, 0.03%) + + + +sort.stable (18 samples, 0.18%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +runtime.lock (1 samples, 0.01%) + + + +runtime.(*lfstack).push (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).ScanImage (2 samples, 0.02%) + + + +github.com/knqyf263/go-deb-version.(*Version).Compare (2 samples, 0.02%) + + + +runtime.growWork_faststr (1 samples, 0.01%) + + + +runtime.makeslice (1 samples, 0.01%) + + + +encoding/json.isSpace (2 samples, 0.02%) + + + +fmt.Sprintf (1 samples, 0.01%) + + + +runtime.markroot.func1 (27 samples, 0.27%) + + + +reflect.Value.Set (2 samples, 0.02%) + + + +encoding/json.indirect (7 samples, 0.07%) + + + +runtime.makemap_small (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23.1 (3 samples, 0.03%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +github.com/gorilla/mux.(*Route).Match (1 samples, 0.01%) + + + +runtime.gcDrain (1,665 samples, 16.68%) +runtime.gcDrain + + +fmt.(*pp).printArg (1 samples, 0.01%) + + + +runtime.lock2 (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +reflect.Value.Cap (1 samples, 0.01%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +runtime.add (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (4 samples, 0.04%) + + + +encoding/json.unquoteBytes (12 samples, 0.12%) + + + +reflect.Value.CanAddr (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.NewArchiveImage (1 samples, 0.01%) + + + +runtime.getempty (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +os.ignoringEINTR (60 samples, 0.60%) + + + +runtime.puintptr.ptr (1 samples, 0.01%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +runtime.heapBitsForAddr (9 samples, 0.09%) + + + +encoding/json.unquoteBytes (174 samples, 1.74%) + + + +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +errors.Is (1 samples, 0.01%) + + + +os.fillFileStatFromSys (9 samples, 0.09%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.(*mcache).refill (4 samples, 0.04%) + + + +runtime.memmove (1 samples, 0.01%) + + + +syscall.fstatat (515 samples, 5.16%) +syscal.. + + +encoding/json.Unmarshal (1,158 samples, 11.60%) +encoding/json.Unm.. + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.lock (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.goschedIfBusy (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.gcDrainN (3 samples, 0.03%) + + + +net/http.initALPNRequest.ServeHTTP (4,932 samples, 49.42%) +net/http.initALPNRequest.ServeHTTP + + +sort.StringSlice.Less (2 samples, 0.02%) + + + +github.com/rs/zerolog.(*Event).Msg (1 samples, 0.01%) + + + +sort.StringSlice.Less (3 samples, 0.03%) + + + +runtime.divRoundUp (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +runtime.(*limiterEvent).stop (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.Detect (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +encoding/json.(*scanner).pushParseState (1 samples, 0.01%) + + + +time.parseStrictRFC3339 (71 samples, 0.71%) + + + +runtime.mapassign_faststr (18 samples, 0.18%) + + + +encoding/json.stateBeginStringOrEmpty (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (536 samples, 5.37%) +encodi.. + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.memmove (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.archiveStandaloneScanner (1 samples, 0.01%) + + + +runtime.newarray (9 samples, 0.09%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.runTrivy (2 samples, 0.02%) + + + +runtime.findObject (1 samples, 0.01%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +reflect.makemap (5 samples, 0.05%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (17 samples, 0.17%) + + + +encoding/json.(*decodeState).rescanLiteral (9 samples, 0.09%) + + + +runtime.(*mcentral).grow (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/scheduler.(*Scheduler).RunScheduler.func1 (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/scheduler.(*Scheduler).R.. + + +runtime.(*mspan).markBitsForIndex (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (4 samples, 0.04%) + + + +go.etcd.io/bbolt.(*branchPageElement).key (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func22 (3 samples, 0.03%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +sort.symMerge (1 samples, 0.01%) + + + +runtime.(*randomEnum).next (23 samples, 0.23%) + + + +encoding/json.indirect (1 samples, 0.01%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +runtime.(*mcache).nextFree (2 samples, 0.02%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.Value.SetMapIndex (10 samples, 0.10%) + + + +runtime/internal/syscall.Syscall6 (10 samples, 0.10%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +os.Stat (12 samples, 0.12%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +syscall.fstatat (60 samples, 0.60%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.mProf_Malloc.func1 (1 samples, 0.01%) + + + +reflect.valueInterface (4 samples, 0.04%) + + + +runtime.newobject (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/scheduler.(*Scheduler).generateTasks (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/scheduler.(*Scheduler).g.. + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime/internal/syscall.EpollWait (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint8).Or (2 samples, 0.02%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (3 samples, 0.03%) + + + +runtime.procPin (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +regexp.(*Regexp).doOnePass (2 samples, 0.02%) + + + +runtime.growslice (3 samples, 0.03%) + + + +runtime.duffzero (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.futex (1 samples, 0.01%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +reflect.Value.Field (3 samples, 0.03%) + + + +encoding/json.(*decodeState).literalStore (42 samples, 0.42%) + + + +syscall.Syscall (6 samples, 0.06%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*BaseService).syncTag (119 samples, 1.19%) + + + +encoding/binary.bigEndian.PutUint64 (61 samples, 0.61%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.RepoMeta2RepoSummary (1 samples, 0.01%) + + + +fmt.(*pp).handleMethods (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch (1 samples, 0.01%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Tx).page (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +sort.rotate (1 samples, 0.01%) + + + +runtime.park_m (115 samples, 1.15%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.unlock2 (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.puintptr.ptr (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.growslice (2 samples, 0.02%) + + + +runtime.spanOfHeap (1 samples, 0.01%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.GetBlob (1 samples, 0.01%) + + + +runtime.heapBits.nextFast (12 samples, 0.12%) + + + +runtime.resolveNameOff (1 samples, 0.01%) + + + +runtime.makeSpanClass (2 samples, 0.02%) + + + +reflect.New (6 samples, 0.06%) + + + +github.com/containers/common/pkg/retry.IfNecessary (119 samples, 1.19%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.(*mcache).refill (7 samples, 0.07%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*gcControllerState).addIdleMarkWorker (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (2 samples, 0.02%) + + + +time.resetTimer (1 samples, 0.01%) + + + +crypto/tls.(*Conn).readFromUntil (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch + + +reflect.Value.Len (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.fileInfo.IsDir (1 samples, 0.01%) + + + +encoding/json.isSpace (2 samples, 0.02%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.goschedImpl (6 samples, 0.06%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.(*mheap).freeMSpanLocked (1 samples, 0.01%) + + + +reflect.packEface (2 samples, 0.02%) + + + +runtime.pallocSum.unpack (1 samples, 0.01%) + + + +reflect.name.readVarint (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (3 samples, 0.03%) + + + +reflect.convertOp (1 samples, 0.01%) + + + +crypto/tls.(*Conn).readRecord (1 samples, 0.01%) + + + +reflect.makeString (7 samples, 0.07%) + + + +runtime/internal/syscall.Syscall6 (10 samples, 0.10%) + + + +time.Unix (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (120 samples, 1.20%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.scanblock (8 samples, 0.08%) + + + +syscall.RawSyscall6 (10 samples, 0.10%) + + + +regexp.(*Regexp).doExecute (2 samples, 0.02%) + + + +runtime.writeHeapBits.flush (6 samples, 0.06%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.initializeArchiveScanner (1 samples, 0.01%) + + + +runtime.nanotime (1 samples, 0.01%) + + + +runtime.(*gcControllerState).memoryLimitHeapGoal (1 samples, 0.01%) + + + +regexp.(*Regexp).doMatch (66 samples, 0.66%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func24 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +reflect.MakeSlice (4 samples, 0.04%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.divRoundUp (3 samples, 0.03%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +strings.IndexByte (4 samples, 0.04%) + + + +time.parseNanoseconds[...] (15 samples, 0.15%) + + + +sync.(*Pool).pin (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 (3 samples, 0.03%) + + + +encoding/json.cachedTypeFields (13 samples, 0.13%) + + + +syscall.Syscall6 (4 samples, 0.04%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).search (30 samples, 0.30%) + + + +syscall.Syscall (3 samples, 0.03%) + + + +os.statNolog (628 samples, 6.29%) +os.statN.. + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (4 samples, 0.04%) + + + +io.Copy (1 samples, 0.01%) + + + +cmpbody (4 samples, 0.04%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +runtime.newMarkBits (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +sort.swapRange (16 samples, 0.16%) + + + +runtime.schedule (113 samples, 1.13%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func22 (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Digest.Validate (2 samples, 0.02%) + + + +encoding/json.(*scanner).popParseState (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +time.tzset (1 samples, 0.01%) + + + +sort.StringSlice.Swap (9 samples, 0.09%) + + + +runtime.slicebytetostring (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.arenaIndex (1 samples, 0.01%) + + + +runtime.pcvalue (1 samples, 0.01%) + + + +regexp.newOnePassMachine (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (3 samples, 0.03%) + + + +reflect.unsafe_New (4 samples, 0.04%) + + + +runtime.(*mcache).allocLarge (1 samples, 0.01%) + + + +runtime.isEmpty (1 samples, 0.01%) + + + +reflect.MakeMap (3 samples, 0.03%) + + + +syscall.Getdents (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch.func2 (1 samples, 0.01%) + + + +reflect.Value.assignTo (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).search (8 samples, 0.08%) + + + +github.com/gorilla/handlers.recoveryHandler.ServeHTTP (1 samples, 0.01%) + + + +runtime.(*lfstack).pop (2 samples, 0.02%) + + + +encoding/json.unquoteBytes (31 samples, 0.31%) + + + +regexp/syntax.(*Inst).MatchRunePos (216 samples, 2.16%) +r.. + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +encoding/json.getu4 (3 samples, 0.03%) + + + +runtime.newobject (1 samples, 0.01%) + + + +sort.swapRange (14 samples, 0.14%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +regexp/syntax.(*Inst).MatchRune (248 samples, 2.48%) +re.. + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.mallocgc (10 samples, 0.10%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.newobject (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetVendor (3 samples, 0.03%) + + + +reflect.cvtBytesString (9 samples, 0.09%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (47 samples, 0.47%) + + + +syscall.RawSyscall6 (3 samples, 0.03%) + + + +syscall.BytePtrFromString (3 samples, 0.03%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (3 samples, 0.03%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +sync.(*entry).load (1 samples, 0.01%) + + + +runtime.(*spanSet).push (5 samples, 0.05%) + + + +reflect.flag.ro (1 samples, 0.01%) + + + +runtime.growslice (1 samples, 0.01%) + + + +reflect.(*rtype).Name (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (1 samples, 0.01%) + + + +encoding/json.indirect (14 samples, 0.14%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).ScanImage (7 samples, 0.07%) + + + +runtime.memclrNoHeapPointers (3 samples, 0.03%) + + + +syscall.Syscall6 (10 samples, 0.10%) + + + +reflect.typedmemmove (1 samples, 0.01%) + + + +runtime.mapaccess1_fast32 (1 samples, 0.01%) + + + +runtime.(*atomicHeadTailIndex).cas (2 samples, 0.02%) + + + +runtime.divRoundUp (2 samples, 0.02%) + + + +reflect.(*rtype).NumMethod (7 samples, 0.07%) + + + +runtime.memmove (3 samples, 0.03%) + + + +cmpbody (5 samples, 0.05%) + + + +sort.symMerge (11 samples, 0.11%) + + + +os.(*File).Readdirnames (221 samples, 2.21%) +o.. + + +runtime.bgscavenge (35 samples, 0.35%) + + + +internal/poll.errnoErr (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (2 samples, 0.02%) + + + +runtime.(*atomicHeadTailIndex).incTail (1 samples, 0.01%) + + + +runtime.hashGrow (6 samples, 0.06%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.getLayersSummaries (28 samples, 0.28%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func22 (3 samples, 0.03%) + + + +runtime.growslice (3 samples, 0.03%) + + + +sort.StringSlice.Less (1 samples, 0.01%) + + + +runtime.(*mcache).refill (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/fanal/artifact/image.Artifact.Inspect (1 samples, 0.01%) + + + +runtime.newobject (4 samples, 0.04%) + + + +runtime.gcMarkDone (5 samples, 0.05%) + + + +runtime.(*pageAlloc).scavenge (33 samples, 0.33%) + + + +syscall.Read (3 samples, 0.03%) + + + +runtime.callers (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (254 samples, 2.55%) +en.. + + +github.com/aquasecurity/trivy/pkg/scanner.Scanner.ScanArtifact (2 samples, 0.02%) + + + +reflect.flag.kind (7 samples, 0.07%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +go.etcd.io/bbolt.unsafeByteSlice (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (584 samples, 5.85%) +encodin.. + + +runtime.(*gcControllerState).heapGoalInternal (2 samples, 0.02%) + + + +runtime.(*bmap).keys (1 samples, 0.01%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +runtime.pidleget (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +io.CopyN (1 samples, 0.01%) + + + +internal/testlog.Stat (7 samples, 0.07%) + + + +runtime.newarray (6 samples, 0.06%) + + + +reflect.New (1 samples, 0.01%) + + + +fmt.(*fmt).fmtS (1 samples, 0.01%) + + + +runtime.systemstack (2 samples, 0.02%) + + + +runtime.heapBitsSetType (3 samples, 0.03%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.newImage (1 samples, 0.01%) + + + +internal/poll.ignoringEINTRIO (8 samples, 0.08%) + + + +encoding/json.stateBeginString (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (2 samples, 0.02%) + + + +runtime.gcTrigger.test (1 samples, 0.01%) + + + +reflect.ValueOf (1 samples, 0.01%) + + + +memeqbody (1 samples, 0.01%) + + + +runtime.unlock (1 samples, 0.01%) + + + +runtime.scanstack (23 samples, 0.23%) + + + +syscall.RawSyscall6 (10 samples, 0.10%) + + + +reflect.PointerTo (2 samples, 0.02%) + + + +runtime.memclrNoHeapPointers (4 samples, 0.04%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 (3 samples, 0.03%) + + + +encoding/json.indirect (1 samples, 0.01%) + + + +reflect.(*rtype).NumMethod (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +encoding/json.stateEndTop (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 (3 samples, 0.03%) + + + +runtime.makeslice (25 samples, 0.25%) + + + +reflect.Value.Kind (2 samples, 0.02%) + + + +runtime.(*sweepLocker).tryAcquire (11 samples, 0.11%) + + + +runtime.bool2int (2 samples, 0.02%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.(*rtype).NumMethod (2 samples, 0.02%) + + + +runtime.newobject (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.arenaIdx.l1 (1 samples, 0.01%) + + + +runtime.suspendG (4 samples, 0.04%) + + + +runtime/internal/atomic.(*Uintptr).Add (4 samples, 0.04%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +path.Base (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +regexp.(*Regexp).doMatch (633 samples, 6.34%) +regexp.(.. + + +os.statNolog (12 samples, 0.12%) + + + +reflect.(*rtype).exportedMethods (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (40 samples, 0.40%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +runtime.gcTrigger.test (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner.Scanner.ScanArtifact (6 samples, 0.06%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Bucket).pageNode (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*lfstack).pop (2 samples, 0.02%) + + + +reflect.Value.Field (4 samples, 0.04%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +internal/poll.(*FD).decref (2 samples, 0.02%) + + + +reflect.Copy (4 samples, 0.04%) + + + +runtime.exitsyscallfast_reacquired (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (3 samples, 0.03%) + + + +runtime/internal/atomic.(*Bool).Load (3 samples, 0.03%) + + + +runtime.(*mspan).objIndex (1 samples, 0.01%) + + + +syscall.Stat (13 samples, 0.13%) + + + +runtime.mallocgc (20 samples, 0.20%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +runtime.writeHeapBits.write (2 samples, 0.02%) + + + +runtime.lock (1 samples, 0.01%) + + + +syscall.RawSyscall6 (10 samples, 0.10%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.ScanImage (2 samples, 0.02%) + + + +reflect.Value.SetLen (1 samples, 0.01%) + + + +os.readIntLE (1 samples, 0.01%) + + + +reflect.(*rtype).Elem (1 samples, 0.01%) + + + +sort.symMerge (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +runtime.(*bucket).mp (1 samples, 0.01%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanWhile (5 samples, 0.05%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +time.(*Time).setLoc (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (2 samples, 0.02%) + + + +internal/poll.(*FD).Init (1 samples, 0.01%) + + + +reflect.Value.Convert (13 samples, 0.13%) + + + +syscall.Stat (7 samples, 0.07%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +cmpbody (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*branchPageElement).key (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (938 samples, 9.40%) +encoding/json.. + + +runtime.slicebytetostring (6 samples, 0.06%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.wbBufFlush (2 samples, 0.02%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.mPark (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.(*bmap).keys (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (6 samples, 0.06%) + + + +sort.swapRange (9 samples, 0.09%) + + + +cmpbody (2 samples, 0.02%) + + + +runtime.(*activeSweep).isDone (1 samples, 0.01%) + + + +runtime.checkTimers (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.(*lfstack).empty (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +reflect.ifaceIndir (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*LocalRegistry).CommitImage (119 samples, 1.19%) + + + +runtime.slicebytetostring (21 samples, 0.21%) + + + +reflect.ifaceIndir (2 samples, 0.02%) + + + +reflect.ValueOf (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (101 samples, 1.01%) + + + +aeshashbody (2 samples, 0.02%) + + + +runtime.releasem (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.ForEachAdvisory (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +path.Clean (9 samples, 0.09%) + + + +runtime.mapassign_faststr (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +encoding/json.stateEndValue (4 samples, 0.04%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.getLockRank (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (13 samples, 0.13%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (348 samples, 3.49%) +zot.. + + +time.(*Time).stripMono (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (6 samples, 0.06%) + + + +runtime.(*gcWork).putBatch (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (1 samples, 0.01%) + + + +reflect.add (1 samples, 0.01%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).spill (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Int64).Add (1 samples, 0.01%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +runtime/internal/atomic.(*Uint64).Add (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.(*rtype).exportedMethods (1 samples, 0.01%) + + + +reflect.(*rtype).hasName (1 samples, 0.01%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +runtime.getempty (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.cmpstring (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 + + +regexp.(*inputString).step (115 samples, 1.15%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +runtime.procPin (1 samples, 0.01%) + + + +runtime.futex (1 samples, 0.01%) + + + +reflect.unpackEface (1 samples, 0.01%) + + + +runtime.memmove (3 samples, 0.03%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.newarray (10 samples, 0.10%) + + + +runtime.(*mcentral).cacheSpan (3 samples, 0.03%) + + + +runtime.(*mcache).refill (3 samples, 0.03%) + + + +runtime.callers (1 samples, 0.01%) + + + +runtime.makeslice (25 samples, 0.25%) + + + +sync.(*Map).Load (1 samples, 0.01%) + + + +strconv.formatBits (5 samples, 0.05%) + + + +encoding/json.unquoteBytes (4 samples, 0.04%) + + + +runtime.runqsteal (1 samples, 0.01%) + + + +runtime.(*stackScanState).getPtr (1 samples, 0.01%) + + + +os.Stat (83 samples, 0.83%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch.func2 (3 samples, 0.03%) + + + +runtime.(*randomEnum).next (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanNext (2 samples, 0.02%) + + + +reflect.add (4 samples, 0.04%) + + + +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do + + +os.direntNamlen (3 samples, 0.03%) + + + +runtime.unlock (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (2 samples, 0.02%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +syscall.RawSyscall6 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/boltdb.(*BoltDB).SearchRepos (2,225 samples, 22.29%) +zotregistry.io/zot/pkg/meta/boltdb... + + +reflect.Value.SetBytes (1 samples, 0.01%) + + + +runtime.lockWithRank (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/storage/common.(*dedupeTask).DoWork (2 samples, 0.02%) + + + +runtime.assertE2I2 (4 samples, 0.04%) + + + +reflect.(*rtype).String (2 samples, 0.02%) + + + +reflect.Value.Kind (2 samples, 0.02%) + + + +go.etcd.io/bbolt.unsafeAdd (1 samples, 0.01%) + + + +reflect.Value.SetMapIndex (1 samples, 0.01%) + + + +time.atoi[...] (3 samples, 0.03%) + + + +runtime.mallocgc (10 samples, 0.10%) + + + +reflect.flag.mustBe (1 samples, 0.01%) + + + +reflect.flag.mustBeExported (1 samples, 0.01%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +aeshashbody (5 samples, 0.05%) + + + +syscall.fstatat (10 samples, 0.10%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (5 samples, 0.05%) + + + +time.(*Location).lookup (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).scanArtifact (7 samples, 0.07%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +runtime.(*mspan).nextFreeIndex (1 samples, 0.01%) + + + +runtime.modtimer (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +reflect.Value.OverflowInt (2 samples, 0.02%) + + + +runtime.(*mheap).allocMSpanLocked (4 samples, 0.04%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 (3 samples, 0.03%) + + + +reflect.(*rtype).String (11 samples, 0.11%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.lockRankMayQueueFinalizer (3 samples, 0.03%) + + + +sync.(*Map).Load (4 samples, 0.04%) + + + +runtime.entersyscall (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +os.(*File).readdir (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).WriteFile (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Cursor).search (52 samples, 0.52%) + + + +github.com/aquasecurity/trivy/pkg/detector/ospkg/ubuntu.(*Scanner).Detect (1 samples, 0.01%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +runtime.findRunnable (111 samples, 1.11%) + + + +runtime.typehash (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 + + +runtime.(*mheap).tryAllocMSpan (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +regexp.newLazyFlag (3 samples, 0.03%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +regexp.freeOnePassMachine (7 samples, 0.07%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23.1 (3 samples, 0.03%) + + + +runtime.newobject (1 samples, 0.01%) + + + +runtime.(*lfstack).push (96 samples, 0.96%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*BaseService).SyncRepo (119 samples, 1.19%) + + + +runtime.nextFreeFast (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).GetNextDigestWithBlobPaths (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/storage/imagestore.(*Ima.. + + +runtime.gentraceback (2 samples, 0.02%) + + + +sort.symMerge (85 samples, 0.85%) + + + +sort.stable (182 samples, 1.82%) +s.. + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func22 (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/scanner.Scanner.ScanArtifact (2 samples, 0.02%) + + + +runtime.mapaccess1_fast32 (1 samples, 0.01%) + + + +runtime.makeslice (42 samples, 0.42%) + + + +github.com/google/go-containerregistry/pkg/v1/layout.(*layoutIndex).findDescriptor (1 samples, 0.01%) + + + +runtime.mallocgc (15 samples, 0.15%) + + + +encoding/json.stateEndValue (6 samples, 0.06%) + + + +encoding/json.(*decodeState).readIndex (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (98 samples, 0.98%) + + + +runtime.writeHeapBits.write (2 samples, 0.02%) + + + +encoding/json.(*decodeState).object (360 samples, 3.61%) +enco.. + + +runtime.futexsleep (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.makeBucketArray (1 samples, 0.01%) + + + +runtime.reentersyscall (1 samples, 0.01%) + + + +fmt.(*pp).printArg (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 (3 samples, 0.03%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.newobject (3 samples, 0.03%) + + + +runtime.(*mcache).refill (2 samples, 0.02%) + + + +reflect.packEface (2 samples, 0.02%) + + + +encoding/json.(*decodeState).literalStore (170 samples, 1.70%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +errors.Is (13 samples, 0.13%) + + + +runtime.(*mcache).refill (3 samples, 0.03%) + + + +runtime.memhash64 (4 samples, 0.04%) + + + +os.newFile (2 samples, 0.02%) + + + +sync.runtime_procPin (2 samples, 0.02%) + + + +runtime.(*mheap).alloc.func1 (2 samples, 0.02%) + + + +reflect.MakeMapWithSize (1 samples, 0.01%) + + + +sort.StringSlice.Swap (11 samples, 0.11%) + + + +reflect.(*rtype).uncommon (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/meta/boltdb.(*BoltDB).SearchRepos (1 samples, 0.01%) + + + +strings.Index (2 samples, 0.02%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (2 samples, 0.02%) + + + +encoding/json.indirect (2 samples, 0.02%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (2 samples, 0.02%) + + + +memeqbody (4 samples, 0.04%) + + + +syscall.SetNonblock (3 samples, 0.03%) + + + +github.com/opencontainers/go-digest.Algorithm.Validate (68 samples, 0.68%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint64).Store (1 samples, 0.01%) + + + +reflect.name.name (7 samples, 0.07%) + + + +internal/poll.(*pollDesc).init (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateImageSummaryVulnerabilities (8 samples, 0.08%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/storage/local.(*Driver)... + + +runtime.(*stackScanState).addObject (1 samples, 0.01%) + + + +runtime.growslice (16 samples, 0.16%) + + + +reflect.Value.Set (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 (3 samples, 0.03%) + + + +runtime.typedmemmove (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.(*mcache).releaseAll (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (5 samples, 0.05%) + + + +encoding/json.(*decodeState).scanNext (12 samples, 0.12%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +reflect.Value.IsNil (2 samples, 0.02%) + + + +go.etcd.io/bbolt.unsafeByteSlice (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Cursor).seek (1 samples, 0.01%) + + + +sync.(*Pool).Get (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.(*pageAlloc).update (11 samples, 0.11%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search.globalSearch (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search.globalSearch + + +reflect.Value.Kind (4 samples, 0.04%) + + + +runtime.handoff (292 samples, 2.93%) +ru.. + + +memeqbody (3 samples, 0.03%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +os.openFileNolog (8 samples, 0.08%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +runtime.procPin (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.mapiternext (3 samples, 0.03%) + + + +encoding/json.(*decodeState).literalStore (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Tx).page (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*LocalRegistry).copyManifest (119 samples, 1.19%) + + + +aeshashbody (2 samples, 0.02%) + + + +reflect.Value.Index (4 samples, 0.04%) + + + +runtime.checkIdleGCNoP (6 samples, 0.06%) + + + +aeshashbody (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search.globalSearch (3 samples, 0.03%) + + + +reflect.packEface (6 samples, 0.06%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +embed.(*openFile).Read (1 samples, 0.01%) + + + +reflect.(*rtype).String (7 samples, 0.07%) + + + +os.OpenFile (2 samples, 0.02%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +runtime.typedmemmove (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*node).spill (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (3 samples, 0.03%) + + + +runtime.(*lfstack).pop (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.callers (1 samples, 0.01%) + + + +syscall.ByteSliceFromString (7 samples, 0.07%) + + + +runtime.mallocgc (8 samples, 0.08%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.runqsteal (10 samples, 0.10%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.funcInfo.entry (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/boltdb.fetchManifestMetaWithCheck (1,909 samples, 19.13%) +zotregistry.io/zot/pkg/meta/b.. + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Int64).Load (1 samples, 0.01%) + + + +runtime.(*consistentHeapStats).release (2 samples, 0.02%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (1,263 samples, 12.66%) +encoding/json.(*dec.. + + +syscall.RawSyscall6 (1 samples, 0.01%) + + + +reflect.MakeMapWithSize (3 samples, 0.03%) + + + +reflect.Value.Type (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +sync.(*Pool).pin (5 samples, 0.05%) + + + +encoding/json.indirect (1 samples, 0.01%) + + + +runtime.mallocgc (15 samples, 0.15%) + + + +runtime.divRoundUp (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (269 samples, 2.70%) +en.. + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +reflect.unsafe_NewArray (10 samples, 0.10%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +os.direntIno (1 samples, 0.01%) + + + +reflect.valueInterface (2 samples, 0.02%) + + + +runtime.mapaccess2_faststr (4 samples, 0.04%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +errors.Is (3 samples, 0.03%) + + + +runtime.(*consistentHeapStats).acquire (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +runtime.nanotime (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.packPallocSum (1 samples, 0.01%) + + + +runtime.spanClass.noscan (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query (1 samples, 0.01%) + + + +runtime.makeslice (4 samples, 0.04%) + + + +fmt.(*pp).doPrintf (1 samples, 0.01%) + + + +reflect.(*rtype).String (6 samples, 0.06%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.exitsyscall (1 samples, 0.01%) + + + +internal/testlog.Logger (5 samples, 0.05%) + + + +runtime.convTslice (5 samples, 0.05%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +os.statNolog.func1 (13 samples, 0.13%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 (1 samples, 0.01%) + + + +runtime.lock2 (2 samples, 0.02%) + + + +runtime.(*mheap).alloc (3 samples, 0.03%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.convTstring (5 samples, 0.05%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/scheduler.(*Scheduler).getTask (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/scheduler.(*Scheduler).g.. + + +runtime.printlock (1 samples, 0.01%) + + + +internal/poll.ignoringEINTRIO (7 samples, 0.07%) + + + +encoding/json.stateBeginString (3 samples, 0.03%) + + + +reflect.MakeMap (9 samples, 0.09%) + + + +runtime.gcMarkWorkAvailable (2 samples, 0.02%) + + + +runtime.mapaccess2_faststr (11 samples, 0.11%) + + + +runtime.stealWork (2 samples, 0.02%) + + + +runtime.gcMarkWorkAvailable (5 samples, 0.05%) + + + +reflect.Value.Len (1 samples, 0.01%) + + + +runtime.(*mspan).initHeapBits (1 samples, 0.01%) + + + +reflect.Value.Convert (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*page).branchPageElements (3 samples, 0.03%) + + + +reflect.Value.Elem (3 samples, 0.03%) + + + +runtime.heapBits.next (15 samples, 0.15%) + + + +reflect.flag.mustBeAssignable (2 samples, 0.02%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +encoding/json.checkValid (1 samples, 0.01%) + + + +runtime.slicebytetostring (7 samples, 0.07%) + + + +reflect.typedmemmove (1 samples, 0.01%) + + + +syscall.Getdents (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Int64).CompareAndSwap (1 samples, 0.01%) + + + +runtime.gcStart (1 samples, 0.01%) + + + +encoding/json.stateEndTop (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.callers (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotationValue (1 samples, 0.01%) + + + +runtime.(*itabTableType).find (4 samples, 0.04%) + + + +reflect.Value.IsNil (3 samples, 0.03%) + + + +runtime.growslice (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/boltdb.NewManifestMetadata (11 samples, 0.11%) + + + +runtime.(*lfstack).empty (2 samples, 0.02%) + + + +runtime.handoff (2 samples, 0.02%) + + + +runtime.(*lfstack).push (83 samples, 0.83%) + + + +runtime.greyobject (303 samples, 3.04%) +run.. + + +syscall.BytePtrFromString (51 samples, 0.51%) + + + +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch (3 samples, 0.03%) + + + +runtime.mProf_FlushLocked (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.tryOCI (1 samples, 0.01%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +reflect.Value.assignTo (2 samples, 0.02%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +runtime.gcAssistAlloc (3 samples, 0.03%) + + + +runtime.(*mcache).nextFree (5 samples, 0.05%) + + + +runtime.mapaccess1_fast32 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.getLayersSummaries (32 samples, 0.32%) + + + +syscall.RawSyscall6 (6 samples, 0.06%) + + + +encoding/json.(*decodeState).readIndex (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).scanWhile (4 samples, 0.04%) + + + +encoding/json.stateInString (1 samples, 0.01%) + + + +fmt.(*pp).fmtString (1 samples, 0.01%) + + + +runtime.(*mspan).initHeapBits (2 samples, 0.02%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateImageSummaryVulnerabilities (2 samples, 0.02%) + + + +reflect.Value.IsNil (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (2 samples, 0.02%) + + + +runtime.newobject (5 samples, 0.05%) + + + +reflect.(*rtype).NumMethod (11 samples, 0.11%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executableSchema).Exec.func1 (3 samples, 0.03%) + + + +runtime.assertE2I2 (2 samples, 0.02%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +syscall.Syscall6 (11 samples, 0.11%) + + + +encoding/json.(*decodeState).object (921 samples, 9.23%) +encoding/json.. + + +runtime.procyield (1 samples, 0.01%) + + + +sync.(*Map).Load (10 samples, 0.10%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (218 samples, 2.18%) +e.. + + +zotregistry.io/zot/pkg/extensions/search/convert.updateRepoSummaryVulnerabilities (8 samples, 0.08%) + + + +runtime.callers (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (939 samples, 9.41%) +encoding/json.. + + +reflect.add (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2,855 samples, 28.61%) +zotregistry.io/zot/pkg/storage/local.(*Driver.. + + +github.com/opencontainers/go-digest.NewDigestFromEncoded (194 samples, 1.94%) +g.. + + +os.statNolog.func1 (10 samples, 0.10%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +reflect.Value.Field (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (4 samples, 0.04%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +reflect.Value.SetString (2 samples, 0.02%) + + + +runtime.addspecial (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.Stack (1 samples, 0.01%) + + + +runtime.convT64 (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +encoding/json.indirect (1 samples, 0.01%) + + + +runtime.makemap (2 samples, 0.02%) + + + +encoding/json.(*decodeState).readIndex (1 samples, 0.01%) + + + +runtime.futex (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.getempty (1 samples, 0.01%) + + + +runtime.(*mcache).refill (2 samples, 0.02%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +os.(*file).close (2 samples, 0.02%) + + + +sort.swapRange (3 samples, 0.03%) + + + +syscall.ReadDirent (7 samples, 0.07%) + + + +runtime.fastrand (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).get (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +runtime.growslice (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.RepoMeta2RepoSummary (2,697 samples, 27.02%) +zotregistry.io/zot/pkg/extensions/search/co.. + + +crypto/tls.(*atLeastReader).Read (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +reflect.(*rtype).String (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/meta/boltdb.(*BoltDB).SearchRepos.func1 (1 samples, 0.01%) + + + +github.com/gorilla/handlers.recoveryHandler.ServeHTTP (4,931 samples, 49.41%) +github.com/gorilla/handlers.recoveryHandler.ServeHTTP + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +runtime.(*scavengerState).init.func2 (34 samples, 0.34%) + + + +bytes.(*Buffer).ReadFrom (1 samples, 0.01%) + + + +runtime.(*gcControllerState).enlistWorker (1 samples, 0.01%) + + + +reflect.cvtBytesString (1 samples, 0.01%) + + + +sort.StringSlice.Less (3 samples, 0.03%) + + + +reflect.makeString (14 samples, 0.14%) + + + +reflect.Value.Cap (2 samples, 0.02%) + + + +syscall.ByteSliceFromString (47 samples, 0.47%) + + + +runtime.mapaccess2_faststr (3 samples, 0.03%) + + + +runtime.unlockWithRank (2 samples, 0.02%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +bufio.(*Writer).Write (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.Descriptor2ImageSummary (2,640 samples, 26.45%) +zotregistry.io/zot/pkg/extensions/search/c.. + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (1 samples, 0.01%) + + + +net/http.serverHandler.ServeHTTP (3 samples, 0.03%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.unlockWithRank (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.getitab (13 samples, 0.13%) + + + +fmt.Sprintf (1 samples, 0.01%) + + + +net.(*netFD).Read (1 samples, 0.01%) + + + +runtime.(*gcWork).tryGet (220 samples, 2.20%) +r.. + + +runtime.newobject (4 samples, 0.04%) + + + +github.com/aquasecurity/trivy/pkg/scanner.Scanner.ScanArtifact (1 samples, 0.01%) + + + +runtime.(*itabTableType).find (10 samples, 0.10%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +fmt.(*pp).free (9 samples, 0.09%) + + + +reflect.(*uncommonType).exportedMethods (3 samples, 0.03%) + + + +runtime.(*mcache).refill (2 samples, 0.02%) + + + +runtime.(*mcentral).uncacheSpan (2 samples, 0.02%) + + + +encoding/json.isSpace (2 samples, 0.02%) + + + +runtime.wakep (1 samples, 0.01%) + + + +runtime.(*gcControllerState).trigger (2 samples, 0.02%) + + + +runtime.markBits.setMarked (1 samples, 0.01%) + + + +net/http.serverHandler.ServeHTTP (4,932 samples, 49.42%) +net/http.serverHandler.ServeHTTP + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.runqgrab (8 samples, 0.08%) + + + +runtime.scanstack.func1 (16 samples, 0.16%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.bucketEvacuated (1 samples, 0.01%) + + + +reflect.Value.Kind (2 samples, 0.02%) + + + +encoding/json.stateInStringEscU123 (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotationValue (6 samples, 0.06%) + + + +reflect.name.data (1 samples, 0.01%) + + + +runtime.arenaIdx.l2 (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.tryOCI (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.getImageBlobsInfo (13 samples, 0.13%) + + + +reflect.(*rtype).Kind (3 samples, 0.03%) + + + +runtime.(*maptype).indirectkey (2 samples, 0.02%) + + + +internal/poll.(*FD).Read (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (362 samples, 3.63%) +enco.. + + +reflect.PointerTo (1 samples, 0.01%) + + + +runtime.procPin (1 samples, 0.01%) + + + +path.Join (3 samples, 0.03%) + + + +runtime.entersyscall (22 samples, 0.22%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).FullBlobUpload (118 samples, 1.18%) + + + +reflect.MakeSlice (26 samples, 0.26%) + + + +runtime.(*mheap).alloc (6 samples, 0.06%) + + + +runtime.lfstackUnpack (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +strconv.ParseInt (2 samples, 0.02%) + + + +time.parseStrictRFC3339 (12 samples, 0.12%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +os.(*File).write (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.gcstopm (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions.addUISecurityHeaders.func1 (1 samples, 0.01%) + + + +encoding/json.stateEndValue (3 samples, 0.03%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +internal/poll.(*FD).ReadDirent (8 samples, 0.08%) + + + +encoding/json.Unmarshal (2 samples, 0.02%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).scanArtifact (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23 (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uintptr).Add (2 samples, 0.02%) + + + +indexbytebody (2 samples, 0.02%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +fmt.Sprintf (15 samples, 0.15%) + + + +reflect.ifaceIndir (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).scanArtifact (1 samples, 0.01%) + + + +reflect.flag.mustBeExported (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Int64).Add (4 samples, 0.04%) + + + +runtime.(*gcControllerState).heapGoalInternal (1 samples, 0.01%) + + + +os.(*File).Readdirnames (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/common.AddExtensionSecurityHeaders.func1.1 (3 samples, 0.03%) + + + +runtime.exitsyscall (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (1 samples, 0.01%) + + + +runtime.(*bmap).keys (1 samples, 0.01%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +regexp.(*Regexp).allMatches (1 samples, 0.01%) + + + +reflect.Value.Field (8 samples, 0.08%) + + + +zotregistry.io/zot/pkg/extensions/search.globalSearch (3 samples, 0.03%) + + + +runtime.getMCache (2 samples, 0.02%) + + + +reflect.(*rtype).Elem (2 samples, 0.02%) + + + +runtime/internal/atomic.(*Uint64).Add (1 samples, 0.01%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +internal/poll.(*FD).Close (2 samples, 0.02%) + + + +runtime.newarray (3 samples, 0.03%) + + + +encoding/json.stateInStringEscU12 (1 samples, 0.01%) + + + +encoding/base64.(*Encoding).Decode (319 samples, 3.20%) +enc.. + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +fmt.(*pp).handleMethods (44 samples, 0.44%) + + + +reflect.(*rtype).exportedMethods (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +reflect.flag.mustBeAssignable (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 (1 samples, 0.01%) + + + +regexp.(*Regexp).doExecute (66 samples, 0.66%) + + + +encoding/json.stateBeginValue (4 samples, 0.04%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +os.statNolog (81 samples, 0.81%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).nsearch (5 samples, 0.05%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +os.(*File).readdir (221 samples, 2.21%) +o.. + + +runtime.procyield (2 samples, 0.02%) + + + +runtime.SetFinalizer (1 samples, 0.01%) + + + +syscall.Close (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.spanOf (90 samples, 0.90%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +github.com/knqyf263/go-deb-version.extract (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.runTrivy (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.runqempty (1 samples, 0.01%) + + + +internal/reflectlite.TypeOf (1 samples, 0.01%) + + + +runtime.gcWriteBarrierCX (1 samples, 0.01%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +runtime.arenaIdx.l2 (1 samples, 0.01%) + + + +runtime.(*mspan).objIndex (21 samples, 0.21%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +syscall.RawSyscall6 (3 samples, 0.03%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage.func1 (2 samples, 0.02%) + + + +runtime.mapaccess2 (14 samples, 0.14%) + + + +runtime.gcTrigger.test (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +path.Base (87 samples, 0.87%) + + + +sort.rotate (5 samples, 0.05%) + + + +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do (1 samples, 0.01%) + + + +fmt.(*buffer).writeString (4 samples, 0.04%) + + + +encoding/json.(*decodeState).scanWhile (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (934 samples, 9.36%) +encoding/json.. + + +encoding/json.(*scanner).pushParseState (3 samples, 0.03%) + + + +encoding/json.stateInStringEsc (6 samples, 0.06%) + + + +syscall.fcntl (2 samples, 0.02%) + + + +runtime.getLockRank (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (3 samples, 0.03%) + + + +crypto/sha256.block (62 samples, 0.62%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (400 samples, 4.01%) +enco.. + + +path.Clean (5 samples, 0.05%) + + + +reflect.(*rtype).typeOff (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateImageSummaryVulnerabilities (2 samples, 0.02%) + + + +reflect.Value.Kind (2 samples, 0.02%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (1 samples, 0.01%) + + + +sort.StringSlice.Swap (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.PaginatedRepoMeta2RepoSummaries (2 samples, 0.02%) + + + +os.Open (7 samples, 0.07%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.systemstack (1,665 samples, 16.68%) +runtime.systemstack + + +internal/reflectlite.toType (2 samples, 0.02%) + + + +sort.StringSlice.Swap (2 samples, 0.02%) + + + +syscall.SetNonblock (1 samples, 0.01%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +runtime.gcMarkWorkAvailable (2 samples, 0.02%) + + + +regexp/syntax.(*Inst).MatchRune (27 samples, 0.27%) + + + +runtime.bucketMask (1 samples, 0.01%) + + + +regexp.(*bitState).push (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (4 samples, 0.04%) + + + +runtime.(*mspan).markBitsForIndex (1 samples, 0.01%) + + + +path.(*lazybuf).string (2 samples, 0.02%) + + + +runtime.(*pageAlloc).scavengeOne (33 samples, 0.33%) + + + +reflect.unsafe_New (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +os.fillFileStatFromSys (49 samples, 0.49%) + + + +runtime.growslice (6 samples, 0.06%) + + + +reflect.ValueOf (2 samples, 0.02%) + + + +os.(*File).Close (1 samples, 0.01%) + + + +runtime.heapBitsSetType (10 samples, 0.10%) + + + +runtime.newarray (1 samples, 0.01%) + + + +memeqbody (12 samples, 0.12%) + + + +sync.(*Pool).pin (1 samples, 0.01%) + + + +reflect.Value.Addr (5 samples, 0.05%) + + + +fmt.(*pp).printArg (1 samples, 0.01%) + + + +reflect.mapassign_faststr (8 samples, 0.08%) + + + +encoding/json.indirect (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (15 samples, 0.15%) + + + +path.(*lazybuf).append (3 samples, 0.03%) + + + +os.(*File).readdir (12 samples, 0.12%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +runtime.(*mheap).freeSpanLocked (21 samples, 0.21%) + + + +runtime.unlock2 (1 samples, 0.01%) + + + +runtime.(*_type).typeOff (7 samples, 0.07%) + + + +runtime.funcspdelta (1 samples, 0.01%) + + + +encoding/json.indirect (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.ScanImage (1 samples, 0.01%) + + + +path.Join (10 samples, 0.10%) + + + +encoding/json.(*decodeState).scanWhile (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*lfstack).empty (3 samples, 0.03%) + + + +syscall.RawSyscall6 (98 samples, 0.98%) + + + +net/http.HandlerFunc.ServeHTTP (4,930 samples, 49.40%) +net/http.HandlerFunc.ServeHTTP + + +go.etcd.io/bbolt.unsafeAdd (1 samples, 0.01%) + + + +sync.runtime_procUnpin (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (2 samples, 0.02%) + + + +encoding/json.(*decodeState).scanWhile (4 samples, 0.04%) + + + +runtime.procPin (2 samples, 0.02%) + + + +github.com/gorilla/mux.(*Router).ServeHTTP (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.detect (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.profilealloc (2 samples, 0.02%) + + + +sync.(*Pool).Put (6 samples, 0.06%) + + + +time.leadingInt[...] (2 samples, 0.02%) + + + +runtime.lock (8 samples, 0.08%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +io.Copy (1 samples, 0.01%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +encoding/json.stateBeginValue (4 samples, 0.04%) + + + +regexp.(*Regexp).doMatch (2 samples, 0.02%) + + + +path.lastSlash (16 samples, 0.16%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (1 samples, 0.01%) + + + +internal/bytealg.IndexByteString (1 samples, 0.01%) + + + +encoding/json.Unmarshal (289 samples, 2.90%) +en.. + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.runTrivy (8 samples, 0.08%) + + + +reflect.name.readVarint (1 samples, 0.01%) + + + +runtime.mallocgc (8 samples, 0.08%) + + + +runtime.(*mheap).allocSpan (3 samples, 0.03%) + + + +sort.rotate (2 samples, 0.02%) + + + +runtime.callers.func1 (2 samples, 0.02%) + + + +regexp.(*Regexp).MatchString (2 samples, 0.02%) + + + +fmt.Sprintf (3 samples, 0.03%) + + + +path.Clean (2 samples, 0.02%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Tx).page (3 samples, 0.03%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.newobject (2 samples, 0.02%) + + + +reflect.Value.Elem (2 samples, 0.02%) + + + +net/http.(*fileHandler).ServeHTTP (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.scanVulnerabilities (3 samples, 0.03%) + + + +runtime.(*mcentral).grow (8 samples, 0.08%) + + + +reflect.Value.Type (2 samples, 0.02%) + + + +reflect.Value.Kind (4 samples, 0.04%) + + + +reflect.Value.Addr (2 samples, 0.02%) + + + +reflect.Value.SetMapIndex (26 samples, 0.26%) + + + +go.etcd.io/bbolt.(*Bucket).pageNode (1 samples, 0.01%) + + + +runtime.(*randomEnum).position (1 samples, 0.01%) + + + +runtime.entersyscall (1 samples, 0.01%) + + + +path.Join (11 samples, 0.11%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 + + +runtime.(*mspan).divideByElemSize (7 samples, 0.07%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +reflect.flag.kind (2 samples, 0.02%) + + + +runtime.typedmemclr (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.getBlob (1 samples, 0.01%) + + + +fmt.newPrinter (25 samples, 0.25%) + + + +reflect.Value.CanAddr (3 samples, 0.03%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.systemstack (2 samples, 0.02%) + + + +reflect.convertOp (4 samples, 0.04%) + + + +encoding/json.stateBeginValueOrEmpty (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +sort.symMerge (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +runtime.newobject (2 samples, 0.02%) + + + +encoding/json.(*decodeState).rescanLiteral (135 samples, 1.35%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 (1 samples, 0.01%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +reflect.(*rtype).typeOff (8 samples, 0.08%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +reflect.Value.Interface (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 (4,930 samples, 49.40%) +github.com/99designs/gqlgen/graphql/executor.processExtensions.func3 + + +sync.(*Map).Load (3 samples, 0.03%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.growslice (1 samples, 0.01%) + + + +runtime.lock2 (1 samples, 0.01%) + + + +os.OpenFile (8 samples, 0.08%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (4 samples, 0.04%) + + + +regexp.(*Regexp).MatchString (634 samples, 6.35%) +regexp.(.. + + +runtime.systemstack (3 samples, 0.03%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +runtime.mapaccess2_faststr (9 samples, 0.09%) + + + +encoding/json.checkValid (213 samples, 2.13%) +e.. + + +runtime.pMask.read (9 samples, 0.09%) + + + +indexbytebody (2 samples, 0.02%) + + + +sort.StringSlice.Less (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.mapassign_faststr (8 samples, 0.08%) + + + +runtime.bucketShift (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +indexbytebody (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (2 samples, 0.02%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.releasem (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.runTrivy (2 samples, 0.02%) + + + +runtime.systemstack (4 samples, 0.04%) + + + +reflect.(*rtype).exportedMethods (3 samples, 0.03%) + + + +runtime.mapaccess2_faststr (5 samples, 0.05%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanWhile (5 samples, 0.05%) + + + +runtime.profilealloc (1 samples, 0.01%) + + + +runtime.newAllocBits (1 samples, 0.01%) + + + +internal/poll.runtime_pollOpen (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotationValue (2 samples, 0.02%) + + + +fmt.(*pp).printValue (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Int64).Load (6 samples, 0.06%) + + + +runtime.entersyscall (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.scanManifest (2 samples, 0.02%) + + + +runtime.(*bmap).overflow (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.lockWithRank (2 samples, 0.02%) + + + +runtime.(*gcCPULimiterState).addIdleTime (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +runtime.advanceEvacuationMark (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (2 samples, 0.02%) + + + +runtime.slicebytetostring (2 samples, 0.02%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint64).CompareAndSwap (4 samples, 0.04%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.forEach (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +os.ignoringEINTR (7 samples, 0.07%) + + + +runtime.(*mcache).prepareForSweep (1 samples, 0.01%) + + + +reflect.name.name (2 samples, 0.02%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.lock (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/common.Contains[...] (4 samples, 0.04%) + + + +runtime.(*mspan).nextFreeIndex (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +reflect.Value.SetString (1 samples, 0.01%) + + + +runtime.newobject (4 samples, 0.04%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +bytes.growSlice (51 samples, 0.51%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.ImageManifest2ImageSummary (1 samples, 0.01%) + + + +runtime.madvise (26 samples, 0.26%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +encoding/json.stateEndValue (6 samples, 0.06%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (2 samples, 0.02%) + + + +syscall.fstatat (7 samples, 0.07%) + + + +encoding/json.(*decodeState).value (347 samples, 3.48%) +enc.. + + +runtime.unlock (1 samples, 0.01%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +runtime/internal/syscall.Syscall6 (1 samples, 0.01%) + + + +time.(*Location).lookup (1 samples, 0.01%) + + + +runtime.(*mheap).alloc.func1 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).readIndex (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch.func2 (3 samples, 0.03%) + + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +runtime.divRoundUp (4 samples, 0.04%) + + + +sort.stable (1 samples, 0.01%) + + + +runtime.makeslice (1 samples, 0.01%) + + + +reflect.New (2 samples, 0.02%) + + + +go.etcd.io/bbolt.(*Cursor).search (46 samples, 0.46%) + + + +time.Unix (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (5 samples, 0.05%) + + + +reflect.name.readVarint (6 samples, 0.06%) + + + +reflect.Value.Addr (1 samples, 0.01%) + + + +sort.insertionSort (7 samples, 0.07%) + + + +encoding/json.stateBeginValue (15 samples, 0.15%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23 (3 samples, 0.03%) + + + +runtime.lock2 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 (3 samples, 0.03%) + + + +reflect.implements (2 samples, 0.02%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (2 samples, 0.02%) + + + +runtime.deductSweepCredit (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/artifact/image.Artifact.Inspect (1 samples, 0.01%) + + + +reflect.Value.Elem (7 samples, 0.07%) + + + +reflect.(*rtype).hasName (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.procPin (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.name.readVarint (7 samples, 0.07%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.mallocgc (7 samples, 0.07%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +encoding/json.stateBeginValue (12 samples, 0.12%) + + + +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia (2 samples, 0.02%) + + + +runtime.sysUnusedOS (26 samples, 0.26%) + + + +reflect.flag.mustBeAssignable (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (12 samples, 0.12%) + + + +runtime/internal/atomic.(*Uint8).Store (1 samples, 0.01%) + + + +runtime.divRoundUp (6 samples, 0.06%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +sort.symMerge (123 samples, 1.23%) + + + +runtime.mallocgc (25 samples, 0.25%) + + + +runtime.releasem (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/sync.(*LocalRegistry).copyBlob (119 samples, 1.19%) + + + +fmt.(*pp).fmtString (7 samples, 0.07%) + + + +runtime/internal/atomic.(*Uint32).Add (1 samples, 0.01%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +runtime.futex (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch (3 samples, 0.03%) + + + +runtime.readgstatus (1 samples, 0.01%) + + + +runtime.gcWriteBarrierSI (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (8 samples, 0.08%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage (21 samples, 0.21%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.gcAssistAlloc (1 samples, 0.01%) + + + +syscall.RawSyscall6 (1 samples, 0.01%) + + + +runtime.packPallocSum (1 samples, 0.01%) + + + +reflect.makemap (1 samples, 0.01%) + + + +sort.StringSlice.Swap (1 samples, 0.01%) + + + +runtime.(*pollCache).free (1 samples, 0.01%) + + + +runtime.markroot (35 samples, 0.35%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +runtime.putempty (1 samples, 0.01%) + + + +runtime.newobject (5 samples, 0.05%) + + + +runtime.newobject (1 samples, 0.01%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +reflect.arrayAt (1 samples, 0.01%) + + + +strconv.ParseInt (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +sync.(*Map).loadReadOnly (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +sort.StringSlice.Swap (10 samples, 0.10%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +encoding/json.checkValid (35 samples, 0.35%) + + + +reflect.(*rtype).Implements (2 samples, 0.02%) + + + +reflect.(*rtype).Name (4 samples, 0.04%) + + + +reflect.MakeMapWithSize (1 samples, 0.01%) + + + +runtime.slicebytetostring (2 samples, 0.02%) + + + +runtime.rawbyteslice (5 samples, 0.05%) + + + +os.(*File).read (3 samples, 0.03%) + + + +runtime.(*mspan).nextFreeIndex (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.gcWriteBarrierDX (1 samples, 0.01%) + + + +runtime.(*moduledata).textAddr (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetSource (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Algorithm.Available (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +fmt.(*pp).printArg (64 samples, 0.64%) + + + +reflect.Value.SetString (3 samples, 0.03%) + + + +runtime.nextSample (1 samples, 0.01%) + + + +runtime.newobject (1 samples, 0.01%) + + + +regexp.(*Regexp).doOnePass (628 samples, 6.29%) +regexp.(.. + + +regexp.freeOnePassMachine (1 samples, 0.01%) + + + +reflect.name.name (1 samples, 0.01%) + + + +github.com/gorilla/handlers.recoveryHandler.ServeHTTP (3 samples, 0.03%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +os.readIntLE (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (10 samples, 0.10%) + + + +runtime.convT64 (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).pageNode (3 samples, 0.03%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (3 samples, 0.03%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +reflect.name.data (3 samples, 0.03%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +syscall.RawSyscall6 (47 samples, 0.47%) + + + +syscall.Close (2 samples, 0.02%) + + + +reflect.mapassign_faststr (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do (3 samples, 0.03%) + + + +encoding/json.(*decodeState).literalStore (55 samples, 0.55%) + + + +os.direntIno (7 samples, 0.07%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.lockWithRank (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetAnnotationValue (2 samples, 0.02%) + + + +runtime.slicebytetostring (2 samples, 0.02%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.(*gcControllerState).heapGoalInternal (1 samples, 0.01%) + + + +runtime.gcTrigger.test (1 samples, 0.01%) + + + +fmt.getField (1 samples, 0.01%) + + + +reflect.(*rtype).nameOff (1 samples, 0.01%) + + + +bytes.Compare (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateRepoSummaryVulnerabilities (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +sync.runtime_procPin (1 samples, 0.01%) + + + +runtime.divRoundUp (2 samples, 0.02%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 (3 samples, 0.03%) + + + +encoding/json.stateBeginValue (3 samples, 0.03%) + + + +runtime.reentersyscall (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.readUintptr (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs.func1 (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner/langpkg.(*scanner).Scan (1 samples, 0.01%) + + + +reflect.Value.SetInt (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetTitle (2 samples, 0.02%) + + + +encoding/json.(*decodeState).array (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).CreateBucket (1 samples, 0.01%) + + + +runtime.(*mcache).refill (2 samples, 0.02%) + + + +regexp.(*Regexp).tryBacktrack (1 samples, 0.01%) + + + +sort.swapRange (2 samples, 0.02%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.NewDigestFromEncoded (2 samples, 0.02%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +runtime.futex (1 samples, 0.01%) + + + +sort.Search (2 samples, 0.02%) + + + +encoding/json.isSpace (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/scheduler.(*Scheduler).poolWorker.func1 (121 samples, 1.21%) + + + +runtime.hashGrow (1 samples, 0.01%) + + + +runtime.mProf_Flush (4 samples, 0.04%) + + + +runtime.getLockRank (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.GetDescription (1 samples, 0.01%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +os.Stat (13 samples, 0.13%) + + + +time.parseNanoseconds[...] (3 samples, 0.03%) + + + +runtime.mallocgc (10 samples, 0.10%) + + + +runtime.nextFreeFast (4 samples, 0.04%) + + + +reflect.Value.assignTo (1 samples, 0.01%) + + + +reflect.Value.Len (3 samples, 0.03%) + + + +runtime.findObject (1 samples, 0.01%) + + + +runtime.stopm (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (28 samples, 0.28%) + + + +reflect.(*rtype).Key (1 samples, 0.01%) + + + +cmpbody (5 samples, 0.05%) + + + +net/http.(*http2Framer).ReadFrame (1 samples, 0.01%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +reflect.MakeMap (6 samples, 0.06%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +reflect.toType (2 samples, 0.02%) + + + +runtime.mallocgc (16 samples, 0.16%) + + + +runtime.growWork_faststr (13 samples, 0.13%) + + + +reflect.flag.mustBeAssignable (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.(*gcWork).put (2 samples, 0.02%) + + + +runtime.isEmpty (1 samples, 0.01%) + + + +strconv.formatBits (7 samples, 0.07%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (252 samples, 2.53%) +en.. + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 (3 samples, 0.03%) + + + +syscall.Syscall (1 samples, 0.01%) + + + +runtime.markrootBlock (7 samples, 0.07%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.getBlob (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +strings.genSplit (1 samples, 0.01%) + + + +reflect.makemap (1 samples, 0.01%) + + + +runtime.markBits.isMarked (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.memmove (2 samples, 0.02%) + + + +runtime.(*mspan).markBitsForIndex (81 samples, 0.81%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.assertE2I2 (4 samples, 0.04%) + + + +runtime.putempty (1 samples, 0.01%) + + + +reflect.Value.SetString (4 samples, 0.04%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +net/http.(*http2serverConn).readFrames (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.GetBlob.func1 (1 samples, 0.01%) + + + +reflect.(*uncommonType).exportedMethods (3 samples, 0.03%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search.globalSearch (1 samples, 0.01%) + + + +encoding/json.state1 (4 samples, 0.04%) + + + +fmt.(*pp).printValue (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.spanOfUnchecked (6 samples, 0.06%) + + + +reflect.name.data (1 samples, 0.01%) + + + +runtime.exitsyscallfast_reacquired (1 samples, 0.01%) + + + +runtime.sysUnused (26 samples, 0.26%) + + + +internal/poll.(*FD).ReadDirent (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/storage/local.fileInfo.IsDir (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.detect (1 samples, 0.01%) + + + +runtime.resolveTypeOff (1 samples, 0.01%) + + + +reflect.New (17 samples, 0.17%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.memmove (3 samples, 0.03%) + + + +memeqbody (1 samples, 0.01%) + + + +reflect.typedslicecopy (4 samples, 0.04%) + + + +sort.rotate (6 samples, 0.06%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +sort.swapRange (2 samples, 0.02%) + + + +encoding/json.stateBeginString (5 samples, 0.05%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (4,930 samples, 49.40%) +net/http.HandlerFunc.ServeHTTP + + +runtime.(*mspan).init (2 samples, 0.02%) + + + +runtime.SetFinalizer.func2 (1 samples, 0.01%) + + + +os.Open (9 samples, 0.09%) + + + +sort.StringSlice.Less (3 samples, 0.03%) + + + +internal/poll.(*fdMutex).incref (1 samples, 0.01%) + + + +fmt.(*pp).doPrintf (1 samples, 0.01%) + + + +runtime.growWork_faststr (7 samples, 0.07%) + + + +runtime.mallocgc (17 samples, 0.17%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +reflect.Value.Elem (10 samples, 0.10%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +encoding/json.isSpace (5 samples, 0.05%) + + + +encoding/json.(*decodeState).rescanLiteral (3 samples, 0.03%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (1 samples, 0.01%) + + + +reflect.Value.IsNil (3 samples, 0.03%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.(*Driver).DetectVulnerabilities (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime.divRoundUp (3 samples, 0.03%) + + + +internal/poll.(*pollDesc).init (1 samples, 0.01%) + + + +runtime.gcAssistAlloc1 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (2 samples, 0.02%) + + + +runtime.gcBgMarkWorker (1,681 samples, 16.84%) +runtime.gcBgMarkWorker + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.mapiterinit (6 samples, 0.06%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +sort.symMerge (8 samples, 0.08%) + + + +runtime.heapBitsSetType (3 samples, 0.03%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +encoding/json.indirect (2 samples, 0.02%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP (3 samples, 0.03%) + + + +runtime.unlock2 (2 samples, 0.02%) + + + +runtime.divRoundUp (4 samples, 0.04%) + + + +runtime.bulkBarrierPreWrite (1 samples, 0.01%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +encoding/json.stateBeginString (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/api.BaseAuthzHandler.func1.1 (1 samples, 0.01%) + + + +runtime.getitab (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.scanManifest (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +reflect.Value.IsValid (1 samples, 0.01%) + + + +runtime.growslice (6 samples, 0.06%) + + + +reflect.MakeSlice (26 samples, 0.26%) + + + +sync.(*Pool).Get (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch (3 samples, 0.03%) + + + +reflect.(*rtype).NumMethod (1 samples, 0.01%) + + + +encoding/json.checkValid (323 samples, 3.24%) +enc.. + + +runtime.slicebytetostring (14 samples, 0.14%) + + + +github.com/opencontainers/go-digest.Digest.Validate (71 samples, 0.71%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.lockWithRankMayAcquire (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (3 samples, 0.03%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +path.(*lazybuf).string (1 samples, 0.01%) + + + +syscall.Open (3 samples, 0.03%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query (3 samples, 0.03%) + + + +runtime/internal/atomic.(*Uint64).Add (2 samples, 0.02%) + + + +runtime.exitsyscallfast (4 samples, 0.04%) + + + +runtime.lockWithRankMayAcquire (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/types.(*Advisory).UnmarshalJSON (1 samples, 0.01%) + + + +strconv.ParseUint (3 samples, 0.03%) + + + +encoding/json.unquoteBytes (477 samples, 4.78%) +encod.. + + +runtime.slicebytetostring (22 samples, 0.22%) + + + +runtime.gcMarkTermination.func4.1 (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint64).CompareAndSwap (2 samples, 0.02%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +encoding/json.indirect (24 samples, 0.24%) + + + +encoding/json.unquoteBytes (2 samples, 0.02%) + + + +runtime.(*limiterEvent).start (1 samples, 0.01%) + + + +os.(*File).Close (1 samples, 0.01%) + + + +encoding/json.indirect (7 samples, 0.07%) + + + +runtime.profilealloc (1 samples, 0.01%) + + + +syscall.Syscall (1 samples, 0.01%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +reflect.Value.Index (1 samples, 0.01%) + + + +runtime.systemstack (3 samples, 0.03%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (23 samples, 0.23%) + + + +syscall.ReadDirent (98 samples, 0.98%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +runtime.(*sweepLocked).sweep (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (12 samples, 0.12%) + + + +reflect.MakeMapWithSize (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/extensions/search.globalSearch (3 samples, 0.03%) + + + +runtime.makeslice (3 samples, 0.03%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.nextFreeFast (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.scanManifest (2 samples, 0.02%) + + + +runtime.(*mcache).refill (2 samples, 0.02%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +runtime/internal/syscall.Syscall6 (3 samples, 0.03%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.heapBitsSetType (3 samples, 0.03%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.flag.mustBeAssignable (2 samples, 0.02%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +cmpbody (2 samples, 0.02%) + + + +runtime/internal/atomic.(*UnsafePointer).StoreNoWB (1 samples, 0.01%) + + + +runtime.newobject (3 samples, 0.03%) + + + +runtime.scanframeworker (16 samples, 0.16%) + + + +time.Date (2 samples, 0.02%) + + + +os.basename (7 samples, 0.07%) + + + +encoding/json.(*decodeState).value (923 samples, 9.25%) +encoding/json.. + + +github.com/gorilla/mux.(*Router).ServeHTTP (4,932 samples, 49.42%) +github.com/gorilla/mux.(*Router).ServeHTTP + + +syscall.openat (4 samples, 0.04%) + + + +internal/poll.(*FD).Init (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner/ospkg.(*scanner).Scan (2 samples, 0.02%) + + + +runtime.writeHeapBitsForAddr (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +os.direntReclen (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/vulnsrc/ubuntu.VulnSrc.Get (1 samples, 0.01%) + + + +os.(*fileStat).IsDir (1 samples, 0.01%) + + + +runtime.save (1 samples, 0.01%) + + + +encoding/json.stateEndValue (3 samples, 0.03%) + + + +runtime.(*lfstack).push (1 samples, 0.01%) + + + +runtime.Stack.func1 (1 samples, 0.01%) + + + +runtime.newobject (5 samples, 0.05%) + + + +runtime.isEmpty (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +reflect.Value.CanAddr (1 samples, 0.01%) + + + +runtime.funcInfo.entry (1 samples, 0.01%) + + + +syscall.Open (4 samples, 0.04%) + + + +runtime.writeHeapBitsForAddr (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +sync.runtime_procPin (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (54 samples, 0.54%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +regexp.(*Regexp).doMatch (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetAdvisories (1 samples, 0.01%) + + + +sort.StringSlice.Swap (3 samples, 0.03%) + + + +reflect.(*uncommonType).exportedMethods (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.systemstack (3 samples, 0.03%) + + + +encoding/json.(*decodeState).scanNext (2 samples, 0.02%) + + + +runtime.convTstring (10 samples, 0.10%) + + + +os.readInt (3 samples, 0.03%) + + + +runtime.convT64 (2 samples, 0.02%) + + + +aeshashbody (3 samples, 0.03%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +fmt.(*pp).catchPanic (2 samples, 0.02%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +reflect.flag.mustBe (1 samples, 0.01%) + + + +runtime.entersyscall (4 samples, 0.04%) + + + +reflect.mapassign_faststr (23 samples, 0.23%) + + + +runtime.pcvalue (1 samples, 0.01%) + + + +reflect.name.name (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +reflect.Value.IsNil (3 samples, 0.03%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +runtime.makeslice (1 samples, 0.01%) + + + +reflect.Copy (4 samples, 0.04%) + + + +sort.symMerge (1 samples, 0.01%) + + + +encoding/json.indirect (2 samples, 0.02%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +reflect.(*rtype).Elem (1 samples, 0.01%) + + + +encoding/json.stateEndTop (1 samples, 0.01%) + + + +reflect.(*rtype).exportedMethods (6 samples, 0.06%) + + + +runtime.convTslice (4 samples, 0.04%) + + + +runtime.spanOf (1 samples, 0.01%) + + + +runtime.(*spanSet).pop (8 samples, 0.08%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +encoding/json.stateEndValue (23 samples, 0.23%) + + + +runtime.(*mcache).nextFree (2 samples, 0.02%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.mPark (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Digest.String (1 samples, 0.01%) + + + +runtime.pcvalue (3 samples, 0.03%) + + + +reflect.Value.Addr (3 samples, 0.03%) + + + +runtime.convT (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (4 samples, 0.04%) + + + +runtime.nextFreeFast (3 samples, 0.03%) + + + +runtime.newobject (42 samples, 0.42%) + + + +github.com/opencontainers/go-digest.Algorithm.Available (12 samples, 0.12%) + + + +runtime.entersyscall (1 samples, 0.01%) + + + +runtime.futexwakeup (1 samples, 0.01%) + + + +sort.StringSlice.Less (23 samples, 0.23%) + + + +reflect.Value.Elem (3 samples, 0.03%) + + + +syscall.BytePtrFromString (1 samples, 0.01%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +reflect.cvtBytesString (1 samples, 0.01%) + + + +os.readIntLE (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (7 samples, 0.07%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.CORSHeadersMiddleware.func1.1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.scan (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.gcResetMarkState.func1 (1 samples, 0.01%) + + + +sort.symMerge (40 samples, 0.40%) + + + +path.Clean (345 samples, 3.46%) +pat.. + + +sync.(*Pool).Put (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +fmt.(*pp).fmtString (6 samples, 0.06%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +reflect.(*rtype).Name (18 samples, 0.18%) + + + +runtime.execute (1 samples, 0.01%) + + + +fmt.(*pp).fmtString (1 samples, 0.01%) + + + +runtime.gcWriteBarrier (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +encoding/json.stateBeginStringOrEmpty (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (3 samples, 0.03%) + + + +runtime.mapaccess1_faststr (7 samples, 0.07%) + + + +reflect.(*rtype).NumMethod (2 samples, 0.02%) + + + +runtime.setprofilebucket (1 samples, 0.01%) + + + +reflect.add (2 samples, 0.02%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.mallocgc (19 samples, 0.19%) + + + +sort.StringSlice.Swap (1 samples, 0.01%) + + + +syscall.Syscall6 (3 samples, 0.03%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/applier.(*applier).ApplyLayers (1 samples, 0.01%) + + + +runtime.arenaIdx.l1 (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query (3 samples, 0.03%) + + + +reflect.(*rtype).Name (9 samples, 0.09%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.futexwakeup (2 samples, 0.02%) + + + +sync.(*Pool).getSlow (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).GetNextDigestWithBlobPaths.func1 (4 samples, 0.04%) + + + +runtime.(*lfstack).pop (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (6 samples, 0.06%) + + + +runtime.checkTimers (10 samples, 0.10%) + + + +time.parseRFC3339[...] (12 samples, 0.12%) + + + +go.etcd.io/bbolt.(*page).fastCheck (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.divRoundUp (2 samples, 0.02%) + + + +fmt.newPrinter (1 samples, 0.01%) + + + +strconv.ParseUint (1 samples, 0.01%) + + + +sync/atomic.(*Pointer[...]).Load (1 samples, 0.01%) + + + +runtime.growslice (3 samples, 0.03%) + + + +fmt.(*pp).printArg (5 samples, 0.05%) + + + +sort.StringSlice.Swap (5 samples, 0.05%) + + + +time.(*Location).lookup (1 samples, 0.01%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.lockWithRankMayAcquire (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +bytes.Compare (5 samples, 0.05%) + + + +os.(*File).Close (4 samples, 0.04%) + + + +encoding/json.unquoteBytes (2 samples, 0.02%) + + + +internal/poll.(*pollDesc).prepareRead (1 samples, 0.01%) + + + +runtime.newobject (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.funcspdelta (2 samples, 0.02%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.(*lfstack).pop (1 samples, 0.01%) + + + +runtime.gcAssistAlloc1 (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.GetBlob.func1 (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +reflect.Value.Kind (3 samples, 0.03%) + + + +runtime.pidlegetSpinning (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (3 samples, 0.03%) + + + +runtime.(*scavengerState).sleep (1 samples, 0.01%) + + + +reflect.Value.Field (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (5 samples, 0.05%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.makeSpanClass (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (1 samples, 0.01%) + + + +runtime.deductAssistCredit (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.forEachP (1 samples, 0.01%) + + + +runtime.growslice (5 samples, 0.05%) + + + +runtime.callers.func1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.traceback (1 samples, 0.01%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +regexp/syntax.(*Inst).MatchRunePos (23 samples, 0.23%) + + + +runtime.mapiterinit (1 samples, 0.01%) + + + +runtime.convTstring (1 samples, 0.01%) + + + +runtime.systemstack (33 samples, 0.33%) + + + +runtime.procUnpin (1 samples, 0.01%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +encoding/json.state0 (1 samples, 0.01%) + + + +fmt.(*fmt).truncateString (3 samples, 0.03%) + + + +runtime.newobject (16 samples, 0.16%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateRepoSummaryVulnerabilities (2 samples, 0.02%) + + + +encoding/json.stateBeginValueOrEmpty (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.PaginatedRepoMeta2RepoSummaries (3 samples, 0.03%) + + + +runtime.(*mcentral).grow (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.Value.Cap (1 samples, 0.01%) + + + +os.(*fileStat).Mode (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (3 samples, 0.03%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +runtime.newArenaMayUnlock (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +time.daysIn (4 samples, 0.04%) + + + +encoding/json.unquoteBytes (1 samples, 0.01%) + + + +runtime.(*sweepLocked).sweep (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (3 samples, 0.03%) + + + +reflect.Value.Kind (9 samples, 0.09%) + + + +syscall.Getdents (98 samples, 0.98%) + + + +runtime.(*mspan).markBitsForIndex (1 samples, 0.01%) + + + +runtime.newobject (3 samples, 0.03%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (6 samples, 0.06%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.scanVulnerabilities (1 samples, 0.01%) + + + +runtime.(*lfstack).push (1 samples, 0.01%) + + + +sort.swapRange (4 samples, 0.04%) + + + +strconv.ParseInt (3 samples, 0.03%) + + + +runtime.nextFreeFast (5 samples, 0.05%) + + + +runtime.divRoundUp (4 samples, 0.04%) + + + +runtime.forEachG (1 samples, 0.01%) + + + +os.statNolog.func1 (7 samples, 0.07%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.newobject (1 samples, 0.01%) + + + +os.openFileNolog (2 samples, 0.02%) + + + +encoding/json.cachedTypeFields (3 samples, 0.03%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.mallocgc (20 samples, 0.20%) + + + +runtime.stopm (4 samples, 0.04%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +runtime.netpollopen (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (4 samples, 0.04%) + + + +runtime.makemap_small (4 samples, 0.04%) + + + +reflect.typedmemclr (1 samples, 0.01%) + + + +runtime.reentersyscall (4 samples, 0.04%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +fmt.glob..func1 (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.(*lfstack).push (2 samples, 0.02%) + + + +reflect.(*rtype).Name (8 samples, 0.08%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.scanVulnerabilities (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 (3 samples, 0.03%) + + + +sync.(*Pool).Get (7 samples, 0.07%) + + + +runtime.resolveTypeOff (2 samples, 0.02%) + + + +fmt.(*pp).handleMethods (3 samples, 0.03%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +reflect.(*rtype).Name (10 samples, 0.10%) + + + +sort.symMerge (3 samples, 0.03%) + + + +runtime.(*memRecordCycle).add (2 samples, 0.02%) + + + +memeqbody (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +io.(*LimitedReader).Read (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (868 samples, 8.70%) +encoding/jso.. + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +runtime.(*itabTableType).find (1 samples, 0.01%) + + + +syscall.RawSyscall6 (3 samples, 0.03%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +github.com/99designs/gqlgen/graphql.(*FieldSet).Dispatch (1 samples, 0.01%) + + + +net.(*conn).Read (1 samples, 0.01%) + + + +runtime.(*mspan).divideByElemSize (1 samples, 0.01%) + + + +runtime.newobject (2 samples, 0.02%) + + + +os.(*fileStat).Mode (1 samples, 0.01%) + + + +runtime.readUintptr (1 samples, 0.01%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +reflect.Value.SetMapIndex (4 samples, 0.04%) + + + +runtime.mapaccess2 (1 samples, 0.01%) + + + +github.com/google/go-containerregistry/pkg/v1/layout.(*layoutIndex).IndexManifest (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (522 samples, 5.23%) +encodi.. + + +sync.(*Map).loadReadOnly (1 samples, 0.01%) + + + +runtime.(*hmap).newoverflow (2 samples, 0.02%) + + + +reflect.Value.Field (2 samples, 0.02%) + + + +internal/poll.ignoringEINTRIO (1 samples, 0.01%) + + + +runtime.(*mheap).allocSpan (6 samples, 0.06%) + + + +runtime.memclrNoHeapPointers (5 samples, 0.05%) + + + +runtime.gcWriteBarrierCX (1 samples, 0.01%) + + + +encoding/json.(*decodeState).literalStore (1 samples, 0.01%) + + + +runtime.putfull (2 samples, 0.02%) + + + +runtime.bool2int (1 samples, 0.01%) + + + +syscall.RawSyscall6 (5 samples, 0.05%) + + + +runtime.(*fixalloc).alloc (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.(*bmap).keys (1 samples, 0.01%) + + + +runtime.mallocgc (45 samples, 0.45%) + + + +runtime.morestack (6 samples, 0.06%) + + + +internal/poll.runtime_pollOpen (1 samples, 0.01%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.mallocgc (11 samples, 0.11%) + + + +runtime.futexsleep (1 samples, 0.01%) + + + +runtime.gcMarkTermination.func4 (1 samples, 0.01%) + + + +runtime.growslice (7 samples, 0.07%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +runtime.divRoundUp (5 samples, 0.05%) + + + +internal/testlog.Logger (2 samples, 0.02%) + + + +runtime.(*pageAlloc).allocToCache (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetAdvisories (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).CheckBlob (1 samples, 0.01%) + + + +runtime.mallocgc (11 samples, 0.11%) + + + +runtime.(*mcache).nextFree (3 samples, 0.03%) + + + +runtime.freedefer (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*DB).View (1 samples, 0.01%) + + + +runtime.greyobject (2 samples, 0.02%) + + + +runtime.(*spanSet).pop (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +os.(*file).close (4 samples, 0.04%) + + + +reflect.Value.assignTo (4 samples, 0.04%) + + + +encoding/json.(*decodeState).literalStore (1 samples, 0.01%) + + + +runtime.procyield (1 samples, 0.01%) + + + +runtime.gcBgMarkWorker.func1 (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetAdvisories (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.GetBlob (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Quer.. + + +sort.symMerge (53 samples, 0.53%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +runtime.itabHashFunc (1 samples, 0.01%) + + + +encoding/json.cachedTypeFields (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.MissingBlobs (1 samples, 0.01%) + + + +runtime.(*gcControllerState).markWorkerStop (6 samples, 0.06%) + + + +runtime.duffzero (2 samples, 0.02%) + + + +runtime.(*mcache).refill (13 samples, 0.13%) + + + +reflect.Value.CanAddr (2 samples, 0.02%) + + + +reflect.(*rtype).Kind (2 samples, 0.02%) + + + +reflect.(*rtype).Key (2 samples, 0.02%) + + + +os.OpenFile (7 samples, 0.07%) + + + +sync/atomic.(*Value).Load (2 samples, 0.02%) + + + +sync/atomic.(*Pointer[...]).Load (3 samples, 0.03%) + + + +syscall.Syscall6 (3 samples, 0.03%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +runtime.slicebytetostring (14 samples, 0.14%) + + + +fmt.(*pp).printValue (1 samples, 0.01%) + + + +fmt.(*fmt).fmtS (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.putfull (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.sweepone (104 samples, 1.04%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23 (3 samples, 0.03%) + + + +runtime.(*lfstack).pop (3 samples, 0.03%) + + + +runtime.(*pallocBits).summarize (9 samples, 0.09%) + + + +runtime.divRoundUp (3 samples, 0.03%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +reflect.makemap (6 samples, 0.06%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +runtime.lock2 (8 samples, 0.08%) + + + +sync.runtime_procPin (2 samples, 0.02%) + + + +runtime.mProf_Malloc (1 samples, 0.01%) + + + +sync.(*Map).Load (4 samples, 0.04%) + + + +reflect.directlyAssignable (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 (4,931 samples, 49.41%) +zotregistry.io/zot/pkg/api.SessionAuditLogger.func1.1 + + +runtime.pcvalue (2 samples, 0.02%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +encoding/json.stateBeginString (1 samples, 0.01%) + + + +github.com/knqyf263/go-deb-version.(*Version).LessThan (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.getBlob (1 samples, 0.01%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime.(*gcBits).bitp (73 samples, 0.73%) + + + +encoding/json.indirect (5 samples, 0.05%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +reflect.Value.Addr (4 samples, 0.04%) + + + +reflect.name.readVarint (1 samples, 0.01%) + + + +bytes.(*Buffer).ReadFrom (54 samples, 0.54%) + + + +reflect.flag.mustBeAssignable (2 samples, 0.02%) + + + +runtime.fastlog2 (1 samples, 0.01%) + + + +regexp.lazyFlag.match (1 samples, 0.01%) + + + +memeqbody (4 samples, 0.04%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.scan (7 samples, 0.07%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (7 samples, 0.07%) + + + +runtime.mergeSummaries (2 samples, 0.02%) + + + +runtime/internal/syscall.Syscall6 (422 samples, 4.23%) +runti.. + + +syscall.RawSyscall6 (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +reflect.(*rtype).Name (2 samples, 0.02%) + + + +runtime.makeslice (5 samples, 0.05%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (646 samples, 6.47%) +zotregis.. + + +runtime.(*mheap).nextSpanForSweep (9 samples, 0.09%) + + + +net/http.http2readFrameHeader (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +internal/poll.(*FD).destroy (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (1 samples, 0.01%) + + + +reflect.ValueOf (1 samples, 0.01%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (5 samples, 0.05%) + + + +encoding/json.(*decodeState).rescanLiteral (417 samples, 4.18%) +enco.. + + +reflect.name.readVarint (1 samples, 0.01%) + + + +encoding/json.stateEndValue (22 samples, 0.22%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +encoding/json.Unmarshal (1,251 samples, 12.54%) +encoding/json.Unma.. + + +runtime.(*pageAlloc).update (2 samples, 0.02%) + + + +runtime.addfinalizer (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).RunDedupeForDigest (2 samples, 0.02%) + + + +reflect.Value.Addr (1 samples, 0.01%) + + + +runtime.(*scavengeIndex).mark (3 samples, 0.03%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (5 samples, 0.05%) + + + +runtime.(*mheap).alloc.func1 (1 samples, 0.01%) + + + +memeqbody (1 samples, 0.01%) + + + +reflect.Value.IsValid (2 samples, 0.02%) + + + +reflect.flag.mustBeExported (1 samples, 0.01%) + + + +sort.symMerge (10 samples, 0.10%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +runtime.addspecial (1 samples, 0.01%) + + + +encoding/json.stateBeginStringOrEmpty (2 samples, 0.02%) + + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (3 samples, 0.03%) + + + +runtime.(*mheap).alloc.func1 (4 samples, 0.04%) + + + +runtime.(*mheap).alloc (3 samples, 0.03%) + + + +runtime.(*mspan).refillAllocCache (1 samples, 0.01%) + + + +runtime.casgstatus (1 samples, 0.01%) + + + +fmt.(*fmt).init (1 samples, 0.01%) + + + +runtime.newobject (7 samples, 0.07%) + + + +runtime.memmove (1 samples, 0.01%) + + + +runtime.(*spanSet).push (2 samples, 0.02%) + + + +runtime.nextFreeFast (1 samples, 0.01%) + + + +path.Join (80 samples, 0.80%) + + + +runtime.(*mspan).objIndex (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1 (3 samples, 0.03%) + + + +reflect.unsafe_New (5 samples, 0.05%) + + + +internal/poll.(*FD).ReadDirent (7 samples, 0.07%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +time.(*Time).stripMono (1 samples, 0.01%) + + + +runtime.(*mheap).allocMSpanLocked (2 samples, 0.02%) + + + +io/fs.FileMode.IsDir (1 samples, 0.01%) + + + +runtime.(*gcBitsArena).tryAlloc (1 samples, 0.01%) + + + +fmt.(*fmt).fmtS (1 samples, 0.01%) + + + +reflect.Value.SetBool (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search.(*queryResolver).GlobalSearch (3 samples, 0.03%) + + + +runtime.(*mcentral).uncacheSpan (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).Add (4 samples, 0.04%) + + + +reflect.Value.Elem (2 samples, 0.02%) + + + +runtime.duffzero (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.(*mspan).countAlloc (2 samples, 0.02%) + + + +sort.rotate (1 samples, 0.01%) + + + +encoding/json.(*decodeState).array (164 samples, 1.64%) + + + +os.readInt (1 samples, 0.01%) + + + +runtime.procyield (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).Get (57 samples, 0.57%) + + + +runtime.exitsyscall (14 samples, 0.14%) + + + +runtime.heapBitsSetType (4 samples, 0.04%) + + + +syscall.Syscall (2 samples, 0.02%) + + + +runtime.newMarkBits (1 samples, 0.01%) + + + +reflect.(*rtype).typeOff (2 samples, 0.02%) + + + +encoding/json.unquoteBytes (61 samples, 0.61%) + + + +fmt.(*fmt).padString (1 samples, 0.01%) + + + +runtime.isEmpty (1 samples, 0.01%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +runtime.(*mcache).refill (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +syscall.RawSyscall6 (2 samples, 0.02%) + + + +runtime.(*mcache).refill (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch.func2 (3 samples, 0.03%) + + + +reflect.Value.Elem (1 samples, 0.01%) + + + +runtime.pcvalue (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.unsafe_NewArray (9 samples, 0.09%) + + + +runtime.resolveTypeOff (2 samples, 0.02%) + + + +sort.StringSlice.Less (6 samples, 0.06%) + + + +runtime.resolveTypeOff (6 samples, 0.06%) + + + +encoding/json.stateEndValue (9 samples, 0.09%) + + + +reflect.valueInterface (5 samples, 0.05%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.futexsleep (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).searchPage (39 samples, 0.39%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointersChunked (17 samples, 0.17%) + + + +reflect.Value.Kind (1 samples, 0.01%) + + + +encoding/json.(*scanner).popParseState (1 samples, 0.01%) + + + +reflect.resolveTypeOff (8 samples, 0.08%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +sync.runtime_procUnpin (1 samples, 0.01%) + + + +reflect.(*rtype).Name (5 samples, 0.05%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1 (3 samples, 0.03%) + + + +runtime.duffcopy (2 samples, 0.02%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.schedule (4 samples, 0.04%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.acquirem (3 samples, 0.03%) + + + +runtime.slicebytetostring (9 samples, 0.09%) + + + +reflect.name.name (3 samples, 0.03%) + + + +runtime.(*pallocBits).summarize (2 samples, 0.02%) + + + +os.(*File).Readdirnames (12 samples, 0.12%) + + + +runtime.writeHeapBits.flush (3 samples, 0.03%) + + + +runtime.convT64 (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).set (1 samples, 0.01%) + + + +reflect.New (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (3 samples, 0.03%) + + + +runtime.gentraceback (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2,958 samples, 29.64%) +zotregistry.io/zot/pkg/storage/local.(*Driver)... + + +reflect.(*rtype).String (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.detect (1 samples, 0.01%) + + + +reflect.Value.IsValid (1 samples, 0.01%) + + + +runtime.(*mspan).nextFreeIndex (2 samples, 0.02%) + + + +runtime.makeslice (1 samples, 0.01%) + + + +runtime.scanobject (703 samples, 7.04%) +runtime.s.. + + +syscall.RawSyscall6 (3 samples, 0.03%) + + + +runtime.putfull (96 samples, 0.96%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (25 samples, 0.25%) + + + +runtime.exitsyscallfast (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/common.ACHeadersMiddleware.func1.1 (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.(*runner).ScanImage (2 samples, 0.02%) + + + +runtime.(*hmap).newoverflow (1 samples, 0.01%) + + + +runtime.notesleep (1 samples, 0.01%) + + + +reflect.(*rtype).Name (4 samples, 0.04%) + + + +runtime.profilealloc (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Walk (2 samples, 0.02%) + + + +reflect.(*rtype).Kind (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Cursor).goToFirstElementOnTheStack (1 samples, 0.01%) + + + +strings.HasSuffix (5 samples, 0.05%) + + + +runtime.makeBucketArray (1 samples, 0.01%) + + + +reflect.resolveTypeOff (2 samples, 0.02%) + + + +sort.rotate (2 samples, 0.02%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +reflect.Value.Addr (6 samples, 0.06%) + + + +bytes.(*Buffer).grow (51 samples, 0.51%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.(*mSpanStateBox).get (1 samples, 0.01%) + + + +encoding/base64.assemble64 (63 samples, 0.63%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.funcspdelta (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +aeshashbody (5 samples, 0.05%) + + + +encoding/json.(*scanner).pushParseState (2 samples, 0.02%) + + + +syscall.Open (4 samples, 0.04%) + + + +bytes.(*Reader).WriteTo (1 samples, 0.01%) + + + +os.statNolog (8 samples, 0.08%) + + + +internal/poll.ignoringEINTRIO (98 samples, 0.98%) + + + +regexp.(*inputs).init (1 samples, 0.01%) + + + +net/http.serveFile (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Tx).Commit (1 samples, 0.01%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +runtime.systemstack (27 samples, 0.27%) + + + +runtime.assertE2I2 (18 samples, 0.18%) + + + +reflect.add (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/scanner/ospkg.(*scanner).Scan (1 samples, 0.01%) + + + +runtime.(*spanSet).push (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetAdvisories (1 samples, 0.01%) + + + +encoding/json.stateBeginString (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*page).fastCheck (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/cve.BaseCveInfo.GetCVESummaryForImageMedia (8 samples, 0.08%) + + + +github.com/aquasecurity/trivy/pkg/scanner/langpkg.(*scanner).Scan (1 samples, 0.01%) + + + +encoding/json.stateInString (58 samples, 0.58%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +runtime.newarray (17 samples, 0.17%) + + + +fmt.newPrinter (3 samples, 0.03%) + + + +aeshashbody (3 samples, 0.03%) + + + +runtime.(*mheap).alloc (1 samples, 0.01%) + + + +runtime.printArgs (1 samples, 0.01%) + + + +reflect.cvtBytesString (24 samples, 0.24%) + + + +runtime.newobject (19 samples, 0.19%) + + + +zotregistry.io/zot/pkg/extensions/search/cve/trivy.Scanner.ScanImage (2 samples, 0.02%) + + + +path.Base (17 samples, 0.17%) + + + +reflect.Value.SetString (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (4,931 samples, 49.41%) +net/http.HandlerFunc.ServeHTTP + + +runtime.step (2 samples, 0.02%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +runtime.convT (6 samples, 0.06%) + + + +runtime.roundupsize (1 samples, 0.01%) + + + +runtime.hashGrow (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*page).fastCheck (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (91 samples, 0.91%) + + + +encoding/json.(*decodeState).unmarshal (927 samples, 9.29%) +encoding/json.. + + +runtime.funcspdelta (1 samples, 0.01%) + + + +reflect.(*rtype).Name (6 samples, 0.06%) + + + +net/http.HandlerFunc.ServeHTTP (3 samples, 0.03%) + + + +runtime.gcAssistAlloc.func1 (3 samples, 0.03%) + + + +net/http.HandlerFunc.ServeHTTP (4,930 samples, 49.40%) +net/http.HandlerFunc.ServeHTTP + + +runtime.makeSpanClass (1 samples, 0.01%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +zotregistry.io/zot/pkg/log.goroutineHook.Run (1 samples, 0.01%) + + + +runtime.wbBufFlush1 (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do (3 samples, 0.03%) + + + +memeqbody (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +runtime.(*mcache).refill (5 samples, 0.05%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +reflect.mapassign_faststr (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.Scan (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (1 samples, 0.01%) + + + +runtime.casgstatus (3 samples, 0.03%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1,293 samples, 12.96%) +encoding/json.(*dec.. + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +runtime.releasem (1 samples, 0.01%) + + + +reflect.(*rtype).Name (26 samples, 0.26%) + + + +encoding/json.stateInStringEscU1 (1 samples, 0.01%) + + + +reflect.ifaceIndir (1 samples, 0.01%) + + + +encoding/json.stateEndValue (1 samples, 0.01%) + + + +reflect.name.readVarint (5 samples, 0.05%) + + + +runtime.divRoundUp (4 samples, 0.04%) + + + +runtime.newobject (3 samples, 0.03%) + + + +github.com/opencontainers/go-digest.NewDigestFromEncoded (25 samples, 0.25%) + + + +runtime.(*mcentral).grow (4 samples, 0.04%) + + + +runtime.(*_type).typeOff (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func23 (3 samples, 0.03%) + + + +github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1 (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy-db/pkg/db.Config.GetVulnerability.func1 (2 samples, 0.02%) + + + +strings.IndexByte (2 samples, 0.02%) + + + +crypto.Hash.Size (3 samples, 0.03%) + + + +encoding/json.(*decodeState).rescanLiteral (58 samples, 0.58%) + + + +runtime.memclrNoHeapPointers (1 samples, 0.01%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +internal/poll.(*FD).Write (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +fmt.(*fmt).truncateString (1 samples, 0.01%) + + + +runtime.(*mcache).nextFree (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/scanner/langpkg.(*scanner).Scan (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*TxStats).IncCursorCount (1 samples, 0.01%) + + + +runtime.slicebytetostring (2 samples, 0.02%) + + + +os.(*File).Readdirnames (31 samples, 0.31%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).List (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.initializeArchiveScanner (1 samples, 0.01%) + + + +runtime.heapBitsSetType (1 samples, 0.01%) + + + +encoding/json.indirect (127 samples, 1.27%) + + + +reflect.MakeMap (1 samples, 0.01%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (1 samples, 0.01%) + + + +reflect.(*rtype).PkgPath (2 samples, 0.02%) + + + +os.(*file).close (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).CompareAndSwap (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (21 samples, 0.21%) + + + +runtime.heapBitsSetType (2 samples, 0.02%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/scheduler.(*generator).generate (2,972 samples, 29.78%) +zotregistry.io/zot/pkg/scheduler.(*generator).g.. + + +time.tzsetName (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/convert.updateImageSummaryVulnerabilities (3 samples, 0.03%) + + + +runtime.makeslice (2 samples, 0.02%) + + + +runtime.(*mcentral).cacheSpan (3 samples, 0.03%) + + + +github.com/containers/common/pkg/retry.RetryIfNecessary (119 samples, 1.19%) + + + +runtime.makeslice (19 samples, 0.19%) + + + +runtime.(*mcache).nextFree (4 samples, 0.04%) + + + +runtime.markBits.isMarked (1 samples, 0.01%) + + + +runtime.findObject (1 samples, 0.01%) + + + +syscall.Syscall6 (52 samples, 0.52%) + + + +runtime.assertE2I2 (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).GetNextDigestWithBlobPaths.func1 (4 samples, 0.04%) + + + +runtime.mapiternext (2 samples, 0.02%) + + + +reflect.convertOp (2 samples, 0.02%) + + + +runtime.mallocgc (5 samples, 0.05%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +time.tzset (2 samples, 0.02%) + + + +runtime.(*lfstack).pop (137 samples, 1.37%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +sort.StringSlice.Less (2 samples, 0.02%) + + + +syscall.Syscall (1 samples, 0.01%) + + + +github.com/opencontainers/go-digest.Algorithm.Size (9 samples, 0.09%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +sync.(*Map).Load (24 samples, 0.24%) + + + +runtime.mapaccess2_faststr (5 samples, 0.05%) + + + +crypto/sha256.(*digest).Write (62 samples, 0.62%) + + + +runtime.mallocgc (6 samples, 0.06%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +internal/poll.ignoringEINTRIO (3 samples, 0.03%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.SessionLogger.func1.1 (1 samples, 0.01%) + + + +runtime.roundupsize (4 samples, 0.04%) + + + +path.Clean (72 samples, 0.72%) + + + +encoding/json.(*decodeState).scanWhile (4 samples, 0.04%) + + + +syscall.Syscall (98 samples, 0.98%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +runtime.(*activeSweep).begin (4 samples, 0.04%) + + + +reflect.packEface (2 samples, 0.02%) + + + +encoding/json.(*decodeState).literalStore (9 samples, 0.09%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func2 (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/storage/local.fileInfo.IsDir (4 samples, 0.04%) + + + +go.etcd.io/bbolt.(*Tx).page (2 samples, 0.02%) + + + +os.fillFileStatFromSys (1 samples, 0.01%) + + + +reflect.name.data (1 samples, 0.01%) + + + +runtime.arenaIndex (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.Detect (1 samples, 0.01%) + + + +sync.(*Pool).pin (2 samples, 0.02%) + + + +runtime.duffcopy (4 samples, 0.04%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.gcTrigger.test (2 samples, 0.02%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +runtime.newMarkBits (9 samples, 0.09%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*Driver).Stat (13 samples, 0.13%) + + + +runtime.nextFreeFast (3 samples, 0.03%) + + + +runtime.lockWithRank (8 samples, 0.08%) + + + +runtime.(*consistentHeapStats).acquire (1 samples, 0.01%) + + + +reflect.(*rtype).ptrTo (3 samples, 0.03%) + + + +go.etcd.io/bbolt.(*page).fastCheck (1 samples, 0.01%) + + + +runtime.lockWithRankMayAcquire (1 samples, 0.01%) + + + +sort.Stable (182 samples, 1.82%) +s.. + + +github.com/aquasecurity/trivy/pkg/scanner/local.Scanner.Scan (2 samples, 0.02%) + + + +io.copyBuffer (1 samples, 0.01%) + + + +runtime.deductAssistCredit (3 samples, 0.03%) + + + +runtime/internal/atomic.(*Int64).Load (1 samples, 0.01%) + + + +runtime.removespecial (1 samples, 0.01%) + + + +runtime.gcResetMarkState (1 samples, 0.01%) + + + +runtime.(*mheap).allocMSpanLocked (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +time.(*Time).setLoc (1 samples, 0.01%) + + + +runtime.(*pageAlloc).scavenge.func1 (33 samples, 0.33%) + + + +runtime.mapaccess2_faststr (1 samples, 0.01%) + + + +runtime.(*mcache).refill (1 samples, 0.01%) + + + +runtime.memmove (1 samples, 0.01%) + + + +github.com/gorilla/handlers.recoveryHandler.ServeHTTP (3 samples, 0.03%) + + + +runtime.findObject (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/detector/ospkg.Detect (1 samples, 0.01%) + + + +runtime.growslice (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (254 samples, 2.55%) +en.. + + +encoding/json.(*decodeState).rescanLiteral (51 samples, 0.51%) + + + +syscall.Stat (10 samples, 0.10%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/commands/artifact.NewRunner (1 samples, 0.01%) + + + +runtime.slicebytetostring (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/meta/boltdb.(*BoltDB).SearchRepos.func1 (2,225 samples, 22.29%) +zotregistry.io/zot/pkg/meta/boltdb... + + +runtime.resettimer (1 samples, 0.01%) + + + +reflect.Value.Type (6 samples, 0.06%) + + + +time.isDigit[...] (9 samples, 0.09%) + + + +zotregistry.io/zot/pkg/storage/local.fileInfo.Path (1 samples, 0.01%) + + + +runtime.mallocgc (7 samples, 0.07%) + + + +os.(*File).Write (1 samples, 0.01%) + + + +encoding/json.(*scanner).pushParseState (1 samples, 0.01%) + + + +runtime.checkRunqsNoP (1 samples, 0.01%) + + + +encoding/json.(*scanner).popParseState (1 samples, 0.01%) + + + +runtime.(*mheap).initSpan (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func24 (3 samples, 0.03%) + + + +encoding/json.indirect (25 samples, 0.25%) + + + +os.newFile (4 samples, 0.04%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +runtime.getMCache (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime/internal/atomic.(*Uint32).Add (1 samples, 0.01%) + + + +runtime.mProf_Malloc (2 samples, 0.02%) + + + +encoding/json.stateInString (11 samples, 0.11%) + + + +runtime.unlock (2 samples, 0.02%) + + + +encoding/json.isSpace (1 samples, 0.01%) + + + +runtime.memmove (3 samples, 0.03%) + + + +runtime.makemap (1 samples, 0.01%) + + + +runtime.(*gcBits).bytep (61 samples, 0.61%) + + + +sort.symMerge (9 samples, 0.09%) + + + +encoding/json.indirect (69 samples, 0.69%) + + + +sort.rotate (3 samples, 0.03%) + + + +reflect.valueInterface (7 samples, 0.07%) + + + +github.com/aquasecurity/trivy/pkg/fanal/cache.FSCache.getBlob (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (12 samples, 0.12%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +os.direntReclen (1 samples, 0.01%) + + + +runtime.add (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (2 samples, 0.02%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.(*Driver).DetectVulnerabilities (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).pageNode (1 samples, 0.01%) + + + +runtime.divRoundUp (1 samples, 0.01%) + + + +runtime.mallocgc (1 samples, 0.01%) + + + +reflect.MakeSlice (15 samples, 0.15%) + + + +reflect.resolveTypeOff (1 samples, 0.01%) + + + +reflect.Value.OverflowInt (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 (4,930 samples, 49.40%) +zotregistry.io/zot/pkg/api.(*AuthnMiddleware).TryAuthnHandlers.func1.1 + + +reflect.Value.Set (12 samples, 0.12%) + + + +runtime.wbBufFlush.func1 (1 samples, 0.01%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +internal/poll.(*FD).destroy (3 samples, 0.03%) + + + +strconv.FormatInt (7 samples, 0.07%) + + + +encoding/json.unquoteBytes (5 samples, 0.05%) + + + +runtime.mapaccess1_fast32 (1 samples, 0.01%) + + + +encoding/json.stateBeginValue (1 samples, 0.01%) + + + +runtime.(*atomicMSpanPointer).Load (1 samples, 0.01%) + + + +runtime.(*pageAlloc).free (14 samples, 0.14%) + + + +runtime.(*mcache).nextFree (4 samples, 0.04%) + + + +runtime.strhash (1 samples, 0.01%) + + + +encoding/json.indirect (5 samples, 0.05%) + + + +os.readIntLE (2 samples, 0.02%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query.func24 (3 samples, 0.03%) + + + +runtime.arenaIdx.l1 (2 samples, 0.02%) + + + +reflect.Value.Set (2 samples, 0.02%) + + + +encoding/json.Unmarshal (1 samples, 0.01%) + + + +runtime.(*gcBitsArena).tryAlloc (1 samples, 0.01%) + + + +runtime.wbBufFlush.func1 (2 samples, 0.02%) + + + +runtime.funcspdelta (1 samples, 0.01%) + + + +runtime.evacuate_faststr (8 samples, 0.08%) + + + +reflect.Value.Set (4 samples, 0.04%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +runtime.systemstack (2 samples, 0.02%) + + + +runtime.divRoundUp (3 samples, 0.03%) + + + +runtime.spanSetSpinePointer.lookup (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (1 samples, 0.01%) + + + +runtime/internal/syscall.Syscall6 (5 samples, 0.05%) + + + +encoding/json.(*decodeState).value (1 samples, 0.01%) + + + +runtime.mallocgc (4 samples, 0.04%) + + + +zotregistry.io/zot/pkg/extensions/search/gql_generated.(*executionContext)._Query_GlobalSearch (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/executor.processExtensions.func4 (3 samples, 0.03%) + + + +runtime.(*lfstack).pop (176 samples, 1.76%) + + + +sync.(*Map).Load (1 samples, 0.01%) + + + +runtime.lock (1 samples, 0.01%) + + + +runtime.mallocgc (2 samples, 0.02%) + + + +path.(*lazybuf).append (4 samples, 0.04%) + + + +os.(*File).readdir (13 samples, 0.13%) + + + +runtime.mallocgc (3 samples, 0.03%) + + + +runtime.(*consistentHeapStats).acquire (1 samples, 0.01%) + + + +reflect.(*rtype).String (3 samples, 0.03%) + + + +runtime.lockWithRank (1 samples, 0.01%) + + + +github.com/aquasecurity/trivy/pkg/fanal/image.newImage (1 samples, 0.01%) + + + +memeqbody (4 samples, 0.04%) + + + +github.com/aquasecurity/trivy/pkg/vulnerability.Client.FillInfo (2 samples, 0.02%) + + + +reflect.(*rtype).ptrTo (2 samples, 0.02%) + + + +runtime.(*atomicSpanSetSpinePointer).Load (1 samples, 0.01%) + + + +reflect.name.data (1 samples, 0.01%) + + + +fmt.(*buffer).writeString (6 samples, 0.06%) + + + +runtime.callers (1 samples, 0.01%) + + + +internal/poll.(*FD).decref (3 samples, 0.03%) + + + +zotregistry.io/zot/pkg/storage/imagestore.(*ImageStore).GetNextDigestWithBlobPaths.func1 (116 samples, 1.16%) + + + +syscall.BytePtrFromString (1 samples, 0.01%) + + + +encoding/json.unquoteBytes (8 samples, 0.08%) + + + +encoding/json.(*decodeState).scanWhile (2 samples, 0.02%) + + + +runtime.gcWriteBarrierDX (1 samples, 0.01%) + + + +runtime.wbBufFlush (1 samples, 0.01%) + + + +runtime.markBits.setMarked (100 samples, 1.00%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (33 samples, 0.33%) + + + +reflect.Value.Field (1 samples, 0.01%) + + + +sync.(*Pool).pin (4 samples, 0.04%) + + + +reflect.makeString (1 samples, 0.01%) + + + +runtime.mapaccess2_faststr (6 samples, 0.06%) + + + +runtime.acquirem (1 samples, 0.01%) + + + +sort.swapRange (6 samples, 0.06%) + + + +github.com/aquasecurity/trivy/pkg/commands/operation.NewCache (1 samples, 0.01%) + + + +runtime.lockRankMayQueueFinalizer (1 samples, 0.01%) + + + +runtime.(*mcentral).grow (2 samples, 0.02%) + + + +encoding/json.(*scanner).popParseState (1 samples, 0.01%) + + + +fmt.(*buffer).writeString (1 samples, 0.01%) + + + +sort.StringSlice.Less (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1,292 samples, 12.95%) +encoding/json.(*dec.. + + +github.com/google/go-containerregistry/pkg/v1/layout.(*layoutIndex).Image (1 samples, 0.01%) + + + +runtime.systemstack (1 samples, 0.01%) + + + +sort.rotate (7 samples, 0.07%) + + + +runtime.(*mspan).init (1 samples, 0.01%) + + + +encoding/json.(*decodeState).rescanLiteral (5 samples, 0.05%) + + + +syscall.Stat (519 samples, 5.20%) +syscal.. + + +runtime/internal/atomic.(*Int64).Add (2 samples, 0.02%) + + + +fmt.(*pp).doPrintf (5 samples, 0.05%) + + + +go.etcd.io/bbolt.(*DB).View (2 samples, 0.02%) + + + +reflect.name.name (4 samples, 0.04%) + + + +runtime.gcMarkDone.func1.1 (1 samples, 0.01%) + + + +runtime.writeHeapBits.flush (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP (3 samples, 0.03%) + + + +runtime.(*mcentral).cacheSpan (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP (1 samples, 0.01%) + + + +net/http.HandlerFunc.ServeHTTP (4,931 samples, 49.41%) +net/http.HandlerFunc.ServeHTTP + + +runtime.slicebytetostring (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanWhile (4 samples, 0.04%) + + + +reflect.(*rtype).uncommon (1 samples, 0.01%) + + + +reflect.Value.Elem (3 samples, 0.03%) + + + +runtime.(*atomicMSpanPointer).StoreNoWB (1 samples, 0.01%) + + + +reflect.flag.kind (1 samples, 0.01%) + + + +runtime.resolveTypeOff (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/log.GoroutineID (1 samples, 0.01%) + + + +runtime.memclrNoHeapPointers (3 samples, 0.03%) + + + +encoding/json.stateEndValue (2 samples, 0.02%) + + + +regexp.(*Regexp).doOnePass (66 samples, 0.66%) + + + +os.Stat (639 samples, 6.40%) +os.Stat + + +runtime.profilealloc (1 samples, 0.01%) + + + +runtime.(*mcache).allocLarge (2 samples, 0.02%) + + + +encoding/json.(*decodeState).literalStore (5 samples, 0.05%) + + + +sync.(*Map).Load (3 samples, 0.03%) + + + +go.etcd.io/bbolt.(*Tx).page (2 samples, 0.02%) + + + +runtime.(*randomEnum).done (1 samples, 0.01%) + + + +runtime.mapaccess2 (8 samples, 0.08%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.gcWriteBarrierDX (1 samples, 0.01%) + + + +runtime.typedmemmove (1 samples, 0.01%) + + + +runtime.gcmarknewobject (1 samples, 0.01%) + + + +encoding/json.(*decodeState).scanNext (2 samples, 0.02%) + + + +runtime.profilealloc (1 samples, 0.01%) + + + +runtime.casgstatus (6 samples, 0.06%) + + + +runtime.(*mheap).allocSpan (1 samples, 0.01%) + + + +runtime.isSweepDone (1 samples, 0.01%) + + + +runtime.convT (1 samples, 0.01%) + + + +runtime.cmpstring (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +github.com/99designs/gqlgen/graphql/handler/transport.GET.Do (3 samples, 0.03%) + + + +runtime.arenaIdx.l2 (1 samples, 0.01%) + + + +reflect.name.name (9 samples, 0.09%) + + + +runtime.gcWriteBarrierCX (1 samples, 0.01%) + + + +zotregistry.io/zot/pkg/storage/local.(*fileWriter).Write (1 samples, 0.01%) + + + +go.etcd.io/bbolt.(*Bucket).CreateBucketIfNotExists (1 samples, 0.01%) + + + +runtime.lockWithRank (1 samples, 0.01%) + + + +reflect.(*rtype).exportedMethods (1 samples, 0.01%) + + + +encoding/json.(*decodeState).unmarshal (1 samples, 0.01%) + + + +encoding/json.(*decodeState).object (1 samples, 0.01%) + + + +runtime.unlock (3 samples, 0.03%) + + + +github.com/aquasecurity/trivy/pkg/detector/library.Detect (1 samples, 0.01%) + + + +github.com/knqyf263/go-deb-version.compare (2 samples, 0.02%) + + + + diff --git a/v2.0.2/assets/images/pull-image.jpg b/v2.0.2/assets/images/pull-image.jpg new file mode 100644 index 0000000..29ccec2 Binary files /dev/null and b/v2.0.2/assets/images/pull-image.jpg differ diff --git a/v2.0.2/assets/images/screen-initial.jpg b/v2.0.2/assets/images/screen-initial.jpg new file mode 100644 index 0000000..7857a23 Binary files /dev/null and b/v2.0.2/assets/images/screen-initial.jpg differ diff --git a/v2.0.2/assets/images/screen-layers.jpg b/v2.0.2/assets/images/screen-layers.jpg new file mode 100644 index 0000000..1cb20a1 Binary files /dev/null and b/v2.0.2/assets/images/screen-layers.jpg differ diff --git a/v2.0.2/assets/images/screen-tags.jpg b/v2.0.2/assets/images/screen-tags.jpg new file mode 100644 index 0000000..3953324 Binary files /dev/null and b/v2.0.2/assets/images/screen-tags.jpg differ diff --git a/v2.0.2/assets/images/screen-view-all.jpg b/v2.0.2/assets/images/screen-view-all.jpg new file mode 100644 index 0000000..cd74404 Binary files /dev/null and b/v2.0.2/assets/images/screen-view-all.jpg differ diff --git a/v2.0.2/assets/images/tile.jpg b/v2.0.2/assets/images/tile.jpg new file mode 100644 index 0000000..2ed8ab1 Binary files /dev/null and b/v2.0.2/assets/images/tile.jpg differ diff --git a/v2.0.2/assets/images/zot-logo-192x192.png b/v2.0.2/assets/images/zot-logo-192x192.png new file mode 100644 index 0000000..92ab98b Binary files /dev/null and b/v2.0.2/assets/images/zot-logo-192x192.png differ diff --git a/v2.0.2/assets/images/zot-logo-70x70.png b/v2.0.2/assets/images/zot-logo-70x70.png new file mode 100644 index 0000000..def5cd9 Binary files /dev/null and b/v2.0.2/assets/images/zot-logo-70x70.png differ diff --git a/v2.0.2/assets/javascripts/bundle.5cf534bf.min.js b/v2.0.2/assets/javascripts/bundle.5cf534bf.min.js new file mode 100644 index 0000000..eb0280e --- /dev/null +++ b/v2.0.2/assets/javascripts/bundle.5cf534bf.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Hi=Object.create;var xr=Object.defineProperty;var Pi=Object.getOwnPropertyDescriptor;var $i=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Ii=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty,an=Object.prototype.propertyIsEnumerable;var on=(e,t,r)=>t in e?xr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))Er.call(t,r)&&on(e,r,t[r]);if(kt)for(var r of kt(t))an.call(t,r)&&on(e,r,t[r]);return e};var sn=(e,t)=>{var r={};for(var n in e)Er.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&an.call(e,n)&&(r[n]=e[n]);return r};var Ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ji=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $i(t))!Er.call(e,o)&&o!==r&&xr(e,o,{get:()=>t[o],enumerable:!(n=Pi(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Hi(Ii(e)):{},ji(t||!e||!e.__esModule?xr(r,"default",{value:e,enumerable:!0}):r,e));var fn=Ht((wr,cn)=>{(function(e,t){typeof wr=="object"&&typeof cn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(wr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function f(O){var Ne=O.type,Ue=O.tagName;return!!(Ue==="INPUT"&&a[Ne]&&!O.readOnly||Ue==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function c(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function u(O){O.hasAttribute("data-focus-visible-added")&&(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(s(r.activeElement)&&c(r.activeElement),n=!0)}function m(O){n=!1}function d(O){s(O.target)&&(n||f(O.target))&&c(O.target)}function h(O){s(O.target)&&(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(O.target))}function v(O){document.visibilityState==="hidden"&&(o&&(n=!0),B())}function B(){document.addEventListener("mousemove",V),document.addEventListener("mousedown",V),document.addEventListener("mouseup",V),document.addEventListener("pointermove",V),document.addEventListener("pointerdown",V),document.addEventListener("pointerup",V),document.addEventListener("touchmove",V),document.addEventListener("touchstart",V),document.addEventListener("touchend",V)}function re(){document.removeEventListener("mousemove",V),document.removeEventListener("mousedown",V),document.removeEventListener("mouseup",V),document.removeEventListener("pointermove",V),document.removeEventListener("pointerdown",V),document.removeEventListener("pointerup",V),document.removeEventListener("touchmove",V),document.removeEventListener("touchstart",V),document.removeEventListener("touchend",V)}function V(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,re())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),B(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var un=Ht(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},a=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(re,V){d.append(V,re)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+c+" due to "+O)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,B=!0,re=this;["append","delete","set"].forEach(function(O){var Ne=h[O];h[O]=function(){Ne.apply(h,arguments),v&&(B=!1,re.search=h.toString(),B=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var V=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==V&&(V=this.search,B&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},a=i.prototype,s=function(f){Object.defineProperty(a,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){s(f)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr)});var Qr=Ht((Lt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Lt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Lt=="object"?Lt.ClipboardJS=r():t.ClipboardJS=r()})(Lt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return ki}});var a=i(279),s=i.n(a),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(F){try{return document.execCommand(F)}catch(T){return!1}}var d=function(T){var w=p()(T);return m("cut"),w},h=d;function v(F){var T=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[T?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(k,"px"),w.setAttribute("readonly",""),w.value=F,w}var B=function(T,w){var k=v(T);w.container.appendChild(k);var j=p()(k);return m("copy"),k.remove(),j},re=function(T){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof T=="string"?k=B(T,w):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?k=B(T.value,w):(k=p()(T),m("copy")),k},V=re;function O(F){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(w){return typeof w}:O=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},O(F)}var Ne=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=T.action,k=w===void 0?"copy":w,j=T.container,N=T.target,Me=T.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(N!==void 0)if(N&&O(N)==="object"&&N.nodeType===1){if(k==="copy"&&N.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(N.hasAttribute("readonly")||N.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return V(Me,{container:j});if(N)return k==="cut"?h(N):V(N,{container:j})},Ue=Ne;function $e(F){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(w){return typeof w}:$e=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},$e(F)}function Oi(F,T){if(!(F instanceof T))throw new TypeError("Cannot call a class as a function")}function nn(F,T){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof j.action=="function"?j.action:this.defaultAction,this.target=typeof j.target=="function"?j.target:this.defaultTarget,this.text=typeof j.text=="function"?j.text:this.defaultText,this.container=$e(j.container)==="object"?j.container:document.body}},{key:"listenClick",value:function(j){var N=this;this.listener=c()(j,"click",function(Me){return N.onClick(Me)})}},{key:"onClick",value:function(j){var N=j.delegateTarget||j.currentTarget,Me=this.action(N)||"copy",Rt=Ue({action:Me,container:this.container,target:this.target(N),text:this.text(N)});this.emit(Rt?"success":"error",{action:Me,text:Rt,trigger:N,clearSelection:function(){N&&N.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(j){return yr("action",j)}},{key:"defaultTarget",value:function(j){var N=yr("target",j);if(N)return document.querySelector(N)}},{key:"defaultText",value:function(j){return yr("text",j)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(j){var N=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return V(j,N)}},{key:"cut",value:function(j){return h(j)}},{key:"isSupported",value:function(){var j=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],N=typeof j=="string"?[j]:j,Me=!!document.queryCommandSupported;return N.forEach(function(Rt){Me=Me&&!!document.queryCommandSupported(Rt)}),Me}}]),w}(s()),ki=Ri},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,f){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(f))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?s.apply(null,arguments):typeof m=="function"?s.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return s(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(m))return c(m,d,h);if(a.nodeList(m))return u(m,d,h);if(a.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return s(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),a=f.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var f=this;function c(){f.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=s.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var is=/["'&<>]/;Jo.exports=as;function as(e){var t=""+e,r=is.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],a;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(a)throw a.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||s(m,d)})})}function s(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof Xe?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){s("next",m)}function u(m){s("throw",m)}function p(m,d){m(d),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof xe=="function"?xe(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(a){return new Promise(function(s,f){a=e[i](a),o(s,f,a.done,a.value)})}}function o(i,a,s,f){Promise.resolve(f).then(function(c){i({value:c,done:s})},a)}}function A(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var $t=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function We(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=xe(a),f=s.next();!f.done;f=s.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var u=this.initialTeardown;if(A(u))try{u()}catch(v){i=v instanceof $t?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=xe(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{dn(h)}catch(v){i=i!=null?i:[],v instanceof $t?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new $t(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)dn(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&We(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&We(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=Ie.EMPTY;function It(e){return e instanceof Ie||e&&"closed"in e&&A(e.remove)&&A(e.add)&&A(e.unsubscribe)}function dn(e){A(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new Ie(function(){n.currentObservers=null,We(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new U;return r.source=this,r},t.create=function(r,n){return new wn(r,n)},t}(U);var wn=function(e){ne(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Tr},t}(E);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ne(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,f=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var a=r.actions;n!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Ut);var Tn=function(e){ne(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var we=new Tn(On);var R=new U(function(e){return e.complete()});function Dt(e){return e&&A(e.schedule)}function kr(e){return e[e.length-1]}function qe(e){return A(kr(e))?e.pop():void 0}function Se(e){return Dt(kr(e))?e.pop():void 0}function Vt(e,t){return typeof kr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return A(e==null?void 0:e.then)}function Nt(e){return A(e[ft])}function qt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ki(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qt=Ki();function Yt(e){return A(e==null?void 0:e[Qt])}function Gt(e){return ln(this,arguments,function(){var r,n,o,i;return Pt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Xe(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Xe(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Xe(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return A(e==null?void 0:e.getReader)}function $(e){if(e instanceof U)return e;if(e!=null){if(Nt(e))return Qi(e);if(pt(e))return Yi(e);if(zt(e))return Gi(e);if(qt(e))return _n(e);if(Yt(e))return Bi(e);if(Bt(e))return Ji(e)}throw Kt(e)}function Qi(e){return new U(function(t){var r=e[ft]();if(A(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Yi(e){return new U(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?M(function(o,i){return e(o,i,n)}):me,Te(1),r?ke(t):zn(function(){return new Xt}))}}function Nn(){for(var e=[],t=0;t=2,!0))}function fe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,f=s===void 0?!0:s;return function(c){var u,p,m,d=0,h=!1,v=!1,B=function(){p==null||p.unsubscribe(),p=void 0},re=function(){B(),u=m=void 0,h=v=!1},V=function(){var O=u;re(),O==null||O.unsubscribe()};return g(function(O,Ne){d++,!v&&!h&&B();var Ue=m=m!=null?m:r();Ne.add(function(){d--,d===0&&!v&&!h&&(p=Fr(V,f))}),Ue.subscribe(Ne),!u&&d>0&&(u=new et({next:function($e){return Ue.next($e)},error:function($e){v=!0,B(),p=Fr(re,o,$e),Ue.error($e)},complete:function(){h=!0,B(),p=Fr(re,a),Ue.complete()}}),$(O).subscribe(u))})(c)}}function Fr(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function q(e,t=document){let r=se(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function se(e,t=document){return t.querySelector(e)||void 0}function je(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(Re(1),l(()=>{let t=je();return typeof t!="undefined"?e.contains(t):!1}),z(e===je()),Y())}function Ye(e){return{x:e.offsetLeft,y:e.offsetTop}}function Yn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ae(0,we),l(()=>Ye(e)),z(Ye(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ae(0,we),l(()=>rr(e)),z(rr(e)))}var Bn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),xa?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ya.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Jn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Zn=typeof WeakMap!="undefined"?new WeakMap:new Bn,eo=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Ea.getInstance(),n=new Ra(t,r,this);Zn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){eo.prototype[e]=function(){var t;return(t=Zn.get(this))[e].apply(t,arguments)}});var ka=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:eo}(),to=ka;var ro=new E,Ha=I(()=>H(new to(e=>{for(let t of e)ro.next(t)}))).pipe(x(e=>L(Oe,H(e)).pipe(C(()=>e.disconnect()))),J(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){return Ha.pipe(S(t=>t.observe(e)),x(t=>ro.pipe(M(({target:r})=>r===e),C(()=>t.unobserve(e)),l(()=>de(e)))),z(de(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var no=new E,Pa=I(()=>H(new IntersectionObserver(e=>{for(let t of e)no.next(t)},{threshold:0}))).pipe(x(e=>L(Oe,H(e)).pipe(C(()=>e.disconnect()))),J(1));function sr(e){return Pa.pipe(S(t=>t.observe(e)),x(t=>no.pipe(M(({target:r})=>r===e),C(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function oo(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=de(e),o=bt(e);return r>=o.height-n.height-t}),Y())}var cr={drawer:q("[data-md-toggle=drawer]"),search:q("[data-md-toggle=search]")};function io(e){return cr[e].checked}function Ge(e,t){cr[e].checked!==t&&cr[e].click()}function Be(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),z(t.checked))}function $a(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ia(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(z(!1))}function ao(){let e=b(window,"keydown").pipe(M(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:io("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),M(({mode:t,type:r})=>{if(t==="global"){let n=je();if(typeof n!="undefined")return!$a(n,r)}return!0}),fe());return Ia().pipe(x(t=>t?R:e))}function _e(){return new URL(location.href)}function ot(e){location.href=e.href}function so(){return new E}function co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)co(e,r)}function _(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)co(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function fo(){return location.hash.substring(1)}function uo(e){let t=_("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function ja(){return b(window,"hashchange").pipe(l(fo),z(fo()),M(e=>e.length>0),J(1))}function po(){return ja().pipe(l(e=>se(`[id="${e}"]`)),M(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(z(t.matches))}function lo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(z(e.matches))}function qr(e,t){return e.pipe(x(r=>r?t():R))}function ur(e,t={credentials:"same-origin"}){return ve(fetch(`${e}`,t)).pipe(ce(()=>R),x(r=>r.status!==200?Ot(()=>new Error(r.statusText)):H(r)))}function Fe(e,t){return ur(e,t).pipe(x(r=>r.json()),J(1))}function mo(e,t){let r=new DOMParser;return ur(e,t).pipe(x(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),J(1))}function pr(e){let t=_("script",{src:e});return I(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(x(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),C(()=>document.head.removeChild(t)),Te(1))))}function ho(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function bo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(ho),z(ho()))}function vo(){return{width:innerWidth,height:innerHeight}}function go(){return b(window,"resize",{passive:!0}).pipe(l(vo),z(vo()))}function yo(){return Q([bo(),go()]).pipe(l(([e,t])=>({offset:e,size:t})),J(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(X("size")),o=Q([n,r]).pipe(l(()=>Ye(e)));return Q([r,t,o]).pipe(l(([{height:i},{offset:a,size:s},{x:f,y:c}])=>({offset:{x:a.x-f,y:a.y-c+i},size:s})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(a=>{let s=document.createElement("script");s.src=i,s.onload=a,document.body.appendChild(s)})),Promise.resolve())}var r=class{constructor(n){this.url=n,this.onerror=null,this.onmessage=null,this.onmessageerror=null,this.m=a=>{a.source===this.w&&(a.stopImmediatePropagation(),this.dispatchEvent(new MessageEvent("message",{data:a.data})),this.onmessage&&this.onmessage(a))},this.e=(a,s,f,c,u)=>{if(s===this.url.toString()){let p=new ErrorEvent("error",{message:a,filename:s,lineno:f,colno:c,error:u});this.dispatchEvent(p),this.onerror&&this.onerror(p)}};let o=new EventTarget;this.addEventListener=o.addEventListener.bind(o),this.removeEventListener=o.removeEventListener.bind(o),this.dispatchEvent=o.dispatchEvent.bind(o);let i=document.createElement("iframe");i.width=i.height=i.frameBorder="0",document.body.appendChild(this.iframe=i),this.w.document.open(),this.w.document.write(`

zot API Command Reference

👉 This article describes the zot REST API commands, parameters, and responses.

The information presented here is adapted from the interactive OpenAPI (formerly swagger) JSON file in the zot Github project.

For instructions and examples of how to use the zot API, see Using the zot API.

/zot/auth/apikey

DELETE /zot/auth/apikey

Revokes one current user API key based on given key ID

Parameters

Name In Type Required Description
id query string true api token id (UUID)

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
400 Bad Request bad request string
401 Unauthorized unauthorized string
500 Internal Server Error internal server error string

This operation does not require authentication

GET /zot/auth/apikey

Get list of all API keys for a logged in user

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
401 Unauthorized unauthorized string
500 Internal Server Error internal server error string

This operation does not require authentication

POST /zot/auth/apikey

Can create an api key for a logged in user, based on the provided label and scopes.

Body parameter

{
+  "expirationDate": "string",
+  "label": "string",
+  "scopes": [
+    "string"
+  ]
+}
+

Parameters

Name In Type Required Description
body body api.APIKeyPayload true api token id (UUID)

Example responses

201 Response

"string"
+

Responses

Status Meaning Description Schema
201 Created created string
400 Bad Request bad request string
401 Unauthorized unauthorized string
500 Internal Server Error internal server error string

This operation does not require authentication

/zot/auth/logout

POST /zot/auth/logout

Logout by removing current session

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok". string
500 Internal Server Error internal server error". string

This operation does not require authentication

/oras/artifacts/v1/{name}/manifests/{digest}/referrers

GET /oras/artifacts/v1/{name}/manifests/{digest}/referrers

Get references for an image given a digest and artifact type

Parameters

Name In Type Required Description
name path string true repository name
digest path string true image digest
artifactType query string true artifact type

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/

GET /v2/

Check if this API version is supported

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok". string

This operation does not require authentication

/v2/_catalog

GET /v2/_catalog

List all image repositories

Example responses

200 Response

{
+  "repositories": [
+    "string"
+  ]
+}
+

Responses

Status Meaning Description Schema
200 OK OK api.RepositoryList
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/_oci/ext/discover

GET /v2/_oci/ext/discover

List all extensions present on registry

Example responses

200 Response

{
+  "extensions": [
+    {
+      "description": "string",
+      "endpoints": [
+        "string"
+      ],
+      "name": "string",
+      "url": "string"
+    }
+  ]
+}
+

Responses

Status Meaning Description Schema
200 OK OK api.ExtensionList

This operation does not require authentication

/v2/_zot/ext/cosign

POST /v2/_zot/ext/cosign

Upload cosign public keys for verifying signatures

Body parameter

string
+

Parameters

Name In Type Required Description
body body string true Public key content

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
400 Bad Request bad request". string
500 Internal Server Error internal server error". string

This operation does not require authentication

/v2/_zot/ext/mgmt

GET /v2/_zot/ext/mgmt

Get current server configuration

Parameters

Name In Type Required Description
resource query string false specify resource

Enumerated Values

Parameter Value
resource config

Example responses

200 Response

{
+  "binaryType": "string",
+  "distSpecVersion": "string",
+  "http": {
+    "auth": {
+      "bearer": {
+        "realm": "string",
+        "service": "string"
+      },
+      "htpasswd": {
+        "path": "string"
+      },
+      "ldap": {
+        "address": "string"
+      },
+      "openid": {
+        "providers": {
+          "property1": {
+            "name": "string"
+          },
+          "property2": {
+            "name": "string"
+          }
+        }
+      }
+    }
+  }
+}
+

Responses

Status Meaning Description Schema
200 OK OK extensions.StrippedConfig
500 Internal Server Error internal server error". string

This operation does not require authentication

/v2/_zot/ext/notation

POST /v2/_zot/ext/notation

Upload notation certificates for verifying signatures

Body parameter

string
+

Parameters

Name In Type Required Description
truststoreType query string false truststore type
body body string true Certificate content

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
400 Bad Request bad request". string
500 Internal Server Error internal server error". string

This operation does not require authentication

/v2/_zot/ext/userprefs

PUT /v2/_zot/ext/userprefs

Add bookmarks/stars info

Parameters

Name In Type Required Description
action query string true specify action
repo query string true repository name

Enumerated Values

Parameter Value
action toggleBookmark
action toggleStar

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
400 Bad Request bad request". string
403 Forbidden forbidden string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/{name}/blobs/{digest}

DELETE /v2/{name}/blobs/{digest}

Delete an image's blob/layer given a digest

Parameters

Name In Type Required Description
name path string true repository name
digest path string true blob/layer digest

Example responses

202 Response

"string"
+

Responses

Status Meaning Description Schema
202 Accepted accepted string

This operation does not require authentication

GET /v2/{name}/blobs/{digest}

Get an image's blob/layer given a digest

Parameters

Name In Type Required Description
name path string true repository name
digest path string true blob/layer digest

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK OK api.ImageManifest

This operation does not require authentication

HEAD /v2/{name}/blobs/{digest}

Check an image's blob/layer given a digest

Parameters

Name In Type Required Description
name path string true repository name
digest path string true blob/layer digest

Example responses

200 Response

{
+  "annotations": {
+    "property1": "string",
+    "property2": "string"
+  },
+  "artifactType": "string",
+  "config": {
+    "annotations": {
+      "property1": "string",
+      "property2": "string"
+    },
+    "artifactType": "string",
+    "data": [
+      0
+    ],
+    "digest": "string",
+    "mediaType": "string",
+    "platform": {
+      "architecture": "string",
+      "os": "string",
+      "os.features": [
+        "string"
+      ],
+      "os.version": "string",
+      "variant": "string"
+    },
+    "size": 0,
+    "urls": [
+      "string"
+    ]
+  },
+  "layers": [
+    {
+      "annotations": {
+        "property1": "string",
+        "property2": "string"
+      },
+      "artifactType": "string",
+      "data": [
+        0
+      ],
+      "digest": "string",
+      "mediaType": "string",
+      "platform": {
+        "architecture": "string",
+        "os": "string",
+        "os.features": [
+          "string"
+        ],
+        "os.version": "string",
+        "variant": "string"
+      },
+      "size": 0,
+      "urls": [
+        "string"
+      ]
+    }
+  ],
+  "mediaType": "string",
+  "schemaVersion": 0,
+  "subject": {
+    "annotations": {
+      "property1": "string",
+      "property2": "string"
+    },
+    "artifactType": "string",
+    "data": [
+      0
+    ],
+    "digest": "string",
+    "mediaType": "string",
+    "platform": {
+      "architecture": "string",
+      "os": "string",
+      "os.features": [
+        "string"
+      ],
+      "os.version": "string",
+      "variant": "string"
+    },
+    "size": 0,
+    "urls": [
+      "string"
+    ]
+  }
+}
+

Responses

Status Meaning Description Schema
200 OK OK api.ImageManifest

Response Headers

Status Header Type Format Description
200 constants.DistContentDigestKey object none

This operation does not require authentication

/v2/{name}/blobs/uploads

POST /v2/{name}/blobs/uploads

Create a new image blob/layer upload

Parameters

Name In Type Required Description
name path string true repository name

Example responses

202 Response

"string"
+

Responses

Status Meaning Description Schema
202 Accepted accepted string
401 Unauthorized unauthorized string
404 Not Found not found string
500 Internal Server Error internal server error string

Response Headers

Status Header Type Format Description
202 Location string /v2/{name}/blobs/uploads/{session_id}
202 Range string 0-0

This operation does not require authentication

/v2/{name}/blobs/uploads/{session_id}

DELETE /v2/{name}/blobs/uploads/{session_id}

Delete an image's blob/layer given a digest

Parameters

Name In Type Required Description
name path string true repository name
session_id path string true upload session_id

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

GET /v2/{name}/blobs/uploads/{session_id}

*Get an image's blob/layer upload given a session_id

Parameters

Name In Type Required Description
name path string true repository name
session_id path string true upload session_id

Example responses

204 Response

"string"
+

Responses

Status Meaning Description Schema
204 No Content no content string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

PATCH /v2/{name}/blobs/uploads/{session_id}

Resume an image's blob/layer upload given an session_id

Parameters

Name In Type Required Description
name path string true repository name
session_id path string true upload session_id

Example responses

202 Response

"string"
+

Responses

Status Meaning Description Schema
202 Accepted accepted string
400 Bad Request bad request string
404 Not Found not found string
416 Range Not Satisfiable range not satisfiable string
500 Internal Server Error internal server error string

Response Headers

Status Header Type Format Description
202 Location string /v2/{name}/blobs/uploads/{session_id}
202 Range string 0-128

This operation does not require authentication

PUT /v2/{name}/blobs/uploads/{session_id}

Update and finish an image's blob/layer upload given a digest

Parameters

Name In Type Required Description
name path string true repository name
session_id path string true upload session_id
digest query string true blob/layer digest

Example responses

201 Response

"string"
+

Responses

Status Meaning Description Schema
201 Created created string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/{name}/manifests/{reference}

DELETE /v2/{name}/manifests/{reference}

Delete an image's manifest given a reference or a digest

Parameters

Name In Type Required Description
name path string true repository name
reference path string true image reference or digest

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string

This operation does not require authentication

GET /v2/{name}/manifests/{reference}

Get an image's manifest given a reference or a digest

Parameters

Name In Type Required Description
name path string true repository name
reference path string true image reference or digest

Example responses

200 Response

{
+  "annotations": {
+    "property1": "string",
+    "property2": "string"
+  },
+  "artifactType": "string",
+  "config": {
+    "annotations": {
+      "property1": "string",
+      "property2": "string"
+    },
+    "artifactType": "string",
+    "data": [
+      0
+    ],
+    "digest": "string",
+    "mediaType": "string",
+    "platform": {
+      "architecture": "string",
+      "os": "string",
+      "os.features": [
+        "string"
+      ],
+      "os.version": "string",
+      "variant": "string"
+    },
+    "size": 0,
+    "urls": [
+      "string"
+    ]
+  },
+  "layers": [
+    {
+      "annotations": {
+        "property1": "string",
+        "property2": "string"
+      },
+      "artifactType": "string",
+      "data": [
+        0
+      ],
+      "digest": "string",
+      "mediaType": "string",
+      "platform": {
+        "architecture": "string",
+        "os": "string",
+        "os.features": [
+          "string"
+        ],
+        "os.version": "string",
+        "variant": "string"
+      },
+      "size": 0,
+      "urls": [
+        "string"
+      ]
+    }
+  ],
+  "mediaType": "string",
+  "schemaVersion": 0,
+  "subject": {
+    "annotations": {
+      "property1": "string",
+      "property2": "string"
+    },
+    "artifactType": "string",
+    "data": [
+      0
+    ],
+    "digest": "string",
+    "mediaType": "string",
+    "platform": {
+      "architecture": "string",
+      "os": "string",
+      "os.features": [
+        "string"
+      ],
+      "os.version": "string",
+      "variant": "string"
+    },
+    "size20": 0,
+    "urls": [
+      "string"
+    ]
+  }
+}
+

Responses

Status Meaning Description Schema
200 OK OK api.ImageManifest
404 Not Found not found string
500 Internal Server Error internal server error string

Response Headers

Status Header Type Format Description
200 constants.DistContentDigestKey object none

This operation does not require authentication

HEAD /v2/{name}/manifests/{reference}

Check an image's manifest given a reference or a digest

Parameters

Name In Type Required Description
name path string true repository name
reference path string true image reference or digest

Example responses

200 Response

"string"
+

Responses

Status Meaning Description Schema
200 OK ok string
404 Not Found not found string
500 Internal Server Error internal server error". string

Response Headers

Status Header Type Format Description
200 constants.DistContentDigestKey object none

This operation does not require authentication

PUT /v2/{name}/manifests/{reference}

Update an image's manifest given a reference or a digest

Parameters

Name In Type Required Description
name path string true repository name
reference path string true image reference or digest

Example responses

201 Response

"string"
+

Responses

Status Meaning Description Schema
201 Created created string
400 Bad Request bad request string
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/{name}/referrers/{digest}

GET /v2/{name}/referrers/{digest}

Get referrers given a digest

Parameters

Name In Type Required Description
name path string true repository name
digest path string true digest
artifactType query string false artifact type

Example responses

200 Response

{
+  "annotations": {
+    "property1": "string",
+    "property2": "string"
+  },
+  "artifactType": "string",
+  "manifests": [
+    {
+      "annotations": {
+        "property1": "string",
+        "property2": "string"
+      },
+      "artifactType": "string",
+      "data": [
+        0
+      ],
+      "digest": "string",
+      "mediaType": "string",
+      "platform": {
+        "architecture": "string",
+        "os": "string",
+        "os.features": [
+          "string"
+        ],
+        "os.version": "string",
+        "variant": "string"
+      },
+      "size": 0,
+      "urls": [
+        "string"
+      ]
+    }
+  ],
+  "mediaType": "string",
+  "schemaVersion": 0,
+  "subject": {
+    "annotations": {
+      "property1": "string",
+      "property2": "string"
+    },
+    "artifactType": "string",
+    "data": [
+      0
+    ],
+    "digest": "string",
+    "mediaType": "string",
+    "platform": {
+      "architecture": "string",
+      "os": "string",
+      "os.features": [
+        "string"
+      ],
+      "os.version": "string",
+      "variant": "string"
+    },
+    "size": 0,
+    "urls": [
+      "string"
+    ]
+  }
+}
+

Responses

Status Meaning Description Schema
200 OK OK api.ImageIndex
404 Not Found not found string
500 Internal Server Error internal server error string

This operation does not require authentication

/v2/{name}/tags/list

GET /v2/{name}/tags/list

List all image tags in a repository

Parameters

Name In Type Required Description
name path string true repository name
n query integer true limit entries for pagination
last query string true last tag value for pagination

Example responses

200 Response

{
+  "name": "string",
+  "tags": [
+    "string"
+  ]
+}
+

Responses

Status Meaning Description Schema
200 OK OK common.ImageTags
400 Bad Request bad request". string
404 Not Found not found string

This operation does not require authentication


Last update: November 17, 2023
\ No newline at end of file diff --git a/v2.0.2/developer-guide/api-user-guide/index.html b/v2.0.2/developer-guide/api-user-guide/index.html new file mode 100644 index 0000000..b957856 --- /dev/null +++ b/v2.0.2/developer-guide/api-user-guide/index.html @@ -0,0 +1,77 @@ + Using the API - zotregistry.dev

Using the zot API

👉 This document describes how to use the zot REST API and provides a number of examples.

For comprehensive details of all zot API commands, see Viewing the complete zot API reference.

The zot API implements the OCI Distribution endpoints along with additional endpoints for supported extensions. You can access the REST API at the same URL and port number used by the GUI and by datapath tools.

✏ The examples in this article assume that the zot registry is located at localhost:8080.

Supported API endpoints

The following is a list of zot API endpoints along with the conditions under which each endpoint is available.

✏ Some API endpoints are available only when a specific extension is enabled in the zot configuration file, or when an extension build label is specified in the make command (for example, make binary EXTENSIONS=ui), or both.

For comprehensive details of the API endpoints, see Viewing the complete zot API reference.

OCI endpoints

Endpoint Actions Description
/v2/ GET OCI specification endpoints
/v2/_catalog GET Lists repositories in a registry.
/v2/_oci/ext/discover GET Discover extensions per the OCI specification
/v2/{repo}/blobs/{digest} DELETE, GET, HEAD Lists or deletes an image's blob/layer given a digest
/v2/{repo}/blobs/uploads POST Creates an image blob/layer upload
/v2/{repo}/blobs/uploads/{session_id} DELETE, GET, PATCH, PUT Creates, lists, or deletes an image's blob/layer upload given a session_id
/v2/{repo}/manifests/{reference} DELETE, GET, HEAD, PUT Creates, lists, or deletes references for an image
/v2/{repo}/referrers/{digest} GET Lists referrers given a digest
/v2/{repo}/tags/list GET List all image tags in a repository

zot OCI extension endpoints

Endpoint Actions Description Availability
/v2/_zot/ext/mgmt GET Mgmt extension endpoints Enabled by using the mgmt build label and enabling the search extension in the configuration file.
/v2/_zot/ext/notation POST With query parameters, uploads certificates for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the notation option enabled.
/v2/_zot/ext/search Enhanced search Enabled by using the search build label and enabling the search extension in the configuration file.
/v2/_zot/ext/cosign POST Uploads keys for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the cosign option enabled.
/v2/_zot/ext/userprefs PUT User preferences endpoints Enabled by using the userprefs build label and enabling both the search and the ui extensions in the configuration file.

zot auth endpoints

Endpoint Actions Description Availability
/zot/auth/apikey DELETE, GET, POST Creates, lists, or deletes API keys Available when API key authentication is enabled in the configuration file ("apikey": true).
/zot/auth/login POST Opens an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication.
/zot/auth/logout POST Ends an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication.
/zot/auth/callback/\<provider> POST Specifies a social authentication service provider for redirecting logins, such as Google or dex. Enabled when an OpenID authentication service provider is specified in the configuration file.

other zot endpoints

Endpoint Actions Description Availability
/v2/_zot/pprof/ GET Returns a current HTML-format profile list along with a count of currently available records for each profile. See Performance Profiling in zot for usage details. Always enabled.
/v2/_zot/debug/graphql-playground# See Using GraphQL for details. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label.

ORAS endpoints

Endpoint Actions Description Availability
/oras/artifacts/v1/{repo}/ manifests/{digest}/referrers GET OCI Registry As Storage (ORAS) endpoints Always enabled.

prometheus endpoint

Endpoint Actions Description Availability
/metrics GET Returns extended metrics for monitoring by prometheus Enabled when the metrics extension is enabled in the configuration file.

OpenAPI (swagger) endpoints

✏ This endpoint is accessed with a browser.

Endpoint Action Description Availability
/swagger/v2/ (browser) Displays an interactive OpenAPI (swagger) API reference. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label.

API authentication

✏ If zot authentication is not configured, any user can access the zot API.

When pushing and pulling images using API calls, your identity can be authenticated by either a password or an API key.

With a valid password, you can specify your credentials in a cURL request as shown in this example:

curl -u <user>:<password> -X GET http://<server>/<endpoint>
+

An API key has advantages in situations where the primary zot authentication does not use the command line, such as a GUI login or social login. Also, you can reduce your security exposure by using an API key instead of your broader credentials, such as an LDAP username and password.

Using API keys

Enabling API keys

To enable the use of API keys, you must set the apikey attribute to true in the zot configuration file, as shown in the following example:

  "http": {
+    "auth": {
+      "apikey": true
+    }
+  }
+

Creating your API key

Before you can create or revoke an API key, you must first log in using a different authentication mechanism, such as logging in through the zot GUI. When you are logged in, you can create an API key for your identity using the following API command:

POST /zot/auth/apikey
+

cURL command example:

curl -u user:password -X POST http://localhost:8080/zot/auth/apikey -d '{"label": "myAPIKEY", "scopes": ["repo1", "repo2"], "expirationDate": "2023-08-28T17:10:05+03:00"}'
+

✏ The scopes and expiration date in this example are optional. By default, an API key has the same permissions as the user who created it.

Command output:

{
+  "createdAt":"2023-08-28T17:09:59.2603515+03:00",
+  "expirationDate":"2023-08-28T17:10:05+03:00",
+  "isExpired":false,
+  "creatorUa":"curl/7.68.0",
+  "generatedBy":"manual",
+  "lastUsed":"0001-01-01T00:00:00Z",
+  "label":"myAPIKEY",
+  "scopes": [
+    "repo1",
+    "repo2"
+  ],
+  "uuid":"c931e635-a80d-4b52-b035-6b57be5f6e74",
+  "apiKey":"zak_ac55a8693d6b4370a2003fa9e10b3682"
+}
+

✏ The API key (apiKey) is shown to the user only in the command output when the key is created. It cannot be later retrieved from zot with any other command.

Using your API key in an API command

The API key replaces a password in the API command, as shown in the following cURL example:

curl -u user:zak_e77bcb9e9f634f1581756abbf9ecd269 http://localhost:8080/v2/_catalog
+

Removing your API key

When logged in, you can revoke your own API key with the following API command:

DELETE /zot/auth/apikey?id=$uuid
+

cURL command example:

curl -u user:password -X DELETE http://localhost:8080/v2/zot/auth/apikey?id=46a45ce7-5d92-498a-a9cb-9654b1da3da1
+

Listing your current API keys

When logged in, you can display a list of your API keys with the following API command:

GET /zot/auth/apikey
+

cURL command example:

curl -u user:password -X GET http://localhost:8080/zot/auth/apikey
+

Command output:

{
+  "apiKeys": [
+    {
+      "createdAt": "2023-05-05T15:39:28.420926+03:00",
+      "expirationDate": "0001-01-01T00:00:00Z",
+      "isExpired": true,
+      "creatorUa": "curl/7.68.0",
+      "generatedBy": "manual",
+      "lastUsed": "0001-01-01T00:00:00Z",
+      "label": "git",
+      "scopes": [
+        "repo1",
+        "repo2"
+      ],
+      "uuid": "46a45ce7-5d92-498a-a9cb-9654b1da3da1"
+    },
+    {
+      "createdAt": "2023-08-11T14:43:00.6459729+03:00",
+      "expirationDate": "2023-08-17T18:24:05+03:00",
+      "isExpired": false,
+      "creatorUa": "curl/7.68.0",
+      "generatedBy": "manual",
+      "lastUsed": "2023-08-11T14:43:47.5559998+03:00",
+      "label": "myAPIKEY",
+      "scopes": null,
+      "uuid": "294abf69-b62f-4e58-b214-dad2aec0bc52"
+    }
+  ]
+}
+

This command output example shows an expired key and a current key for this user.

✏ The actual API key (apiKey) is not shown. The key is shown to the user only when it is created.

API examples

✏ The following examples assume that the zot registry is located at localhost:8080.

Listing repositories

To get a list of all image repositories in the registry, use the following API endpoint:

GET /v2/_catalog
+

cURL command example:

curl -X GET http://localhost:8080/v2/_catalog
+

Command output:

{
+    "repositories": ["alpine", "busybox"]
+}
+

Discovering extension endpoints

To list the installed and enabled zot extensions that can be accessed through the API, use the following OCI API endpoint:

GET /v2/_oci/ext/discover
+

cURL command example:

curl -X GET http://localhost:8080/v2/_oci/ext/discover
+

Command output:

{
+  "extensions": [
+  {
+    "name": "_zot",
+    "url": "https://github.com/project-zot/zot/blob//pkg/extensions/_zot.md",
+    "description": "zot registry extensions",
+    "endpoints": ["/v2/_zot/ext/search", "/v2/_zot/ext/userprefs", "/v2/_zot/ext/mgmt"]
+  }]
+}
+

Uploading a certificate for Notation

To upload a certificate for notation, use the following endpoint:

POST /v2/_zot/ext/notation
+

cURL command example:

curl --data-binary @certificate.crt -X POST "http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca"
+

Viewing the complete zot API reference

You can find comprehensive details of all zot API commands in either of the following locations:

There are many ways to view a swagger file as an interactive document. If you have the npm package installed, for example, you can execute the following command:

  $ npx open-swagger-ui swagger.json
+

This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.


Last update: November 29, 2023
\ No newline at end of file diff --git a/v2.0.2/developer-guide/contributing/index.html b/v2.0.2/developer-guide/contributing/index.html new file mode 100644 index 0000000..7be687e --- /dev/null +++ b/v2.0.2/developer-guide/contributing/index.html @@ -0,0 +1 @@ + Contributing - zotregistry.dev

Contributing to zot Development

👉 The zot project is built for developers by developers. The zot project welcomes the participation of the open source community in extending and improving zot.

Submission Requirements

Summary: All contributions must meet these requirements:

  • Adhere to the Apache license
  • Be submitted by a pull request (PR) from your fork
  • Commits must have a

License

zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.

Submitting a Pull Request (PR)

First, fork the zot project on GitHub and submit a commit to your fork. Then open a new pull request (PR) to the zot project. All pull requests must meet these requirements:

  • License statement

Either the commit message or the PR description must contain the following statement:

"By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license."

  • Developer Certificate of Origin (DCO) and sign-off

All commits require a Developer Certificate of Origin via the "Signed-off-by:" commit message and commit signatures using GPG keys. Include the -s flag in your git commit command.

  • Commit message format

The commit message must follow the Convention Commits format. The message must begin with a keyword that categorizes the commit, followed by a colon. Validation of a commit message is determined by this expression:

"^((build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.+\))?(!)?(: (.*\s*)*))"

An example of a valid commit message is "docs: Fixes a typo in module.md."

In addition, any new PR requires a brief form to be completed by the submitter with details about the PR. Appropriate code owners are automatically identified and will be notified of the new PR.

CI/CD Checks

We take code quality very seriously. All PRs must pass various CI/CD checks that enforce code quality such as code coverage, security scanning, performance regressions, distribution spec conformance, ecosystem client tool compatibility, etc.

Reporting Issues

Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.

Filing a Functional Issue

No software is perfect, and we expect users to find issues with the zot code base. First, check whether your issue has already been filed by someone else by performing an issue search. If the issue is not found, file a new issue by clicking the New issue button on the zot/issues page and answering the questions. The more information that you can provide, the easier it becomes to triage the issue.

Filing a Security Issue

Security issues are best filed by sending an email to security@zotregistry.dev. After 45 days, we will make the issue public and give credit to the original filer of the issue.

Code of Conduct

The zot project follows the CNCF Code of Conduct.

Reporting Conduct Incidents

To report a conduct-related incident occurring on the zot project, contact the zot project conduct committee by sending an email to conduct@zotregistry.dev. You can expect a response within three business days.


Last update: January 16, 2024
\ No newline at end of file diff --git a/v2.0.2/developer-guide/extensions-dev/index.html b/v2.0.2/developer-guide/extensions-dev/index.html new file mode 100644 index 0000000..7a61ee9 --- /dev/null +++ b/v2.0.2/developer-guide/extensions-dev/index.html @@ -0,0 +1,18 @@ + Extensions - zotregistry.dev

Developing New Extensions

👉 You can add new functionality to the zot registry by developing extensions for integration into zot.

The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.

✏ When planning the development of a new extension, be sure to familiarize yourself with the OCI documentation and guidelines for extensions.

Current extensions

The following extensions are currently available in the zot project:

  • metrics
  • sync
  • search
  • scrub
  • lint

You can examine the implementation of these extensions in the zot project extensions section. The operation and configuration of the current extensions is described in Configuring zot.

Guidelines for developing new extensions

  • Each file to be included in the binary for only a specific extension must contain the following syntax at the beginning of the file. For example, a file to be included in the build for extension foo must begin with the following lines:
  //go:build foo
+  // +build foo
+
+  package foo
+
+  ...
+
- The first line (`//go:build foo`) is added automatically by the linter if not already present.
+
+- The second line and the third (blank) line are mandatory.
+
  • For each file that contains functions specific to the extension, create a corresponding "no-op" file that contains exactly the same function names. In this file:

    • Each function is a "no-op," performing no action other than to return a "success" value if expected.
    • We recommend naming this "no-op" file by appending -disabled to the name of the original file. For example, if the extension is implemented by extension-foo.go, the corresponding "no-op" file could be named extension-foo-disabled.go.
    • The first two lines declare an "anti-tag" (for example, !foo). In the foo extension example, the "no-op" file will be included in binaries that don't implement the foo extension, but won't be included in binaries that implement the foo extension. The foo example "no-op" file begins with the following lines:

    //go:build !foo
+    // +build !foo
+
+    package foo
+
+    ...
+
See extension lint-disabled.go in the zot project for an example of a "no-op" file.

  • When developing a new extension, you should create a blackbox test in which a binary containing the new extension can be tested in a usage scenario. See the test/blackbox folder in the zot project for examples of extension tests.

  • When configuring multiple extensions in the extensions section of the zot configuration file, list new extensions after the current extensions in the recommended order, such as:

    metrics, sync, search, scrub, lint, new_extension_1, new_extension_2, ...

Building zot with extensions

When you build the full zot image (for example, make binary), all extensions listed in the EXTENSIONS variable in Makefile are included in the build. When you've created a new extension, you must modify the EXTENSIONS variable in Makefile by adding the new extension.

To build an image with only selected extensions, you can specify the desired extensions by declaring them in the build command:

make binary EXTENSIONS=extension1,extension2,extension3...
+

For example, to build with only sync and scrub, the command would be:

make binary EXTENSIONS=sync,scrub
+

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/developer-guide/onboarding/index.html b/v2.0.2/developer-guide/onboarding/index.html new file mode 100644 index 0000000..f4e3f64 --- /dev/null +++ b/v2.0.2/developer-guide/onboarding/index.html @@ -0,0 +1,29 @@ + Onboarding - zotregistry.dev

Onboarding zot for Development

👉 zot is a production-ready, open-source, extensible OCI-native image registry, built for developers by developers.

Getting Started

Supported Developer Platforms

Development is officially supported on Linux and Apple MacOS platforms. However, development should be possible on any platform that supports the golang toolchain.

OS ARCH Platform
linux amd64 Intel-based Linux servers
linux arm64 ARM-based servers and Raspberry Pi4
darwin amd64 Intel-based MacOS
darwin arm64 ARM-based MacOS (Apple M1)

Supported platforms and architectures

Prerequisites

Install golang

Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.

✏ You must use a golang version of at least the minimum specified in go.mod or the build will fail.

Cloning zot

The zot registry code base is hosted on GitHub at https://github.com/project-zot/zot.

To clone the zot project, use this command:

$ git clone https://github.com/project-zot/zot.git
+

Building zot

To build zot, execute the make command in the zot directory using the following general syntax:

$ make OS=os ARCH=architecture {binary | binary-minimal}

  • The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.

  • The binary option builds the full zot binary image with all extensions.

  • The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.

For example, to build a zot image with extensions for an Intel-based linux server, use the following command:

make OS=linux ARCH=amd64 binary
+

The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-minimal-linux-amd64.

Click here to view an example of the getting started process.

Running zot

The behavior of zot is controlled via configuration only. To launch the zot server, execute the following command:

$  bin/zot-linux-amd64 serve examples/config-minimal.json
+

Debugging zot

To produce a zot binary that includes extensive debugging information, build zot with the binary-debug option, as shown in this example:

make OS=linux ARCH=amd64 binary-debug
+

You can then attach and run a debugging tool such as Delve to the running zot process.

Delve is a powerful open-source debugger for the Go programming language. Downloads and documentation for Delve are available on GitHub at https://github.com/go-delve/delve.

Performance profiling

Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

For detailed information about performance profiling, see Performance Profiling in zot.

Code Organization

The zot project codebase is organized as follows:

/
+- pkg/              # Source code for all libraries
+  - api/            # Source code for HTTP APIs
+    - config/       # Global configuration model
+  - storage/        # Source code for storage backends
+  - cli/            # Source code for command line interface (cli)
+  - common/         # Source code for common utility routines
+  - compliance/     # Source code for dist-spec conformance tests
+  - log/            # Source code for logging framework
+  - test/           # Internal test scripts/data
+  - extensions/     # Source code for all extensions
+    - config/
+    - sync/
+    - monitoring/
+    - sync/
+  - exporter/       # Source code for metrics exporter
+- cmd/              # Source code for binary main()s
+  - zot/            # Source code for zot binary
+  - zli/            # Source code for zot cli
+  - zb/             # Source code for zb, the dist-spec benchmarking tool
+- errors/           # Source code for error codes
+- examples/         # Configuration examples
+- swagger/          # Swagger integration
+- docs/             # Documentation
+

Additional state in zot

In addition to the storage of repository images, zot stores data for various processes in local and remote storage and databases. The following table shows the storage locations for different processes and types of data.

Data or Process Storage Location Description
images local and
AWS S3
Image blobs
repository synchronization local
/<repo_name>/.sync
The sync operation temporarily copies the upstream blobs to:
/<repo_name>/.sync/${UUID}/<repo_name>, then copies to /<repo_name> and deletes the temporary directory ${UUID}
deduplication local
/cache.db
Cache for deduplication of files stored locally
AWS DynamoDB Cache for deduplication of files stored in AWS
CVE local
/_trivy
Database of Common Vulnerabilities and Exposures (CVE) information and scan results
user sessions local
/_sessions
zot user session authentication (for zui)
PKI authentication documents local
/_cosign
Private keys for signature verification using cosign
local
/_notation
Certificates for signature verification using notation
metadata local
/repo.db
Local storage of manifests, configurations, download counters, signature verification results
AWS DynamoDB Cloud storage of manifests, configurations, download counters, signature verification results

Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.2/general/architecture/index.html b/v2.0.2/general/architecture/index.html new file mode 100644 index 0000000..284de57 --- /dev/null +++ b/v2.0.2/general/architecture/index.html @@ -0,0 +1 @@ + Architecture - zotregistry.dev

Architecture

👉 zot is an OCI-native container image registry. This document discusses the design goals, the overall architecture, and the design choices made in the implementation of the design goals.

Design Goals

OCI-first

  • HTTP APIs strictly conforms to the OCI Distribution Specification

    zot intends to be a production reference implementation for the OCI Distribution Specification. In fact, zot does not support any other vendor protocol or specification.

  • Storage layout follows the OCI Image Specification

    The default and only supported storage layout is the OCI Image Layout. The implications of this choice are that any OCI image layout can be served by zot and conversely, zot converts data on-the-wire into an OCI image layout.

Single binary model

zot is a single binary image with all features included so that deployment is extremely simple in various environments, including bare-metal, cloud, and embedded devices. Behavior is controlled by a single configuration file.

Enable Only What You Need

A clear separation exists between (1) the core OCI-compliant HTTP APIs and storage functionality, and (2) other add-on features modeled as extensions. The extension features can be selectively enabled both at build-time and run-time.

For more information, see "Conditional Builds" in zot's security posture document.

Overall Architecture

As shown in the following figure, the architecture of zot is organized as:

👉 zot-full = zot-minimal + extensions

504567.jpg

The minimal build is the core OCI-compliant registry functionality as described by the OCI Distribution Specification.

The full build adds features that are not a part of the Distribution Specification, but are allowed to be added as Extensions.

External Interaction

External interaction with zot consists of the following two types:

  • Client-initiated data or meta-data queries

  • Admin-initiated configuration

All client-side interaction occurs over HTTP APIs. The core data path queries are governed by the OCI Distribution Specification. All additional meta-data queries are handled based on the setting of the search extension:

  • If the search extension is enabled, enhanced registry searching and filtering is supported, using graphQL. A database is maintained by zot to efficiently answer complex queries on data stored in the database.

  • If the search extension is not enabled, basic queries are supported using the core APIs. These queries are less efficient and search actual storage, which is limited in content.

Configuration

A single configuration file governs zot instance behavior. An exception can be made for security concerns, wherein configuration items containing sensitive credentials can be stored in separate files referenced by the main configuration file. Using separate files allows stricter permissions to be enforced on those files if stored locally. Also, modeling as external files allows for storing Kubernetes Secrets.

The configuration file is divided into sections for http, storage, log, and extension, governing the behavior of the respective components.

Authentication and Authorization

A robust set of authentication and authorization options are supported natively in zot. These controls are enforced before access is allowed into the storage layer.

For more information, see User Authentication and Authorization with zot.

Storage Driver Support

zot supports any modern local filesystem. Remote filesystems, such as AWS S3 or any AWS S3-compatible storage system, are supported. Additional driver support is planned in the roadmap.

✏ Deduplication is supported for both local and remote filesystems, but deduplication requires a filesystem with hard-link support.

For more information, see Storage Planning with zot.

Security Scanning

zot integrates with the trivy security scanner to scan container images for vulnerabilities. The database is kept current by periodically downloading any vulnerability database updates at a configurable interval. The user remains agnostic of the actual scanner implementation, which may change over time.

Extensions

Additional registry features that are not a part of the Distribution Specification are added as Extensions.

✏ Extension features of zot are available only with a full zot image. They are not supported in a minimal zot image.

For more information about zot's extensions, see Extensions.

Background Tasks

Several periodic tasks occur in the registry, such as garbage collection, sync mirroring, and scrubbing. A task scheduler handles these tasks in the background, taking care not to degrade or interrupt foreground tasks running in the context of HTTP APIs.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/general/concepts/index.html b/v2.0.2/general/concepts/index.html new file mode 100644 index 0000000..6d6d979 --- /dev/null +++ b/v2.0.2/general/concepts/index.html @@ -0,0 +1 @@ + Concepts - zotregistry.dev

Concepts

What is zot?

👉 zot is a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.

Two broad trends are changing how we build, distribute, and consume software. The first trend is the increasing adoption of container technologies. The second trend is that software solutions are being composed by combining elements from various sources rather than being built entirely from scratch. The latter trend raises the importance of software provenance and supply chain security. In both trends, zot intends to play an important role by providing a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.

What is an OCI image registry?

An OCI image registry is a server-based application that allows you to store, manage, and share container images. A developer uploads (pushes) an image to the registry for distribution. Users can then download (pull) the image to run on their systems. The OCI Distribution Specification, published by the Open Container Initiative (OCI), defines a standard API protocol for these and other image registry operations.

An image registry can be a part of your continuous integration and continuous deployment (CI/CD) pipeline when you host zot on your public or private server. In its minimal form, you can also embed a zot registry in a product. In either case, zot provides a secure software supply chain for container images.

Why zot?

👉 zot = OCI Distribution Specification + OCI Image Format

At its heart, zot is a production-ready, vendor-neutral OCI image registry with images stored in the OCI image format and with the OCI distribution specification on-the-wire. zot is built for developers by developers, offering features such as minimal deployment using a single binary image, built-in authentication and authorization, and inline garbage collection and storage deduplication.

504566

Some of the principal advantages of zot are:

  • Open source

  • OCI standards-only both on-the-wire and on-disk

  • Clear separation between core distribution spec and zot-specific extensions

  • Software supply chain security, including support for cosign and notation

  • Security hardening

  • Single binary with many features built-in

  • Suitable for deployments in cloud, bare-metal, and embedded devices

zot fully conforms to the OCI Distribution Specification.

The following table lists additional advantages of zot:

Distribution Spec conformance yes
CNCF project accepted as a Sandbox Project
License Apache 2.0
On-premises deployment yes
OCI conformance* yes
Single binary image* yes
Minimal build* yes
Storage Layout OCI v1 Image Layout
Authentication built-in
Authorization built-in
Garbage collection inline
Storage deduplication inline
Cloud storage support yes
Delete by tag yes
Vulnerability scanning built-in
Command line interface (cli) yes
UI yes
External contributions beta available
Image signatures built-in

✏ * The minimal build feature is the ability to build a minimal Distribution Spec compliant registry in order to reduce library dependencies and the possible attack surface.


Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.2/general/extensions/index.html b/v2.0.2/general/extensions/index.html new file mode 100644 index 0000000..686ac9c --- /dev/null +++ b/v2.0.2/general/extensions/index.html @@ -0,0 +1 @@ + Extensions - zotregistry.dev

Extensions

👉 Extensions provide additional registry features that are not a part of the Distribution Specification.

The following extensions are currently available with zot:

  • Search (enhanced)
  • Sync
  • Lint
  • Scrub
  • Trust
  • Metrics
  • Graphical user interface
  • User preferences

💡 For detailed information about configuring zot extensions, see Configuring zot.

About extensions

The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.

Wherever applicable, extensions can be dynamically discovered using the extensions support of the OCI Distribution Specification.

⚠ Extension features of zot are available only with a full zot image. They are excluded from the minimal zot image.

Extensions implemented in zot

The extensions implemented in zot include administrator-configured functionality and end-user features.

✏ Currently, search, trust, and userprefs are the only zot extensions operable by end users. Only these extensions are accessible through HTTP APIs and are discoverable using the OCI extensions mechanism.

The following extensions are currently supported by zot:

One of the key functions of a container image registry (which is essentially a graph of blobs) is the ability to perform interesting image and graph traversal queries. The user interacts with the search extension via a graphQL endpoint. The schema is published with every release.

Examples of queries are:

  • "Does an image exist?"
  • "What is its size?"
  • "Does an image depend on this image via its layers?"
  • "What vulnerabilities exist in an image or its dependent images?"

Sync

You can deploy a local mirror pointing to an upstream zot instance with various container image download policies, including on-demand and periodic downloads. The sync function is useful to avoid overwhelming the upstream instance, or if the upstream instance has rate-limited access.

💡 docker.io is supported as an upstream mirror.

Lint

The lint extension helps to avoid image compliance issues by enforcing certain policies about the image or the image metadata. Currently, lint can check an uploaded image to enforce the presence of required annotations such as the author or the license.

Scrub

Although container images are content-addressable with their SHA256 checksums, and validations are performed during storage and retrieval, it is possible that bit-rot sets in when not in use. The scrub extension actively scans container images in the background to proactively detect errors.

Trust

Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user through the zot API. The trust extension enables and configures this function.

Metrics

The metrics extension adds a node exporter, which is not present in the minimal build.

Graphical user interface

Using the zot graphical user interface (GUI), you can browse a zot registry for container images and artifacts. From the web interface, you can copy the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.

User preferences

The userprefs extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.

The functions currently implemented by this extension include:

  • Toggling the star (favorites) icon for a repository.
  • Toggling the bookmark icon for a repository.

💡 For information about configuring zot extensions, see Configuring zot.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/general/features/index.html b/v2.0.2/general/features/index.html new file mode 100644 index 0000000..8980be7 --- /dev/null +++ b/v2.0.2/general/features/index.html @@ -0,0 +1 @@ + Key Features - zotregistry.dev

Summary of Key Features

  • Conforms to OCI distribution spec APIs
  • Uses OCI image layout for image storage
    • Can serve any OCI image layout as a registry
  • Single binary for all the features
  • Doesn't require root privileges
  • Clear separation between core dist-spec and zot-specific extensions
  • Supports container image signatures - cosign and notation
  • Supports helm charts
  • Behavior controlled via configuration
  • Binaries released for multiple operating systems and architectures
  • Supports advanced image queries using search extension
  • Supports image deletion by tag
  • Currently suitable for on-premises deployments (e.g. colocated with Kubernetes)
  • Compatible with ecosystem tools such as skopeo and cri-o
  • Vulnerability scanning of images
  • TLS support Authentication via:
    • TLS mutual authentication
    • HTTP Basic (local htpasswd and LDAP)
    • HTTP Bearer token
  • Supports Identity-Based Access Control
  • Supports live modifications on the configuration file while zot is running (Authorization configuration only)
  • Inline storage optimizations:
    • Automatic garbage collection of orphaned blobs
    • Layer deduplication using hard links when content is identical
    • Data scrubbing
  • Serve multiple storage paths (and backends) using a single zot server
  • Pull and synchronize from other dist-spec conformant registries
  • Supports rate limiting including per HTTP method
  • Metrics with Prometheus
    • Using a node exporter in case of minimal zot
  • Swagger based documentation
  • zli: command-line client support
  • zb: a benchmarking tool for dist-spec conformant registries
  • Released under Apache 2.0 License

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.2/general/glossary/index.html b/v2.0.2/general/glossary/index.html new file mode 100644 index 0000000..7db41bd --- /dev/null +++ b/v2.0.2/general/glossary/index.html @@ -0,0 +1 @@ + Glossary - zotregistry.dev

Glossary

Documentation Icons

Icon Description
✏ Note — A point of emphasis or caution.
💡 Tip — A helpful suggestion or a reference to additional material not covered in this document.
⚠ Warning — A suggestion or advisory intended to avoid a loss of service or data.

Definitions

Term Description
artifact A file of any kind produced during a container build process or associated with the operation of a container. For example, a Helm chart is an artifact that might be stored along with a container.
CNCF As part of the Linux Foundation, the Cloud Native Computing Foundation provides support, oversight, and direction for open-source, cloud native projects.
cosign cosign is a tool that performs container signing, verification, and storage in an OCI registry.
cosigned cosigned is an image admission controller that validates container images before deploying them.
cri-o cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes.
deduplication A storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content.
digest A hashed checksum, such as SHA-256, for verifying the integrity of the downloaded image.
Distribution Specification The OCI Distribution Specification project defines an API protocol to facilitate and standardize the distribution of content.
extensions Additional registry features (APIs) that are not a part of the Distribution Specification can be added as Extensions.
helm chart A helm chart is a package of files that orchestrate the deployment of Kubernetes resources into a Kubernetes cluster.
manifest An image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system.
node exporter A software component that collects hardware and operating system level metrics exposed by the kernel.
OCI The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.
ORAS OCI Registry as Storage (ORAS) is a tool for distributing OCI artifacts across OCI registries.
prometheus Prometheus is a node exporter that exposes a wide variety of hardware- and kernel-related metrics.
referrer An image containing a non-nil subject field with a descriptor to the referred image.
registry A service that stores and distributes container images and artifacts.
repository A collection of images with the same name, differentiated by tags.
skopeo skopeo is a command line utility that performs various operations on container images and image repositories.
stacker stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout.
tag A label applied to an image that distinguishes the image from other images in the same repository. A common example is a version tag.
zb A benchmarking tool, available as a zot companion binary, for benchmarking a zot registry or any other container image registry that conforms to the OCI Distribution Specification.
zli A zot companion binary that implements a set of command line commands for interacting with the zot registry server.
zui A zot companion binary that implements a graphical user interface (GUI) for interacting with the zot registry server.
zxp A node exporter, available as a zot companion binary, that can be deployed with a minimal zot image in order to scrape metrics from the zot server.

Last update: August 4, 2023
\ No newline at end of file diff --git a/v2.0.2/general/project/index.html b/v2.0.2/general/project/index.html new file mode 100644 index 0000000..d5bb372 --- /dev/null +++ b/v2.0.2/general/project/index.html @@ -0,0 +1 @@ + About - zotregistry.dev
\ No newline at end of file diff --git a/v2.0.2/general/releases/index.html b/v2.0.2/general/releases/index.html new file mode 100644 index 0000000..e18a2ee --- /dev/null +++ b/v2.0.2/general/releases/index.html @@ -0,0 +1,3 @@ + Released Images - zotregistry.dev

Released Images for zot

👉 This document describes the available zot images for the various supported hardware and software platforms, along with information about image variations, image locations, and image naming formats.

Supported platforms

zot is supported on Linux and Apple MacOS platforms with Intel or ARM processors.

Table: Supported platforms and architectures

OS ARCH Platform
linux amd64 Intel-based Linux servers
linux arm64 ARM-based servers and Raspberry Pi4
darwin amd64 Intel-based MacOS
darwin arm64 ARM-based MacOS (Apple M1)
freebsd amd64 Intel-based FreeBSD*
freebsd arm64 ARM-based FreeBSD*

**NOTE:* While binary images are available for FreeBSD, building container images is not supported at this time.

Full and minimal binary images

In addition to variations for specific platforms and architectures, binary images are also available in full and minimal flavors:

  • A full zot binary image is compiled with all extensions. Extensions include functions such as metrics, registry synchronization, search, and scrub.

  • A minimal distribution-spec conformant zot binary image is compiled with only a minimal set of code and libraries, reducing the attack surface. This option might be optimal for a registry embedded in a shipping product.

Binary image file naming

An executable binary image for zot is named using the target platform and architecture from the Supported platforms and architectures table. The general format of a binary image file name is one of these two:

zot-<os>-<architecture>

  • A full zot binary image with all extensions has a filename of the form zot-<os>-<architecture>. For example, the full binary image for an Intel-based linux server is zot-linux-amd64.

zot-<os>-<architecture>-minimal

  • A minimal distribution-spec conformant zot binary image has a filename of the form zot-<os>-<architecture>-minimal. For example, the minimal binary image for an Intel-based linux server is zot-linux-amd64-minimal.

💡 For convenience, you can rename the binary image file to simply zot after downloading.

Where to get zot

You can download native executable binary images or container (Docker) images.

Getting binary images

The zot project is hosted on GitHub at project-zot.

To download a binary image, go to the zot releases and select a release. Go to the Assets section of the release page and download the binary for your platform and architecture.

✏ You may need to use the chmod command to make the image executable.

✏ When downloading a binary image for MacOS, download the darwin image.

Getting container images

You can download a container image from ghcr.io by forming a URL with the desired image name, such as:

https://ghcr.io/project-zot/zot-<os>-<architecture>[-<build>]
+

If <build> is not specified, the default is full. For example, to download the minimal binary image for an Intel-based linux server. The URL is:

https://ghcr.io/project-zot/zot-linux-amd64-minimal
+

✏ When downloading a container image for MacOS, download the linux image, not the darwin image.

Licensing

zot is released under the Apache License 2.0.


Last update: July 31, 2023
\ No newline at end of file diff --git a/v2.0.2/general/whats-new/index.html b/v2.0.2/general/whats-new/index.html new file mode 100644 index 0000000..07fd76f --- /dev/null +++ b/v2.0.2/general/whats-new/index.html @@ -0,0 +1,2 @@ + What's New - zotregistry.dev

What's New

v2.0.2

CVE Query Enhancements

It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.

Documentation for "Immutable Image Tags"

A new article has been added to document how image tags can be made immutable.

Cross-repo tag search in UI

You can now search for a tag across all repos by starting your query as ':' in the UI, which will return all images that have that tag.

Support for ORAS Artifacts removed

OCI distribution spec 1.1.0 has added support "artifacts" which is likely to gain wider adoption. ORAS artifacts are not widely used or supported.

:warning:  Support is removed starting from this version.
+

v2.0.1

Support for hot reloading of LDAP credentials file

Since v2.0.0, LDAP credentials have been specified in a separate file. Starting with this version, the file is watched and changes applied without restarting zot.

Bugfixes and performance improvements

Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.

v2.0.0

Updated OCI support

Built-in UI support

  • Using the new zot GUI, you can browse a zot registry for container images and artifacts. The web interface provides the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.

Support for social logins

Group policies for authorization

  • When creating authorization policies, you can assign multiple users to a named group. A group-specific authorization policy can then be defined, specifying allowed access and actions for the group.

    ✏  Configuration syntax change: In the previous release, authorization policies were defined directly under the accessControl key in the zot configuration file. With the new ability to create authorization groups, it becomes necessary to add a new repositories key below accessControl. Beginning with zot v2.0.0, the set of authorization policies are now defined under the repositories key.

Signature verification

  • The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.

LDAP credentials stored separately from configuration

  • The LDAP credentials are removed from zot's LDAP configuration and stored in a separate file. See zot's LDAP documentation.

    ⚠ This LDAP configuration change is incompatible with previous zot releases. When upgrading, you must reconfigure your LDAP credentials if you use LDAP.

Storage deduplication on startup

  • Deduplication, a storage space saving feature, now runs or reverts at startup depending on whether the feature is enabled or disabled. You can trigger deduplication by enabling it and then restarting zot.

Retention policies

  • To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.

CVE scanning support for image indexes

  • The trivy backend now supports vulnerability scanning of image indexes. Previously, only images were scanned.

Bookmarks

  • In the zot GUI, you can bookmark an image so that it can be easily found later. Bookmarked images appear in search queries when the bookmarked option is enabled.

Ability to delete tags from the UI

  • The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.

Search by digest

  • You can perform a global search for a digest (SHA hash) using either the UI or the CLI. This function is useful when an issue is found in a layer that is used by multiple images. In the UI Search box, for example, begin typing sha256: followed by a partial or complete digest value to see a dropdown list of images that contain the layer with the digest value.
  • A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. In addition to supporting direct GraphQL queries through the API, zot hosts the GraphQL Playground, which provides an interactive graphical environment for GraphQL queries.

Scheduling of background tasks

  • You can adjust the background scheduler based on your deployment requirements for tasks that are handled in the background, such as garbage collection. See Configuring zot.

Performance profiling for troubleshooting

Binaries for FreeBSD

  • zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.

    ✏  zot container images for FreeBSD will be available in a future release.


v1.4.3

Remote-only Storage Support

  • The two types of state (images and image metadata) can both now be on remote storage so that zot process lifecycle and its storage can be managed and scaled independently.

Digest Collision Detection During Image Deletion

  • When two or more image tags point to the same image digest and the image is deleted by digest causes data loss and dangling references. A new behavior-based policy called detectManifestCollision was added to prevent this.

Last update: March 13, 2024
\ No newline at end of file diff --git a/v2.0.2/index.html b/v2.0.2/index.html new file mode 100644 index 0000000..57435e5 --- /dev/null +++ b/v2.0.2/index.html @@ -0,0 +1 @@ + Zot Registry - zotregistry.dev

Zot Registry

OCI-native container image registry, simplified

  accepted as a CNCF Sandbox Project

@zothub #zot Community

Get Started User Guide

Try out our beta deployment at zothub.io

Pair zot with stacker, an OCI-native Image Builder and other ecosystem tools

OCI-native Image Registry

  • OCI Standards

    Strongly conforms to OCI Standards (Distribution and Image Specifications)

  • Single Binary

    One statically built binary for simplified download and install with no additional dependencies or services.

  • Unprivileged

    Doesn't require elevated privileges on host.

  • Features vs Security

    Separate Full (all features included) or Minimal (stripped for security) builds.

  • Support For Multiple Platforms

    Linux, MacOS, Intel, Arm, Raspberry PI, Cloud, Bare-metal ...

  • Batteries Included

    All features such as security scanning, authentication, authorization, garbage collection, deduplication and so on, included in the same binary.

  • Open Source

    Released as an open source project under Apache2 License.

  • Sponsors

  • Adopters

\ No newline at end of file diff --git a/v2.0.2/install-guides/install-guide-k8s/index.html b/v2.0.2/install-guides/install-guide-k8s/index.html new file mode 100644 index 0000000..01f9230 --- /dev/null +++ b/v2.0.2/install-guides/install-guide-k8s/index.html @@ -0,0 +1,79 @@ + Installing zot with Kubernetes and Helm - zotregistry.dev

Installing zot with Kubernetes and Helm

👉 Using Kubernetes with Helm charts for zot, you can easily deploy zot as an application in a Kubernetes cluster.

Before you begin

Prerequisites

  • kubectl must be installed and a Kubernetes cluster must be ready.

  • Helm must be installed.

Supported platforms

You can install zot on standard Linux platforms with Intel or ARM processors and with systemd installed.

OS ARCH Platform
linux amd64 Intel-based Linux servers
linux arm64 ARM-based servers and Raspberry Pi4

Supported platforms and architectures

About binary images

Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

Installing zot

Step 1: Locate the Helm charts in a remote repository

  1. Specify a remote repository that contains the Helm charts for zot. Give the repo a local name, such as project-zot, as in this example:

    helm repo add project-zot http://zotregistry.dev/helm-charts

    "project-zot" has been added to your repositories
    +

    ✏

    The Helm charts for zot are currently hosted in these publicly-accessible repositories:
    - zotregistry.dev
    - artifacthub.io

  2. Search the repository to see the Helm charts for zot installation. Search using the keyword 'project-zot' or 'zot', as in this example:

    helm search repo project-zot

    NAME             CHART VERSION  APP VERSION  DESCRIPTION
    +project-zot/zot  <chart-version>          v2.0.2       A Helm chart for Kubernetes
    +

    ✏

    The APP VERSION is the version/tag of the zot image used for the deployment.

  3. Update to the latest information of available charts from the chart repository, as shown in this example:

    helm repo update project-zot

    Hang tight while we grab the latest from your chart repositories...
    +...Successfully got an update from the "project-zot" chart repository
    +Update Complete. ⎈Happy Helming!⎈
    +
  4. Display the default information of the Helm chart, as shown in this example:

helm show all project-zot/zot

    apiVersion: v2
+    appVersion: v2.0.2
+    description: A Helm chart for Kubernetes
+    name: zot
+    type: application
+    version: <chart-version>
+
+    # Default values for zot.
+    # This is a YAML-formatted file.
+    # Declare variables to be passed into your templates.
+    replicaCount: 1
+    image:
+      repository: ghcr.io/project-zot/zot-linux-amd64
+      pullPolicy: IfNotPresent
+      tag: "v2.0.2"
+    serviceAccount:
+      create: true
+      annotations: {}
+      name: ""
+    service:
+      type: NodePort
+      port: 5000
+

Step 2: Determine any needed changes from the Helm chart’s defaults

Inspect the default information of the Helm chart, as shown in the previous step. In many cases, the default chart values may be acceptable. If your installation requires any non-default settings, you may be able to specify them during the installation. Not all chart values are configurable, but you can display those that are configurable using the command in the following example:

helm show values project-zot/zot

  # Default values for zot.
+  # This is a YAML-formatted file.
+  # Declare variables to be passed into your templates.
+  replicaCount: 1
+  image:
+    repository: ghcr.io/project-zot/zot-linux-amd64
+    pullPolicy: IfNotPresent
+    tag: "v2.0.2"
+  serviceAccount:
+    create: true
+    annotations: {}
+    name: ""
+  service:
+    type: NodePort
+    port: 5000
+

The configurable settings in the chart are listed in the following table:

parameter description

replicaCount

Desired number of replicas of the application

image.repository

Repository and image name for the application

image.pullPolicy

Whether to pull the image from the repository. If not specified, the policy depends on image.tag:

  • If tag is :latest or no tag: Always

  • If tag is other than :latest: IfNotPresent

image.tag

Identifies different versions the image. default is the chart appVersion.

Examples: :latest (the default) or :v2.0.2

serviceAccount.create

Specifies whether a service account should be created

serviceAccount.annotations

Annotations to add to the service account

serviceAccount.name

Name of the service account to use. If name is not set and create is true, a name is generated using the fullname template.

service.type

ClusterIP (default), NodePort, LoadBalancer, ExternalName, or Headless

service.port

Port number for calling the service

strategy.type

Kubernetes deployment strategy type. [More Info](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy)

Customizing the Helm chart using 'set'

To override the default values in the chart, you can pass your custom values by adding the --set flag in the helm install command.

For example, if your servers use an ARM processor instead of Intel, you must change the image.repository name from zot-linux-amd64 to zot-linux-arm64:

--set image.repository=ghcr.io/project-zot/zot-linux-arm64

You can change multiple settings with one --set statement. For example, you might want your installation to have more replicas or a different port number:

--set replicaCount=2,service.port=5050

Customizing the Helm chart using a file

You can also create a YAML file with your overrides and then add the new file by adding the -f flag to the helm install command. For example, to override the replica count and port number, the contents of your YAML file (for example, "myfile.yaml") would be:

replicaCount: 2
+service:
+  port: 5050
+

and the following flag would be added to the helm install command:

-f myfile.yaml

Additional information

See the Helm documentation for further information about modifying the Helm chart.

Step 3: Install zot

Install zot using the helm install command. The first example shows how to perform a default installation. The additional examples show different ways to modify the helm install command to override default settings in the Helm chart:

Example 1: use default chart parameters

helm install zot project-zot/zot

NAME: zot
+LAST DEPLOYED: Thu Aug 11 19:13:02 2022
+NAMESPACE: default
+STATUS: deployed
+REVISION: 1
+NOTES:
+ Get the application URL by running these commands:
+ export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services zot)
+ export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
+ echo http://$NODE_IP:$NODE_PORT
+

Example 2: modify specific chart parameters with 'set'

helm install --set replicaCount=2,service.port=5050 zot project-zot/zot

Example 3: modify specific chart parameters with a file

helm install -f myfile.yaml zot project-zot/zot

Example 4: use a specific version of the Helm chart

helm install zot project-zot/zot --version 0.1.0

Example 5: link to a kubeconfig file

helm install zot project-zot/zot --kubeconfig $HOME/.kube/config

After the installation

Verify the installation

  1. List all releases that are either deployed or failed.

    helm list

    NAME  NAMESPACE  REVISION  UPDATED    STATUS    CHART      APP VERSION
    +zot   default    1         <datetime> deployed  <chart-version>  v2.0.2
    +

    This response indicates that zot is deployed.

  2. After making sure that your pods are up and running, execute the following commands:

    $ export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services zot)
    +$ export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
    +$ echo http://$NODE_IP:$NODE_PORT
    +$ curl http://$NODE_IP:$NODE_PORT/v2/_catalog
    +

    The response should display the current contents of your zot repository, which should be empty immediately after installation:

    {"repositories":[]}
    +

Edit the zot configuration file

The zot configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:

  • network

  • storage

  • authentication

  • authorization

  • logging

  • metrics

  • synchronization with other registries

  • clustering

The Helm chart installs a minimal JSON configuration file as shown below:

{
+    "storage":
+    {
+        "rootDirectory": "/var/lib/registry"
+    },
+    "http":
+    {
+        "address": "0.0.0.0",
+        "port": "5000"
+    },
+    "log":
+    {
+        "level": "debug"
+    }
+}
+

The zot configuration file is located at /etc/zot/config.json.

Refer to Configuring zot for complete information on configuring the zot server with the zot configuration file.

Uninstalling zot

Should you need to uninstall zot, use the helm uninstall command, as in this example:

helm uninstall zot


Last update: February 22, 2024
\ No newline at end of file diff --git a/v2.0.2/install-guides/install-guide-linux/index.html b/v2.0.2/install-guides/install-guide-linux/index.html new file mode 100644 index 0000000..96ed18d --- /dev/null +++ b/v2.0.2/install-guides/install-guide-linux/index.html @@ -0,0 +1,115 @@ + Installing zot on Bare Metal Linux - zotregistry.dev

Installing zot on Bare Metal Linux

👉 Using an available executable zot image, you can easily deploy zot on a Linux server.

Before you begin

About binary images

Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.

Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

Installation

Step 1: Get zot

Using wget, download the appropriate zot binary image for your platform from the zot GitHub project. Download the image to the`/usr/bin/` directory and rename it to zot, as in this example:

sudo wget -O /usr/bin/zot https://github.com/project-zot/zot/releases/download/v2.0.2/zot-linux-amd64
+

Then fix permissions to it:

sudo chmod +x /usr/bin/zot
+sudo chown root:root /usr/bin/zot
+

Step 2: Create a zot configuration file

Create a zot configuration file as /etc/zot/config.json.

See Configuration file options for an example file with options and recommendations. You can find other configuration file examples in the zot GitHub project and in Configuring zot.

Step 3: Configure a local authentication account

If you want to use local authentication with zot, create a /etc/zot/htpasswd file with an initial account entry using the htpasswd command as in this example:

htpasswd -bnB myUserName myPassword > /etc/zot/htpasswd
+

To add additional local users, use the >> redirect as in this example:

htpasswd -bnB myUserName2 myPassword2 >> /etc/zot/htpasswd
+

Step 4: Define the zot service

Create a /etc/systemd/system/zot.service file to define the zot service in systemd. The following is an example service file for zot:

[Unit]
+Description=OCI Distribution Registry
+Documentation=https://zotregistry.dev/
+After=network.target auditd.service local-fs.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/zot serve /etc/zot/config.json
+Restart=on-failure
+User=zot
+Group=zot
+LimitNOFILE=500000
+MemoryHigh=30G
+MemoryMax=32G
+
+[Install]
+WantedBy=multi-user.target
+

✏ Be sure to configure a dedicated non-root user ID as the User and Group in the zot service definition. The 'zot' user ID in this example is created in the next step.

Step 5: Create a user ID to own the zot service

Create a non-root user ID to be the owner of the zot service and its resources.

In this example, the user ID 'zot' is created with the adduser command, and resource ownership is assigned.

sudo adduser --no-create-home --disabled-password --gecos --disabled-login zot
+
+sudo mkdir -p /data/zot
+sudo chown -R zot:zot /data/zot
+
+sudo mkdir -p /var/log/zot
+sudo chown -R zot:zot /var/log/zot
+
+sudo chown -R root:root /etc/zot/
+

With the adduser options shown, the 'zot' user ID has no local directory. There is no ability to log into the zot user account, and the account has no finger information.

Step 6: Start zot

Reload systemd config:

sudo systemctl daemon-reload
+

Enable and start the zot service with these commands:

sudo systemctl enable zot
+sudo systemctl start zot
+

Check if zot config is valid:

sudo -u zot zot verify /etc/zot/config.json
+

When the zot service has started, you can check its status with this command:

sudo systemctl status zot
+

After the installation

If your zot registry server is public facing, we recommend that you test your TLS configuration using a service such as the Qualys SSL Server Test.

Refer to Configuring zot for further information about maintaining your zot registry server.

Configuration file options and recommendations

The following zot configuration file (config.json) can be used as a template for your own installation. You can modify this file to suit your own environment.

Click here to view the sample configuration file.
{
+  "distSpecVersion":"1.0.1",
+  "storage":{
+    "dedupe": true,
+    "gc": true,
+    "gcDelay": "1h",
+    "gcInterval": "6h",
+    "rootDirectory":"/data/zot/"
+  },
+  "http": {
+    "address":"0.0.0.0",
+    "port":"443",
+    "realm":"zot",
+    "tls": {
+      "cert": "/etc/letsencrypt/live/zothub.io/fullchain.pem",
+      "key": "/etc/letsencrypt/live/zothub.io/privkey.pem"
+    },
+    "auth": {
+      "htpasswd": {
+        "path": "/etc/zot/htpasswd"
+      },
+      "failDelay": 5
+    },
+    "allowReadAccess": true
+  },
+  "log":{
+    "level":"debug",
+    "output":"/var/log/zot/zot.log",
+    "audit":"/var/log/zot/zot-audit.log"
+  },
+  "extensions": {
+    "search": {
+      "enable": true,
+      "cve": {
+        "updateInterval": "24h"
+      }
+    },
+    "sync": {
+      "enable": false,
+      "registries": [
+        {
+          "urls": ["https://mirror.gcr.io/library"],
+          "onDemand": true,
+          "maxRetries": 3,
+          "retryDelay": "5m",
+          "pollInterval": "6h"
+        },
+        {
+          "urls": ["https://docker.io/library"],
+          "onDemand": true
+        }
+      ]
+    },
+    "scrub": {
+      "interval": "24h"
+    }
+  }
+}
+

Refer to Configuring zot for more details about configuration file options.

TLS encryption

We recommend using a certificate authority such as Let’s Encrypt that offers TLS encryption, as shown in this configuration example:

"tls": {
+  "cert": "/etc/letsencrypt/live/zothub.io/fullchain.pem",
+  "key": "/etc/letsencrypt/live/zothub.io/privkey.pem"
+}
+

Registry synchronization

The example file enables registry synchronization with two other container registries. In the example, the zot server synchronizes with the Google and Docker container registries, as shown here:

"sync": {
+  "enable": false,
+  "registries": [
+    {
+      "urls": ["https://mirror.gcr.io/library"],
+      "onDemand": true,
+      "maxRetries": 3,
+      "retryDelay": "5m",
+      "pollInterval": "6h"
+    },
+    {
+      "urls": ["https://docker.io/library"],
+      "onDemand": true
+    }
+  ]
+}
+

Last update: February 22, 2024
\ No newline at end of file diff --git a/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js b/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js new file mode 100644 index 0000000..eda9dda --- /dev/null +++ b/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js @@ -0,0 +1,16 @@ +!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=10)}([,,function(e,t){(function(){var e,n,r,o,i,s,u,c,l,a,h,f,d,p,b,v;t.score=function(e,t,r){var o,s,u;return o=r.preparedQuery,r.allowErrors||i(e,o.core_lw,o.core_up)?(u=e.toLowerCase(),s=n(e,u,o),Math.ceil(s)):0},t.isMatch=i=function(e,t,n){var r,o,i,s,u,c,l;if(i=e.length,s=t.length,!i||s>i)return!1;for(r=-1,o=-1;++o-1)return d(e,t,E,A,S,_,y);for(I=new Array(_),u=new Array(_),q=v(_,y),x=g=Math.ceil(.75*_)+5,b=!0,w=-1;++w<_;)I[w]=0,u[w]=0;for(m=-1;++mC&&(C=k),p=0,A[w]===j)if(P=c(m,e,t),p=s>0?s:h(e,t,E,A,m,w,P),(i=O+a(m,w,P,o,p))>C)C=i,x=g;else{if(T&&--x<=0)return Math.max(C,I[_-1])*q;T=!1}O=k,s=u[w],u[w]=p,I[w]=C}return(C=I[_-1])*q},t.isWordStart=c=function(e,t,n){var r,o;return 0===e||(r=t[e],o=t[e-1],s(o)||r!==n[e]&&o===n[e-1])},t.isWordEnd=u=function(e,t,n,r){var o,i;return e===r-1||(o=t[e],i=t[e+1],s(i)||o===n[e]&&i!==n[e+1])},s=function(e){return" "===e||"."===e||"-"===e||"_"===e||"/"===e||"\\"===e},b=function(e){var t;return e<20?100+(t=20-e)*t:Math.max(120-e,0)},t.scoreSize=v=function(e,t){return 150/(150+Math.abs(t-e))},f=function(e,t,n,r){return 2*e*(150*n+b(r))*v(e,t)},t.scorePattern=p=function(e,t,n,r,o){var i,s;return s=e,i=6,n===e&&(i+=2),r&&(i+=3),o&&(i+=1),e===t&&(r&&(s+=n===t?2:1),o&&(i+=1)),n+s*(s+i)},t.scoreCharacter=a=function(e,t,n,r,o){var i;return i=b(e),n?i+150*((r>o?r:o)+10):i+150*o},t.scoreConsecutives=h=function(e,t,n,r,o,i,s){var c,l,a,h,f,d,b;for(c=(a=(l=e.length)-o)<(f=(h=n.length)-i)?a:f,d=0,b=0,n[i]===e[o]&&d++;++b-1&&(b=c(h,e,t))&&(o=h),a=-1,d=0;++a1&&b>1))return r;for(l=0,y=0,g=0,m=0,h=-1,f=-1;++f-1){y++;continue}break}for(;++h12*n.length)return!1;for(i=-1;++ir)return!1;return!0}}).call(this)},function(e,t,n){(function(t){(function(){var r,o,i,s,u,c,l,a;i=n(7),s=n(8),a=n(2),c=n(4),r=n(5),l=null,o="win32"===(null!=t?t.platform:void 0)?"\\":"/",e.exports={filter:function(e,t,n){return null==n&&(n={}),(null!=t?t.length:void 0)&&(null!=e?e.length:void 0)?(n=u(n,t),i(e,t,n)):[]},score:function(e,t,n){return null==n&&(n={}),(null!=e?e.length:void 0)&&(null!=t?t.length:void 0)?(n=u(n,t)).usePathScoring?c.score(e,t,n):a.score(e,t,n):0},match:function(e,t,n){var r;return null==n&&(n={}),e&&t?e===t?function(){r=[];for(var t=0,n=e.length;0<=n?tn;0<=n?t++:t--)r.push(t);return r}.apply(this):(n=u(n,t),s.match(e,t,n)):[]},wrap:function(e,t,n){return null==n&&(n={}),e&&t?(n=u(n,t),s.wrap(e,t,n)):[]},prepareQuery:function(e,t){return null==t&&(t={}),(t=u(t,e)).preparedQuery}},u=function(e,t){return null==e.allowErrors&&(e.allowErrors=!1),null==e.usePathScoring&&(e.usePathScoring=!0),null==e.useExtensionBonus&&(e.useExtensionBonus=!1),null==e.pathSeparator&&(e.pathSeparator=o),null==e.optCharRegEx&&(e.optCharRegEx=null),null==e.wrap&&(e.wrap=null),null==e.preparedQuery&&(e.preparedQuery=l&&l.query===t?l:l=new r(t,e)),e}}).call(this)}).call(this,n(6))},function(e,t,n){(function(){var e,r,o,i,s,u,c;c=n(2),i=c.isMatch,e=c.computeScore,u=c.scoreSize,t.score=function(t,n,r){var o,u,c;return o=r.preparedQuery,r.allowErrors||i(t,o.core_lw,o.core_up)?(c=t.toLowerCase(),u=e(t,c,o),u=s(t,c,u,r),Math.ceil(u)):0},s=function(t,n,i,s){var c,l,a,h,f,d,p,b,v,m;if(0===i)return 0;for(v=s.preparedQuery,m=s.useExtensionBonus,b=s.pathSeparator,f=t.length-1;t[f]===b;)f--;if(p=f-(a=t.lastIndexOf(b,f)),d=1,m&&(i*=d+=o(n,v.ext,a,f,2)),-1===a)return i;for(h=v.depth;a>-1&&h-- >0;)a=t.lastIndexOf(b,a-1);return l=-1===a?i:d*e(t.slice(a+1,f+1),n.slice(a+1,f+1),v),(c=10/(20+r(t,f+1,b)))*l+(1-c)*i*u(0,2.5*p)},t.countDir=r=function(e,t,n){var r,o;if(t<1)return 0;for(r=0,o=-1;++on))return 0;for((s=r-l)<(c=t.length)&&(c=s,s=t.length),l++,u=-1;++u0?.9*o(e,t,n,l-2,i-1):u/s}}).call(this)},function(e,t,n){(function(){var t,r,o,i,s,u,c;c=n(4),r=c.countDir,i=c.getExtension,e.exports=function(e,n){var s,c,l;if(s=(l=null!=n?n:{}).optCharRegEx,c=l.pathSeparator,!e||!e.length)return null;this.query=e,this.query_lw=e.toLowerCase(),this.core=t(e,s),this.core_lw=this.core.toLowerCase(),this.core_up=u(this.core),this.depth=r(e,e.length,c),this.ext=i(this.query_lw),this.charCodes=o(this.query_lw)},s=/[ _\-:\/\\]/g,t=function(e,t){return null==t&&(t=s),e.replace(t,"")},u=function(e){var t,n,r;for(t="",n=0,r=e.length;n1)for(var n=1;n0?a:e.length+1,u=null!=l,d=m?t:o,w=0,y=e.length;w0)||(p.push({candidate:c,score:f}),--b));w++);return p.sort(i),e=p.map(r),null!=h&&(e=e.slice(0,h)),e}}).call(this)},function(e,t,n){(function(){var e,r,o,i,s,u,c,l,a,h;h=n(2),o=h.isMatch,i=h.isWordStart,a=h.scoreConsecutives,l=h.scoreCharacter,c=h.scoreAcronyms,t.match=s=function(t,n,i){var s,c,l,a,h,f;return s=i.allowErrors,h=i.preparedQuery,a=i.pathSeparator,s||o(t,h.core_lw,h.core_up)?(f=t.toLowerCase(),0===(l=r(t,f,h)).length||t.indexOf(a)>-1&&(c=e(t,f,h,a),l=u(l,c)),l):[]},t.wrap=function(e,t,n){var r,o,i,u,c,l,a,h,f;if(null!=n.wrap&&(l=(f=n.wrap).tagClass,h=f.tagOpen,a=f.tagClose),null==l&&(l="highlight"),null==h&&(h=''),null==a&&(a=""),e===t)return h+e+a;if(0===(i=s(e,0,n)).length)return e;for(u="",r=-1,c=0;++rc&&(u+=e.substring(c,o),c=o);++rc&&(u+=h,u+=e.substring(c,o),u+=a,c=o)}return c<=e.length-1&&(u+=e.substring(c)),u},e=function(e,t,n,o){var i,s,u;for(u=e.length-1;e[u]===o;)u--;if(-1===(i=e.lastIndexOf(o,u)))return[];for(s=n.depth;s-- >0;)if(-1===(i=e.lastIndexOf(o,i-1)))return[];return i++,u++,r(e.slice(i,u),t.slice(i,u),n,i)},u=function(e,t){var n,r,o,i,s,u,c;if(s=e.length,0===(u=t.length))return e.slice();if(0===s)return t.slice();for(o=-1,r=t[i=0],c=[];++o0?h:a(e,t,x,_,p,b,O),s=E+l(p,b,O,o,d)),T=A[b],h=f[b],S>T?w=2:(S=T,w=1),s>S?(S=s,w=3):d=0,A[b]=S,f[b]=d,I[++g]=S>0?w:0;for(g=(p=v-1)*y+(b=y-1),u=!0,m=[];u&&p>=0&&b>=0;)switch(I[g]){case 1:p--,g-=y;break;case 2:b--,g--;break;case 3:m.push(p+r),b--,p--,g-=y+1;break;default:u=!1}return m.reverse(),m}}).call(this)},,function(e,t,n){"use strict";function r(e){return"function"==typeof e}function o(e){return t=>{if(function(e){return r(null==e?void 0:e.lift)}(t))return t.lift((function(t){try{return e(t,this)}catch(e){this.error(e)}}));throw new TypeError("Unable to lift unknown Observable type")}}function i(e){const t=e(e=>{Error.call(e),e.stack=(new Error).stack});return t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,t}n.r(t);const s=i(e=>function(t){e(this),this.message=t?`${t.length} errors occurred during unsubscription:\n${t.map((e,t)=>`${t+1}) ${e.toString()}`).join("\n ")}`:"",this.name="UnsubscriptionError",this.errors=t});function u(e,t){if(e){const n=e.indexOf(t);0<=n&&e.splice(n,1)}}class c{constructor(e){this.initialTeardown=e,this.closed=!1,this._parentage=null,this._teardowns=null}unsubscribe(){let e;if(!this.closed){this.closed=!0;const{_parentage:t}=this;if(Array.isArray(t))for(const e of t)e.remove(this);else null==t||t.remove(this);const{initialTeardown:n}=this;if(r(n))try{n()}catch(t){e=t instanceof s?t.errors:[t]}const{_teardowns:o}=this;if(o){this._teardowns=null;for(const t of o)try{h(t)}catch(t){e=null!=e?e:[],t instanceof s?e=[...e,...t.errors]:e.push(t)}}if(e)throw new s(e)}}add(e){var t;if(e&&e!==this)if(this.closed)h(e);else{if(e instanceof c){if(e.closed||e._hasParent(this))return;e._addParent(this)}(this._teardowns=null!==(t=this._teardowns)&&void 0!==t?t:[]).push(e)}}_hasParent(e){const{_parentage:t}=this;return t===e||Array.isArray(t)&&t.includes(e)}_addParent(e){const{_parentage:t}=this;this._parentage=Array.isArray(t)?(t.push(e),t):t?[t,e]:e}_removeParent(e){const{_parentage:t}=this;t===e?this._parentage=null:Array.isArray(t)&&u(t,e)}remove(e){const{_teardowns:t}=this;t&&u(t,e),e instanceof c&&e._removeParent(this)}}c.EMPTY=(()=>{const e=new c;return e.closed=!0,e})();const l=c.EMPTY;function a(e){return e instanceof c||e&&"closed"in e&&r(e.remove)&&r(e.add)&&r(e.unsubscribe)}function h(e){r(e)?e():e.unsubscribe()}const f={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1},d={setTimeout(...e){const{delegate:t}=d;return((null==t?void 0:t.setTimeout)||setTimeout)(...e)},clearTimeout(e){const{delegate:t}=d;return((null==t?void 0:t.clearTimeout)||clearTimeout)(e)},delegate:void 0};function p(e){d.setTimeout(()=>{const{onUnhandledError:t}=f;if(!t)throw e;t(e)})}function b(){}const v=m("C",void 0,void 0);function m(e,t,n){return{kind:e,value:t,error:n}}class w extends c{constructor(e){super(),this.isStopped=!1,e?(this.destination=e,a(e)&&e.add(this)):this.destination=_}static create(e,t,n){return new y(e,t,n)}next(e){this.isStopped?x(function(e){return m("N",e,void 0)}(e),this):this._next(e)}error(e){this.isStopped?x(m("E",void 0,e),this):(this.isStopped=!0,this._error(e))}complete(){this.isStopped?x(v,this):(this.isStopped=!0,this._complete())}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe())}_next(e){this.destination.next(e)}_error(e){this.destination.error(e),this.unsubscribe()}_complete(){this.destination.complete(),this.unsubscribe()}}class y extends w{constructor(e,t,n){if(super(),this.destination=_,(e||t||n)&&e!==_){let o;if(r(e))o=e;else if(e){let r;({next:o,error:t,complete:n}=e),this&&f.useDeprecatedNextContext?(r=Object.create(e),r.unsubscribe=()=>this.unsubscribe()):r=e,o=null==o?void 0:o.bind(r),t=null==t?void 0:t.bind(r),n=null==n?void 0:n.bind(r)}this.destination={next:o||b,error:t||g,complete:n||b}}}}function g(e){if(f.useDeprecatedSynchronousErrorHandling)throw e;p(e)}function x(e,t){const{onStoppedNotification:n}=f;n&&d.setTimeout(()=>n(e,t))}const _={closed:!0,next:b,error:g,complete:b};class S extends w{constructor(e,t,n,r,o){super(e),this.onUnsubscribe=o,this._next=t?function(e){try{t(e)}catch(e){this.destination.error(e)}}:super._next,this._error=n?function(e){try{n(e)}catch(e){this.destination.error(e)}this.unsubscribe()}:super._error,this._complete=r?function(){try{r()}catch(e){this.destination.error(e)}this.unsubscribe()}:super._complete}unsubscribe(){var e;!this.closed&&(null===(e=this.onUnsubscribe)||void 0===e||e.call(this)),super.unsubscribe()}}function E(e,t){return o((n,r)=>{let o=0;n.subscribe(new S(r,n=>{r.next(e.call(t,n,o++))}))})} +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */function A(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function u(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,u)}c((r=r.apply(e,t||[])).next())}))}Object.create;function T(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=T(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}Object.create;const O=e=>e&&"number"==typeof e.length&&"function"!=typeof e;function I(e){return r(null==e?void 0:e.then)}const k="function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator",j="function"==typeof Symbol&&Symbol.observable||"@@observable";function P(e){return e}function q(e){return 0===e.length?P:1===e.length?e[0]:function(t){return e.reduce((e,t)=>t(e),t)}}class L{constructor(e){e&&(this._subscribe=e)}lift(e){const t=new L;return t.source=this,t.operator=e,t}subscribe(e,t,n){const o=(i=e)&&i instanceof w||function(e){return e&&r(e.next)&&r(e.error)&&r(e.complete)}(i)&&a(i)?e:new y(e,t,n);var i;const{operator:s,source:u}=this;return o.add(s?s.call(o,u):u||f.useDeprecatedSynchronousErrorHandling?this._subscribe(o):this._trySubscribe(o)),o}_trySubscribe(e){try{return this._subscribe(e)}catch(t){if(f.useDeprecatedSynchronousErrorHandling)throw t;e.error(t)}}forEach(e,t){return new(t=M(t))((t,n)=>{let r;r=this.subscribe(t=>{try{e(t)}catch(e){n(e),null==r||r.unsubscribe()}},n,t)})}_subscribe(e){var t;return null===(t=this.source)||void 0===t?void 0:t.subscribe(e)}[j](){return this}pipe(...e){return e.length?q(e)(this):this}toPromise(e){return new(e=M(e))((e,t)=>{let n;this.subscribe(e=>n=e,e=>t(e),()=>e(n))})}}function M(e){var t;return null!==(t=null!=e?e:f.Promise)&&void 0!==t?t:Promise}function $(e,t){return new L(n=>{let r=0;return t.schedule((function(){r===e.length?n.complete():(n.next(e[r++]),n.closed||this.schedule())}))})}function F(e){return r(e[j])}function z(e){return r(null==e?void 0:e[k])}function H(e){return Symbol.asyncIterator&&r(null==e?void 0:e[Symbol.asyncIterator])}function D(e){return new TypeError(`You provided ${null!==e&&"object"==typeof e?"an invalid object":`'${e}'`} where a stream was expected. You can provide an Observable, Promise, Array, AsyncIterable, or Iterable.`)}function R(e,t){if(null!=e){if(F(e))return function(e,t){return new L(n=>{const r=new c;return r.add(t.schedule(()=>{const o=e[j]();r.add(o.subscribe({next(e){r.add(t.schedule(()=>n.next(e)))},error(e){r.add(t.schedule(()=>n.error(e)))},complete(){r.add(t.schedule(()=>n.complete()))}}))})),r})}(e,t);if(O(e))return $(e,t);if(I(e))return function(e,t){return new L(n=>t.schedule(()=>e.then(e=>{n.add(t.schedule(()=>{n.next(e),n.add(t.schedule(()=>n.complete()))}))},e=>{n.add(t.schedule(()=>n.error(e)))})))}(e,t);if(H(e))return function(e,t){if(!e)throw new Error("Iterable cannot be null");return new L(n=>{const r=new c;return r.add(t.schedule(()=>{const o=e[Symbol.asyncIterator]();r.add(t.schedule((function(){o.next().then(e=>{e.done?n.complete():(n.next(e.value),this.schedule())})})))})),r})}(e,t);if(z(e))return function(e,t){return new L(n=>{let o;return n.add(t.schedule(()=>{o=e[k](),function(e,t,n,r=0){const o=t.schedule((function(){try{n.call(this)}catch(t){e.error(t)}}),r);e.add(o)}(n,t,(function(){const{value:e,done:t}=o.next();t?n.complete():(n.next(e),this.schedule())}))})),()=>r(null==o?void 0:o.return)&&o.return()})}(e,t)}throw D(e)}function U(e,t){return t?R(e,t):W(e)}function W(e){if(e instanceof L)return e;if(null!=e){if(F(e))return i=e,new L(e=>{const t=i[j]();if(r(t.subscribe))return t.subscribe(e);throw new TypeError("Provided object does not correctly implement Symbol.observable")});if(O(e))return N(e);if(I(e))return o=e,new L(e=>{o.then(t=>{e.closed||(e.next(t),e.complete())},t=>e.error(t)).then(null,p)});if(H(e))return n=e,new L(e=>{(function(e,t){var n,r,o,i;return A(this,void 0,void 0,(function*(){try{for(n=C(e);!(r=yield n.next()).done;){const e=r.value;t.next(e)}}catch(e){o={error:e}}finally{try{r&&!r.done&&(i=n.return)&&(yield i.call(n))}finally{if(o)throw o.error}}t.complete()}))})(n,e).catch(t=>e.error(t))});if(z(e))return t=e,new L(e=>{const n=t[k]();for(;!e.closed;){const{done:t,value:r}=n.next();t?e.complete():e.next(r)}return()=>r(null==n?void 0:n.return)&&n.return()})}var t,n,o,i;throw D(e)}function N(e){return new L(t=>{for(let n=0;nE((e,o)=>t(n,e,r,o))(W(e(n,r))),n):("number"==typeof t&&(n=t),o((t,r)=>function(e,t,n,r,o,i,s,u){let c=[],l=0,a=0,h=!1;const f=()=>{!h||c.length||l||t.complete()},d=e=>l{i&&t.next(e),l++,W(n(e,a++)).subscribe(new S(t,e=>{null==o||o(e),i?d(e):t.next(e)},void 0,()=>{for(l--;c.length&&lp(e))):p(e)}f()}))};return e.subscribe(new S(t,d,void 0,()=>{h=!0,f()})),()=>{c=null,null==u||u()}}(t,r,e,n)))}L.create=e=>new L(e);function B(e=1/0){return Q(P,e)}function Y(e,t){return t?$(e,t):N(e)}const{isArray:Z}=Array;function J(e){return 1===e.length&&Z(e[0])?e[0]:e}const G=new L(e=>e.complete());function K(e){return e&&r(e.schedule)}function V(e){return e[e.length-1]}function X(e){return r(V(e))?e.pop():void 0}function ee(e){return K(V(e))?e.pop():void 0}function te(...e){const t=ee(e),n=function(e,t){return"number"==typeof V(e)?e.pop():t}(e,1/0),r=J(e);return r.length?1===r.length?W(r[0]):B(n)(Y(r,t)):G}function ne(e,t){return o((n,r)=>{let o=null,i=0,s=!1;const u=()=>s&&!o&&r.complete();n.subscribe(new S(r,n=>{null==o||o.unsubscribe();let s=0;const c=i++;W(e(n,c)).subscribe(o=new S(r,e=>r.next(t?t(n,e,c,s++):e),void 0,()=>{o=null,u()}))},void 0,()=>{s=!0,u()}))})}const re=i(e=>function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"});class oe extends L{constructor(){super(),this.observers=[],this.closed=!1,this.isStopped=!1,this.hasError=!1,this.thrownError=null}lift(e){const t=new ie(this,this);return t.operator=e,t}_throwIfClosed(){if(this.closed)throw new re}next(e){if(this._throwIfClosed(),!this.isStopped){const t=this.observers.slice();for(const n of t)n.next(e)}}error(e){if(this._throwIfClosed(),!this.isStopped){this.hasError=this.isStopped=!0,this.thrownError=e;const{observers:t}=this;for(;t.length;)t.shift().error(e)}}complete(){if(this._throwIfClosed(),!this.isStopped){this.isStopped=!0;const{observers:e}=this;for(;e.length;)e.shift().complete()}}unsubscribe(){this.isStopped=this.closed=!0,this.observers=null}_trySubscribe(e){return this._throwIfClosed(),super._trySubscribe(e)}_subscribe(e){return this._throwIfClosed(),this._checkFinalizedStatuses(e),this._innerSubscribe(e)}_innerSubscribe(e){const{hasError:t,isStopped:n,observers:r}=this;return t||n?l:(r.push(e),new c(()=>u(this.observers,e)))}_checkFinalizedStatuses(e){const{hasError:t,thrownError:n,isStopped:r}=this;t?e.error(n):r&&e.complete()}asObservable(){const e=new L;return e.source=this,e}}oe.create=(e,t)=>new ie(e,t);class ie extends oe{constructor(e,t){super(),this.destination=e,this.source=t}next(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.next)||void 0===n||n.call(t,e)}error(e){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.error)||void 0===n||n.call(t,e)}complete(){var e,t;null===(t=null===(e=this.destination)||void 0===e?void 0:e.complete)||void 0===t||t.call(e)}_subscribe(e){var t,n;return null!==(n=null===(t=this.source)||void 0===t?void 0:t.subscribe(e))&&void 0!==n?n:l}}const se={now:()=>(se.delegate||Date).now(),delegate:void 0};class ue extends oe{constructor(e=1/0,t=1/0,n=se){super(),this.bufferSize=e,this.windowTime=t,this.timestampProvider=n,this.buffer=[],this.infiniteTimeWindow=!0,this.infiniteTimeWindow=t===1/0,this.bufferSize=Math.max(1,e),this.windowTime=Math.max(1,t)}next(e){const{isStopped:t,buffer:n,infiniteTimeWindow:r,timestampProvider:o,windowTime:i}=this;t||(n.push(e),!r&&n.push(o.now()+i)),this.trimBuffer(),super.next(e)}_subscribe(e){this._throwIfClosed(),this.trimBuffer();const t=this._innerSubscribe(e),{infiniteTimeWindow:n,buffer:r}=this,o=r.slice();for(let t=0;tfunction(e,t){return ce(t)?e(...t):e(t)}(e,t))}const ae=["addListener","removeListener"],he=["addEventListener","removeEventListener"],fe=["on","off"];function de(e,t,n,o){if(r(n)&&(o=n,n=void 0),o)return de(e,t,n).pipe(le(o));const[i,s]=function(e){return r(e.addEventListener)&&r(e.removeEventListener)}(e)?he.map(r=>o=>e[r](t,o,n)):function(e){return r(e.addListener)&&r(e.removeListener)}(e)?ae.map(pe(e,t)):function(e){return r(e.on)&&r(e.off)}(e)?fe.map(pe(e,t)):[];return!i&&O(e)?Q(e=>de(e,t,n))(Y(e)):new L(e=>{if(!i)throw new TypeError("Invalid event target");const t=(...t)=>e.next(1s(t)})}function pe(e,t){return n=>r=>e[n](t,r)}function be(e){return o((t,n)=>{t.subscribe(new S(n,()=>n.next(e)))})}function ve(e,t=document){return t.querySelector(e)||void 0}function me(e,t=document){const n=ve(e,t);if(void 0===n)throw new ReferenceError(`Missing element: expected "${e}" to be present`);return n}function we(){return document.activeElement instanceof HTMLElement?document.activeElement:void 0}function ye(...e){return B(1)(Y(e,ee(e)))}function ge(...e){const t=ee(e);return o((n,r)=>{(t?ye(e,n,t):ye(e,n)).subscribe(r)})}function xe(e,t){return e=null!=e?e:_e,o((n,r)=>{let o,i=!0;n.subscribe(new S(r,n=>{(i&&(o=n,1)||!e(o,o=t?t(n):n))&&r.next(n),i=!1}))})}function _e(e,t){return e===t}function Se(...e){const t=ee(e);return t?$(e,t):Y(e)}const Ee=new L(b);function Ae(e){return o((t,n)=>{t.subscribe(n),n.add(e)})}function Te(e){e=e||{};const{connector:t=(()=>new oe),resetOnComplete:n=!0,resetOnError:r=!0,resetOnRefCountZero:i=!0}=e;let s=null,u=null,c=0,l=!1,a=!1;const h=()=>{s=u=null,l=a=!1};return o((e,o)=>{c++,u||(u=t());const f=u.subscribe(o);return s||(s=U(e).subscribe({next:e=>u.next(e),error:e=>{a=!0;const t=u;r&&h(),t.error(e)},complete:()=>{l=!0;const e=u;n&&h(),e.complete()}})),()=>{if(c--,f.unsubscribe(),!c&&i&&!a&&!l){const e=s;h(),null==e||e.unsubscribe()}}})}function Ce(e,t,n){var r,o;let i,s=!1;return e&&"object"==typeof e?(i=null!==(r=e.bufferSize)&&void 0!==r?r:1/0,t=null!==(o=e.windowTime)&&void 0!==o?o:1/0,s=!!e.refCount,n=e.scheduler):i=null!=e?e:1/0,Te({connector:()=>new ue(i,t,n),resetOnError:!0,resetOnComplete:!1,resetOnRefCountZero:s})}function Oe(e,t,n){const i=r(e)||t||n?{next:e,error:t,complete:n}:e;return i?o((e,t)=>{e.subscribe(new S(t,e=>{var n;null===(n=i.next)||void 0===n||n.call(i,e),t.next(e)},e=>{var n;null===(n=i.error)||void 0===n||n.call(i,e),t.error(e)},()=>{var e;null===(e=i.complete)||void 0===e||e.call(i),t.complete()}))}):P}function Ie(e,t){return o((n,r)=>{let o=0;n.subscribe(new S(r,n=>e.call(t,n,o++)&&r.next(n)))})}const ke=new oe;(je=()=>Se(new ResizeObserver(e=>{for(const t of e)ke.next(t)})),new L(e=>{W(je()).subscribe(e)})).pipe(ne(e=>Ee.pipe(ge(e)).pipe(Ae(()=>e.disconnect()))),Ce(1));var je;function Pe(e){return{width:e.offsetWidth,height:e.offsetHeight}}function qe(e){return{x:e.scrollLeft,y:e.scrollTop}}function Le(e,t=16){return function(e){return te(de(e,"scroll"),de(window,"resize")).pipe(E(()=>qe(e)),ge(qe(e)))}(e).pipe(E(({y:n})=>{const r=Pe(e);return n>=function(e){return{width:e.scrollWidth,height:e.scrollHeight}}(e).height-r.height-t}),xe())}me("[data-md-toggle=drawer]"),me("[data-md-toggle=search]");function Me(){return new URL(location.href)}function $e(e,t={credentials:"same-origin"}){return U(fetch(e,t)).pipe(Ie(e=>200===e.status))}const{isArray:Fe}=Array,{getPrototypeOf:ze,prototype:He,keys:De}=Object;function Re(e){if(1===e.length){const n=e[0];if(Fe(n))return{args:n,keys:null};if((t=n)&&"object"==typeof t&&ze(t)===He){const e=De(n);return{args:e.map(e=>n[e]),keys:e}}}var t;return{args:e,keys:null}}function Ue(...e){const t=ee(e),n=X(e),{args:r,keys:o}=Re(e);if(0===r.length)return U([],t);const i=new L(function(e,t,n=P){return r=>{Ne(t,()=>{const{length:o}=e,i=new Array(o);let s=o;const u=e.map(()=>!1);let c=!0;for(let l=0;l{U(e[l],t).subscribe(new We(r,e=>{i[l]=e,c&&(u[l]=!0,c=!u.every(P)),c||r.next(n(i.slice()))},()=>0==--s))},r)}},r)}}(r,t,o?e=>{const t={};for(let n=0;nt?t(n[e],r[e]):n[e]===r[e])}function Be(e,t=document){return me(`[data-mdx-component=${e}]`,t)}function Ye(e,t=document){return function(e,t=document){return Array.from(t.querySelectorAll(e))}(`[data-mdx-component=${e}]`,t)}const Ze=me("#__config"),Je=JSON.parse(Ze.textContent);function Ge(e,t){return void 0!==t?Je.translations[e].replace("#",t.toString()):Je.translations[e]}Je.base=new URL(Je.base,Me()).toString().replace(/\/$/,"");class Ke extends c{constructor(e,t){super()}schedule(e,t=0){return this}}const Ve={setInterval(...e){const{delegate:t}=Ve;return((null==t?void 0:t.setInterval)||setInterval)(...e)},clearInterval(e){const{delegate:t}=Ve;return((null==t?void 0:t.clearInterval)||clearInterval)(e)},delegate:void 0};class Xe extends Ke{constructor(e,t){super(e,t),this.scheduler=e,this.work=t,this.pending=!1}schedule(e,t=0){if(this.closed)return this;this.state=e;const n=this.id,r=this.scheduler;return null!=n&&(this.id=this.recycleAsyncId(r,n,t)),this.pending=!0,this.delay=t,this.id=this.id||this.requestAsyncId(r,this.id,t),this}requestAsyncId(e,t,n=0){return Ve.setInterval(e.flush.bind(e,this),n)}recycleAsyncId(e,t,n=0){if(null!=n&&this.delay===n&&!1===this.pending)return t;Ve.clearInterval(t)}execute(e,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;const n=this._execute(e,t);if(n)return n;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))}_execute(e,t){let n,r=!1;try{this.work(e)}catch(e){r=!0,n=!!e&&e||new Error(e)}if(r)return this.unsubscribe(),n}unsubscribe(){if(!this.closed){const{id:e,scheduler:t}=this,{actions:n}=t;this.work=this.state=this.scheduler=null,this.pending=!1,u(n,this),null!=e&&(this.id=this.recycleAsyncId(t,e,null)),this.delay=null,super.unsubscribe()}}}class et{constructor(e,t=et.now){this.schedulerActionCtor=e,this.now=t}schedule(e,t=0,n){return new this.schedulerActionCtor(this,e).schedule(n,t)}}et.now=se.now;class tt extends et{constructor(e,t=et.now){super(e,t),this.actions=[],this.active=!1,this.scheduled=void 0}flush(e){const{actions:t}=this;if(this.active)return void t.push(e);let n;this.active=!0;do{if(n=e.execute(e.state,e.delay))break}while(e=t.shift());if(this.active=!1,n){for(;e=t.shift();)e.unsubscribe();throw n}}}const nt=new tt(Xe),rt=nt;function ot(e){return e<=0?()=>G:o((t,n)=>{let r=0;t.subscribe(new S(n,t=>{++r<=e&&(n.next(t),e<=r&&n.complete())}))})}function it(e,t){return t?n=>ye(t.pipe(ot(1),o((e,t)=>{e.subscribe(new S(t,b))})),n.pipe(it(e))):Q((t,n)=>e(t,n).pipe(ot(1),be(t)))}function st(e=0,t,n=rt){let r=-1;return null!=t&&(K(t)?n=t:r=t),new L(t=>{let o=(i=e)instanceof Date&&!isNaN(i)?+e-n.now():e;var i;o<0&&(o=0);let s=0;return n.schedule((function(){t.closed||(t.next(s++),0<=r?this.schedule(void 0,r):t.complete())}),o)})}function ut(...e){const t=X(e);return o((n,r)=>{const o=e.length,i=new Array(o);let s=e.map(()=>!1),u=!1;for(let t=0;t{i[t]=e,u||s[t]||(s[t]=!0,(u=s.every(P))&&(s=null))},void 0,b));n.subscribe(new S(r,e=>{if(u){const n=[e,...i];r.next(t?t(...n):n)}}))})}function ct(e){const t=function(e){return te(de(e,"focus"),de(e,"blur")).pipe(E(({type:e})=>"focus"===e),ge(e===we()))}(e),n=te(de(e,"keyup"),de(e,"focus").pipe(function(e,t=nt){const n=st(e,t);return it(()=>n)}(1))).pipe(E(()=>e.value),ge(e.value),xe());return t.pipe(Ie(e=>!e),ut(n)).subscribe(([,e])=>{const t=document.location.pathname;ga("send","pageview",`${t}?q=[icon]+${e}`)}),Ue([n,t]).pipe(E(([t,n])=>({ref:e,value:t,focus:n})))}var lt=n(3);const at={schedule(e){let t=requestAnimationFrame,n=cancelAnimationFrame;const{delegate:r}=at;r&&(t=r.requestAnimationFrame,n=r.cancelAnimationFrame);const o=t(t=>{n=void 0,e(t)});return new c(()=>null==n?void 0:n(o))},requestAnimationFrame(...e){const{delegate:t}=at;return((null==t?void 0:t.requestAnimationFrame)||requestAnimationFrame)(...e)},cancelAnimationFrame(...e){const{delegate:t}=at;return((null==t?void 0:t.cancelAnimationFrame)||cancelAnimationFrame)(...e)},delegate:void 0};const ht=new class extends tt{flush(e){this.active=!0,this.scheduled=void 0;const{actions:t}=this;let n,r=-1;e=e||t.shift();const o=t.length;do{if(n=e.execute(e.state,e.delay))break}while(++r0?super.requestAsyncId(e,t,n):(e.actions.push(this),e.scheduled||(e.scheduled=at.requestAnimationFrame(()=>e.flush(void 0))))}recycleAsyncId(e,t,n=0){if(null!=n&&n>0||null==n&&this.delay>0)return super.recycleAsyncId(e,t,n);0===e.actions.length&&(at.cancelAnimationFrame(t),e.scheduled=void 0)}});function ft(e,t=0){return o((n,r)=>{n.subscribe(new S(r,n=>r.add(e.schedule(()=>r.next(n),t)),n=>r.add(e.schedule(()=>r.error(n),t)),()=>r.add(e.schedule(()=>r.complete(),t))))})}function dt(...e){return o((t,n)=>{(function(...e){const t=X(e),n=J(e);return n.length?new L(e=>{let r=n.map(()=>[]),o=n.map(()=>!1);e.add(()=>{r=o=null});for(let i=0;!e.closed&&i{if(r[i].push(n),r.every(e=>e.length)){const n=r.map(e=>e.shift());e.next(t?t(...n):n),r.some((e,t)=>!e.length&&o[t])&&e.complete()}},void 0,()=>{o[i]=!0,!r[i].length&&e.complete()}));return()=>{r=o=null}}):G})(t,...e).subscribe(n)})}function pt(e,t){if("string"==typeof t||"number"==typeof t)e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(const n of t)pt(e,n)}function bt(e,t,...n){const r=document.createElement(e);if(t)for(const e of Object.keys(t))"boolean"!=typeof t[e]?r.setAttribute(e,t[e]):t[e]&&r.setAttribute(e,"");for(const e of n)pt(r,e);return r}function vt(e,t){return bt("li",{class:"mdx-icon-search-result__item"},bt("span",{class:"twemoji"},bt("img",{src:e.url})),bt("button",{class:"md-clipboard--inline",title:Ge("clipboard.copy"),"data-clipboard-text":`:${e.shortcode}:`},bt("code",null,`:${function(e,t){return Object(lt.wrap)(e.shortcode,t,{wrap:{tagOpen:"",tagClose:""}})}(e,t)}:`)))}function mt(e,{index$:t,query$:n}){const r=new oe,i=Le(e).pipe(Ie(Boolean)),s=me(":scope > :first-child",e);r.pipe(ft(ht),ut(n)).subscribe(([{data:e},{value:t}])=>{t?function(e,t){switch(t){case 0:e.textContent=Ge("search.result.none");break;case 1:e.textContent=Ge("search.result.one");break;default:e.textContent=Ge("search.result.other",function(e){if(e>999){return((e+1e-6)/1e3).toFixed(+((e-950)%1e3>99))+"k"}return e.toString()}(t))}}(s,e.length):function(e){e.textContent=Ge("search.result.placeholder")}(s)});const c=me(":scope > :last-child",e);return r.pipe(ft(ht),Oe(()=>function(e){e.innerHTML=""}(c)),ne(({data:e})=>te(Se(...e.slice(0,10)),Se(...e.slice(10)).pipe(function(e,t=null){return t=null!=t?t:e,o((n,r)=>{let o=[],i=0;n.subscribe(new S(r,n=>{let s=null;i++%t==0&&o.push([]);for(const t of o)t.push(n),e<=t.length&&(s=null!=s?s:[],s.push(t));if(s)for(const e of s)u(o,e),r.next(e)},void 0,()=>{for(const e of o)r.next(e);r.complete()},()=>{o=null}))})}(10),function(...e){return dt(...e)}(i),ne(([e])=>Se(...e))))),ut(n)).subscribe(([e,{value:t}])=>{!function(e,t){e.appendChild(t)}(c,vt(e,t))}),function(e,{index$:t,query$:n}){return Ue([n.pipe(Qe("value")),t.pipe(E(({icons:e,emojis:t})=>[...Object.keys(e.data),...Object.keys(t.data)]))]).pipe(E(([{value:e},t])=>Object(lt.filter)(t,e)),ne(e=>t.pipe(E(({icons:t,emojis:n})=>({data:e.map(e=>{const r=e in t.data?t:n;return{shortcode:e,url:[r.base,r.data[e]].join("")}})})))))}(0,{query$:n,index$:t}).pipe(Oe(r),Ae(()=>r.complete()),E(t=>Object.assign({ref:e},t)))}function wt(e){const t=$e(Je.base+"/overrides/assets/javascripts/icon_search_index.json",n).pipe(ne(e=>e.json()),Ce(1));var n;const r=Be("icon-search-query",e),o=Be("icon-search-result",e),i=ct(r);return te(i,mt(o,{index$:t,query$:i}))}de(document.body,"click").subscribe(e=>{if(e.target instanceof HTMLElement){const t=e.target.closest("a[href^=http]");t instanceof HTMLLinkElement&&ga("send","event","outbound","click",t.href)}}),document$.pipe(ne(()=>te(...Ye("icon-search").map(e=>wt(e))))).subscribe()}])); +//# sourceMappingURL=bundle.e5217812.min.js.map \ No newline at end of file diff --git a/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js.map b/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js.map new file mode 100644 index 0000000..359dd7a --- /dev/null +++ b/v2.0.2/overrides/assets/javascripts/bundle.e5217812.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./node_modules/fuzzaldrin-plus/lib/scorer.js","webpack:///./node_modules/fuzzaldrin-plus/lib/fuzzaldrin.js","webpack:///./node_modules/fuzzaldrin-plus/lib/pathScorer.js","webpack:///./node_modules/fuzzaldrin-plus/lib/query.js","webpack:///./node_modules/process/browser.js","webpack:///./node_modules/fuzzaldrin-plus/lib/filter.js","webpack:///./node_modules/fuzzaldrin-plus/lib/matcher.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isFunction.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/lift.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/createErrorClass.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/UnsubscriptionError.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/arrRemove.js","webpack:///./node_modules/rxjs/dist/esm/internal/Subscription.js","webpack:///./node_modules/rxjs/dist/esm/internal/config.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/timeoutProvider.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/reportUnhandledError.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/noop.js","webpack:///./node_modules/rxjs/dist/esm/internal/NotificationFactories.js","webpack:///./node_modules/rxjs/dist/esm/internal/Subscriber.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/OperatorSubscriber.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/map.js","webpack:///./node_modules/tslib/tslib.es6.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isArrayLike.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isPromise.js","webpack:///./node_modules/rxjs/dist/esm/internal/symbol/iterator.js","webpack:///./node_modules/rxjs/dist/esm/internal/symbol/observable.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/identity.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/pipe.js","webpack:///./node_modules/rxjs/dist/esm/internal/Observable.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/scheduleArray.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isInteropObservable.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isIterable.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isAsyncIterable.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/throwUnobservableError.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/scheduled.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/scheduleObservable.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/schedulePromise.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/scheduleAsyncIterable.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduled/scheduleIterable.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/caughtSchedule.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/from.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/mergeMap.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/mergeInternals.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/mergeAll.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/fromArray.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/argsOrArgArray.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/empty.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isScheduler.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/args.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/merge.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/switchMap.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/ObjectUnsubscribedError.js","webpack:///./node_modules/rxjs/dist/esm/internal/Subject.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/dateTimestampProvider.js","webpack:///./node_modules/rxjs/dist/esm/internal/ReplaySubject.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/mapOneOrManyArgs.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/fromEvent.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/mapTo.js","webpack:///./src/assets/javascripts/browser/element/_/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/observable/concat.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/concatAll.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/startWith.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/distinctUntilChanged.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/of.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/never.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/finalize.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/share.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/shareReplay.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/tap.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/filter.js","webpack:///./src/assets/javascripts/browser/element/size/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/observable/defer.js","webpack:///./src/assets/javascripts/browser/element/offset/index.ts","webpack:///./src/assets/javascripts/browser/toggle/index.ts","webpack:///./src/assets/javascripts/browser/location/_/index.ts","webpack:///./src/assets/javascripts/browser/request/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/util/argsArgArrayOrObject.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/combineLatest.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/distinctUntilKeyChanged.js","webpack:///./src/overrides/assets/javascripts/components/_/index.ts","webpack:///./src/assets/javascripts/_/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/Action.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/intervalProvider.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/AsyncAction.js","webpack:///./node_modules/rxjs/dist/esm/internal/Scheduler.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/AsyncScheduler.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/async.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/take.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/delayWhen.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/ignoreElements.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/timer.js","webpack:///./node_modules/rxjs/dist/esm/internal/util/isDate.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/withLatestFrom.js","webpack:///./src/overrides/assets/javascripts/components/icon-search/query/index.ts","webpack:///./src/assets/javascripts/browser/element/focus/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/operators/delay.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/animationFrameProvider.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/animationFrame.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/AnimationFrameScheduler.js","webpack:///./node_modules/rxjs/dist/esm/internal/scheduler/AnimationFrameAction.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/observeOn.js","webpack:///./node_modules/rxjs/dist/esm/internal/operators/zipWith.js","webpack:///./node_modules/rxjs/dist/esm/internal/observable/zip.js","webpack:///./src/assets/javascripts/utilities/h/index.ts","webpack:///./src/overrides/assets/javascripts/templates/icon-search/index.tsx","webpack:///./src/overrides/assets/javascripts/components/icon-search/result/index.ts","webpack:///./src/assets/javascripts/actions/search/result/index.ts","webpack:///./src/assets/javascripts/utilities/string/index.ts","webpack:///./node_modules/rxjs/dist/esm/internal/operators/bufferCount.js","webpack:///./src/overrides/assets/javascripts/components/icon-search/_/index.ts","webpack:///./src/overrides/assets/javascripts/integrations/analytics/index.ts","webpack:///./src/overrides/assets/javascripts/index.ts"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","AcronymResult","computeScore","emptyAcronymResult","isAcronymFullWord","isMatch","isSeparator","isWordEnd","isWordStart","scoreAcronyms","scoreCharacter","scoreConsecutives","scoreExact","scoreExactMatch","scorePattern","scorePosition","scoreSize","score","string","query","options","preparedQuery","string_lw","allowErrors","core_lw","core_up","toLowerCase","Math","ceil","subject","query_lw","query_up","j","qj_lw","qj_up","si","length","charCodeAt","subject_lw","acro","acro_score","align","csc_diag","csc_row","csc_score","csc_should_rebuild","miss_budget","miss_left","pos","record_miss","score_diag","score_row","score_up","si_lw","start","sz","count","indexOf","Array","charCodes","max","curr_s","prev_s","len","next_s","sc","abs","quality","sameCase","end","bonus","posBonus","startOfWord","k","mi","nj","pos2","this","fullWord","sepCount","sumPos","nbAcronymInQuery","Query","defaultPathSeparator","filter","matcher","parseOptions","pathScorer","preparedQueryCache","scorer","process","platform","candidates","usePathScoring","match","_results","_i","_ref","push","apply","wrap","prepareQuery","useExtensionBonus","pathSeparator","optCharRegEx","countDir","getExtensionScore","scorePath","fullPathScore","alpha","basePathScore","basePos","depth","extAdjust","fileLength","lastIndexOf","ext","slice","path","getExtension","str","substr","candidate","startPos","endPos","maxDepth","matched","coreChars","getCharCodes","opt_char_re","truncatedUpperCase","_arg","_ref1","core","replace","upper","_len","toUpperCase","cachedSetTimeout","cachedClearTimeout","defaultSetTimout","Error","defaultClearTimeout","runTimeout","fun","setTimeout","e","clearTimeout","currentQueue","queue","draining","queueIndex","cleanUpNextTick","concat","drainQueue","timeout","run","marker","runClearTimeout","Item","array","noop","nextTick","args","arguments","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","binding","cwd","chdir","dir","umask","pluckCandidates","sortCandidates","a","b","bKey","maxInners","maxResults","scoreProvider","scoredCandidates","spotLeft","sort","map","basenameMatch","computeMatch","mergeMatches","baseMatches","matches","matchIndex","matchPos","matchPositions","output","strPos","tagClass","tagClose","tagOpen","substring","ai","bj","out","offset","backtrack","move","trace","reverse","isFunction","operate","init","source","lift","hasLift","liftedSource","err","error","TypeError","createErrorClass","createImpl","ctorFunc","instance","stack","constructor","UnsubscriptionError","_super","errors","message","toString","join","arrRemove","arr","item","index","splice","initialTeardown","closed","_parentage","_teardowns","isArray","parent","remove","teardown","execTeardown","_a","_hasParent","_addParent","includes","_removeParent","EMPTY","empty","EMPTY_SUBSCRIPTION","isSubscription","add","unsubscribe","onUnhandledError","onStoppedNotification","Promise","undefined","useDeprecatedSynchronousErrorHandling","useDeprecatedNextContext","timeoutProvider","delegate","handle","reportUnhandledError","COMPLETE_NOTIFICATION","createNotification","kind","destination","super","isStopped","EMPTY_OBSERVER","next","complete","handleStoppedNotification","nextNotification","_next","_error","_complete","observerOrNext","context","defaultErrorHandler","notification","subscriber","onNext","onError","onComplete","onUnsubscribe","project","thisArg","subscribe","__awaiter","_arguments","P","generator","resolve","reject","fulfilled","step","rejected","result","done","then","__values","iterator","__asyncValues","asyncIterator","verb","v","settle","isArrayLike","x","isPromise","observable","identity","pipeFromArray","fns","input","reduce","prev","fn","_subscribe","operator","isObserver","_trySubscribe","sink","promiseCtor","getPromiseCtor","subscription","operations","scheduleArray","scheduler","schedule","isInteropObservable","isIterable","isAsyncIterable","obj","createInvalidObservableTypeError","scheduled","sub","scheduleObservable","schedulePromise","scheduleAsyncIterable","execute","delay","caughtSchedule","return","scheduleIterable","from","innerFrom","obs","fromArrayLike","promise","asyncIterable","asyncIterable_1","asyncIterable_1_1","e_1","e_1_1","catch","iterable","mergeMap","resultSelector","concurrent","Infinity","ii","onBeforeNext","expand","innerSubScheduler","additionalTeardown","buffer","active","isComplete","checkComplete","outerNext","doInnerSub","innerValue","bufferedValue","shift","mergeInternals","mergeAll","internalFromArray","argsOrArgArray","isScheduler","last","popResultSelector","pop","popScheduler","merge","defaultValue","popNumber","sources","switchMap","innerSubscriber","innerIndex","outerIndex","ObjectUnsubscribedError","observers","hasError","thrownError","_throwIfClosed","copy","observer","_checkFinalizedStatuses","_innerSubscribe","_b","dateTimestampProvider","now","Date","bufferSize","windowTime","timestampProvider","infiniteTimeWindow","trimBuffer","adjustedBufferSize","mapOneOrManyArgs","callOrApply","nodeEventEmitterMethods","eventTargetMethods","jqueryMethods","fromEvent","target","eventName","pipe","addEventListener","removeEventListener","isEventTarget","methodName","handler","isNodeStyleEventEmitter","toCommonHandlerRegistry","isJQueryStyleEventEmitter","subTarget","mapTo","getElement","selector","node","document","querySelector","getElementOrThrow","el","ReferenceError","getActiveElement","activeElement","HTMLElement","concatAll","startWith","values","distinctUntilChanged","compare","keySelector","defaultCompare","first","of","NEVER","finalize","callback","share","connector","resetOnComplete","resetOnError","resetOnRefCountZero","connection","refCount","hasCompleted","hasErrored","reset","castSubscription","dest","conn","shareReplay","configOrBufferSize","tap","tapObserver","predicate","entry$","observableFactory","ResizeObserver","entries","entry","resize","disconnect","getElementSize","width","offsetWidth","height","offsetHeight","getElementOffset","scrollLeft","y","scrollTop","watchElementThreshold","threshold","window","watchElementOffset","visible","scrollWidth","scrollHeight","getElementContentSize","getLocation","URL","location","href","url","credentials","fetch","res","status","getPrototypeOf","objectProto","keys","getKeys","argsArgArrayOrObject","combineLatest","observables","valueTransform","maybeSchedule","hasValues","waitingForFirstValues","every","combineLatestInit","shouldComplete","distinctUntilKeyChanged","getComponentElement","type","getComponentElements","querySelectorAll","getElements","script","JSON","parse","textContent","translation","translations","base","work","state","intervalProvider","setInterval","clearInterval","pending","id","recycleAsyncId","requestAsyncId","_id","flush","_scheduler","_execute","_delay","errorValue","errored","actions","Scheduler","schedulerActionCtor","SchedulerAction","action","asyncScheduler","take","seen","delayWhen","delayDurationSelector","subscriptionDelay","timer","dueTime","intervalOrScheduler","intervalDuration","due","isNaN","withLatestFrom","inputs","otherValues","hasValue","ready","mountIconSearchQuery","focus$","watchElementFocus","value$","duration","pathname","ga","focus","ref","animationFrameProvider","request","requestAnimationFrame","cancel","cancelAnimationFrame","timestamp","animationFrameScheduler","observeOn","buffers","completed","sourceIndex","some","zip","appendChild","child","innerHTML","Node","h","tag","attributes","children","createElement","attr","setAttribute","renderIconSearchResult","icon","class","src","shortcode","highlight","mountIconSearchResult","index$","query$","internal$","boundary$","Boolean","meta","data","toFixed","round","setSearchResultMeta","resetSearchResultMeta","list","resetSearchResultList","startBufferEvery","toEmit","bufferCount","otherInputs","zipWith","chunk","addToSearchResultList","_el","icons","emojis","shortcodes","category","watchIconSearchResult","mountIconSearch","json","body","ev","closest","HTMLLinkElement","document$"],"mappings":"4DACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,I,mBClFrD,WACE,IAAIC,EAAeC,EAAcC,EAAoBC,EAAmBC,EAASC,EAAaC,EAAWC,EAAoCC,EAAeC,EAAgBC,EAAmBC,EAAYC,EAAiBC,EAAcC,EAAeC,EAUzPjD,EAAQkD,MAAQ,SAASC,EAAQC,EAAOC,GACtC,IAAiBC,EAAeJ,EAAOK,EAEvC,OADAD,EAAgBD,EAAQC,cAA6BD,EAAQG,aACxClB,EAAQa,EAAQG,EAAcG,QAASH,EAAcI,UAG1EH,EAAYJ,EAAOQ,cACnBT,EAAQf,EAAagB,EAAQI,EAAWD,GACjCM,KAAKC,KAAKX,IAJR,GAOXlD,EAAQsC,QAAUA,EAAU,SAASwB,EAASC,EAAUC,GACtD,IAAI9D,EAAG+D,EAAG3D,EAAGqB,EAAGuC,EAAOC,EAAOC,EAG9B,GAFA9D,EAAIwD,EAAQO,OACZ1C,EAAIoC,EAASM,QACR/D,GAAKqB,EAAIrB,EACZ,OAAO,EAIT,IAFAJ,GAAK,EACL+D,GAAK,IACIA,EAAItC,GAAG,CAGd,IAFAuC,EAAQH,EAASO,WAAWL,GAC5BE,EAAQH,EAASM,WAAWL,KACnB/D,EAAII,IACX8D,EAAKN,EAAQQ,WAAWpE,MACbgE,GAASE,IAAOD,IAI7B,GAAIjE,IAAMI,EACR,OAAO,EAGX,OAAO,GAGTN,EAAQmC,aAAeA,EAAe,SAAS2B,EAASS,EAAYjB,GAClE,IAAIkB,EAAMC,EAAYC,EAAOC,EAAUC,EAASC,EAAWC,EAAoB5E,EAAG+D,EAAG3D,EAAGyE,EAAaC,EAAWrD,EAAGsD,EAAK7B,EAAOW,EAAUmB,EAAahC,EAAOiC,EAAYC,EAAWC,EAAUC,EAAOC,EAAOC,EAO5M,GANApC,EAAQE,EAAcF,MACtBW,EAAWT,EAAcS,SACzBzD,EAAIwD,EAAQO,OACZ1C,EAAIyB,EAAMiB,OAEVI,GADAD,EAAO9B,EAAcoB,EAASS,EAAYnB,EAAOW,IAC/Bb,MACdsB,EAAKiB,QAAU9D,EACjB,OAAOkB,EAAWlB,EAAGrB,EAAGmE,EAAYD,EAAKS,KAG3C,IADAA,EAAMV,EAAWmB,QAAQ3B,KACd,EACT,OAAOjB,EAAgBgB,EAASS,EAAYnB,EAAOW,EAAUkB,EAAKtD,EAAGrB,GASvE,IAPA8E,EAAY,IAAIO,MAAMhE,GACtBiD,EAAU,IAAIe,MAAMhE,GACpB6D,EAAKvC,EAAUtB,EAAGrB,GAElB0E,EADAD,EAAcnB,KAAKC,KAxDR,IAwD0BlC,GAAK,EAE1CmD,GAAqB,EACrBb,GAAK,IACIA,EAAItC,GACXyD,EAAUnB,GAAK,EACfW,EAAQX,GAAK,EAGf,IADA/D,GAAK,IACIA,EAAII,GAEX,KADAgF,EAAQf,EAAWrE,IACRoE,WAAW,KAAMhB,EAAcsC,WACxC,GAAId,EAAoB,CAEtB,IADAb,GAAK,IACIA,EAAItC,GACXiD,EAAQX,GAAK,EAEfa,GAAqB,QAUzB,IANA5B,EAAQ,EACRiC,EAAa,EACbR,EAAW,EACXO,GAAc,EACdJ,GAAqB,EACrBb,GAAK,IACIA,EAAItC,GAAG,CAMd,IALA0D,EAAWD,EAAUnB,IACNf,IACbA,EAAQmC,GAEVR,EAAY,EACRd,EAASE,KAAOqB,EAIlB,GAHAC,EAAQ9C,EAAYvC,EAAG4D,EAASS,GAChCM,EAAYF,EAAW,EAAIA,EAAW/B,EAAkBkB,EAASS,EAAYnB,EAAOW,EAAU7D,EAAG+D,EAAGsB,IACpGb,EAAQS,EAAaxC,EAAezC,EAAG+D,EAAGsB,EAAOd,EAAYI,IACjD3B,EACVA,EAAQwB,EACRM,EAAYD,MACP,CACL,GAAIG,KAAiBF,GAAa,EAChC,OAAOpB,KAAKiC,IAAI3C,EAAOkC,EAAUzD,EAAI,IAAM6D,EAE7CN,GAAc,EAGlBC,EAAaE,EACbV,EAAWC,EAAQX,GACnBW,EAAQX,GAAKY,EACbO,EAAUnB,GAAKf,EAInB,OADAA,EAAQkC,EAAUzD,EAAI,IACP6D,GAGjBxF,EAAQyC,YAAcA,EAAc,SAASwC,EAAKnB,EAASS,GACzD,IAAIuB,EAAQC,EACZ,OAAY,IAARd,IAGJa,EAAShC,EAAQmB,GACjBc,EAASjC,EAAQmB,EAAM,GAChB1C,EAAYwD,IAAYD,IAAWvB,EAAWU,IAAQc,IAAWxB,EAAWU,EAAM,KAG3FjF,EAAQwC,UAAYA,EAAY,SAASyC,EAAKnB,EAASS,EAAYyB,GACjE,IAAIF,EAAQG,EACZ,OAAIhB,IAAQe,EAAM,IAGlBF,EAAShC,EAAQmB,GACjBgB,EAASnC,EAAQmB,EAAM,GAChB1C,EAAY0D,IAAYH,IAAWvB,EAAWU,IAAQgB,IAAW1B,EAAWU,EAAM,KAG3F1C,EAAc,SAAShC,GACrB,MAAa,MAANA,GAAmB,MAANA,GAAmB,MAANA,GAAmB,MAANA,GAAmB,MAANA,GAAmB,OAANA,GAG1EyC,EAAgB,SAASiC,GACvB,IAAIiB,EACJ,OAAIjB,EA/IM,GAiJD,KADPiB,EAhJQ,GAgJSjB,GACCiB,EAEXtC,KAAKiC,IAAI,IAAkBZ,EAAK,IAI3CjF,EAAQiD,UAAYA,EAAY,SAAStB,EAAGrB,GAC1C,OAtJS,SAsJqBsD,KAAKuC,IAAI7F,EAAIqB,KAG7CkB,EAAa,SAASlB,EAAGrB,EAAG8F,EAASnB,GACnC,OAAO,EAAItD,GA9JR,IA8JkByE,EAAUpD,EAAciC,IAAQhC,EAAUtB,EAAGrB,IAGpEN,EAAQ+C,aAAeA,EAAe,SAAS0C,EAAOO,EAAKK,EAAUd,EAAOe,GAC1E,IAAIC,EAAOf,EAwBX,OAvBAA,EAAKC,EACLc,EAAQ,EACJF,IAAaZ,IACfc,GAAS,GAEPhB,IACFgB,GAAS,GAEPD,IACFC,GAAS,GAEPd,IAAUO,IACRT,IAEAC,GADEa,IAAaL,EACT,EAEA,GAGNM,IACFC,GAAS,IAGNF,EAAWb,GAAMA,EAAKe,IAG/BvG,EAAQ2C,eAAiBA,EAAiB,SAASzC,EAAG+D,EAAGsB,EAAOd,EAAYI,GAC1E,IAAI2B,EAEJ,OADAA,EAAWxD,EAAc9C,GACrBqF,EACKiB,EAjMN,MAiMwB/B,EAAaI,EAAYJ,EAAaI,GAAa,IAEvE2B,EAnMJ,IAmMoB3B,GAGzB7E,EAAQ4C,kBAAoBA,EAAoB,SAASkB,EAASS,EAAYnB,EAAOW,EAAU7D,EAAG+D,EAAGwC,GACnG,IAAIC,EAAGpG,EAAGqG,EAAIhF,EAAGiF,EAAIP,EAAUb,EAW/B,IANAkB,GAFAC,GAFArG,EAAIwD,EAAQO,QAEHnE,IACT0G,GAFAjF,EAAIyB,EAAMiB,QAEDJ,GACK0C,EAAKC,EACnBP,EAAW,EACXb,EAAK,EACDpC,EAAMa,KAAOH,EAAQ5D,IACvBmG,MAEOb,EAAKkB,GAAK3C,IAAWE,KAAOM,IAAarE,IAC5CkD,EAAMa,KAAOH,EAAQ5D,IACvBmG,IAMJ,OAHIb,EAAKkB,GACPxG,IAES,IAAPsF,EACK,EAAI,EAAIa,EAEVtD,EAAayC,EAAI7D,EAAG0E,EAAUI,EAAajE,EAAUtC,EAAG4D,EAASS,EAAYjE,KAGtFN,EAAQ8C,gBAAkBA,EAAkB,SAASgB,EAASS,EAAYnB,EAAOW,EAAUkB,EAAKtD,EAAGrB,GACjG,IAAIgG,EAAKpG,EAAG2G,EAAMR,EAAUd,EAa5B,KAZAA,EAAQ9C,EAAYwC,EAAKnB,EAASS,MAEhCsC,EAAOtC,EAAWmB,QAAQ3B,EAAUkB,EAAM,KAC9B,IACVM,EAAQ9C,EAAYoE,EAAM/C,EAASS,MAEjCU,EAAM4B,GAIZ3G,GAAK,EACLmG,EAAW,IACFnG,EAAIyB,GACPyB,EAAM6B,EAAM/E,KAAO4D,EAAQ5D,IAC7BmG,IAIJ,OADAC,EAAM9D,EAAUyC,EAAMtD,EAAI,EAAGmC,EAASS,EAAYjE,GAC3CuC,EAAWlB,EAAGrB,EAAGyC,EAAapB,EAAGA,EAAG0E,EAAUd,EAAOe,GAAMrB,IAcpE7C,EAAqB,IAXrBF,EACE,SAAuBgB,EAAO+B,EAAKQ,GACjCqB,KAAK5D,MAAQA,EACb4D,KAAK7B,IAAMA,EACX6B,KAAKrB,MAAQA,IAOsB,EAAG,GAAK,GAE/CzF,EAAQ0C,cAAgBA,EAAgB,SAASoB,EAASS,EAAYnB,EAAOW,GAC3E,IAAI0B,EAAOsB,EAAU7G,EAAG+D,EAAG3D,EAAGqB,EAAGuC,EAAOmC,EAAUnD,EAAO8D,EAAUC,EAGnE,GAFA3G,EAAIwD,EAAQO,OACZ1C,EAAIyB,EAAMiB,SACJ/D,EAAI,GAAKqB,EAAI,GACjB,OAAOS,EAQT,IANAqD,EAAQ,EACRuB,EAAW,EACXC,EAAS,EACTZ,EAAW,EACXnG,GAAK,EACL+D,GAAK,IACIA,EAAItC,GAAG,CAEd,GADAuC,EAAQH,EAASE,GACb1B,EAAY2B,GAAQ,CAEtB,IADAhE,EAAIqE,EAAWmB,QAAQxB,EAAOhE,EAAI,KACzB,EAAG,CACV8G,IACA,SAEA,MAGJ,OAAS9G,EAAII,GACX,GAAI4D,IAAUK,EAAWrE,IAAMuC,EAAYvC,EAAG4D,EAASS,GAAa,CAC9DnB,EAAMa,KAAOH,EAAQ5D,IACvBmG,IAEFY,GAAU/G,EACVuF,IACA,MAGJ,GAAIvF,IAAMI,EACR,MAGJ,OAAImF,EAAQ,EACHrD,GAET2E,EAAWtB,IAAU9D,GAAIU,EAAkByB,EAASS,EAAYnB,EAAOqC,GACvEvC,EAAQH,EAAa0C,EAAO9D,EAAG0E,GAAU,EAAMU,GACxC,IAAI7E,EAAcgB,EAAO+D,EAASxB,EAAOA,EAAQuB,KAG1D3E,EAAoB,SAASyB,EAASS,EAAYnB,EAAO8D,GACvD,IAAIzB,EAAOvF,EAAGI,EAId,GADAmF,EAAQ,GAFRnF,EAAIwD,EAAQO,QAGJ,GAFJjB,EAAMiB,OAGR,OAAO,EAGT,IADAnE,GAAK,IACIA,EAAII,GACX,GAAImC,EAAYvC,EAAG4D,EAASS,MAAiBkB,EAAQyB,EACnD,OAAO,EAGX,OAAO,KAGR7G,KAAKyG,O,iBCtUR,wBACE,IAAIK,EAAOC,EAAsBC,EAAQC,EAASC,EAAcC,EAAYC,EAAoBC,EAEhGL,EAAS,EAAQ,GAEjBC,EAAU,EAAQ,GAElBI,EAAS,EAAQ,GAEjBF,EAAa,EAAQ,GAErBL,EAAQ,EAAQ,GAEhBM,EAAqB,KAErBL,EAA4G,WAApF,MAAOO,EAA8CA,EAAQC,cAAW,GAAsB,KAAO,IAE7H3H,EAAOD,QAAU,CACfqH,OAAQ,SAASQ,EAAYzE,EAAOC,GAIlC,OAHe,MAAXA,IACFA,EAAU,KAEI,MAATD,EAAgBA,EAAMiB,YAAS,KAA0B,MAAdwD,EAAqBA,EAAWxD,YAAS,IAG3FhB,EAAUkE,EAAalE,EAASD,GACzBiE,EAAOQ,EAAYzE,EAAOC,IAHxB,IAKXH,MAAO,SAASC,EAAQC,EAAOC,GAI7B,OAHe,MAAXA,IACFA,EAAU,KAEK,MAAVF,EAAiBA,EAAOkB,YAAS,KAAqB,MAATjB,EAAgBA,EAAMiB,YAAS,IAGnFhB,EAAUkE,EAAalE,EAASD,IACpB0E,eACHN,EAAWtE,MAAMC,EAAQC,EAAOC,GAEhCqE,EAAOxE,MAAMC,EAAQC,EAAOC,GAN5B,GASX0E,MAAO,SAAS5E,EAAQC,EAAOC,GAC7B,IAAc2E,EAId,OAHe,MAAX3E,IACFA,EAAU,IAEPF,GAGAC,EAGDD,IAAWC,EACN,WACL4E,EAAW,GACX,IAAK,IAAIC,EAAK,EAAGC,EAAO/E,EAAOkB,OAAQ,GAAK6D,EAAOD,EAAKC,EAAOD,EAAKC,EAAM,GAAKA,EAAOD,IAAOA,IAAOD,EAASG,KAAKF,GAClH,OAAOD,GACNI,MAAMtB,OAEXzD,EAAUkE,EAAalE,EAASD,GACzBkE,EAAQS,MAAM5E,EAAQC,EAAOC,IAb3B,IAeXgF,KAAM,SAASlF,EAAQC,EAAOC,GAI5B,OAHe,MAAXA,IACFA,EAAU,IAEPF,GAGAC,GAGLC,EAAUkE,EAAalE,EAASD,GACzBkE,EAAQe,KAAKlF,EAAQC,EAAOC,IAN1B,IAQXiF,aAAc,SAASlF,EAAOC,GAK5B,OAJe,MAAXA,IACFA,EAAU,KAEZA,EAAUkE,EAAalE,EAASD,IACjBE,gBAInBiE,EAAe,SAASlE,EAASD,GAsB/B,OArB2B,MAAvBC,EAAQG,cACVH,EAAQG,aAAc,GAEM,MAA1BH,EAAQyE,iBACVzE,EAAQyE,gBAAiB,GAEM,MAA7BzE,EAAQkF,oBACVlF,EAAQkF,mBAAoB,GAED,MAAzBlF,EAAQmF,gBACVnF,EAAQmF,cAAgBpB,GAEE,MAAxB/D,EAAQoF,eACVpF,EAAQoF,aAAe,MAEL,MAAhBpF,EAAQgF,OACVhF,EAAQgF,KAAO,MAEY,MAAzBhF,EAAQC,gBACVD,EAAQC,cAAgBmE,GAAsBA,EAAmBrE,QAAUA,EAAQqE,EAAsBA,EAAqB,IAAIN,EAAM/D,EAAOC,IAE1IA,KAGRhD,KAAKyG,Q,kCC9GR,WACE,IAAI3E,EAAcuG,EAAoCC,EAAmBrG,EAASsG,EAAW3F,EAAsBiF,EAEnHA,EAAO,EAAQ,GAAa5F,EAAU4F,EAAK5F,QAASH,EAAe+F,EAAK/F,aAAcc,EAAYiF,EAAKjF,UAMvGjD,EAAQkD,MAAQ,SAASC,EAAQC,EAAOC,GACtC,IAAiBC,EAAeJ,EAAOK,EAEvC,OADAD,EAAgBD,EAAQC,cAA6BD,EAAQG,aACxClB,EAAQa,EAAQG,EAAcG,QAASH,EAAcI,UAG1EH,EAAYJ,EAAOQ,cACnBT,EAAQf,EAAagB,EAAQI,EAAWD,GACxCJ,EAAQ0F,EAAUzF,EAAQI,EAAWL,EAAOG,GACrCO,KAAKC,KAAKX,IALR,GAQX0F,EAAY,SAAS9E,EAASS,EAAYsE,EAAexF,GACvD,IAAIyF,EAAOC,EAAeC,EAASC,EAAO3C,EAAK4C,EAAWC,EAAYX,EAAelF,EAAeiF,EACpG,GAAsB,IAAlBM,EACF,OAAO,EAIT,IAFAvF,EAAgBD,EAAQC,cAAeiF,EAAoBlF,EAAQkF,kBAAmBC,EAAgBnF,EAAQmF,cAC9GlC,EAAMxC,EAAQO,OAAS,EAChBP,EAAQwC,KAASkC,GACtBlC,IASF,GANA6C,EAAa7C,GADb0C,EAAUlF,EAAQsF,YAAYZ,EAAelC,IAE7C4C,EAAY,EACRX,IAEFM,GADAK,GAAaP,EAAkBpE,EAAYjB,EAAc+F,IAAKL,EAAS1C,EAAK,KAG7D,IAAb0C,EACF,OAAOH,EAGT,IADAI,EAAQ3F,EAAc2F,MACfD,GAAW,GAAKC,KAAU,GAC/BD,EAAUlF,EAAQsF,YAAYZ,EAAeQ,EAAU,GAIzD,OAFAD,GAA6B,IAAbC,EAAiBH,EAAgBK,EAAY/G,EAAa2B,EAAQwF,MAAMN,EAAU,EAAG1C,EAAM,GAAI/B,EAAW+E,MAAMN,EAAU,EAAG1C,EAAM,GAAIhD,IACvJwF,EAAQ,IAzCE,GAyC6BJ,EAAS5E,EAASwC,EAAM,EAAGkC,KACnDO,GAAiB,EAAID,GAASD,EAAgB5F,EAAU,EAxC5D,IAwC4EkG,IAGzFnJ,EAAQ0I,SAAWA,EAAW,SAASa,EAAMjD,EAAKkC,GAChD,IAAI/C,EAAOvF,EACX,GAAIoG,EAAM,EACR,OAAO,EAIT,IAFAb,EAAQ,EACRvF,GAAK,IACIA,EAAIoG,GAAOiD,EAAKrJ,KAAOsI,IAGhC,OAAStI,EAAIoG,GACX,GAAIiD,EAAKrJ,KAAOsI,EAEd,IADA/C,MACSvF,EAAIoG,GAAOiD,EAAKrJ,KAAOsI,IAKpC,OAAO/C,GAGTzF,EAAQwJ,aAA8B,SAASC,GAC7C,IAAIxE,EAEJ,OADAA,EAAMwE,EAAIL,YAAY,MACZ,EACD,GAEAK,EAAIC,OAAOzE,EAAM,IAI5B0D,EAAoB,SAASgB,EAAWN,EAAKO,EAAUC,EAAQC,GAC7D,IAAIxJ,EAAGyJ,EAASpI,EAAGsD,EACnB,IAAKoE,EAAIhF,OACP,OAAO,EAGT,MADAY,EAAM0E,EAAUP,YAAY,IAAKS,IACrBD,GACV,OAAO,EAUT,KAPAtJ,EAAIuJ,EAAS5E,IADbtD,EAAI0H,EAAIhF,UAGN1C,EAAIrB,EACJA,EAAI+I,EAAIhF,QAEVY,IACA8E,GAAW,IACFA,EAAUpI,GACbgI,EAAU1E,EAAM8E,KAAaV,EAAIU,KAIvC,OAAgB,IAAZA,GAAiBD,EAAW,EACvB,GAAMnB,EAAkBgB,EAAWN,EAAKO,EAAU3E,EAAM,EAAG6E,EAAW,GAExEC,EAAUzJ,KAGlBD,KAAKyG,O,iBC7GR,WACE,IAAWkD,EAAWtB,EAAUuB,EAAcT,EAAcU,EAAaC,EAAoBjC,EAE7FA,EAAO,EAAQ,GAAiBQ,EAAWR,EAAKQ,SAAUc,EAAetB,EAAKsB,aAE9EvJ,EAAOD,QACL,SAAeoD,EAAOgH,GACpB,IAAI3B,EAAcD,EAAe6B,EAEjC,GADkC5B,GAAlC4B,EAAgB,MAARD,EAAeA,EAAO,IAAyB3B,aAAcD,EAAgB6B,EAAM7B,eACrFpF,IAASA,EAAMiB,OACnB,OAAO,KAETyC,KAAK1D,MAAQA,EACb0D,KAAK/C,SAAWX,EAAMO,cACtBmD,KAAKwD,KAAON,EAAU5G,EAAOqF,GAC7B3B,KAAKrD,QAAUqD,KAAKwD,KAAK3G,cACzBmD,KAAKpD,QAAUyG,EAAmBrD,KAAKwD,MACvCxD,KAAKmC,MAAQP,EAAStF,EAAOA,EAAMiB,OAAQmE,GAC3C1B,KAAKuC,IAAMG,EAAa1C,KAAK/C,UAC7B+C,KAAKlB,UAAYqE,EAAanD,KAAK/C,WAOvCmG,EAAc,eAEdF,EAAY,SAAS5G,EAAOqF,GAI1B,OAHoB,MAAhBA,IACFA,EAAeyB,GAEV9G,EAAMmH,QAAQ9B,EAAc,KAGrC0B,EAAqB,SAASV,GAC5B,IAAUe,EAAOvC,EAAIwC,EAErB,IADAD,EAAQ,GACHvC,EAAK,EAAGwC,EAAOhB,EAAIpF,OAAQ4D,EAAKwC,EAAMxC,IAEzCuC,GADOf,EAAIxB,GACGyC,cAAc,GAE9B,OAAOF,GAGTP,EAAe,SAASR,GACtB,IAAI7D,EAAW1F,EAAG8F,EAIlB,IAHAA,EAAMyD,EAAIpF,OACVnE,GAAK,EACL0F,EAAY,KACH1F,EAAI8F,GACXJ,EAAU6D,EAAInF,WAAWpE,KAAM,EAEjC,OAAO0F,KAGRvF,KAAKyG,O,cCvDR,IAOI6D,EACAC,EARAjD,EAAU1H,EAAOD,QAAU,GAU/B,SAAS6K,IACL,MAAM,IAAIC,MAAM,mCAEpB,SAASC,IACL,MAAM,IAAID,MAAM,qCAsBpB,SAASE,EAAWC,GAChB,GAAIN,IAAqBO,WAErB,OAAOA,WAAWD,EAAK,GAG3B,IAAKN,IAAqBE,IAAqBF,IAAqBO,WAEhE,OADAP,EAAmBO,WACZA,WAAWD,EAAK,GAE3B,IAEI,OAAON,EAAiBM,EAAK,GAC/B,MAAME,GACJ,IAEI,OAAOR,EAAiBtK,KAAK,KAAM4K,EAAK,GAC1C,MAAME,GAEJ,OAAOR,EAAiBtK,KAAKyG,KAAMmE,EAAK,MAvCnD,WACG,IAEQN,EADsB,mBAAfO,WACYA,WAEAL,EAEzB,MAAOM,GACLR,EAAmBE,EAEvB,IAEQD,EADwB,mBAAjBQ,aACcA,aAEAL,EAE3B,MAAOI,GACLP,EAAqBG,GAjB7B,GAwEA,IAEIM,EAFAC,EAAQ,GACRC,GAAW,EAEXC,GAAc,EAElB,SAASC,IACAF,GAAaF,IAGlBE,GAAW,EACPF,EAAahH,OACbiH,EAAQD,EAAaK,OAAOJ,GAE5BE,GAAc,EAEdF,EAAMjH,QACNsH,KAIR,SAASA,IACL,IAAIJ,EAAJ,CAGA,IAAIK,EAAUZ,EAAWS,GACzBF,GAAW,EAGX,IADA,IAAIvF,EAAMsF,EAAMjH,OACV2B,GAAK,CAGP,IAFAqF,EAAeC,EACfA,EAAQ,KACCE,EAAaxF,GACdqF,GACAA,EAAaG,GAAYK,MAGjCL,GAAc,EACdxF,EAAMsF,EAAMjH,OAEhBgH,EAAe,KACfE,GAAW,EAnEf,SAAyBO,GACrB,GAAIlB,IAAuBQ,aAEvB,OAAOA,aAAaU,GAGxB,IAAKlB,IAAuBG,IAAwBH,IAAuBQ,aAEvE,OADAR,EAAqBQ,aACdA,aAAaU,GAExB,IAEWlB,EAAmBkB,GAC5B,MAAOX,GACL,IAEI,OAAOP,EAAmBvK,KAAK,KAAMyL,GACvC,MAAOX,GAGL,OAAOP,EAAmBvK,KAAKyG,KAAMgF,KAgD7CC,CAAgBH,IAiBpB,SAASI,EAAKf,EAAKgB,GACfnF,KAAKmE,IAAMA,EACXnE,KAAKmF,MAAQA,EAYjB,SAASC,KA5BTvE,EAAQwE,SAAW,SAAUlB,GACzB,IAAImB,EAAO,IAAIzG,MAAM0G,UAAUhI,OAAS,GACxC,GAAIgI,UAAUhI,OAAS,EACnB,IAAK,IAAInE,EAAI,EAAGA,EAAImM,UAAUhI,OAAQnE,IAClCkM,EAAKlM,EAAI,GAAKmM,UAAUnM,GAGhCoL,EAAMnD,KAAK,IAAI6D,EAAKf,EAAKmB,IACJ,IAAjBd,EAAMjH,QAAiBkH,GACvBP,EAAWW,IASnBK,EAAKlK,UAAU+J,IAAM,WACjB/E,KAAKmE,IAAI7C,MAAM,KAAMtB,KAAKmF,QAE9BtE,EAAQ2E,MAAQ,UAChB3E,EAAQ4E,SAAU,EAClB5E,EAAQ6E,IAAM,GACd7E,EAAQ8E,KAAO,GACf9E,EAAQ+E,QAAU,GAClB/E,EAAQgF,SAAW,GAInBhF,EAAQiF,GAAKV,EACbvE,EAAQkF,YAAcX,EACtBvE,EAAQmF,KAAOZ,EACfvE,EAAQoF,IAAMb,EACdvE,EAAQqF,eAAiBd,EACzBvE,EAAQsF,mBAAqBf,EAC7BvE,EAAQuF,KAAOhB,EACfvE,EAAQwF,gBAAkBjB,EAC1BvE,EAAQyF,oBAAsBlB,EAE9BvE,EAAQ0F,UAAY,SAAU5M,GAAQ,MAAO,IAE7CkH,EAAQ2F,QAAU,SAAU7M,GACxB,MAAM,IAAIqK,MAAM,qCAGpBnD,EAAQ4F,IAAM,WAAc,MAAO,KACnC5F,EAAQ6F,MAAQ,SAAUC,GACtB,MAAM,IAAI3C,MAAM,mCAEpBnD,EAAQ+F,MAAQ,WAAa,OAAO,I,iBCvLpC,WACE,IAAWlG,EAAYmG,EAAiBjG,EAAQkG,EAEhDlG,EAAS,EAAQ,GAEjBF,EAAa,EAAQ,GAEb,EAAQ,GAEhBmG,EAAkB,SAASE,GACzB,OAAOA,EAAElE,WAGXiE,EAAiB,SAASC,EAAGC,GAC3B,OAAOA,EAAE5K,MAAQ2K,EAAE3K,OAGrBjD,EAAOD,QAAU,SAAS6H,EAAYzE,EAAOC,GAC3C,IAAI0K,EAAMpE,EAAWlI,EAAKuM,EAAWC,EAAY/K,EAAOgL,EAAeC,EAAkBC,EAAUjL,EAAQ2E,EAAgBG,EAAIwC,EAM/H,IALA0D,EAAmB,GACnB1M,EAAM4B,EAAQ5B,IAAKwM,EAAa5K,EAAQ4K,WAAYD,EAAY3K,EAAQ2K,UAAWlG,EAAiBzE,EAAQyE,eAC5GsG,EAAyB,MAAbJ,GAAsBA,EAAY,EAAIA,EAAYnG,EAAWxD,OAAS,EAClF0J,EAAc,MAAPtM,EACPyM,EAAgBpG,EAAiBN,EAAaE,EACzCO,EAAK,EAAGwC,EAAO5C,EAAWxD,OAAQ4D,EAAKwC,IAC1Cd,EAAY9B,EAAWI,MACvB9E,EAAS4K,EAAOpE,EAAUlI,GAAOkI,KAIjCzG,EAAQgL,EAAchL,MAAMC,EAAQC,EAAOC,IAC/B,KACV8K,EAAiBhG,KAAK,CACpBwB,UAAWA,EACXzG,MAAOA,MAEFkL,IAZuCnG,KAsBlD,OALAkG,EAAiBE,KAAKT,GACtB/F,EAAasG,EAAiBG,IAAIX,GAChB,MAAdM,IACFpG,EAAaA,EAAWyB,MAAM,EAAG2E,IAE5BpG,KAGRxH,KAAKyG,O,iBCjDR,WACE,IAAIyH,EAAeC,EAAclM,EAASG,EAAasF,EAAO0G,EAAc/L,EAAeC,EAAgBC,EAAmBsF,EAE9HA,EAAO,EAAQ,GAAa5F,EAAU4F,EAAK5F,QAASG,EAAcyF,EAAKzF,YAAaG,EAAoBsF,EAAKtF,kBAAmBD,EAAiBuF,EAAKvF,eAAgBD,EAAgBwF,EAAKxF,cAE3L1C,EAAQ+H,MAAQA,EAAQ,SAAS5E,EAAQC,EAAOC,GAC9C,IAAIG,EAAakL,EAAaC,EAASnG,EAAelF,EAAeC,EAErE,OADAC,EAAcH,EAAQG,YAAaF,EAAgBD,EAAQC,cAAekF,EAAgBnF,EAAQmF,cAC5FhF,GAAelB,EAAQa,EAAQG,EAAcG,QAASH,EAAcI,UAG1EH,EAAYJ,EAAOQ,cAEI,KADvBgL,EAAUH,EAAarL,EAAQI,EAAWD,IAC9Be,QAGRlB,EAAOuC,QAAQ8C,IAAkB,IACnCkG,EAAcH,EAAcpL,EAAQI,EAAWD,EAAekF,GAC9DmG,EAAUF,EAAaE,EAASD,IAJzBC,GALA,IAcX3O,EAAQqI,KAAO,SAASlF,EAAQC,EAAOC,GACrC,IAAIuL,EAAYC,EAAUC,EAAgBC,EAAQC,EAAQC,EAAUC,EAAUC,EAAS9E,EAavF,GAZqB,MAAhBhH,EAAQgF,OACW4G,GAAtB5E,EAAQhH,EAAQgF,MAAuB4G,SAAUE,EAAU9E,EAAM8E,QAASD,EAAW7E,EAAM6E,UAE7E,MAAZD,IACFA,EAAW,aAEE,MAAXE,IACFA,EAAU,kBAAoBF,EAAW,MAE3B,MAAZC,IACFA,EAAW,aAET/L,IAAWC,EACb,OAAO+L,EAAUhM,EAAS+L,EAG5B,GAA8B,KAD9BJ,EAAiB/G,EAAM5E,EAAQC,EAAOC,IACnBgB,OACjB,OAAOlB,EAKT,IAHA4L,EAAS,GACTH,GAAc,EACdI,EAAS,IACAJ,EAAaE,EAAezK,QAAQ,CAM3C,KALAwK,EAAWC,EAAeF,IACXI,IACbD,GAAU5L,EAAOiM,UAAUJ,EAAQH,GACnCG,EAASH,KAEFD,EAAaE,EAAezK,QAAQ,CAC3C,GAAIyK,EAAeF,KAAgBC,EAAW,EAEvC,CACLD,IACA,MAHAC,MAMJA,EACeG,IACbD,GAAUI,EACVJ,GAAU5L,EAAOiM,UAAUJ,EAAQH,GACnCE,GAAUG,EACVF,EAASH,GAMb,OAHIG,GAAU7L,EAAOkB,OAAS,IAC5B0K,GAAU5L,EAAOiM,UAAUJ,IAEtBD,GAGTR,EAAgB,SAASzK,EAASS,EAAYjB,EAAekF,GAC3D,IAAIQ,EAASC,EAAO3C,EAEpB,IADAA,EAAMxC,EAAQO,OAAS,EAChBP,EAAQwC,KAASkC,GACtBlC,IAGF,IAAiB,KADjB0C,EAAUlF,EAAQsF,YAAYZ,EAAelC,IAE3C,MAAO,GAGT,IADA2C,EAAQ3F,EAAc2F,MACfA,KAAU,GAEf,IAAiB,KADjBD,EAAUlF,EAAQsF,YAAYZ,EAAeQ,EAAU,IAErD,MAAO,GAKX,OAFAA,IACA1C,IACOkI,EAAa1K,EAAQwF,MAAMN,EAAS1C,GAAM/B,EAAW+E,MAAMN,EAAS1C,GAAMhD,EAAe0F,IAGlGyF,EAAe,SAASZ,EAAGC,GACzB,IAAIuB,EAAIC,EAAIpP,EAAG+D,EAAG3D,EAAGqB,EAAG4N,EAGxB,GAFAjP,EAAIuN,EAAExJ,OAEI,KADV1C,EAAImM,EAAEzJ,QAEJ,OAAOwJ,EAAEvE,QAEX,GAAU,IAANhJ,EACF,OAAOwN,EAAExE,QAMX,IAJApJ,GAAK,EAELoP,EAAKxB,EADL7J,EAAI,GAEJsL,EAAM,KACGrP,EAAII,GAAG,CAEd,IADA+O,EAAKxB,EAAE3N,GACAoP,GAAMD,KAAQpL,EAAItC,GACnB2N,EAAKD,GACPE,EAAIpH,KAAKmH,GAEXA,EAAKxB,EAAE7J,GAETsL,EAAIpH,KAAKkH,GAEX,KAAOpL,EAAItC,GACT4N,EAAIpH,KAAK2F,EAAE7J,MAEb,OAAOsL,GAGTf,EAAe,SAAS1K,EAASS,EAAYjB,EAAekM,GAC1D,IAA8B/K,EAAYC,EAAO+K,EAAW9K,EAAUC,EAASC,EAAW3E,EAAG+D,EAAG3D,EAAGqO,EAASe,EAAM/N,EAAGsD,EAAK7B,EAAOW,EAAUb,EAAOiC,EAAYC,EAAWC,EAAUC,EAAOC,EAAOoK,EAkBjM,IAjBc,MAAVH,IACFA,EAAS,GAEXpM,EAAQE,EAAcF,MACtBW,EAAWT,EAAcS,SACzBzD,EAAIwD,EAAQO,OACZ1C,EAAIyB,EAAMiB,OACVI,EAAa/B,EAAcoB,EAASS,EAAYnB,EAAOW,GAAUb,MACjEkC,EAAY,IAAIO,MAAMhE,GACtBiD,EAAU,IAAIe,MAAMhE,GACb,EACF,EACE,EACI,EACXgO,EAAQ,IAAIhK,MAAMrF,EAAIqB,GACtBsD,GAAO,EACPhB,GAAK,IACIA,EAAItC,GACXyD,EAAUnB,GAAK,EACfW,EAAQX,GAAK,EAGf,IADA/D,GAAK,IACIA,EAAII,GAMX,IALA4C,EAAQ,EACRmC,EAAW,EACXV,EAAW,EACXW,EAAQf,EAAWrE,GACnB+D,GAAK,IACIA,EAAItC,GACXkD,EAAY,EACZH,EAAQ,EACRS,EAAaE,EACTtB,EAASE,KAAOqB,IAClBC,EAAQ9C,EAAYvC,EAAG4D,EAASS,GAChCM,EAAYF,EAAW,EAAIA,EAAW/B,EAAkBkB,EAASS,EAAYnB,EAAOW,EAAU7D,EAAG+D,EAAGsB,GACpGb,EAAQS,EAAaxC,EAAezC,EAAG+D,EAAGsB,EAAOd,EAAYI,IAE/DQ,EAAWD,EAAUnB,GACrBU,EAAWC,EAAQX,GACff,EAAQmC,EACVqK,EA5BC,GA8BDxM,EAAQmC,EACRqK,EAhCD,GAkCGhL,EAAQxB,GACVA,EAAQwB,EACRgL,EAlCK,GAoCL7K,EAAY,EAEdO,EAAUnB,GAAKf,EACf0B,EAAQX,GAAKY,EACb8K,IAAQ1K,GAAO/B,EAAQ,EAAIwM,EA3CxB,EAmDP,IAHAzK,GAFA/E,EAAII,EAAI,GAEEqB,GADVsC,EAAItC,EAAI,GAER8N,GAAY,EACZd,EAAU,GACHc,GAAavP,GAAK,GAAK+D,GAAK,GACjC,OAAQ0L,EAAM1K,IACZ,KApDC,EAqDC/E,IACA+E,GAAOtD,EACP,MACF,KAvDG,EAwDDsC,IACAgB,IACA,MACF,KA1DO,EA2DL0J,EAAQxG,KAAKjI,EAAIsP,GACjBvL,IACA/D,IACA+E,GAAOtD,EAAI,EACX,MACF,QACE8N,GAAY,EAIlB,OADAd,EAAQiB,UACDjB,KAGRtO,KAAKyG,O,8BCtND,SAAS+I,EAAW1O,GACvB,MAAwB,mBAAVA,ECGX,SAAS2O,EAAQC,GACpB,OAAQC,IACJ,GALD,SAAiBA,GACpB,OAAOH,EAAWG,aAAuC,EAASA,EAAOC,MAIjEC,CAAQF,GACR,OAAOA,EAAOC,MAAK,SAAUE,GACzB,IACI,OAAOJ,EAAKI,EAAcrJ,MAE9B,MAAOsJ,GACHtJ,KAAKuJ,MAAMD,OAIvB,MAAM,IAAIE,UAAU,2CChBrB,SAASC,EAAiBC,GAC7B,MAIMC,EAAWD,EAJDE,IACZ5F,MAAMzK,KAAKqQ,GACXA,EAASC,OAAQ,IAAI7F,OAAQ6F,QAKjC,OAFAF,EAAS3O,UAAYlB,OAAOY,OAAOsJ,MAAMhJ,WACzC2O,EAAS3O,UAAU8O,YAAcH,EAC1BA,E,OCPJ,MAAMI,EAAsBN,EAAkBO,GAAW,SAAiCC,GAC7FD,EAAOhK,MACPA,KAAKkK,QAAUD,EACT,GAAGA,EAAO1M,kDAClB0M,EAAOzC,IAAI,CAAC8B,EAAKlQ,IAAM,GAAGA,EAAI,MAAMkQ,EAAIa,cAAcC,KAAK,UACnD,GACNpK,KAAKrG,KAAO,sBACZqG,KAAKiK,OAASA,ICRX,SAASI,EAAUC,EAAKC,GAC3B,GAAID,EAAK,CACL,MAAME,EAAQF,EAAI1L,QAAQ2L,GAC1B,GAAKC,GAASF,EAAIG,OAAOD,EAAO,ICAjC,MAAM,EACT,YAAYE,GACR1K,KAAK0K,gBAAkBA,EACvB1K,KAAK2K,QAAS,EACd3K,KAAK4K,WAAa,KAClB5K,KAAK6K,WAAa,KAEtB,cACI,IAAIZ,EACJ,IAAKjK,KAAK2K,OAAQ,CACd3K,KAAK2K,QAAS,EACd,MAAM,WAAEC,GAAe5K,KACvB,GAAInB,MAAMiM,QAAQF,GACd,IAAK,MAAMG,KAAUH,EACjBG,EAAOC,OAAOhL,WAIlB4K,SAAwDA,EAAWI,OAAOhL,MAE9E,MAAM,gBAAE0K,GAAoB1K,KAC5B,GAAI+I,EAAW2B,GACX,IACIA,IAEJ,MAAOrG,GACH4F,EAAS5F,aAAa0F,EAAsB1F,EAAE4F,OAAS,CAAC5F,GAGhE,MAAM,WAAEwG,GAAe7K,KACvB,GAAI6K,EAAY,CACZ7K,KAAK6K,WAAa,KAClB,IAAK,MAAMI,KAAYJ,EACnB,IACIK,EAAaD,GAEjB,MAAO3B,GACHW,EAASA,QAAuCA,EAAS,GACrDX,aAAeS,EACfE,EAAS,IAAIA,KAAWX,EAAIW,QAG5BA,EAAO5I,KAAKiI,IAK5B,GAAIW,EACA,MAAM,IAAIF,EAAoBE,IAI1C,IAAIgB,GACA,IAAIE,EACJ,GAAIF,GAAYA,IAAajL,KACzB,GAAIA,KAAK2K,OACLO,EAAaD,OAEZ,CACD,GAAIA,aAAoB,EAAc,CAClC,GAAIA,EAASN,QAAUM,EAASG,WAAWpL,MACvC,OAEJiL,EAASI,WAAWrL,OAEvBA,KAAK6K,WAAwC,QAA1BM,EAAKnL,KAAK6K,kBAA+B,IAAPM,EAAgBA,EAAK,IAAI9J,KAAK4J,IAIhG,WAAWF,GACP,MAAM,WAAEH,GAAe5K,KACvB,OAAO4K,IAAeG,GAAWlM,MAAMiM,QAAQF,IAAeA,EAAWU,SAASP,GAEtF,WAAWA,GACP,MAAM,WAAEH,GAAe5K,KACvBA,KAAK4K,WAAa/L,MAAMiM,QAAQF,IAAeA,EAAWvJ,KAAK0J,GAASH,GAAcA,EAAa,CAACA,EAAYG,GAAUA,EAE9H,cAAcA,GACV,MAAM,WAAEH,GAAe5K,KACnB4K,IAAeG,EACf/K,KAAK4K,WAAa,KAEb/L,MAAMiM,QAAQF,IACnBP,EAAUO,EAAYG,GAG9B,OAAOE,GACH,MAAM,WAAEJ,GAAe7K,KACvB6K,GAAcR,EAAUQ,EAAYI,GAChCA,aAAoB,GACpBA,EAASM,cAAcvL,OAInC,EAAawL,MAAQ,MACjB,MAAMC,EAAQ,IAAI,EAElB,OADAA,EAAMd,QAAS,EACRc,GAHU,GAKd,MAAMC,EAAqB,EAAaF,MACxC,SAASG,EAAetR,GAC3B,OAAQA,aAAiB,GACpBA,GAAS,WAAYA,GAAS0O,EAAW1O,EAAM2Q,SAAWjC,EAAW1O,EAAMuR,MAAQ7C,EAAW1O,EAAMwR,aAE7G,SAASX,EAAaD,GACdlC,EAAWkC,GACXA,IAGAA,EAASY,cChHV,MAAM,EAAS,CAClBC,iBAAkB,KAClBC,sBAAuB,KACvBC,aAASC,EACTC,uCAAuC,EACvCC,0BAA0B,GCLjBC,EAAkB,CAC3B,cAAc9G,GACV,MAAM,SAAE+G,GAAaD,EACrB,QAASC,aAA2C,EAASA,EAASjI,aAAeA,eAAekB,IAExG,aAAagH,GACT,MAAM,SAAED,GAAaD,EACrB,QAASC,aAA2C,EAASA,EAAS/H,eAAiBA,cAAcgI,IAEzGD,cAAUJ,GCPP,SAASM,EAAqBjD,GACjC8C,EAAgBhI,WAAW,KACvB,MAAM,iBAAE0H,GAAqB,EAC7B,IAAIA,EAIA,MAAMxC,EAHNwC,EAAiBxC,KCNtB,SAASlE,KCAT,MAAMoH,EAA+BC,EAAmB,SAAKR,OAAWA,GAOxE,SAASQ,EAAmBC,EAAMrS,EAAOkP,GAC5C,MAAO,CACHmD,OACArS,QACAkP,SCJD,MAAM,UAAmB,EAC5B,YAAYoD,GACRC,QACA5M,KAAK6M,WAAY,EACbF,GACA3M,KAAK2M,YAAcA,EACfhB,EAAegB,IACfA,EAAYf,IAAI5L,OAIpBA,KAAK2M,YAAcG,EAG3B,cAAcC,EAAMxD,EAAOyD,GACvB,OAAO,IAAI,EAAeD,EAAMxD,EAAOyD,GAE3C,KAAK3S,GACG2F,KAAK6M,UACLI,EDtBL,SAA0B5S,GAC7B,OAAOoS,EAAmB,IAAKpS,OAAO4R,GCqBJiB,CAAiB7S,GAAQ2F,MAGnDA,KAAKmN,MAAM9S,GAGnB,MAAMiP,GACEtJ,KAAK6M,UACLI,EDhCDR,EAAmB,SAAKR,ECgCqB3C,GAAMtJ,OAGlDA,KAAK6M,WAAY,EACjB7M,KAAKoN,OAAO9D,IAGpB,WACQtJ,KAAK6M,UACLI,EAA0BT,EAAuBxM,OAGjDA,KAAK6M,WAAY,EACjB7M,KAAKqN,aAGb,cACSrN,KAAK2K,SACN3K,KAAK6M,WAAY,EACjBD,MAAMf,eAGd,MAAMxR,GACF2F,KAAK2M,YAAYI,KAAK1S,GAE1B,OAAOiP,GACHtJ,KAAK2M,YAAYpD,MAAMD,GACvBtJ,KAAK6L,cAET,YACI7L,KAAK2M,YAAYK,WACjBhN,KAAK6L,eAGN,MAAM,UAAuB,EAChC,YAAYyB,EAAgB/D,EAAOyD,GAG/B,GAFAJ,QACA5M,KAAK2M,YAAcG,GACdQ,GAAkB/D,GAASyD,IAAaM,IAAmBR,EAAgB,CAC5E,IAAIC,EACJ,GAAIhE,EAAWuE,GACXP,EAAOO,OAEN,GAAIA,EAAgB,CAErB,IAAIC,IADDR,OAAMxD,QAAOyD,YAAaM,GAEzBtN,MAAQ,EAAOmM,0BACfoB,EAAUzT,OAAOY,OAAO4S,GACxBC,EAAQ1B,YAAc,IAAM7L,KAAK6L,eAGjC0B,EAAUD,EAEdP,EAAOA,aAAmC,EAASA,EAAKnS,KAAK2S,GAC7DhE,EAAQA,aAAqC,EAASA,EAAM3O,KAAK2S,GACjEP,EAAWA,aAA2C,EAASA,EAASpS,KAAK2S,GAEjFvN,KAAK2M,YAAc,CACfI,KAAMA,GAAQ3H,EACdmE,MAAOA,GAASiE,EAChBR,SAAUA,GAAY5H,KAKtC,SAASoI,EAAoBlE,GACzB,GAAI,EAAO4C,sCACP,MAAM5C,EAEViD,EAAqBjD,GAEzB,SAAS2D,EAA0BQ,EAAcC,GAC7C,MAAM,sBAAE3B,GAA0B,EAClCA,GAAyBK,EAAgBhI,WAAW,IAAM2H,EAAsB0B,EAAcC,IAE3F,MAAMZ,EAAiB,CAC1BnC,QAAQ,EACRoC,KAAM3H,EACNmE,MAAOiE,EACPR,SAAU5H,GChHP,MAAM,UAA2B,EACpC,YAAYuH,EAAagB,EAAQC,EAASC,EAAYC,GAClDlB,MAAMD,GACN3M,KAAK8N,cAAgBA,EACrB9N,KAAKmN,MAAQQ,EACP,SAAUtT,GACR,IACIsT,EAAOtT,GAEX,MAAOiP,GACHtJ,KAAK2M,YAAYpD,MAAMD,KAG7BsD,MAAMO,MACZnN,KAAKoN,OAASQ,EACR,SAAUtE,GACR,IACIsE,EAAQtE,GAEZ,MAAOA,GACHtJ,KAAK2M,YAAYpD,MAAMD,GAE3BtJ,KAAK6L,eAEPe,MAAMQ,OACZpN,KAAKqN,UAAYQ,EACX,WACE,IACIA,IAEJ,MAAOvE,GACHtJ,KAAK2M,YAAYpD,MAAMD,GAE3BtJ,KAAK6L,eAEPe,MAAMS,UAEhB,cACI,IAAIlC,GACHnL,KAAK2K,SAAyC,QAA7BQ,EAAKnL,KAAK8N,qBAAkC,IAAP3C,GAAyBA,EAAG5R,KAAKyG,OACxF4M,MAAMf,eCvCP,SAASrE,EAAIuG,EAASC,GACzB,OAAOhF,EAAQ,CAACE,EAAQwE,KACpB,IAAIlD,EAAQ,EACZtB,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,IACjDqT,EAAWX,KAAKgB,EAAQxU,KAAKyU,EAAS3T,EAAOmQ;;;;;;;;;;;;;;gFC+DlD,SAAS0D,EAAUF,EAASG,EAAYC,EAAGC,GAE9C,OAAO,IAAKD,IAAMA,EAAIpC,WAAU,SAAUsC,EAASC,GAC/C,SAASC,EAAUnU,GAAS,IAAMoU,EAAKJ,EAAUtB,KAAK1S,IAAW,MAAOgK,GAAKkK,EAAOlK,IACpF,SAASqK,EAASrU,GAAS,IAAMoU,EAAKJ,EAAiB,MAAEhU,IAAW,MAAOgK,GAAKkK,EAAOlK,IACvF,SAASoK,EAAKE,GAJlB,IAAetU,EAIasU,EAAOC,KAAON,EAAQK,EAAOtU,QAJ1CA,EAIyDsU,EAAOtU,MAJhDA,aAAiB+T,EAAI/T,EAAQ,IAAI+T,GAAE,SAAUE,GAAWA,EAAQjU,OAITwU,KAAKL,EAAWE,GAClGD,GAAMJ,EAAYA,EAAU/M,MAAM0M,EAASG,GAAc,KAAKpB,WAgCzCjT,OAAOY,OAY7B,SAASoU,EAASjV,GACrB,IAAIsB,EAAsB,mBAAXhB,QAAyBA,OAAO4U,SAAUvV,EAAI2B,GAAKtB,EAAEsB,GAAI/B,EAAI,EAC5E,GAAII,EAAG,OAAOA,EAAED,KAAKM,GACrB,GAAIA,GAAyB,iBAAbA,EAAE0D,OAAqB,MAAO,CAC1CwP,KAAM,WAEF,OADIlT,GAAKT,GAAKS,EAAE0D,SAAQ1D,OAAI,GACrB,CAAEQ,MAAOR,GAAKA,EAAET,KAAMwV,MAAO/U,KAG5C,MAAM,IAAI2P,UAAUrO,EAAI,0BAA4B,mCAgEjD,SAAS6T,EAAcnV,GAC1B,IAAKM,OAAO8U,cAAe,MAAM,IAAIzF,UAAU,wCAC/C,IAAiCpQ,EAA7BI,EAAIK,EAAEM,OAAO8U,eACjB,OAAOzV,EAAIA,EAAED,KAAKM,IAAMA,EAAqCiV,EAASjV,GAA2BT,EAAI,GAAI8V,EAAK,QAASA,EAAK,SAAUA,EAAK,UAAW9V,EAAEe,OAAO8U,eAAiB,WAAc,OAAOjP,MAAS5G,GAC9M,SAAS8V,EAAKrU,GAAKzB,EAAEyB,GAAKhB,EAAEgB,IAAM,SAAUsU,GAAK,OAAO,IAAInD,SAAQ,SAAUsC,EAASC,IACvF,SAAgBD,EAASC,EAAQ7U,EAAGyV,GAAKnD,QAAQsC,QAAQa,GAAGN,MAAK,SAASM,GAAKb,EAAQ,CAAEjU,MAAO8U,EAAGP,KAAMlV,MAAS6U,IADJa,CAAOd,EAASC,GAA7BY,EAAItV,EAAEgB,GAAGsU,IAA8BP,KAAMO,EAAE9U,YAS3HP,OAAOY,OC7MzB,MAAM2U,EAAgBC,GAAMA,GAAyB,iBAAbA,EAAE/R,QAAoC,mBAAN+R,ECCxE,SAASC,EAAUlV,GACtB,OAAO0O,EAAW1O,aAAqC,EAASA,EAAMwU,MCInE,MAAM,EALa,mBAAX1U,QAA0BA,OAAO4U,SAGrC5U,OAAO4U,SAFH,aCFF,EAAuC,mBAAX5U,QAAyBA,OAAOqV,YAAe,eCAjF,SAASC,EAASH,GACrB,OAAOA,ECGJ,SAASI,EAAcC,GAC1B,OAAmB,IAAfA,EAAIpS,OACGkS,EAEQ,IAAfE,EAAIpS,OACGoS,EAAI,GAER,SAAeC,GAClB,OAAOD,EAAIE,OAAO,CAACC,EAAMC,IAAOA,EAAGD,GAAOF,ICN3C,MAAM,EACT,YAAY3B,GACJA,IACAjO,KAAKgQ,WAAa/B,GAG1B,KAAKgC,GACD,MAAMT,EAAa,IAAI,EAGvB,OAFAA,EAAWtG,OAASlJ,KACpBwP,EAAWS,SAAWA,EACfT,EAEX,UAAUlC,EAAgB/D,EAAOyD,GAC7B,MAAMU,GA+DQrT,EA/DkBiT,IAgEnBjT,aAAiB,GAJtC,SAAoBA,GAChB,OAAOA,GAAS0O,EAAW1O,EAAM0S,OAAShE,EAAW1O,EAAMkP,QAAUR,EAAW1O,EAAM2S,UAGpCkD,CAAW7V,IAAUsR,EAAetR,GAhEhCiT,EAAiB,IAAI,EAAeA,EAAgB/D,EAAOyD,GA+DrH,IAAsB3S,EA9Dd,MAAM,SAAE4V,EAAQ,OAAE/G,GAAWlJ,KAM7B,OALA0N,EAAW9B,IAAIqE,EACTA,EAAS1W,KAAKmU,EAAYxE,GAC1BA,GAAU,EAAOgD,sCACblM,KAAKgQ,WAAWtC,GAChB1N,KAAKmQ,cAAczC,IACtBA,EAEX,cAAc0C,GACV,IACI,OAAOpQ,KAAKgQ,WAAWI,GAE3B,MAAO9G,GACH,GAAI,EAAO4C,sCACP,MAAM5C,EAEV8G,EAAK7G,MAAMD,IAGnB,QAAQyD,EAAMsD,GAEV,OAAO,IADPA,EAAcC,EAAeD,IACN,CAAC/B,EAASC,KAC7B,IAAIgC,EACJA,EAAevQ,KAAKiO,UAAW5T,IAC3B,IACI0S,EAAK1S,GAET,MAAOiP,GACHiF,EAAOjF,GACPiH,SAA4DA,EAAa1E,gBAE9E0C,EAAQD,KAGnB,WAAWZ,GACP,IAAIvC,EACJ,OAA8B,QAAtBA,EAAKnL,KAAKkJ,cAA2B,IAAPiC,OAAgB,EAASA,EAAG8C,UAAUP,GAEhF,CAAC,KACG,OAAO1N,KAEX,QAAQwQ,GACJ,OAAOA,EAAWjT,OAASmS,EAAcc,EAAdd,CAA0B1P,MAAQA,KAEjE,UAAUqQ,GAEN,OAAO,IADPA,EAAcC,EAAeD,IACN,CAAC/B,EAASC,KAC7B,IAAIlU,EACJ2F,KAAKiO,UAAWqB,GAAOjV,EAAQiV,EAAKhG,GAAQiF,EAAOjF,GAAM,IAAMgF,EAAQjU,OAOnF,SAASiW,EAAeD,GACpB,IAAIlF,EACJ,OAAgG,QAAxFA,EAAKkF,QAAiDA,EAAc,EAAOrE,eAA4B,IAAPb,EAAgBA,EAAKa,QC5E1H,SAASyE,EAAcb,EAAOc,GACjC,OAAO,IAAI,EAAYhD,IACnB,IAAItU,EAAI,EACR,OAAOsX,EAAUC,UAAS,WAClBvX,IAAMwW,EAAMrS,OACZmQ,EAAWV,YAGXU,EAAWX,KAAK6C,EAAMxW,MACjBsU,EAAW/C,QACZ3K,KAAK2Q,iBCTlB,SAASC,EAAoBhB,GAChC,OAAO7G,EAAW6G,EAAM,ICDrB,SAASiB,EAAWjB,GACvB,OAAO7G,EAAW6G,aAAqC,EAASA,EAAM,ICFnE,SAASkB,EAAgBC,GAC5B,OAAO5W,OAAO8U,eAAiBlG,EAAWgI,aAAiC,EAASA,EAAI5W,OAAO8U,gBCF5F,SAAS+B,EAAiCpB,GAC7C,OAAO,IAAIpG,UAAU,gBAA0B,OAAVoG,GAAmC,iBAAVA,EAAqB,oBAAsB,IAAIA,gHCU1G,SAASqB,EAAUrB,EAAOc,GAC7B,GAAa,MAATd,EAAe,CACf,GAAIgB,EAAoBhB,GACpB,OCXL,SAA4BA,EAAOc,GACtC,OAAO,IAAI,EAAWhD,IAClB,MAAMwD,EAAM,IAAI,EAShB,OARAA,EAAItF,IAAI8E,EAAUC,SAAS,KACvB,MAAMnB,EAAaI,EAAM,KACzBsB,EAAItF,IAAI4D,EAAWvB,UAAU,CACzB,KAAK5T,GAAS6W,EAAItF,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWX,KAAK1S,MAC/D,MAAMiP,GAAO4H,EAAItF,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWnE,MAAMD,MAC/D,WAAa4H,EAAItF,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWV,oBAG1DkE,IDAIC,CAAmBvB,EAAOc,GAErC,GAAIrB,EAAYO,GACZ,OAAOa,EAAcb,EAAOc,GAEhC,GAAInB,EAAUK,GACV,OEnBL,SAAyBA,EAAOc,GACnC,OAAO,IAAI,EAAYhD,GACZgD,EAAUC,SAAS,IAAMf,EAAMf,KAAMxU,IACxCqT,EAAW9B,IAAI8E,EAAUC,SAAS,KAC9BjD,EAAWX,KAAK1S,GAChBqT,EAAW9B,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWV,iBAEvD1D,IACAoE,EAAW9B,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWnE,MAAMD,SFWlD8H,CAAgBxB,EAAOc,GAElC,GAAII,EAAgBlB,GAChB,OGrBL,SAA+BA,EAAOc,GACzC,IAAKd,EACD,MAAM,IAAI5L,MAAM,2BAEpB,OAAO,IAAI,EAAW0J,IAClB,MAAMwD,EAAM,IAAI,EAehB,OAdAA,EAAItF,IAAI8E,EAAUC,SAAS,KACvB,MAAM5B,EAAWa,EAAMzV,OAAO8U,iBAC9BiC,EAAItF,IAAI8E,EAAUC,UAAS,WACvB5B,EAAShC,OAAO8B,KAAKF,IACbA,EAAOC,KACPlB,EAAWV,YAGXU,EAAWX,KAAK4B,EAAOtU,OACvB2F,KAAK2Q,qBAKdO,IHCIG,CAAsBzB,EAAOc,GAExC,GAAIG,EAAWjB,GACX,OItBL,SAA0BA,EAAOc,GACpC,OAAO,IAAI,EAAYhD,IACnB,IAAIqB,EAcJ,OAbArB,EAAW9B,IAAI8E,EAAUC,SAAS,KAC9B5B,EAAWa,EAAM,KCRtB,SAAwBlC,EAAYgD,EAAWY,EAASC,EAAQ,GACnE,MAAMhB,EAAeG,EAAUC,UAAS,WACpC,IACIW,EAAQ/X,KAAKyG,MAEjB,MAAOsJ,GACHoE,EAAWnE,MAAMD,MAEtBiI,GACH7D,EAAW9B,IAAI2E,GDAPiB,CAAe9D,EAAYgD,GAAW,WAClC,MAAM,MAAErW,EAAK,KAAEuU,GAASG,EAAShC,OAC7B6B,EACAlB,EAAWV,YAGXU,EAAWX,KAAK1S,GAChB2F,KAAK2Q,kBAIV,IAAM5H,EAAWgG,aAA2C,EAASA,EAAS0C,SAAW1C,EAAS0C,WJM9FC,CAAiB9B,EAAOc,GAGvC,MAAMM,EAAiCpB,GMhBpC,SAAS+B,EAAK/B,EAAOc,GACxB,OAAOA,EAAYO,EAAUrB,EAAOc,GAAakB,EAAUhC,GAExD,SAASgC,EAAUhC,GACtB,GAAIA,aAAiB,EACjB,OAAOA,EAEX,GAAa,MAATA,EAAe,CACf,GAAIgB,EAAoBhB,GACpB,OAiBmBmB,EAjBUnB,EAkB9B,IAAI,EAAYlC,IACnB,MAAMmE,EAAMd,EAAI,KAChB,GAAIhI,EAAW8I,EAAI5D,WACf,OAAO4D,EAAI5D,UAAUP,GAEzB,MAAM,IAAIlE,UAAU,oEArBpB,GAAI6F,EAAYO,GACZ,OAAOkC,EAAclC,GAEzB,GAAIL,EAAUK,GACV,OA4BSmC,EA5BUnC,EA6BpB,IAAI,EAAYlC,IACnBqE,EACKlD,KAAMxU,IACFqT,EAAW/C,SACZ+C,EAAWX,KAAK1S,GAChBqT,EAAWV,aAEf1D,GAAQoE,EAAWnE,MAAMD,IACxBuF,KAAK,KAAMtC,KAnChB,GAAIuE,EAAgBlB,GAChB,OAoDeoC,EApDUpC,EAqD1B,IAAI,EAAYlC,KAI3B,SAAiBsE,EAAetE,GAC5B,IAAIuE,EAAiBC,EACjBC,EAAKhH,EACT,OAAO+C,EAAUlO,UAAM,OAAQ,GAAQ,YACnC,IACI,IAAKiS,EAAkBjD,EAAcgD,KAAgBE,QAA0BD,EAAgBlF,QAA2B6B,MAAO,CAC7H,MAAMvU,EAAQ6X,EAAkB7X,MAChCqT,EAAWX,KAAK1S,IAGxB,MAAO+X,GAASD,EAAM,CAAE5I,MAAO6I,GAC/B,QACI,IACQF,IAAsBA,EAAkBtD,OAASzD,EAAK8G,EAAgBR,gBAAetG,EAAG5R,KAAK0Y,IAErG,QAAU,GAAIE,EAAK,MAAMA,EAAI5I,OAEjCmE,EAAWV,eApBXnM,CAAQmR,EAAetE,GAAY2E,MAAO/I,GAAQoE,EAAWnE,MAAMD,MApDnE,GAAIuH,EAAWjB,GACX,OAkCU0C,EAlCU1C,EAmCrB,IAAI,EAAYlC,IACnB,MAAMqB,EAAWuD,EAAS,KAC1B,MAAQ5E,EAAW/C,QAAQ,CACvB,MAAM,KAAEiE,EAAI,MAAEvU,GAAU0U,EAAShC,OAC7B6B,EACAlB,EAAWV,WAGXU,EAAWX,KAAK1S,GAGxB,MAAO,IAAM0O,EAAWgG,aAA2C,EAASA,EAAS0C,SAAW1C,EAAS0C,WAZjH,IAAsBa,EAeKN,EA3BND,EAjBUhB,EAF3B,MAAMC,EAAiCpB,GAWpC,SAASkC,EAAc3M,GAC1B,OAAO,IAAI,EAAYuI,IACnB,IAAK,IAAItU,EAAI,EAAGA,EAAI+L,EAAM5H,SAAWmQ,EAAW/C,OAAQvR,IACpDsU,EAAWX,KAAK5H,EAAM/L,IAE1BsU,EAAWV,aChDZ,SAASuF,EAASxE,EAASyE,EAAgBC,EAAaC,KAC3D,OAAI3J,EAAWyJ,GACJD,EAAS,CAACxL,EAAG3N,IAAMoO,EAAI,CAACR,EAAG2L,IAAOH,EAAezL,EAAGC,EAAG5N,EAAGuZ,GAAvCnL,CAA4CoK,EAAU7D,EAAQhH,EAAG3N,KAAMqZ,IAElE,iBAAnBD,IACZC,EAAaD,GAEVxJ,EAAQ,CAACE,EAAQwE,ICVrB,SAAwBxE,EAAQwE,EAAYK,EAAS0E,EAAYG,EAAcC,EAAQC,EAAmBC,GAC7G,IAAIC,EAAS,GACTC,EAAS,EACTzI,EAAQ,EACR0I,GAAa,EACjB,MAAMC,EAAgB,MACdD,GAAeF,EAAOzV,QAAW0V,GACjCvF,EAAWV,YAGboG,EAAa/Y,GAAW4Y,EAASR,EAAaY,EAAWhZ,GAAS2Y,EAAO3R,KAAKhH,GAC9EgZ,EAAchZ,IAChBwY,GAAUnF,EAAWX,KAAK1S,GAC1B4Y,IACArB,EAAU7D,EAAQ1T,EAAOmQ,MAAUyD,UAAU,IAAI,EAAmBP,EAAa4F,IAC7EV,SAA4DA,EAAaU,GACrET,EACAO,EAAUE,GAGV5F,EAAWX,KAAKuG,SAErBrH,EAAW,KAEV,IADAgH,IACOD,EAAOzV,QAAU0V,EAASR,GAAY,CACzC,MAAMc,EAAgBP,EAAOQ,QAC7BV,EAAoBpF,EAAW9B,IAAIkH,EAAkBnC,SAAS,IAAM0C,EAAWE,KAAmBF,EAAWE,GAEjHJ,QAOR,OAJAjK,EAAO+E,UAAU,IAAI,EAAmBP,EAAY0F,OAAWnH,EAAW,KACtEiH,GAAa,EACbC,OAEG,KACHH,EAAS,KACTD,SAAwEA,KD3BrCU,CAAevK,EAAQwE,EAAYK,EAAS0E,Kb4DvF,EAAW/X,OAAUuT,GACV,IAAI,EAAWA,GevEnB,SAASyF,EAASjB,EAAaC,KAClC,OAAOH,EAAS9C,EAAUgD,GCDvB,SAASkB,EAAkB/D,EAAOc,GACrC,OAAOA,EAAYD,EAAcb,EAAOc,GAAaoB,EAAclC,GCHvE,MAAM,QAAE9E,GAAYjM,MACb,SAAS+U,EAAetO,GAC3B,OAAuB,IAAhBA,EAAK/H,QAAgBuN,EAAQxF,EAAK,IAAMA,EAAK,GAAKA,ECDtD,MAAMkG,EAAQ,IAAI,EAAWkC,GAAcA,EAAWV,YCAtD,SAAS6G,EAAYxZ,GACxB,OAAOA,GAAS0O,EAAW1O,EAAMsW,UCArC,SAASmD,EAAKxJ,GACV,OAAOA,EAAIA,EAAI/M,OAAS,GAErB,SAASwW,EAAkBzO,GAC9B,OAAOyD,EAAW+K,EAAKxO,IAASA,EAAK0O,WAAQ/H,EAE1C,SAASgI,GAAa3O,GACzB,OAAOuO,EAAYC,EAAKxO,IAASA,EAAK0O,WAAQ/H,ECH3C,SAASiI,MAAS5O,GACrB,MAAMoL,EAAYuD,GAAa3O,GACzBmN,EDGH,SAAmBnN,EAAM6O,GAC5B,MAA6B,iBAAfL,EAAKxO,GAAqBA,EAAK0O,MAAQG,ECJlCC,CAAU9O,EAAMoN,KAC7B2B,EAAUT,EAAetO,GAC/B,OAAQ+O,EAAQ9W,OAGS,IAAnB8W,EAAQ9W,OAEFqU,EAAUyC,EAAQ,IAElBX,EAASjB,EAATiB,CAAqBC,EAAkBU,EAAS3D,IALpDlF,ECTL,SAAS8I,GAAUvG,EAASyE,GAC/B,OAAOxJ,EAAQ,CAACE,EAAQwE,KACpB,IAAI6G,EAAkB,KAClB/J,EAAQ,EACR0I,GAAa,EACjB,MAAMC,EAAgB,IAAMD,IAAeqB,GAAmB7G,EAAWV,WACzE9D,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,IACjDka,SAAkEA,EAAgB1I,cAClF,IAAI2I,EAAa,EACjB,MAAMC,EAAajK,IACnBoH,EAAU7D,EAAQ1T,EAAOoa,IAAaxG,UAAWsG,EAAkB,IAAI,EAAmB7G,EAAa4F,GAAe5F,EAAWX,KAAKyF,EAAiBA,EAAenY,EAAOiZ,EAAYmB,EAAYD,KAAgBlB,QAAarH,EAAW,KACzOsI,EAAkB,KAClBpB,aAELlH,EAAW,KACViH,GAAa,EACbC,SClBL,MAAMuB,GAA0BjL,EAAkBO,GAAW,WAChEA,EAAOhK,MACPA,KAAKrG,KAAO,0BACZqG,KAAKkK,QAAU,wBCAZ,MAAM,WAAgB,EACzB,cACI0C,QACA5M,KAAK2U,UAAY,GACjB3U,KAAK2K,QAAS,EACd3K,KAAK6M,WAAY,EACjB7M,KAAK4U,UAAW,EAChB5U,KAAK6U,YAAc,KAEvB,KAAK5E,GACD,MAAMjT,EAAU,IAAI,GAAiBgD,KAAMA,MAE3C,OADAhD,EAAQiT,SAAWA,EACZjT,EAEX,iBACI,GAAIgD,KAAK2K,OACL,MAAM,IAAI+J,GAGlB,KAAKra,GAED,GADA2F,KAAK8U,kBACA9U,KAAK6M,UAAW,CACjB,MAAMkI,EAAO/U,KAAK2U,UAAUnS,QAC5B,IAAK,MAAMwS,KAAYD,EACnBC,EAASjI,KAAK1S,IAI1B,MAAMiP,GAEF,GADAtJ,KAAK8U,kBACA9U,KAAK6M,UAAW,CACjB7M,KAAK4U,SAAW5U,KAAK6M,WAAY,EACjC7M,KAAK6U,YAAcvL,EACnB,MAAM,UAAEqL,GAAc3U,KACtB,KAAO2U,EAAUpX,QACboX,EAAUnB,QAAQjK,MAAMD,IAIpC,WAEI,GADAtJ,KAAK8U,kBACA9U,KAAK6M,UAAW,CACjB7M,KAAK6M,WAAY,EACjB,MAAM,UAAE8H,GAAc3U,KACtB,KAAO2U,EAAUpX,QACboX,EAAUnB,QAAQxG,YAI9B,cACIhN,KAAK6M,UAAY7M,KAAK2K,QAAS,EAC/B3K,KAAK2U,UAAY,KAErB,cAAcjH,GAEV,OADA1N,KAAK8U,iBACElI,MAAMuD,cAAczC,GAE/B,WAAWA,GAGP,OAFA1N,KAAK8U,iBACL9U,KAAKiV,wBAAwBvH,GACtB1N,KAAKkV,gBAAgBxH,GAEhC,gBAAgBA,GACZ,MAAM,SAAEkH,EAAQ,UAAE/H,EAAS,UAAE8H,GAAc3U,KAC3C,OAAO4U,GAAY/H,EACbnB,GACCiJ,EAAUtT,KAAKqM,GAAa,IAAI,EAAa,IAAMrD,EAAUrK,KAAK2U,UAAWjH,KAExF,wBAAwBA,GACpB,MAAM,SAAEkH,EAAQ,YAAEC,EAAW,UAAEhI,GAAc7M,KACzC4U,EACAlH,EAAWnE,MAAMsL,GAEZhI,GACLa,EAAWV,WAGnB,eACI,MAAMwC,EAAa,IAAI,EAEvB,OADAA,EAAWtG,OAASlJ,KACbwP,GAGf,GAAQ9U,OAAS,CAACiS,EAAazD,IACpB,IAAI,GAAiByD,EAAazD,GAEtC,MAAM,WAAyB,GAClC,YAAYyD,EAAazD,GACrB0D,QACA5M,KAAK2M,YAAcA,EACnB3M,KAAKkJ,OAASA,EAElB,KAAK7O,GACD,IAAI8Q,EAAIgK,EACwE,QAA/EA,EAAiC,QAA3BhK,EAAKnL,KAAK2M,mBAAgC,IAAPxB,OAAgB,EAASA,EAAG4B,YAAyB,IAAPoI,GAAyBA,EAAG5b,KAAK4R,EAAI9Q,GAEjI,MAAMiP,GACF,IAAI6B,EAAIgK,EACyE,QAAhFA,EAAiC,QAA3BhK,EAAKnL,KAAK2M,mBAAgC,IAAPxB,OAAgB,EAASA,EAAG5B,aAA0B,IAAP4L,GAAyBA,EAAG5b,KAAK4R,EAAI7B,GAElI,WACI,IAAI6B,EAAIgK,EAC4E,QAAnFA,EAAiC,QAA3BhK,EAAKnL,KAAK2M,mBAAgC,IAAPxB,OAAgB,EAASA,EAAG6B,gBAA6B,IAAPmI,GAAyBA,EAAG5b,KAAK4R,GAEjI,WAAWuC,GACP,IAAIvC,EAAIgK,EACR,OAAmG,QAA3FA,EAA4B,QAAtBhK,EAAKnL,KAAKkJ,cAA2B,IAAPiC,OAAgB,EAASA,EAAG8C,UAAUP,UAAgC,IAAPyH,EAAgBA,EAAKzJ,GC9GjI,MAAM0J,GAAwB,CACjCC,IAAG,KACSD,GAAsB/I,UAAYiJ,MAAMD,MAEpDhJ,cAAUJ,GCFP,MAAM,WAAsB,GAC/B,YAAYsJ,EAAa7C,IAAU8C,EAAa9C,IAAU+C,EAAoBL,IAC1ExI,QACA5M,KAAKuV,WAAaA,EAClBvV,KAAKwV,WAAaA,EAClBxV,KAAKyV,kBAAoBA,EACzBzV,KAAKgT,OAAS,GACdhT,KAAK0V,oBAAqB,EAC1B1V,KAAK0V,mBAAqBF,IAAe9C,IACzC1S,KAAKuV,WAAazY,KAAKiC,IAAI,EAAGwW,GAC9BvV,KAAKwV,WAAa1Y,KAAKiC,IAAI,EAAGyW,GAElC,KAAKnb,GACD,MAAM,UAAEwS,EAAS,OAAEmG,EAAM,mBAAE0C,EAAkB,kBAAED,EAAiB,WAAED,GAAexV,KAC5E6M,IACDmG,EAAO3R,KAAKhH,IACXqb,GAAsB1C,EAAO3R,KAAKoU,EAAkBJ,MAAQG,IAEjExV,KAAK2V,aACL/I,MAAMG,KAAK1S,GAEf,WAAWqT,GACP1N,KAAK8U,iBACL9U,KAAK2V,aACL,MAAMpF,EAAevQ,KAAKkV,gBAAgBxH,IACpC,mBAAEgI,EAAkB,OAAE1C,GAAWhT,KACjC+U,EAAO/B,EAAOxQ,QACpB,IAAK,IAAIpJ,EAAI,EAAGA,EAAI2b,EAAKxX,SAAWmQ,EAAW/C,OAAQvR,GAAKsc,EAAqB,EAAI,EACjFhI,EAAWX,KAAKgI,EAAK3b,IAGzB,OADA4G,KAAKiV,wBAAwBvH,GACtB6C,EAEX,aACI,MAAM,WAAEgF,EAAU,kBAAEE,EAAiB,OAAEzC,EAAM,mBAAE0C,GAAuB1V,KAChE4V,GAAsBF,EAAqB,EAAI,GAAKH,EAE1D,GADAA,EAAa7C,KAAYkD,EAAqB5C,EAAOzV,QAAUyV,EAAOvI,OAAO,EAAGuI,EAAOzV,OAASqY,IAC3FF,EAAoB,CACrB,MAAML,EAAMI,EAAkBJ,MAC9B,IAAIvB,EAAO,EACX,IAAK,IAAI1a,EAAI,EAAGA,EAAI4Z,EAAOzV,QAAUyV,EAAO5Z,IAAMic,EAAKjc,GAAK,EACxD0a,EAAO1a,EAEX0a,GAAQd,EAAOvI,OAAO,EAAGqJ,EAAO,KC5C5C,MAAQhJ,QAAO,IAAKjM,MAIb,SAASgX,GAAiB9F,GAC7B,OAAOvI,EAAIlC,GAJf,SAAqByK,EAAIzK,GACrB,OAAO,GAAQA,GAAQyK,KAAMzK,GAAQyK,EAAGzK,GAGrBwQ,CAAY/F,EAAIzK,ICAvC,MAAMyQ,GAA0B,CAAC,cAAe,kBAC1CC,GAAqB,CAAC,mBAAoB,uBAC1CC,GAAgB,CAAC,KAAM,OACtB,SAASC,GAAUC,EAAQC,EAAW7Z,EAASiW,GAKlD,GAJIzJ,EAAWxM,KACXiW,EAAiBjW,EACjBA,OAAU0P,GAEVuG,EACA,OAAO0D,GAAUC,EAAQC,EAAW7Z,GAAS8Z,KAAKR,GAAiBrD,IAEvE,MAAO5G,EAAKZ,GA+BhB,SAAuBmL,GACnB,OAAOpN,EAAWoN,EAAOG,mBAAqBvN,EAAWoN,EAAOI,qBAhC1CC,CAAcL,GAC9BH,GAAmBxO,IAAKiP,GAAgBC,GAAYP,EAAOM,GAAYL,EAAWM,EAASna,IAwBrG,SAAiC4Z,GAC7B,OAAOpN,EAAWoN,EAAOpQ,cAAgBgD,EAAWoN,EAAOjQ,gBAvBnDyQ,CAAwBR,GAClBJ,GAAwBvO,IAAIoP,GAAwBT,EAAQC,IAwB9E,SAAmCD,GAC/B,OAAOpN,EAAWoN,EAAOrQ,KAAOiD,EAAWoN,EAAOlQ,KAxBpC4Q,CAA0BV,GACtBF,GAAczO,IAAIoP,GAAwBT,EAAQC,IAClD,GAClB,OAAKxK,GACGyD,EAAY8G,GACL5D,EAAUuE,GAAcZ,GAAUY,EAAWV,EAAW7Z,GAAxDgW,CAAkEoB,EAAkBwC,IAG5F,IAAI,EAAYzI,IACnB,IAAK9B,EACD,MAAM,IAAIpC,UAAU,wBAExB,MAAMkN,EAAU,IAAIpR,IAASoI,EAAWX,KAAK,EAAIzH,EAAK/H,OAAS+H,EAAOA,EAAK,IAE3E,OADAsG,EAAI8K,GACG,IAAM1L,EAAO0L,KAG5B,SAASE,GAAwBT,EAAQC,GACrC,OAAQK,GAAgBC,GAAYP,EAAOM,GAAYL,EAAWM,GCtC/D,SAASK,GAAM1c,GAClB,OAAO2O,EAAQ,CAACE,EAAQwE,KACpBxE,EAAO+E,UAAU,IAAI,EAAmBP,EAAY,IAAMA,EAAWX,KAAK1S,OCwC3E,SAAS2c,GACdC,EAAkBC,EAAmBC,UAErC,OAAOD,EAAKE,cAAiBH,SAAahL,EAqBrC,SAASoL,GACdJ,EAAkBC,EAAmBC,UAErC,MAAMG,EAAKN,GAAcC,EAAUC,GACnC,QAAkB,IAAPI,EACT,MAAM,IAAIC,eACR,8BAA8BN,oBAElC,OAAOK,EAQF,SAASE,KACd,OAAOL,SAASM,yBAAyBC,YACrCP,SAASM,mBACTxL,ECpFC,SAASrH,MAAUU,GACtB,OCFOoO,EAAS,EDETiE,CAAYhE,EAAkBrO,EAAM2O,GAAa3O,KEDrD,SAASsS,MAAaC,GACzB,MAAMnH,EAAYuD,GAAa4D,GAC/B,OAAO7O,EAAQ,CAACE,EAAQwE,MACnBgD,EAAY9L,GAAOiT,EAAQ3O,EAAQwH,GAAa9L,GAAOiT,EAAQ3O,IAAS+E,UAAUP,KCJpF,SAASoK,GAAqBC,EAASC,GAE1C,OADAD,EAAUA,QAAyCA,EAAUE,GACtDjP,EAAQ,CAACE,EAAQwE,KACpB,IAAIoC,EACAoI,GAAQ,EACZhP,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,KAC/C6d,IAAWpI,EAAOzV,EAAQ,KAAQ0d,EAAQjI,EAAOA,EAAOkI,EAAcA,EAAY3d,GAASA,KACzFqT,EAAWX,KAAK1S,GACpB6d,GAAQ,OAIpB,SAASD,GAAelR,EAAGC,GACvB,OAAOD,IAAMC,ECZV,SAASmR,MAAM7S,GAClB,MAAMoL,EAAYuD,GAAa3O,GAC/B,OAAOoL,EAAYD,EAAcnL,EAAMoL,GAAaiD,EAAkBrO,GCHnE,MAAM8S,GAAQ,IAAI,EAAWhT,GCD7B,SAASiT,GAASC,GACrB,OAAOtP,EAAQ,CAACE,EAAQwE,KACpBxE,EAAO+E,UAAUP,GACjBA,EAAW9B,IAAI0M,KCDhB,SAASC,GAAMhc,GAClBA,EAAUA,GAAW,GACrB,MAAM,UAAEic,EAAY,KAAM,IAAI,IAAS,gBAAEC,GAAkB,EAAI,aAAEC,GAAe,EAAI,oBAAEC,GAAsB,GAASpc,EACrH,IAAIqc,EAAa,KACb5b,EAAU,KACV6b,EAAW,EACXC,GAAe,EACfC,GAAa,EACjB,MAAMC,EAAQ,KACVJ,EAAa5b,EAAU,KACvB8b,EAAeC,GAAa,GAEhC,OAAO/P,EAAQ,CAACE,EAAQwE,KACpBmL,IACK7b,IACDA,EAAUwb,KAEd,MAAMS,EAAmBjc,EAAQiR,UAAUP,GAsB3C,OArBKkL,IACDA,EAAajH,EAAKzI,GAAQ+E,UAAU,CAChClB,KAAO1S,GAAU2C,EAAQ+P,KAAK1S,GAC9BkP,MAAQD,IACJyP,GAAa,EACb,MAAMG,EAAOlc,EACT0b,GACAM,IAEJE,EAAK3P,MAAMD,IAEf0D,SAAU,KACN8L,GAAe,EACf,MAAMI,EAAOlc,EACTyb,GACAO,IAEJE,EAAKlM,eAIV,KAGH,GAFA6L,IACAI,EAAiBpN,eACZgN,GAAYF,IAAwBI,IAAeD,EAAc,CAClE,MAAMK,EAAOP,EACbI,IACAG,SAA4CA,EAAKtN,kBC9C1D,SAASuN,GAAYC,EAAoB7D,EAAY9E,GACxD,IAAIvF,EAAIgK,EACR,IAAII,EACAsD,GAAW,EAUf,OATIQ,GAAoD,iBAAvBA,GAC7B9D,EAAsD,QAAxCpK,EAAKkO,EAAmB9D,kBAA+B,IAAPpK,EAAgBA,EAAKuH,IACnF8C,EAAsD,QAAxCL,EAAKkE,EAAmB7D,kBAA+B,IAAPL,EAAgBA,EAAKzC,IACnFmG,IAAaQ,EAAmBR,SAChCnI,EAAY2I,EAAmB3I,WAG/B6E,EAAa8D,QAA+DA,EAAqB3G,IAE9F6F,GAAM,CACTC,UAAW,IAAM,IAAI,GAAcjD,EAAYC,EAAY9E,GAC3DgI,cAAc,EACdD,iBAAiB,EACjBE,oBAAqBE,ICftB,SAASS,GAAIhM,EAAgB/D,EAAOyD,GACvC,MAAMuM,EAAcxQ,EAAWuE,IAAmB/D,GAASyD,EAAW,CAAED,KAAMO,EAAgB/D,QAAOyD,YAAaM,EAClH,OAAOiM,EACDvQ,EAAQ,CAACE,EAAQwE,KACfxE,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,IACjD,IAAI8Q,EACwB,QAA3BA,EAAKoO,EAAYxM,YAAyB,IAAP5B,GAAyBA,EAAG5R,KAAKggB,EAAalf,GAClFqT,EAAWX,KAAK1S,IAChBiP,IACA,IAAI6B,EACyB,QAA5BA,EAAKoO,EAAYhQ,aAA0B,IAAP4B,GAAyBA,EAAG5R,KAAKggB,EAAajQ,GACnFoE,EAAWnE,MAAMD,IAClB,KACC,IAAI6B,EAC4B,QAA/BA,EAAKoO,EAAYvM,gBAA6B,IAAP7B,GAAyBA,EAAG5R,KAAKggB,GACzE7L,EAAWV,gBAIfyC,ECrBL,SAASlP,GAAOiZ,EAAWxL,GAC9B,OAAOhF,EAAQ,CAACE,EAAQwE,KACpB,IAAIlD,EAAQ,EACZtB,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,GAAUmf,EAAUjgB,KAAKyU,EAAS3T,EAAOmQ,MAAYkD,EAAWX,KAAK1S,OCqDlI,MAAMof,GAAS,IAAI,ICxDGC,GDoEE,IAAMvB,GAC5B,IAAIwB,eAAeC,IACjB,IAAK,MAAMC,KAASD,EAClBH,GAAO1M,KAAK8M,MCtEP,IAAI,EAAYnM,IACnBkE,EAAU8H,MAAqBzL,UAAUP,MDwE9C2I,KACC/B,GAAUwF,GAAU1B,GAAM/B,KAAKuB,GAAUkC,IACtCzD,KACCgC,GAAS,IAAMyB,EAAOC,gBAG1BX,GAAY,IChFT,IAAeM,GD8Ff,SAASM,GAAe1C,GAC7B,MAAO,CACL2C,MAAQ3C,EAAG4C,YACXC,OAAQ7C,EAAG8C,cEjDR,SAASC,GAAiB/C,GAC/B,MAAO,CACLhI,EAAGgI,EAAGgD,WACNC,EAAGjD,EAAGkD,WAqCH,SAASC,GACdnD,EAAiBoD,EAAY,IAE7B,OA3BK,SACLpD,GAEA,OAAOpD,GACLgC,GAAUoB,EAAI,UACdpB,GAAUyE,OAAQ,WAEjBtE,KACC7O,EAAI,IAAM6S,GAAiB/C,IAC3BM,GAAUyC,GAAiB/C,KAkBxBsD,CAAmBtD,GACvBjB,KACC7O,EAAI,EAAG+S,QACL,MAAMM,EAAUb,GAAe1C,GAE/B,OAAOiD,GFYR,SAA+BjD,GACpC,MAAO,CACL2C,MAAQ3C,EAAGwD,YACXX,OAAQ7C,EAAGyD,cEhBSC,CAAsB1D,GAE5B6C,OAASU,EAAQV,OAASO,IAGtC5C,MCxDIT,GAAkB,2BAClBA,GAAkB,2BCTrB,SAAS4D,KACd,OAAO,IAAIC,IAAIC,SAASC,MCGnB,SAAS,GACdC,EAAa9e,EAAuB,CAAE+e,YAAa,gBAEnD,OAAO3J,EAAK4J,MAAMF,EAAK9e,IACpB8Z,KACC9V,GAAOib,GAAsB,MAAfA,EAAIC,SC/CxB,MAAQ3Q,QAAO,IAAKjM,OACd,eAAE6c,GAAgB1gB,UAAW2gB,GAAaC,KAAMC,IAAY/hB,OAC3D,SAASgiB,GAAqBxW,GACjC,GAAoB,IAAhBA,EAAK/H,OAAc,CACnB,MAAM2a,EAAQ5S,EAAK,GACnB,GAAI,GAAQ4S,GACR,MAAO,CAAE5S,KAAM4S,EAAO0D,KAAM,MAEhC,IAUQ7K,EAVGmH,IAWc,iBAARnH,GAAoB2K,GAAe3K,KAAS4K,GAX1C,CACf,MAAMC,EAAOC,GAAQ3D,GACrB,MAAO,CACH5S,KAAMsW,EAAKpU,IAAK7M,GAAQud,EAAMvd,IAC9BihB,SAMhB,IAAgB7K,EAFZ,MAAO,CAAEzL,KAAMA,EAAMsW,KAAM,MCTxB,SAASG,MAAiBzW,GAC7B,MAAMoL,EAAYuD,GAAa3O,GACzBkN,EAAiBuB,EAAkBzO,IACjCA,KAAM0W,EAAW,KAAEJ,GAASE,GAAqBxW,GACzD,GAA2B,IAAvB0W,EAAYze,OACZ,OAAOoU,EAAK,GAAIjB,GAEpB,MAAM/B,EAAS,IAAI,EA+BhB,SAA2BqN,EAAatL,EAAWuL,EAAiBxM,GACvE,OAAQ/B,IAyBJwO,GAAcxL,EAxBW,KACrB,MAAM,OAAEnT,GAAWye,EACbnE,EAAS,IAAIhZ,MAAMtB,GACzB,IAAI0V,EAAS1V,EACb,MAAM4e,EAAYH,EAAYxU,IAAI,KAAM,GACxC,IAAI4U,GAAwB,EAE5B,IAAK,IAAIhjB,EAAI,EAAGA,EAAImE,EAAQnE,IAAK,CAc7B8iB,GAAcxL,EAbI,KACCiB,EAAKqK,EAAY5iB,GAAIsX,GAC7BzC,UAAU,IAAI,GAAwBP,EAAarT,IACtDwd,EAAOze,GAAKiB,EACR+hB,IACAD,EAAU/iB,IAAK,EACfgjB,GAAyBD,EAAUE,MAAM5M,IAExC2M,GAVE1O,EAAWX,KAAKkP,EAAepE,EAAOrV,WAa9C,IAAmB,KAAXyQ,KAEqBvF,KAGDA,IAzDjB4O,CAAkBN,EAAatL,EAAWkL,EAE/D/D,IACG,MAAMxd,EAAQ,GACd,IAAK,IAAIjB,EAAI,EAAGA,EAAIye,EAAOta,OAAQnE,IAC/BiB,EAAMuhB,EAAKxiB,IAAMye,EAAOze,GAE5B,OAAOiB,GAGXoV,IACR,OAAI+C,EACO7D,EAAO0H,KAAKR,GAAiBrD,IAEjC7D,EAEX,MAAM,WAAgC,EAClC,YAAYhC,EAAaQ,EAAOoP,GAC5B3P,MAAMD,GACN3M,KAAKmN,MAAQA,EACbnN,KAAKuc,eAAiBA,EAE1B,YACQvc,KAAKuc,iBACL3P,MAAMS,YAGNrN,KAAK6L,eAiCjB,SAASqQ,GAAcxL,EAAWY,EAASf,GACnCG,EACAH,EAAa3E,IAAI8E,EAAUC,SAASW,IAGpCA,IC9ED,SAASkL,GAAwB7hB,EAAKod,GACzC,OAAOD,GAAqB,CAACxI,EAAGiL,IAAMxC,EAAUA,EAAQzI,EAAE3U,GAAM4f,EAAE5f,IAAQ2U,EAAE3U,KAAS4f,EAAE5f,IC8DpF,SAAS8hB,GACdC,EAAqBxF,EAAmBC,UAExC,OAAOE,GAAkB,uBAAuBqF,KAASxF,GAapD,SAASyF,GACdD,EAAqBxF,EAAmBC,UAExC,OrByBK,SACLF,EAAkBC,EAAmBC,UAErC,OAAOtY,MAAM8S,KAAKuF,EAAK0F,iBAAoB3F,IqB5BpC4F,CAAY,uBAAuBH,KAASxF,GCArD,MAAM4F,GAASzF,GAAkB,aAC3B,GAAiB0F,KAAKC,MAAMF,GAAOG,aAqClC,SAASC,GACdviB,EAAkBN,GAElB,YAAwB,IAAVA,EACV,GAAO8iB,aAAaxiB,GAAK8I,QAAQ,IAAKpJ,EAAM8P,YAC5C,GAAOgT,aAAaxiB,GAzC1B,GAAOyiB,KAAO,IAAIlC,IAAI,GAAOkC,KAAMnC,MAChC9Q,WACA1G,QAAQ,MAAO,ICtFX,MAAM,WAAe,EACxB,YAAYiN,EAAW2M,GACnBzQ,QAEJ,SAAS0Q,EAAO/L,EAAQ,GACpB,OAAOvR,MCNR,MAAMud,GAAmB,CAC5B,eAAejY,GACX,MAAM,SAAE+G,GAAakR,GACrB,QAASlR,aAA2C,EAASA,EAASmR,cAAgBA,gBAAgBlY,IAE1G,cAAcgH,GACV,MAAM,SAAED,GAAakR,GACrB,QAASlR,aAA2C,EAASA,EAASoR,gBAAkBA,eAAenR,IAE3GD,cAAUJ,GCNP,MAAM,WAAoB,GAC7B,YAAYyE,EAAW2M,GACnBzQ,MAAM8D,EAAW2M,GACjBrd,KAAK0Q,UAAYA,EACjB1Q,KAAKqd,KAAOA,EACZrd,KAAK0d,SAAU,EAEnB,SAASJ,EAAO/L,EAAQ,GACpB,GAAIvR,KAAK2K,OACL,OAAO3K,KAEXA,KAAKsd,MAAQA,EACb,MAAMK,EAAK3d,KAAK2d,GACVjN,EAAY1Q,KAAK0Q,UAOvB,OANU,MAANiN,IACA3d,KAAK2d,GAAK3d,KAAK4d,eAAelN,EAAWiN,EAAIpM,IAEjDvR,KAAK0d,SAAU,EACf1d,KAAKuR,MAAQA,EACbvR,KAAK2d,GAAK3d,KAAK2d,IAAM3d,KAAK6d,eAAenN,EAAW1Q,KAAK2d,GAAIpM,GACtDvR,KAEX,eAAe0Q,EAAWoN,EAAKvM,EAAQ,GACnC,OAAOgM,GAAiBC,YAAY9M,EAAUqN,MAAMnjB,KAAK8V,EAAW1Q,MAAOuR,GAE/E,eAAeyM,EAAYL,EAAIpM,EAAQ,GACnC,GAAa,MAATA,GAAiBvR,KAAKuR,QAAUA,IAA0B,IAAjBvR,KAAK0d,QAC9C,OAAOC,EAEXJ,GAAiBE,cAAcE,GAGnC,QAAQL,EAAO/L,GACX,GAAIvR,KAAK2K,OACL,OAAO,IAAI3G,MAAM,gCAErBhE,KAAK0d,SAAU,EACf,MAAMnU,EAAQvJ,KAAKie,SAASX,EAAO/L,GACnC,GAAIhI,EACA,OAAOA,GAEe,IAAjBvJ,KAAK0d,SAAgC,MAAX1d,KAAK2d,KACpC3d,KAAK2d,GAAK3d,KAAK4d,eAAe5d,KAAK0Q,UAAW1Q,KAAK2d,GAAI,OAG/D,SAASL,EAAOY,GACZ,IACIC,EADAC,GAAU,EAEd,IACIpe,KAAKqd,KAAKC,GAEd,MAAOjZ,GACH+Z,GAAU,EACVD,IAAgB9Z,GAAKA,GAAM,IAAIL,MAAMK,GAEzC,GAAI+Z,EAEA,OADApe,KAAK6L,cACEsS,EAGf,cACI,IAAKne,KAAK2K,OAAQ,CACd,MAAM,GAAEgT,EAAE,UAAEjN,GAAc1Q,MACpB,QAAEqe,GAAY3N,EACpB1Q,KAAKqd,KAAOrd,KAAKsd,MAAQtd,KAAK0Q,UAAY,KAC1C1Q,KAAK0d,SAAU,EACfrT,EAAUgU,EAASre,MACT,MAAN2d,IACA3d,KAAK2d,GAAK3d,KAAK4d,eAAelN,EAAWiN,EAAI,OAEjD3d,KAAKuR,MAAQ,KACb3E,MAAMf,gBCzEX,MAAMyS,GACT,YAAYC,EAAqBlJ,EAAMiJ,GAAUjJ,KAC7CrV,KAAKue,oBAAsBA,EAC3Bve,KAAKqV,IAAMA,EAEf,SAASgI,EAAM9L,EAAQ,EAAG+L,GACtB,OAAO,IAAItd,KAAKue,oBAAoBve,KAAMqd,GAAM1M,SAAS2M,EAAO/L,IAGxE+M,GAAUjJ,IAAMD,GAAsBC,ICT/B,MAAM,WAAuBiJ,GAChC,YAAYE,EAAiBnJ,EAAMiJ,GAAUjJ,KACzCzI,MAAM4R,EAAiBnJ,GACvBrV,KAAKqe,QAAU,GACfre,KAAKiT,QAAS,EACdjT,KAAKiR,eAAYhF,EAErB,MAAMwS,GACF,MAAM,QAAEJ,GAAYre,KACpB,GAAIA,KAAKiT,OAEL,YADAoL,EAAQhd,KAAKod,GAGjB,IAAIlV,EACJvJ,KAAKiT,QAAS,EACd,GACI,GAAI1J,EAAQkV,EAAOnN,QAAQmN,EAAOnB,MAAOmB,EAAOlN,OAC5C,YAECkN,EAASJ,EAAQ7K,SAE1B,GADAxT,KAAKiT,QAAS,EACV1J,EAAO,CACP,KAAOkV,EAASJ,EAAQ7K,SACpBiL,EAAO5S,cAEX,MAAMtC,ICxBX,MAAMmV,GAAiB,IAAI,GAAe,IACpC,GAAQA,GCAd,SAASC,GAAKhgB,GACjB,OAAOA,GAAS,EAER,IAAM6M,EACRxC,EAAQ,CAACE,EAAQwE,KACf,IAAIkR,EAAO,EACX1V,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,MAC3CukB,GAAQjgB,IACV+O,EAAWX,KAAK1S,GACZsE,GAASigB,GACTlR,EAAWV,iBCR5B,SAAS6R,GAAUC,EAAuBC,GAC7C,OAAIA,EACQ7V,GAAWtE,GAAOma,EAAkB1I,KAAKsI,GAAK,GCHnD3V,EAAQ,CAACE,EAAQwE,KACpBxE,EAAO+E,UAAU,IAAI,EAAmBP,EAAYtI,ODEyB8D,EAAOmN,KAAKwI,GAAUC,KAEhGvM,EAAS,CAAClY,EAAOmQ,IAAUsU,EAAsBzkB,EAAOmQ,GAAO6L,KAAKsI,GAAK,GAAI5H,GAAM1c,KELvF,SAAS2kB,GAAMC,EAAU,EAAGC,EAAqBxO,EAAY,IAChE,IAAIyO,GAAoB,EASxB,OAR2B,MAAvBD,IACIrL,EAAYqL,GACZxO,EAAYwO,EAGZC,EAAmBD,GAGpB,IAAI,EAAYxR,IACnB,IAAI0R,GCfgB/kB,EDeE4kB,aCdF3J,OAAS+J,MAAMhlB,IDcD4kB,EAAUvO,EAAU2E,MAAQ4J,ECf/D,IAAqB5kB,EDgBhB+kB,EAAM,IACNA,EAAM,GAEV,IAAIvkB,EAAI,EACR,OAAO6V,EAAUC,UAAS,WACjBjD,EAAW/C,SACZ+C,EAAWX,KAAKlS,KACZ,GAAKskB,EACLnf,KAAK2Q,cAAS1E,EAAWkT,GAGzBzR,EAAWV,cAGpBoS,KExBJ,SAASE,MAAkBC,GAC9B,MAAMxR,EAAUgG,EAAkBwL,GAClC,OAAOvW,EAAQ,CAACE,EAAQwE,KACpB,MAAMxO,EAAMqgB,EAAOhiB,OACbiiB,EAAc,IAAI3gB,MAAMK,GAC9B,IAAIugB,EAAWF,EAAO/X,IAAI,KAAM,GAC5BkY,GAAQ,EACZ,IAAK,IAAItmB,EAAI,EAAGA,EAAI8F,EAAK9F,IACrBwY,EAAU2N,EAAOnmB,IAAI6U,UAAU,IAAI,EAAmBP,EAAarT,IAC/DmlB,EAAYpmB,GAAKiB,EACZqlB,GAAUD,EAASrmB,KACpBqmB,EAASrmB,IAAK,GACbsmB,EAAQD,EAASpD,MAAM5M,MAAegQ,EAAW,aAEvDxT,EAAW7G,IAElB8D,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,IACjD,GAAIqlB,EAAO,CACP,MAAM7H,EAAS,CAACxd,KAAUmlB,GAC1B9R,EAAWX,KAAKgB,EAAUA,KAAW8J,GAAUA,SCkCxD,SAAS8H,GACdrI,GAIA,MAAMsI,ECTD,SACLtI,GAEA,OAAOpD,GACLgC,GAAsBoB,EAAI,SAC1BpB,GAAsBoB,EAAI,SAEzBjB,KACC7O,EAAI,EAAGkV,UAAoB,UAATA,GAClB9E,GAAUN,IAAOE,ODANqI,CAAkBvI,GAC3BwI,EAAS5L,GACbgC,GAAUoB,EAAI,SACdpB,GAAUoB,EAAI,SAASjB,KEhEpB,SAAe+I,EAAK1O,EAAYgO,IACnC,MAAMqB,EAAWf,GAAMI,EAAK1O,GAC5B,OAAOmO,GAAU,IAAMkB,GF8DK,CAAM,KAEjC1J,KACC7O,EAAI,IAAM8P,EAAGjd,OACbud,GAAUN,EAAGjd,OACbyd,MAeJ,OAXA8H,EACGvJ,KACC9V,GAAO0S,IAAWA,GAClBqM,GAAeQ,IAEd7R,UAAU,EAAE,CAAE5T,MACb,MAAMoI,EAAO0U,SAASgE,SAAS6E,SAC/BC,GAAG,OAAQ,WAAY,GAAGxd,cAAiBpI,OAI1C0hB,GAAc,CAAC+D,EAAQF,IAC3BvJ,KACC7O,EAAI,EAAEnN,EAAO6lB,MAAW,CAAGC,IAAK7I,EAAIjd,QAAO6lB,Y,YGxF1C,MAAME,GAAyB,CAClC,SAAS9H,GACL,IAAI+H,EAAUC,sBACVC,EAASC,qBACb,MAAM,SAAEnU,GAAa+T,GACjB/T,IACAgU,EAAUhU,EAASiU,sBACnBC,EAASlU,EAASmU,sBAEtB,MAAMlU,EAAS+T,EAASI,IACpBF,OAAStU,EACTqM,EAASmI,KAEb,OAAO,IAAI,EAAa,IAAMF,aAAuC,EAASA,EAAOjU,KAEzF,yBAAyBhH,GACrB,MAAM,SAAE+G,GAAa+T,GACrB,QAAS/T,aAA2C,EAASA,EAASiU,wBAA0BA,0BAA0Bhb,IAE9H,wBAAwBA,GACpB,MAAM,SAAE+G,GAAa+T,GACrB,QAAS/T,aAA2C,EAASA,EAASmU,uBAAyBA,yBAAyBlb,IAE5H+G,cAAUJ,GCtBP,MAAMyU,GAA0B,ICDhC,cAAsC,GACzC,MAAMjC,GACFze,KAAKiT,QAAS,EACdjT,KAAKiR,eAAYhF,EACjB,MAAM,QAAEoS,GAAYre,KACpB,IAAIuJ,EACAiB,GAAS,EACbiU,EAASA,GAAUJ,EAAQ7K,QAC3B,MAAM7U,EAAQ0f,EAAQ9gB,OACtB,GACI,GAAIgM,EAAQkV,EAAOnN,QAAQmN,EAAOnB,MAAOmB,EAAOlN,OAC5C,cAEG/G,EAAQ7L,IAAU8f,EAASJ,EAAQ7K,UAE9C,GADAxT,KAAKiT,QAAS,EACV1J,EAAO,CACP,OAASiB,EAAQ7L,IAAU8f,EAASJ,EAAQ7K,UACxCiL,EAAO5S,cAEX,MAAMtC,KClBX,cAAmC,GACtC,YAAYmH,EAAW2M,GACnBzQ,MAAM8D,EAAW2M,GACjBrd,KAAK0Q,UAAYA,EACjB1Q,KAAKqd,KAAOA,EAEhB,eAAe3M,EAAWiN,EAAIpM,EAAQ,GAClC,OAAc,OAAVA,GAAkBA,EAAQ,EACnB3E,MAAMiR,eAAenN,EAAWiN,EAAIpM,IAE/Cb,EAAU2N,QAAQhd,KAAKrB,MAChB0Q,EAAUO,YAAcP,EAAUO,UAAYmP,GAAuBE,sBAAsB,IAAM5P,EAAUqN,WAAM9R,MAE5H,eAAeyE,EAAWiN,EAAIpM,EAAQ,GAClC,GAAc,MAATA,GAAiBA,EAAQ,GAAgB,MAATA,GAAiBvR,KAAKuR,MAAQ,EAC/D,OAAO3E,MAAMgR,eAAelN,EAAWiN,EAAIpM,GAEd,IAA7Bb,EAAU2N,QAAQ9gB,SAClB6iB,GAAuBI,qBAAqB7C,GAC5CjN,EAAUO,eAAYhF,MCnB3B,SAAS0U,GAAUjQ,EAAWa,EAAQ,GACzC,OAAOvI,EAAQ,CAACE,EAAQwE,KACpBxE,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,GAAUqT,EAAW9B,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWX,KAAK1S,GAAQkX,IAAUjI,GAAQoE,EAAW9B,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWnE,MAAMD,GAAMiI,IAAS,IAAM7D,EAAW9B,IAAI8E,EAAUC,SAAS,IAAMjD,EAAWV,WAAYuE,QCF/R,SAAS,MAAO8C,GACnB,OAAOrL,EAAQ,CAACE,EAAQwE,MCGrB,YAAgBpI,GACnB,MAAMkN,EAAiBuB,EAAkBzO,GACnC+O,EAAUT,EAAetO,GAC/B,OAAO+O,EAAQ9W,OACT,IAAI,EAAYmQ,IACd,IAAIkT,EAAUvM,EAAQ7M,IAAI,IAAM,IAC5BqZ,EAAYxM,EAAQ7M,IAAI,KAAM,GAClCkG,EAAW9B,IAAI,KACXgV,EAAUC,EAAY,OAE1B,IAAK,IAAIC,EAAc,GAAIpT,EAAW/C,QAAUmW,EAAczM,EAAQ9W,OAAQujB,IAC1ElP,EAAUyC,EAAQyM,IAAc7S,UAAU,IAAI,EAAmBP,EAAarT,IAE1E,GADAumB,EAAQE,GAAazf,KAAKhH,GACtBumB,EAAQvE,MAAOrJ,GAAWA,EAAOzV,QAAS,CAC1C,MAAMoR,EAASiS,EAAQpZ,IAAKwL,GAAWA,EAAOQ,SAC9C9F,EAAWX,KAAKyF,EAAiBA,KAAkB7D,GAAUA,GACzDiS,EAAQG,KAAK,CAAC/N,EAAQ5Z,KAAO4Z,EAAOzV,QAAUsjB,EAAUznB,KACxDsU,EAAWV,kBAGpBf,EAAW,KACV4U,EAAUC,IAAe,GACxBF,EAAQE,GAAavjB,QAAUmQ,EAAWV,cAGnD,MAAO,KACH4T,EAAUC,EAAY,QAG5BrV,GD/BFwV,CAAU9X,KAAWmL,GAASpG,UAAUP,KEmDhD,SAASuT,GAAY3J,EAAiB4J,GAGpC,GAAqB,iBAAVA,GAAuC,iBAAVA,EACtC5J,EAAG6J,WAAaD,EAAM/W,gBAGjB,GAAI+W,aAAiBE,KAC1B9J,EAAG2J,YAAYC,QAGV,GAAIriB,MAAMiM,QAAQoW,GACvB,IAAK,MAAMhK,KAAQgK,EACjBD,GAAY3J,EAAIJ,GAiBf,SAASmK,GACdC,EAAaC,KAAkCC,GAE/C,MAAMlK,EAAKH,SAASsK,cAAcH,GAGlC,GAAIC,EACF,IAAK,MAAMG,KAAQ5nB,OAAO8hB,KAAK2F,GACG,kBAArBA,EAAWG,GACpBpK,EAAGqK,aAAaD,EAAMH,EAAWG,IAC1BH,EAAWG,IAClBpK,EAAGqK,aAAaD,EAAM,IAG5B,IAAK,MAAMR,KAASM,EAClBP,GAAY3J,EAAI4J,GAGlB,OAAO5J,EC/BF,SAASsK,GACdC,EAAYvlB,GAEZ,OACE,SAAIwlB,MAAM,gCACR,WAAMA,MAAM,WACV,UAAKC,IAAKF,EAAKxG,OAEjB,aACEyG,MAAM,uBACNtc,MAAO0X,GAAY,kBAAiB,sBACf,IAAI2E,EAAKG,cAE9B,eAAO,IAlCf,SAAmBH,EAAYvlB,GAC7B,OAAO,gBAAKulB,EAAKG,UAAW1lB,EAAO,CACjCiF,KAAM,CACJ8G,QAAS,MACTD,SAAU,UA8BG6Z,CAAUJ,EAAMvlB,SC6D5B,SAAS4lB,GACd5K,GAAiB,OAAE6K,EAAM,OAAEC,IAE3B,MAAMC,EAAY,IAAI,GAChBC,EAAY7H,GAAsBnD,GACrCjB,KACC9V,GAAOgiB,UAILC,EAAOnL,GAAkB,wBAAyBC,GACxD+K,EACGhM,KACCsK,GAAUD,IACVpB,GAAe8C,IAEdnU,UAAU,GAAIwU,SAAUpoB,aACnBA,EChIL,SACLid,EAAiBjd,GAEjB,OAAQA,GAGN,KAAK,EACHid,EAAG2F,YAAcC,GAAY,sBAC7B,MAGF,KAAK,EACH5F,EAAG2F,YAAcC,GAAY,qBAC7B,MAGF,QACE5F,EAAG2F,YAAcC,GAAY,sBCY5B,SAAe7iB,GACpB,GAAIA,EAAQ,IAAK,CAEf,QAAYA,EAAQ,MAAY,KAAMqoB,WADpBroB,EAAQ,KAAO,IAAO,KACjC,IAEP,OAAOA,EAAM8P,WDjByCwY,CAAMtoB,KDgHtDuoB,CAAoBJ,EAAMC,EAAKllB,QCvGlC,SACL+Z,GAEAA,EAAG2F,YAAcC,GAAY,6BDsGrB2F,CAAsBL,KAI9B,MAAMM,EAAOzL,GAAkB,uBAAwBC,GAqBvD,OApBA+K,EACGhM,KACCsK,GAAUD,IACVpH,GAAI,ICxFH,SACLhC,GAEAA,EAAG6J,UAAY,GDqFD4B,CAAsBD,IAChCxO,GAAU,EAAGmO,UAAWvO,GACtBiE,MAAMsK,EAAKjgB,MAAM,EAAG,KACpB2V,MAAMsK,EAAKjgB,MAAM,KACd6T,KG/KJ,SAAqBd,EAAYyN,EAAmB,MAEvD,OADAA,EAAmBA,QAA2DA,EAAmBzN,EAC1FvM,EAAQ,CAACE,EAAQwE,KACpB,IAAIkT,EAAU,GACVjiB,EAAQ,EACZuK,EAAO+E,UAAU,IAAI,EAAmBP,EAAarT,IACjD,IAAI4oB,EAAS,KACTtkB,IAAUqkB,GAAqB,GAC/BpC,EAAQvf,KAAK,IAEjB,IAAK,MAAM2R,KAAU4N,EACjB5N,EAAO3R,KAAKhH,GACRkb,GAAcvC,EAAOzV,SACrB0lB,EAASA,QAAuCA,EAAS,GACzDA,EAAO5hB,KAAK2R,IAGpB,GAAIiQ,EACA,IAAK,MAAMjQ,KAAUiQ,EACjB5Y,EAAUuW,EAAS5N,GACnBtF,EAAWX,KAAKiG,SAGzB/G,EAAW,KACV,IAAK,MAAM+G,KAAU4N,EACjBlT,EAAWX,KAAKiG,GAEpBtF,EAAWV,YACZ,KACC4T,EAAU,UHmJVsC,CAAY,IJ5KjB,YAAoBC,GACvB,OAAO,MAAOA,GI4KNC,CAAQd,GACRhO,GAAU,EAAE+O,KAAWlL,MAAMkL,OAGnC/D,GAAe8C,IAEdnU,UAAU,EAAEU,GAAUtU,cC/GtB,SACLid,EAAiB4J,GAEjB5J,EAAG2J,YAAYC,GD6GToC,CAAsBR,EAAMlB,GAAuBjT,EAAQtU,MApF5D,SACLkpB,GAAkB,OAAEpB,EAAM,OAAEC,IAE5B,OAAOrG,GAAc,CACnBqG,EAAO/L,KAAKmG,GAAwB,UACpC2F,EACG9L,KACC7O,EAAI,EAAGgc,QAAOC,YAAa,IACtB3pB,OAAO8hB,KAAK4H,EAAMf,SAClB3oB,OAAO8hB,KAAK6H,EAAOhB,WAI3BpM,KACC7O,EAAI,GAAInN,SAASooB,KAAU,kBAAOA,EAAMpoB,IACxCia,GAAUoP,GAAcvB,EAAO9L,KAC7B7O,EAAI,EAAGgc,QAAOC,aAAa,CACzBhB,KAAMiB,EAAWlc,IAAUwa,IACzB,MAAM2B,EACJ3B,KAAawB,EAAMf,KACfe,EACAC,EACN,MAAO,CACLzB,YACA3G,IAAK,CACHsI,EAASvG,KACTuG,EAASlB,KAAKT,IACd5X,KAAK,aA6DZwZ,CAAsBtM,EAAI,CAAE8K,SAAQD,WACxC9L,KACCiD,GAAI+I,GACJhK,GAAS,IAAMgK,EAAUrV,YACzBxF,EAAI8V,GAAU,OAAD,QAAG6C,IAAK7I,GAAOgG,KItH3B,SAASuG,GACdvM,GAEA,MACM6K,ElCjBC,GKmCA,G6BjBK/E,KAAV,uDlClBkB7gB,GACjB8Z,KACC/B,GAAUkH,GAAOA,EAAIsI,QACrB1K,GAAY,IANX,IACQ7c,EkCwBb,MAAMD,EAASmgB,GAAoB,oBAAqBnF,GAClD3I,EAAS8N,GAAoB,qBAAsBnF,GAGnD8K,EAASzC,GAAqBrjB,GACpC,OAAO4X,GACLkO,EACAF,GAAsBvT,EAAQ,CAAEwT,SAAQC,YC7D1ClM,GAAUiB,SAAS4M,KAAM,SACtB9V,UAAU+V,IACT,GAAIA,EAAG7N,kBAAkBuB,YAAa,CACpC,MAAMJ,EAAK0M,EAAG7N,OAAO8N,QAAQ,iBACzB3M,aAAc4M,iBAChBjE,GAAG,OAAQ,QAAS,WAAY,QAAS3I,EAAG8D,SCGtD+I,UACG9N,KACC/B,GAAU,IAAMJ,MAGXyI,GAAqB,eACrBnV,IAAI8P,GAAMuM,GAAgBvM,OAG9BrJ","file":"overrides/assets/javascripts/bundle.e5217812.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 10);\n","(function() {\n var AcronymResult, computeScore, emptyAcronymResult, isAcronymFullWord, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_size, wm;\n\n wm = 150;\n\n pos_bonus = 20;\n\n tau_size = 150;\n\n miss_coeff = 0.75;\n\n exports.score = function(string, query, options) {\n var allowErrors, preparedQuery, score, string_lw;\n preparedQuery = options.preparedQuery, allowErrors = options.allowErrors;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return 0;\n }\n string_lw = string.toLowerCase();\n score = computeScore(string, string_lw, preparedQuery);\n return Math.ceil(score);\n };\n\n exports.isMatch = isMatch = function(subject, query_lw, query_up) {\n var i, j, m, n, qj_lw, qj_up, si;\n m = subject.length;\n n = query_lw.length;\n if (!m || n > m) {\n return false;\n }\n i = -1;\n j = -1;\n while (++j < n) {\n qj_lw = query_lw.charCodeAt(j);\n qj_up = query_up.charCodeAt(j);\n while (++i < m) {\n si = subject.charCodeAt(i);\n if (si === qj_lw || si === qj_up) {\n break;\n }\n }\n if (i === m) {\n return false;\n }\n }\n return true;\n };\n\n exports.computeScore = computeScore = function(subject, subject_lw, preparedQuery) {\n var acro, acro_score, align, csc_diag, csc_row, csc_score, csc_should_rebuild, i, j, m, miss_budget, miss_left, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz;\n query = preparedQuery.query;\n query_lw = preparedQuery.query_lw;\n m = subject.length;\n n = query.length;\n acro = scoreAcronyms(subject, subject_lw, query, query_lw);\n acro_score = acro.score;\n if (acro.count === n) {\n return scoreExact(n, m, acro_score, acro.pos);\n }\n pos = subject_lw.indexOf(query_lw);\n if (pos > -1) {\n return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m);\n }\n score_row = new Array(n);\n csc_row = new Array(n);\n sz = scoreSize(n, m);\n miss_budget = Math.ceil(miss_coeff * n) + 5;\n miss_left = miss_budget;\n csc_should_rebuild = true;\n j = -1;\n while (++j < n) {\n score_row[j] = 0;\n csc_row[j] = 0;\n }\n i = -1;\n while (++i < m) {\n si_lw = subject_lw[i];\n if (!si_lw.charCodeAt(0) in preparedQuery.charCodes) {\n if (csc_should_rebuild) {\n j = -1;\n while (++j < n) {\n csc_row[j] = 0;\n }\n csc_should_rebuild = false;\n }\n continue;\n }\n score = 0;\n score_diag = 0;\n csc_diag = 0;\n record_miss = true;\n csc_should_rebuild = true;\n j = -1;\n while (++j < n) {\n score_up = score_row[j];\n if (score_up > score) {\n score = score_up;\n }\n csc_score = 0;\n if (query_lw[j] === si_lw) {\n start = isWordStart(i, subject, subject_lw);\n csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);\n align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);\n if (align > score) {\n score = align;\n miss_left = miss_budget;\n } else {\n if (record_miss && --miss_left <= 0) {\n return Math.max(score, score_row[n - 1]) * sz;\n }\n record_miss = false;\n }\n }\n score_diag = score_up;\n csc_diag = csc_row[j];\n csc_row[j] = csc_score;\n score_row[j] = score;\n }\n }\n score = score_row[n - 1];\n return score * sz;\n };\n\n exports.isWordStart = isWordStart = function(pos, subject, subject_lw) {\n var curr_s, prev_s;\n if (pos === 0) {\n return true;\n }\n curr_s = subject[pos];\n prev_s = subject[pos - 1];\n return isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]);\n };\n\n exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) {\n var curr_s, next_s;\n if (pos === len - 1) {\n return true;\n }\n curr_s = subject[pos];\n next_s = subject[pos + 1];\n return isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]);\n };\n\n isSeparator = function(c) {\n return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\\\';\n };\n\n scorePosition = function(pos) {\n var sc;\n if (pos < pos_bonus) {\n sc = pos_bonus - pos;\n return 100 + sc * sc;\n } else {\n return Math.max(100 + pos_bonus - pos, 0);\n }\n };\n\n exports.scoreSize = scoreSize = function(n, m) {\n return tau_size / (tau_size + Math.abs(m - n));\n };\n\n scoreExact = function(n, m, quality, pos) {\n return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m);\n };\n\n exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) {\n var bonus, sz;\n sz = count;\n bonus = 6;\n if (sameCase === count) {\n bonus += 2;\n }\n if (start) {\n bonus += 3;\n }\n if (end) {\n bonus += 1;\n }\n if (count === len) {\n if (start) {\n if (sameCase === len) {\n sz += 2;\n } else {\n sz += 1;\n }\n }\n if (end) {\n bonus += 1;\n }\n }\n return sameCase + sz * (sz + bonus);\n };\n\n exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) {\n var posBonus;\n posBonus = scorePosition(i);\n if (start) {\n return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10);\n }\n return posBonus + wm * csc_score;\n };\n\n exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, startOfWord) {\n var k, m, mi, n, nj, sameCase, sz;\n m = subject.length;\n n = query.length;\n mi = m - i;\n nj = n - j;\n k = mi < nj ? mi : nj;\n sameCase = 0;\n sz = 0;\n if (query[j] === subject[i]) {\n sameCase++;\n }\n while (++sz < k && query_lw[++j] === subject_lw[++i]) {\n if (query[j] === subject[i]) {\n sameCase++;\n }\n }\n if (sz < k) {\n i--;\n }\n if (sz === 1) {\n return 1 + 2 * sameCase;\n }\n return scorePattern(sz, n, sameCase, startOfWord, isWordEnd(i, subject, subject_lw, m));\n };\n\n exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) {\n var end, i, pos2, sameCase, start;\n start = isWordStart(pos, subject, subject_lw);\n if (!start) {\n pos2 = subject_lw.indexOf(query_lw, pos + 1);\n if (pos2 > -1) {\n start = isWordStart(pos2, subject, subject_lw);\n if (start) {\n pos = pos2;\n }\n }\n }\n i = -1;\n sameCase = 0;\n while (++i < n) {\n if (query[pos + i] === subject[i]) {\n sameCase++;\n }\n }\n end = isWordEnd(pos + n - 1, subject, subject_lw, m);\n return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos);\n };\n\n AcronymResult = (function() {\n function AcronymResult(score, pos, count) {\n this.score = score;\n this.pos = pos;\n this.count = count;\n }\n\n return AcronymResult;\n\n })();\n\n emptyAcronymResult = new AcronymResult(0, 0.1, 0);\n\n exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) {\n var count, fullWord, i, j, m, n, qj_lw, sameCase, score, sepCount, sumPos;\n m = subject.length;\n n = query.length;\n if (!(m > 1 && n > 1)) {\n return emptyAcronymResult;\n }\n count = 0;\n sepCount = 0;\n sumPos = 0;\n sameCase = 0;\n i = -1;\n j = -1;\n while (++j < n) {\n qj_lw = query_lw[j];\n if (isSeparator(qj_lw)) {\n i = subject_lw.indexOf(qj_lw, i + 1);\n if (i > -1) {\n sepCount++;\n continue;\n } else {\n break;\n }\n }\n while (++i < m) {\n if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) {\n if (query[j] === subject[i]) {\n sameCase++;\n }\n sumPos += i;\n count++;\n break;\n }\n }\n if (i === m) {\n break;\n }\n }\n if (count < 2) {\n return emptyAcronymResult;\n }\n fullWord = count === n ? isAcronymFullWord(subject, subject_lw, query, count) : false;\n score = scorePattern(count, n, sameCase, true, fullWord);\n return new AcronymResult(score, sumPos / count, count + sepCount);\n };\n\n isAcronymFullWord = function(subject, subject_lw, query, nbAcronymInQuery) {\n var count, i, m, n;\n m = subject.length;\n n = query.length;\n count = 0;\n if (m > 12 * n) {\n return false;\n }\n i = -1;\n while (++i < m) {\n if (isWordStart(i, subject, subject_lw) && ++count > nbAcronymInQuery) {\n return false;\n }\n }\n return true;\n };\n\n}).call(this);\n","(function() {\n var Query, defaultPathSeparator, filter, matcher, parseOptions, pathScorer, preparedQueryCache, scorer;\n\n filter = require('./filter');\n\n matcher = require('./matcher');\n\n scorer = require('./scorer');\n\n pathScorer = require('./pathScorer');\n\n Query = require('./query');\n\n preparedQueryCache = null;\n\n defaultPathSeparator = (typeof process !== \"undefined\" && process !== null ? process.platform : void 0) === \"win32\" ? '\\\\' : '/';\n\n module.exports = {\n filter: function(candidates, query, options) {\n if (options == null) {\n options = {};\n }\n if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) {\n return [];\n }\n options = parseOptions(options, query);\n return filter(candidates, query, options);\n },\n score: function(string, query, options) {\n if (options == null) {\n options = {};\n }\n if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) {\n return 0;\n }\n options = parseOptions(options, query);\n if (options.usePathScoring) {\n return pathScorer.score(string, query, options);\n } else {\n return scorer.score(string, query, options);\n }\n },\n match: function(string, query, options) {\n var _i, _ref, _results;\n if (options == null) {\n options = {};\n }\n if (!string) {\n return [];\n }\n if (!query) {\n return [];\n }\n if (string === query) {\n return (function() {\n _results = [];\n for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }\n return _results;\n }).apply(this);\n }\n options = parseOptions(options, query);\n return matcher.match(string, query, options);\n },\n wrap: function(string, query, options) {\n if (options == null) {\n options = {};\n }\n if (!string) {\n return [];\n }\n if (!query) {\n return [];\n }\n options = parseOptions(options, query);\n return matcher.wrap(string, query, options);\n },\n prepareQuery: function(query, options) {\n if (options == null) {\n options = {};\n }\n options = parseOptions(options, query);\n return options.preparedQuery;\n }\n };\n\n parseOptions = function(options, query) {\n if (options.allowErrors == null) {\n options.allowErrors = false;\n }\n if (options.usePathScoring == null) {\n options.usePathScoring = true;\n }\n if (options.useExtensionBonus == null) {\n options.useExtensionBonus = false;\n }\n if (options.pathSeparator == null) {\n options.pathSeparator = defaultPathSeparator;\n }\n if (options.optCharRegEx == null) {\n options.optCharRegEx = null;\n }\n if (options.wrap == null) {\n options.wrap = null;\n }\n if (options.preparedQuery == null) {\n options.preparedQuery = preparedQueryCache && preparedQueryCache.query === query ? preparedQueryCache : (preparedQueryCache = new Query(query, options));\n }\n return options;\n };\n\n}).call(this);\n","(function() {\n var computeScore, countDir, file_coeff, getExtension, getExtensionScore, isMatch, scorePath, scoreSize, tau_depth, _ref;\n\n _ref = require('./scorer'), isMatch = _ref.isMatch, computeScore = _ref.computeScore, scoreSize = _ref.scoreSize;\n\n tau_depth = 20;\n\n file_coeff = 2.5;\n\n exports.score = function(string, query, options) {\n var allowErrors, preparedQuery, score, string_lw;\n preparedQuery = options.preparedQuery, allowErrors = options.allowErrors;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return 0;\n }\n string_lw = string.toLowerCase();\n score = computeScore(string, string_lw, preparedQuery);\n score = scorePath(string, string_lw, score, options);\n return Math.ceil(score);\n };\n\n scorePath = function(subject, subject_lw, fullPathScore, options) {\n var alpha, basePathScore, basePos, depth, end, extAdjust, fileLength, pathSeparator, preparedQuery, useExtensionBonus;\n if (fullPathScore === 0) {\n return 0;\n }\n preparedQuery = options.preparedQuery, useExtensionBonus = options.useExtensionBonus, pathSeparator = options.pathSeparator;\n end = subject.length - 1;\n while (subject[end] === pathSeparator) {\n end--;\n }\n basePos = subject.lastIndexOf(pathSeparator, end);\n fileLength = end - basePos;\n extAdjust = 1.0;\n if (useExtensionBonus) {\n extAdjust += getExtensionScore(subject_lw, preparedQuery.ext, basePos, end, 2);\n fullPathScore *= extAdjust;\n }\n if (basePos === -1) {\n return fullPathScore;\n }\n depth = preparedQuery.depth;\n while (basePos > -1 && depth-- > 0) {\n basePos = subject.lastIndexOf(pathSeparator, basePos - 1);\n }\n basePathScore = basePos === -1 ? fullPathScore : extAdjust * computeScore(subject.slice(basePos + 1, end + 1), subject_lw.slice(basePos + 1, end + 1), preparedQuery);\n alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1, pathSeparator));\n return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * fileLength);\n };\n\n exports.countDir = countDir = function(path, end, pathSeparator) {\n var count, i;\n if (end < 1) {\n return 0;\n }\n count = 0;\n i = -1;\n while (++i < end && path[i] === pathSeparator) {\n continue;\n }\n while (++i < end) {\n if (path[i] === pathSeparator) {\n count++;\n while (++i < end && path[i] === pathSeparator) {\n continue;\n }\n }\n }\n return count;\n };\n\n exports.getExtension = getExtension = function(str) {\n var pos;\n pos = str.lastIndexOf(\".\");\n if (pos < 0) {\n return \"\";\n } else {\n return str.substr(pos + 1);\n }\n };\n\n getExtensionScore = function(candidate, ext, startPos, endPos, maxDepth) {\n var m, matched, n, pos;\n if (!ext.length) {\n return 0;\n }\n pos = candidate.lastIndexOf(\".\", endPos);\n if (!(pos > startPos)) {\n return 0;\n }\n n = ext.length;\n m = endPos - pos;\n if (m < n) {\n n = m;\n m = ext.length;\n }\n pos++;\n matched = -1;\n while (++matched < n) {\n if (candidate[pos + matched] !== ext[matched]) {\n break;\n }\n }\n if (matched === 0 && maxDepth > 0) {\n return 0.9 * getExtensionScore(candidate, ext, startPos, pos - 2, maxDepth - 1);\n }\n return matched / m;\n };\n\n}).call(this);\n","(function() {\n var Query, coreChars, countDir, getCharCodes, getExtension, opt_char_re, truncatedUpperCase, _ref;\n\n _ref = require(\"./pathScorer\"), countDir = _ref.countDir, getExtension = _ref.getExtension;\n\n module.exports = Query = (function() {\n function Query(query, _arg) {\n var optCharRegEx, pathSeparator, _ref1;\n _ref1 = _arg != null ? _arg : {}, optCharRegEx = _ref1.optCharRegEx, pathSeparator = _ref1.pathSeparator;\n if (!(query && query.length)) {\n return null;\n }\n this.query = query;\n this.query_lw = query.toLowerCase();\n this.core = coreChars(query, optCharRegEx);\n this.core_lw = this.core.toLowerCase();\n this.core_up = truncatedUpperCase(this.core);\n this.depth = countDir(query, query.length, pathSeparator);\n this.ext = getExtension(this.query_lw);\n this.charCodes = getCharCodes(this.query_lw);\n }\n\n return Query;\n\n })();\n\n opt_char_re = /[ _\\-:\\/\\\\]/g;\n\n coreChars = function(query, optCharRegEx) {\n if (optCharRegEx == null) {\n optCharRegEx = opt_char_re;\n }\n return query.replace(optCharRegEx, '');\n };\n\n truncatedUpperCase = function(str) {\n var char, upper, _i, _len;\n upper = \"\";\n for (_i = 0, _len = str.length; _i < _len; _i++) {\n char = str[_i];\n upper += char.toUpperCase()[0];\n }\n return upper;\n };\n\n getCharCodes = function(str) {\n var charCodes, i, len;\n len = str.length;\n i = -1;\n charCodes = [];\n while (++i < len) {\n charCodes[str.charCodeAt(i)] = true;\n }\n return charCodes;\n };\n\n}).call(this);\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","(function() {\n var Query, pathScorer, pluckCandidates, scorer, sortCandidates;\n\n scorer = require('./scorer');\n\n pathScorer = require('./pathScorer');\n\n Query = require('./query');\n\n pluckCandidates = function(a) {\n return a.candidate;\n };\n\n sortCandidates = function(a, b) {\n return b.score - a.score;\n };\n\n module.exports = function(candidates, query, options) {\n var bKey, candidate, key, maxInners, maxResults, score, scoreProvider, scoredCandidates, spotLeft, string, usePathScoring, _i, _len;\n scoredCandidates = [];\n key = options.key, maxResults = options.maxResults, maxInners = options.maxInners, usePathScoring = options.usePathScoring;\n spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length + 1;\n bKey = key != null;\n scoreProvider = usePathScoring ? pathScorer : scorer;\n for (_i = 0, _len = candidates.length; _i < _len; _i++) {\n candidate = candidates[_i];\n string = bKey ? candidate[key] : candidate;\n if (!string) {\n continue;\n }\n score = scoreProvider.score(string, query, options);\n if (score > 0) {\n scoredCandidates.push({\n candidate: candidate,\n score: score\n });\n if (!--spotLeft) {\n break;\n }\n }\n }\n scoredCandidates.sort(sortCandidates);\n candidates = scoredCandidates.map(pluckCandidates);\n if (maxResults != null) {\n candidates = candidates.slice(0, maxResults);\n }\n return candidates;\n };\n\n}).call(this);\n","(function() {\n var basenameMatch, computeMatch, isMatch, isWordStart, match, mergeMatches, scoreAcronyms, scoreCharacter, scoreConsecutives, _ref;\n\n _ref = require('./scorer'), isMatch = _ref.isMatch, isWordStart = _ref.isWordStart, scoreConsecutives = _ref.scoreConsecutives, scoreCharacter = _ref.scoreCharacter, scoreAcronyms = _ref.scoreAcronyms;\n\n exports.match = match = function(string, query, options) {\n var allowErrors, baseMatches, matches, pathSeparator, preparedQuery, string_lw;\n allowErrors = options.allowErrors, preparedQuery = options.preparedQuery, pathSeparator = options.pathSeparator;\n if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) {\n return [];\n }\n string_lw = string.toLowerCase();\n matches = computeMatch(string, string_lw, preparedQuery);\n if (matches.length === 0) {\n return matches;\n }\n if (string.indexOf(pathSeparator) > -1) {\n baseMatches = basenameMatch(string, string_lw, preparedQuery, pathSeparator);\n matches = mergeMatches(matches, baseMatches);\n }\n return matches;\n };\n\n exports.wrap = function(string, query, options) {\n var matchIndex, matchPos, matchPositions, output, strPos, tagClass, tagClose, tagOpen, _ref1;\n if ((options.wrap != null)) {\n _ref1 = options.wrap, tagClass = _ref1.tagClass, tagOpen = _ref1.tagOpen, tagClose = _ref1.tagClose;\n }\n if (tagClass == null) {\n tagClass = 'highlight';\n }\n if (tagOpen == null) {\n tagOpen = '';\n }\n if (tagClose == null) {\n tagClose = '';\n }\n if (string === query) {\n return tagOpen + string + tagClose;\n }\n matchPositions = match(string, query, options);\n if (matchPositions.length === 0) {\n return string;\n }\n output = '';\n matchIndex = -1;\n strPos = 0;\n while (++matchIndex < matchPositions.length) {\n matchPos = matchPositions[matchIndex];\n if (matchPos > strPos) {\n output += string.substring(strPos, matchPos);\n strPos = matchPos;\n }\n while (++matchIndex < matchPositions.length) {\n if (matchPositions[matchIndex] === matchPos + 1) {\n matchPos++;\n } else {\n matchIndex--;\n break;\n }\n }\n matchPos++;\n if (matchPos > strPos) {\n output += tagOpen;\n output += string.substring(strPos, matchPos);\n output += tagClose;\n strPos = matchPos;\n }\n }\n if (strPos <= string.length - 1) {\n output += string.substring(strPos);\n }\n return output;\n };\n\n basenameMatch = function(subject, subject_lw, preparedQuery, pathSeparator) {\n var basePos, depth, end;\n end = subject.length - 1;\n while (subject[end] === pathSeparator) {\n end--;\n }\n basePos = subject.lastIndexOf(pathSeparator, end);\n if (basePos === -1) {\n return [];\n }\n depth = preparedQuery.depth;\n while (depth-- > 0) {\n basePos = subject.lastIndexOf(pathSeparator, basePos - 1);\n if (basePos === -1) {\n return [];\n }\n }\n basePos++;\n end++;\n return computeMatch(subject.slice(basePos, end), subject_lw.slice(basePos, end), preparedQuery, basePos);\n };\n\n mergeMatches = function(a, b) {\n var ai, bj, i, j, m, n, out;\n m = a.length;\n n = b.length;\n if (n === 0) {\n return a.slice();\n }\n if (m === 0) {\n return b.slice();\n }\n i = -1;\n j = 0;\n bj = b[j];\n out = [];\n while (++i < m) {\n ai = a[i];\n while (bj <= ai && ++j < n) {\n if (bj < ai) {\n out.push(bj);\n }\n bj = b[j];\n }\n out.push(ai);\n }\n while (j < n) {\n out.push(b[j++]);\n }\n return out;\n };\n\n computeMatch = function(subject, subject_lw, preparedQuery, offset) {\n var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace;\n if (offset == null) {\n offset = 0;\n }\n query = preparedQuery.query;\n query_lw = preparedQuery.query_lw;\n m = subject.length;\n n = query.length;\n acro_score = scoreAcronyms(subject, subject_lw, query, query_lw).score;\n score_row = new Array(n);\n csc_row = new Array(n);\n STOP = 0;\n UP = 1;\n LEFT = 2;\n DIAGONAL = 3;\n trace = new Array(m * n);\n pos = -1;\n j = -1;\n while (++j < n) {\n score_row[j] = 0;\n csc_row[j] = 0;\n }\n i = -1;\n while (++i < m) {\n score = 0;\n score_up = 0;\n csc_diag = 0;\n si_lw = subject_lw[i];\n j = -1;\n while (++j < n) {\n csc_score = 0;\n align = 0;\n score_diag = score_up;\n if (query_lw[j] === si_lw) {\n start = isWordStart(i, subject, subject_lw);\n csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);\n align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);\n }\n score_up = score_row[j];\n csc_diag = csc_row[j];\n if (score > score_up) {\n move = LEFT;\n } else {\n score = score_up;\n move = UP;\n }\n if (align > score) {\n score = align;\n move = DIAGONAL;\n } else {\n csc_score = 0;\n }\n score_row[j] = score;\n csc_row[j] = csc_score;\n trace[++pos] = score > 0 ? move : STOP;\n }\n }\n i = m - 1;\n j = n - 1;\n pos = i * n + j;\n backtrack = true;\n matches = [];\n while (backtrack && i >= 0 && j >= 0) {\n switch (trace[pos]) {\n case UP:\n i--;\n pos -= n;\n break;\n case LEFT:\n j--;\n pos--;\n break;\n case DIAGONAL:\n matches.push(i + offset);\n j--;\n i--;\n pos -= n + 1;\n break;\n default:\n backtrack = false;\n }\n }\n matches.reverse();\n return matches;\n };\n\n}).call(this);\n","export function isFunction(value) {\n return typeof value === 'function';\n}\n//# sourceMappingURL=isFunction.js.map","import { isFunction } from './isFunction';\nexport function hasLift(source) {\n return isFunction(source === null || source === void 0 ? void 0 : source.lift);\n}\nexport function operate(init) {\n return (source) => {\n if (hasLift(source)) {\n return source.lift(function (liftedSource) {\n try {\n return init(liftedSource, this);\n }\n catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n//# sourceMappingURL=lift.js.map","export function createErrorClass(createImpl) {\n const _super = (instance) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n//# sourceMappingURL=createErrorClass.js.map","import { createErrorClass } from './createErrorClass';\nexport const UnsubscriptionError = createErrorClass((_super) => function UnsubscriptionErrorImpl(errors) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n});\n//# sourceMappingURL=UnsubscriptionError.js.map","export function arrRemove(arr, item) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n//# sourceMappingURL=arrRemove.js.map","import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { arrRemove } from './util/arrRemove';\nexport class Subscription {\n constructor(initialTeardown) {\n this.initialTeardown = initialTeardown;\n this.closed = false;\n this._parentage = null;\n this._teardowns = null;\n }\n unsubscribe() {\n let errors;\n if (!this.closed) {\n this.closed = true;\n const { _parentage } = this;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n }\n else {\n _parentage === null || _parentage === void 0 ? void 0 : _parentage.remove(this);\n }\n const { initialTeardown } = this;\n if (isFunction(initialTeardown)) {\n try {\n initialTeardown();\n }\n catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n const { _teardowns } = this;\n if (_teardowns) {\n this._teardowns = null;\n for (const teardown of _teardowns) {\n try {\n execTeardown(teardown);\n }\n catch (err) {\n errors = errors !== null && errors !== void 0 ? errors : [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n }\n else {\n errors.push(err);\n }\n }\n }\n }\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n add(teardown) {\n var _a;\n if (teardown && teardown !== this) {\n if (this.closed) {\n execTeardown(teardown);\n }\n else {\n if (teardown instanceof Subscription) {\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._teardowns = (_a = this._teardowns) !== null && _a !== void 0 ? _a : []).push(teardown);\n }\n }\n }\n _hasParent(parent) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n _addParent(parent) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n _removeParent(parent) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n }\n else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n remove(teardown) {\n const { _teardowns } = this;\n _teardowns && arrRemove(_teardowns, teardown);\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\nSubscription.EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n})();\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\nexport function isSubscription(value) {\n return (value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe)));\n}\nfunction execTeardown(teardown) {\n if (isFunction(teardown)) {\n teardown();\n }\n else {\n teardown.unsubscribe();\n }\n}\n//# sourceMappingURL=Subscription.js.map","export const config = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n//# sourceMappingURL=config.js.map","export const timeoutProvider = {\n setTimeout(...args) {\n const { delegate } = timeoutProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) || setTimeout)(...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);\n },\n delegate: undefined,\n};\n//# sourceMappingURL=timeoutProvider.js.map","import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\nexport function reportUnhandledError(err) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n onUnhandledError(err);\n }\n else {\n throw err;\n }\n });\n}\n//# sourceMappingURL=reportUnhandledError.js.map","export function noop() { }\n//# sourceMappingURL=noop.js.map","export const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined))();\nexport function errorNotification(error) {\n return createNotification('E', undefined, error);\n}\nexport function nextNotification(value) {\n return createNotification('N', value, undefined);\n}\nexport function createNotification(kind, value, error) {\n return {\n kind,\n value,\n error,\n };\n}\n//# sourceMappingURL=NotificationFactories.js.map","import { isFunction } from './util/isFunction';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nexport class Subscriber extends Subscription {\n constructor(destination) {\n super();\n this.isStopped = false;\n if (destination) {\n this.destination = destination;\n if (isSubscription(destination)) {\n destination.add(this);\n }\n }\n else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n static create(next, error, complete) {\n return new SafeSubscriber(next, error, complete);\n }\n next(value) {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n }\n else {\n this._next(value);\n }\n }\n error(err) {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n }\n else {\n this.isStopped = true;\n this._error(err);\n }\n }\n complete() {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n }\n else {\n this.isStopped = true;\n this._complete();\n }\n }\n unsubscribe() {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n }\n }\n _next(value) {\n this.destination.next(value);\n }\n _error(err) {\n this.destination.error(err);\n this.unsubscribe();\n }\n _complete() {\n this.destination.complete();\n this.unsubscribe();\n }\n}\nexport class SafeSubscriber extends Subscriber {\n constructor(observerOrNext, error, complete) {\n super();\n this.destination = EMPTY_OBSERVER;\n if ((observerOrNext || error || complete) && observerOrNext !== EMPTY_OBSERVER) {\n let next;\n if (isFunction(observerOrNext)) {\n next = observerOrNext;\n }\n else if (observerOrNext) {\n ({ next, error, complete } = observerOrNext);\n let context;\n if (this && config.useDeprecatedNextContext) {\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n }\n else {\n context = observerOrNext;\n }\n next = next === null || next === void 0 ? void 0 : next.bind(context);\n error = error === null || error === void 0 ? void 0 : error.bind(context);\n complete = complete === null || complete === void 0 ? void 0 : complete.bind(context);\n }\n this.destination = {\n next: next || noop,\n error: error || defaultErrorHandler,\n complete: complete || noop,\n };\n }\n }\n}\nfunction defaultErrorHandler(err) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n throw err;\n }\n reportUnhandledError(err);\n}\nfunction handleStoppedNotification(notification, subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\nexport const EMPTY_OBSERVER = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n//# sourceMappingURL=Subscriber.js.map","import { Subscriber } from '../Subscriber';\nexport class OperatorSubscriber extends Subscriber {\n constructor(destination, onNext, onError, onComplete, onUnsubscribe) {\n super(destination);\n this.onUnsubscribe = onUnsubscribe;\n this._next = onNext\n ? function (value) {\n try {\n onNext(value);\n }\n catch (err) {\n this.destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (err) {\n try {\n onError(err);\n }\n catch (err) {\n this.destination.error(err);\n }\n this.unsubscribe();\n }\n : super._error;\n this._complete = onComplete\n ? function () {\n try {\n onComplete();\n }\n catch (err) {\n this.destination.error(err);\n }\n this.unsubscribe();\n }\n : super._complete;\n }\n unsubscribe() {\n var _a;\n !this.closed && ((_a = this.onUnsubscribe) === null || _a === void 0 ? void 0 : _a.call(this));\n super.unsubscribe();\n }\n}\n//# sourceMappingURL=OperatorSubscriber.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function map(project, thisArg) {\n return operate((source, subscriber) => {\n let index = 0;\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n subscriber.next(project.call(thisArg, value, index++));\n }));\n });\n}\n//# sourceMappingURL=map.js.map","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from) {\r\n for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)\r\n to[j] = from[i];\r\n return to;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","export const isArrayLike = ((x) => x && typeof x.length === 'number' && typeof x !== 'function');\n//# sourceMappingURL=isArrayLike.js.map","import { isFunction } from \"./isFunction\";\nexport function isPromise(value) {\n return isFunction(value === null || value === void 0 ? void 0 : value.then);\n}\n//# sourceMappingURL=isPromise.js.map","export function getSymbolIterator() {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator';\n }\n return Symbol.iterator;\n}\nexport const iterator = getSymbolIterator();\nexport const $$iterator = iterator;\n//# sourceMappingURL=iterator.js.map","export const observable = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n//# sourceMappingURL=observable.js.map","export function identity(x) {\n return x;\n}\n//# sourceMappingURL=identity.js.map","import { identity } from './identity';\nexport function pipe(...fns) {\n return pipeFromArray(fns);\n}\nexport function pipeFromArray(fns) {\n if (fns.length === 0) {\n return identity;\n }\n if (fns.length === 1) {\n return fns[0];\n }\n return function piped(input) {\n return fns.reduce((prev, fn) => fn(prev), input);\n };\n}\n//# sourceMappingURL=pipe.js.map","import { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription } from './Subscription';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nexport class Observable {\n constructor(subscribe) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n lift(operator) {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n subscribe(observerOrNext, error, complete) {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n const { operator, source } = this;\n subscriber.add(operator\n ? operator.call(subscriber, source)\n : source || config.useDeprecatedSynchronousErrorHandling\n ? this._subscribe(subscriber)\n : this._trySubscribe(subscriber));\n return subscriber;\n }\n _trySubscribe(sink) {\n try {\n return this._subscribe(sink);\n }\n catch (err) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n throw err;\n }\n sink.error(err);\n }\n }\n forEach(next, promiseCtor) {\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor((resolve, reject) => {\n let subscription;\n subscription = this.subscribe((value) => {\n try {\n next(value);\n }\n catch (err) {\n reject(err);\n subscription === null || subscription === void 0 ? void 0 : subscription.unsubscribe();\n }\n }, reject, resolve);\n });\n }\n _subscribe(subscriber) {\n var _a;\n return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);\n }\n [Symbol_observable]() {\n return this;\n }\n pipe(...operations) {\n return operations.length ? pipeFromArray(operations)(this) : this;\n }\n toPromise(promiseCtor) {\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor((resolve, reject) => {\n let value;\n this.subscribe((x) => (value = x), (err) => reject(err), () => resolve(value));\n });\n }\n}\nObservable.create = (subscribe) => {\n return new Observable(subscribe);\n};\nfunction getPromiseCtor(promiseCtor) {\n var _a;\n return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config.Promise) !== null && _a !== void 0 ? _a : Promise;\n}\nfunction isObserver(value) {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\nfunction isSubscriber(value) {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n//# sourceMappingURL=Observable.js.map","import { Observable } from '../Observable';\nexport function scheduleArray(input, scheduler) {\n return new Observable((subscriber) => {\n let i = 0;\n return scheduler.schedule(function () {\n if (i === input.length) {\n subscriber.complete();\n }\n else {\n subscriber.next(input[i++]);\n if (!subscriber.closed) {\n this.schedule();\n }\n }\n });\n });\n}\n//# sourceMappingURL=scheduleArray.js.map","import { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\nexport function isInteropObservable(input) {\n return isFunction(input[Symbol_observable]);\n}\n//# sourceMappingURL=isInteropObservable.js.map","import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\nexport function isIterable(input) {\n return isFunction(input === null || input === void 0 ? void 0 : input[Symbol_iterator]);\n}\n//# sourceMappingURL=isIterable.js.map","import { isFunction } from './isFunction';\nexport function isAsyncIterable(obj) {\n return Symbol.asyncIterator && isFunction(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);\n}\n//# sourceMappingURL=isAsyncIterable.js.map","export function createInvalidObservableTypeError(input) {\n return new TypeError(`You provided ${input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`} where a stream was expected. You can provide an Observable, Promise, Array, AsyncIterable, or Iterable.`);\n}\n//# sourceMappingURL=throwUnobservableError.js.map","import { scheduleObservable } from './scheduleObservable';\nimport { schedulePromise } from './schedulePromise';\nimport { scheduleArray } from './scheduleArray';\nimport { scheduleIterable } from './scheduleIterable';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isPromise } from '../util/isPromise';\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isIterable } from '../util/isIterable';\nimport { scheduleAsyncIterable } from './scheduleAsyncIterable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nexport function scheduled(input, scheduler) {\n if (input != null) {\n if (isInteropObservable(input)) {\n return scheduleObservable(input, scheduler);\n }\n if (isArrayLike(input)) {\n return scheduleArray(input, scheduler);\n }\n if (isPromise(input)) {\n return schedulePromise(input, scheduler);\n }\n if (isAsyncIterable(input)) {\n return scheduleAsyncIterable(input, scheduler);\n }\n if (isIterable(input)) {\n return scheduleIterable(input, scheduler);\n }\n }\n throw createInvalidObservableTypeError(input);\n}\n//# sourceMappingURL=scheduled.js.map","import { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport function scheduleObservable(input, scheduler) {\n return new Observable(subscriber => {\n const sub = new Subscription();\n sub.add(scheduler.schedule(() => {\n const observable = input[Symbol_observable]();\n sub.add(observable.subscribe({\n next(value) { sub.add(scheduler.schedule(() => subscriber.next(value))); },\n error(err) { sub.add(scheduler.schedule(() => subscriber.error(err))); },\n complete() { sub.add(scheduler.schedule(() => subscriber.complete())); },\n }));\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleObservable.js.map","import { Observable } from '../Observable';\nexport function schedulePromise(input, scheduler) {\n return new Observable((subscriber) => {\n return scheduler.schedule(() => input.then((value) => {\n subscriber.add(scheduler.schedule(() => {\n subscriber.next(value);\n subscriber.add(scheduler.schedule(() => subscriber.complete()));\n }));\n }, (err) => {\n subscriber.add(scheduler.schedule(() => subscriber.error(err)));\n }));\n });\n}\n//# sourceMappingURL=schedulePromise.js.map","import { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nexport function scheduleAsyncIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n return new Observable(subscriber => {\n const sub = new Subscription();\n sub.add(scheduler.schedule(() => {\n const iterator = input[Symbol.asyncIterator]();\n sub.add(scheduler.schedule(function () {\n iterator.next().then(result => {\n if (result.done) {\n subscriber.complete();\n }\n else {\n subscriber.next(result.value);\n this.schedule();\n }\n });\n }));\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleAsyncIterable.js.map","import { Observable } from '../Observable';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from '../util/isFunction';\nimport { caughtSchedule } from '../util/caughtSchedule';\nexport function scheduleIterable(input, scheduler) {\n return new Observable((subscriber) => {\n let iterator;\n subscriber.add(scheduler.schedule(() => {\n iterator = input[Symbol_iterator]();\n caughtSchedule(subscriber, scheduler, function () {\n const { value, done } = iterator.next();\n if (done) {\n subscriber.complete();\n }\n else {\n subscriber.next(value);\n this.schedule();\n }\n });\n }));\n return () => isFunction(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return();\n });\n}\n//# sourceMappingURL=scheduleIterable.js.map","export function caughtSchedule(subscriber, scheduler, execute, delay = 0) {\n const subscription = scheduler.schedule(function () {\n try {\n execute.call(this);\n }\n catch (err) {\n subscriber.error(err);\n }\n }, delay);\n subscriber.add(subscription);\n return subscription;\n}\n//# sourceMappingURL=caughtSchedule.js.map","import { __asyncValues, __awaiter } from \"tslib\";\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isPromise } from '../util/isPromise';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { Observable } from '../Observable';\nimport { scheduled } from '../scheduled/scheduled';\nimport { isFunction } from '../util/isFunction';\nimport { reportUnhandledError } from '../util/reportUnhandledError';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nimport { isIterable } from '../util/isIterable';\nexport function from(input, scheduler) {\n return scheduler ? scheduled(input, scheduler) : innerFrom(input);\n}\nexport function innerFrom(input) {\n if (input instanceof Observable) {\n return input;\n }\n if (input != null) {\n if (isInteropObservable(input)) {\n return fromInteropObservable(input);\n }\n if (isArrayLike(input)) {\n return fromArrayLike(input);\n }\n if (isPromise(input)) {\n return fromPromise(input);\n }\n if (isAsyncIterable(input)) {\n return fromAsyncIterable(input);\n }\n if (isIterable(input)) {\n return fromIterable(input);\n }\n }\n throw createInvalidObservableTypeError(input);\n}\nfunction fromInteropObservable(obj) {\n return new Observable((subscriber) => {\n const obs = obj[Symbol_observable]();\n if (isFunction(obs.subscribe)) {\n return obs.subscribe(subscriber);\n }\n throw new TypeError('Provided object does not correctly implement Symbol.observable');\n });\n}\nexport function fromArrayLike(array) {\n return new Observable((subscriber) => {\n for (let i = 0; i < array.length && !subscriber.closed; i++) {\n subscriber.next(array[i]);\n }\n subscriber.complete();\n });\n}\nfunction fromPromise(promise) {\n return new Observable((subscriber) => {\n promise\n .then((value) => {\n if (!subscriber.closed) {\n subscriber.next(value);\n subscriber.complete();\n }\n }, (err) => subscriber.error(err))\n .then(null, reportUnhandledError);\n });\n}\nfunction fromIterable(iterable) {\n return new Observable((subscriber) => {\n const iterator = iterable[Symbol_iterator]();\n while (!subscriber.closed) {\n const { done, value } = iterator.next();\n if (done) {\n subscriber.complete();\n }\n else {\n subscriber.next(value);\n }\n }\n return () => isFunction(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return();\n });\n}\nfunction fromAsyncIterable(asyncIterable) {\n return new Observable((subscriber) => {\n process(asyncIterable, subscriber).catch((err) => subscriber.error(err));\n });\n}\nfunction process(asyncIterable, subscriber) {\n var asyncIterable_1, asyncIterable_1_1;\n var e_1, _a;\n return __awaiter(this, void 0, void 0, function* () {\n try {\n for (asyncIterable_1 = __asyncValues(asyncIterable); asyncIterable_1_1 = yield asyncIterable_1.next(), !asyncIterable_1_1.done;) {\n const value = asyncIterable_1_1.value;\n subscriber.next(value);\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return)) yield _a.call(asyncIterable_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n subscriber.complete();\n });\n}\n//# sourceMappingURL=from.js.map","import { map } from './map';\nimport { innerFrom } from '../observable/from';\nimport { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\nimport { isFunction } from '../util/isFunction';\nexport function mergeMap(project, resultSelector, concurrent = Infinity) {\n if (isFunction(resultSelector)) {\n return mergeMap((a, i) => map((b, ii) => resultSelector(a, b, i, ii))(innerFrom(project(a, i))), concurrent);\n }\n else if (typeof resultSelector === 'number') {\n concurrent = resultSelector;\n }\n return operate((source, subscriber) => mergeInternals(source, subscriber, project, concurrent));\n}\nexport const flatMap = mergeMap;\n//# sourceMappingURL=mergeMap.js.map","import { innerFrom } from '../observable/from';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalTeardown) {\n let buffer = [];\n let active = 0;\n let index = 0;\n let isComplete = false;\n const checkComplete = () => {\n if (isComplete && !buffer.length && !active) {\n subscriber.complete();\n }\n };\n const outerNext = (value) => (active < concurrent ? doInnerSub(value) : buffer.push(value));\n const doInnerSub = (value) => {\n expand && subscriber.next(value);\n active++;\n innerFrom(project(value, index++)).subscribe(new OperatorSubscriber(subscriber, (innerValue) => {\n onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);\n if (expand) {\n outerNext(innerValue);\n }\n else {\n subscriber.next(innerValue);\n }\n }, undefined, () => {\n active--;\n while (buffer.length && active < concurrent) {\n const bufferedValue = buffer.shift();\n innerSubScheduler ? subscriber.add(innerSubScheduler.schedule(() => doInnerSub(bufferedValue))) : doInnerSub(bufferedValue);\n }\n checkComplete();\n }));\n };\n source.subscribe(new OperatorSubscriber(subscriber, outerNext, undefined, () => {\n isComplete = true;\n checkComplete();\n }));\n return () => {\n buffer = null;\n additionalTeardown === null || additionalTeardown === void 0 ? void 0 : additionalTeardown();\n };\n}\n//# sourceMappingURL=mergeInternals.js.map","import { mergeMap } from './mergeMap';\nimport { identity } from '../util/identity';\nexport function mergeAll(concurrent = Infinity) {\n return mergeMap(identity, concurrent);\n}\n//# sourceMappingURL=mergeAll.js.map","import { scheduleArray } from '../scheduled/scheduleArray';\nimport { fromArrayLike } from './from';\nexport function internalFromArray(input, scheduler) {\n return scheduler ? scheduleArray(input, scheduler) : fromArrayLike(input);\n}\n//# sourceMappingURL=fromArray.js.map","const { isArray } = Array;\nexport function argsOrArgArray(args) {\n return args.length === 1 && isArray(args[0]) ? args[0] : args;\n}\n//# sourceMappingURL=argsOrArgArray.js.map","import { Observable } from '../Observable';\nexport const EMPTY = new Observable(subscriber => subscriber.complete());\nexport function empty(scheduler) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\nfunction emptyScheduled(scheduler) {\n return new Observable(subscriber => scheduler.schedule(() => subscriber.complete()));\n}\n//# sourceMappingURL=empty.js.map","import { isFunction } from './isFunction';\nexport function isScheduler(value) {\n return value && isFunction(value.schedule);\n}\n//# sourceMappingURL=isScheduler.js.map","import { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\nfunction last(arr) {\n return arr[arr.length - 1];\n}\nexport function popResultSelector(args) {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\nexport function popScheduler(args) {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\nexport function popNumber(args, defaultValue) {\n return typeof last(args) === 'number' ? args.pop() : defaultValue;\n}\n//# sourceMappingURL=args.js.map","import { mergeAll } from '../operators/mergeAll';\nimport { internalFromArray } from './fromArray';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { innerFrom } from './from';\nimport { EMPTY } from './empty';\nimport { popNumber, popScheduler } from '../util/args';\nexport function merge(...args) {\n const scheduler = popScheduler(args);\n const concurrent = popNumber(args, Infinity);\n const sources = argsOrArgArray(args);\n return !sources.length\n ?\n EMPTY\n : sources.length === 1\n ?\n innerFrom(sources[0])\n :\n mergeAll(concurrent)(internalFromArray(sources, scheduler));\n}\n//# sourceMappingURL=merge.js.map","import { innerFrom } from '../observable/from';\nimport { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function switchMap(project, resultSelector) {\n return operate((source, subscriber) => {\n let innerSubscriber = null;\n let index = 0;\n let isComplete = false;\n const checkComplete = () => isComplete && !innerSubscriber && subscriber.complete();\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe();\n let innerIndex = 0;\n const outerIndex = index++;\n innerFrom(project(value, outerIndex)).subscribe((innerSubscriber = new OperatorSubscriber(subscriber, (innerValue) => subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue), undefined, () => {\n innerSubscriber = null;\n checkComplete();\n })));\n }, undefined, () => {\n isComplete = true;\n checkComplete();\n }));\n });\n}\n//# sourceMappingURL=switchMap.js.map","import { createErrorClass } from './createErrorClass';\nexport const ObjectUnsubscribedError = createErrorClass((_super) => function ObjectUnsubscribedErrorImpl() {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n});\n//# sourceMappingURL=ObjectUnsubscribedError.js.map","import { Observable } from './Observable';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nexport class Subject extends Observable {\n constructor() {\n super();\n this.observers = [];\n this.closed = false;\n this.isStopped = false;\n this.hasError = false;\n this.thrownError = null;\n }\n lift(operator) {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator;\n return subject;\n }\n _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n next(value) {\n this._throwIfClosed();\n if (!this.isStopped) {\n const copy = this.observers.slice();\n for (const observer of copy) {\n observer.next(value);\n }\n }\n }\n error(err) {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift().error(err);\n }\n }\n }\n complete() {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift().complete();\n }\n }\n }\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = null;\n }\n _trySubscribe(subscriber) {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n _subscribe(subscriber) {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n _innerSubscribe(subscriber) {\n const { hasError, isStopped, observers } = this;\n return hasError || isStopped\n ? EMPTY_SUBSCRIPTION\n : (observers.push(subscriber), new Subscription(() => arrRemove(this.observers, subscriber)));\n }\n _checkFinalizedStatuses(subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n }\n else if (isStopped) {\n subscriber.complete();\n }\n }\n asObservable() {\n const observable = new Observable();\n observable.source = this;\n return observable;\n }\n}\nSubject.create = (destination, source) => {\n return new AnonymousSubject(destination, source);\n};\nexport class AnonymousSubject extends Subject {\n constructor(destination, source) {\n super();\n this.destination = destination;\n this.source = source;\n }\n next(value) {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);\n }\n error(err) {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);\n }\n complete() {\n var _a, _b;\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);\n }\n _subscribe(subscriber) {\n var _a, _b;\n return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;\n }\n}\n//# sourceMappingURL=Subject.js.map","export const dateTimestampProvider = {\n now() {\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n//# sourceMappingURL=dateTimestampProvider.js.map","import { Subject } from './Subject';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\nexport class ReplaySubject extends Subject {\n constructor(bufferSize = Infinity, windowTime = Infinity, timestampProvider = dateTimestampProvider) {\n super();\n this.bufferSize = bufferSize;\n this.windowTime = windowTime;\n this.timestampProvider = timestampProvider;\n this.buffer = [];\n this.infiniteTimeWindow = true;\n this.infiniteTimeWindow = windowTime === Infinity;\n this.bufferSize = Math.max(1, bufferSize);\n this.windowTime = Math.max(1, windowTime);\n }\n next(value) {\n const { isStopped, buffer, infiniteTimeWindow, timestampProvider, windowTime } = this;\n if (!isStopped) {\n buffer.push(value);\n !infiniteTimeWindow && buffer.push(timestampProvider.now() + windowTime);\n }\n this.trimBuffer();\n super.next(value);\n }\n _subscribe(subscriber) {\n this._throwIfClosed();\n this.trimBuffer();\n const subscription = this._innerSubscribe(subscriber);\n const { infiniteTimeWindow, buffer } = this;\n const copy = buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i]);\n }\n this._checkFinalizedStatuses(subscriber);\n return subscription;\n }\n trimBuffer() {\n const { bufferSize, timestampProvider, buffer, infiniteTimeWindow } = this;\n const adjustedBufferSize = (infiniteTimeWindow ? 1 : 2) * bufferSize;\n bufferSize < Infinity && adjustedBufferSize < buffer.length && buffer.splice(0, buffer.length - adjustedBufferSize);\n if (!infiniteTimeWindow) {\n const now = timestampProvider.now();\n let last = 0;\n for (let i = 1; i < buffer.length && buffer[i] <= now; i += 2) {\n last = i;\n }\n last && buffer.splice(0, last + 1);\n }\n }\n}\n//# sourceMappingURL=ReplaySubject.js.map","import { map } from \"../operators/map\";\nconst { isArray } = Array;\nfunction callOrApply(fn, args) {\n return isArray(args) ? fn(...args) : fn(args);\n}\nexport function mapOneOrManyArgs(fn) {\n return map(args => callOrApply(fn, args));\n}\n//# sourceMappingURL=mapOneOrManyArgs.js.map","import { Observable } from '../Observable';\nimport { mergeMap } from '../operators/mergeMap';\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isFunction } from '../util/isFunction';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { internalFromArray } from './fromArray';\nconst nodeEventEmitterMethods = ['addListener', 'removeListener'];\nconst eventTargetMethods = ['addEventListener', 'removeEventListener'];\nconst jqueryMethods = ['on', 'off'];\nexport function fromEvent(target, eventName, options, resultSelector) {\n if (isFunction(options)) {\n resultSelector = options;\n options = undefined;\n }\n if (resultSelector) {\n return fromEvent(target, eventName, options).pipe(mapOneOrManyArgs(resultSelector));\n }\n const [add, remove] = isEventTarget(target)\n ? eventTargetMethods.map((methodName) => (handler) => target[methodName](eventName, handler, options))\n :\n isNodeStyleEventEmitter(target)\n ? nodeEventEmitterMethods.map(toCommonHandlerRegistry(target, eventName))\n : isJQueryStyleEventEmitter(target)\n ? jqueryMethods.map(toCommonHandlerRegistry(target, eventName))\n : [];\n if (!add) {\n if (isArrayLike(target)) {\n return mergeMap((subTarget) => fromEvent(subTarget, eventName, options))(internalFromArray(target));\n }\n }\n return new Observable((subscriber) => {\n if (!add) {\n throw new TypeError('Invalid event target');\n }\n const handler = (...args) => subscriber.next(1 < args.length ? args : args[0]);\n add(handler);\n return () => remove(handler);\n });\n}\nfunction toCommonHandlerRegistry(target, eventName) {\n return (methodName) => (handler) => target[methodName](eventName, handler);\n}\nfunction isNodeStyleEventEmitter(target) {\n return isFunction(target.addListener) && isFunction(target.removeListener);\n}\nfunction isJQueryStyleEventEmitter(target) {\n return isFunction(target.on) && isFunction(target.off);\n}\nfunction isEventTarget(target) {\n return isFunction(target.addEventListener) && isFunction(target.removeEventListener);\n}\n//# sourceMappingURL=fromEvent.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function mapTo(value) {\n return operate((source, subscriber) => {\n source.subscribe(new OperatorSubscriber(subscriber, () => subscriber.next(value)));\n });\n}\n//# sourceMappingURL=mapTo.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElementOrThrow(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElementOrThrow(\n selector: string, node?: ParentNode\n): T\n\nexport function getElementOrThrow(\n selector: string, node: ParentNode = document\n): T {\n const el = getElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n return el\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement\n : undefined\n}\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Create an element\n *\n * @template T - Tag name type\n *\n * @param tagName - Tag name\n *\n * @returns Element\n */\nexport function createElement(\n tagName: T\n): HTMLElementTagNameMap[T] {\n return document.createElement(tagName)\n}\n\n/**\n * Replace an element with another element\n *\n * @param source - Source element\n * @param target - Target element\n */\nexport function replaceElement(\n source: HTMLElement, target: Node\n): void {\n source.replaceWith(target)\n}\n","import { concatAll } from '../operators/concatAll';\nimport { internalFromArray } from './fromArray';\nimport { popScheduler } from '../util/args';\nexport function concat(...args) {\n return concatAll()(internalFromArray(args, popScheduler(args)));\n}\n//# sourceMappingURL=concat.js.map","import { mergeAll } from './mergeAll';\nexport function concatAll() {\n return mergeAll(1);\n}\n//# sourceMappingURL=concatAll.js.map","import { concat } from '../observable/concat';\nimport { popScheduler } from '../util/args';\nimport { operate } from '../util/lift';\nexport function startWith(...values) {\n const scheduler = popScheduler(values);\n return operate((source, subscriber) => {\n (scheduler ? concat(values, source, scheduler) : concat(values, source)).subscribe(subscriber);\n });\n}\n//# sourceMappingURL=startWith.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function distinctUntilChanged(compare, keySelector) {\n compare = compare !== null && compare !== void 0 ? compare : defaultCompare;\n return operate((source, subscriber) => {\n let prev;\n let first = true;\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n ((first && ((prev = value), 1)) || !compare(prev, (prev = keySelector ? keySelector(value) : value))) &&\n subscriber.next(value);\n first = false;\n }));\n });\n}\nfunction defaultCompare(a, b) {\n return a === b;\n}\n//# sourceMappingURL=distinctUntilChanged.js.map","import { internalFromArray } from './fromArray';\nimport { scheduleArray } from '../scheduled/scheduleArray';\nimport { popScheduler } from '../util/args';\nexport function of(...args) {\n const scheduler = popScheduler(args);\n return scheduler ? scheduleArray(args, scheduler) : internalFromArray(args);\n}\n//# sourceMappingURL=of.js.map","import { Observable } from '../Observable';\nimport { noop } from '../util/noop';\nexport const NEVER = new Observable(noop);\nexport function never() {\n return NEVER;\n}\n//# sourceMappingURL=never.js.map","import { operate } from '../util/lift';\nexport function finalize(callback) {\n return operate((source, subscriber) => {\n source.subscribe(subscriber);\n subscriber.add(callback);\n });\n}\n//# sourceMappingURL=finalize.js.map","import { Subject } from '../Subject';\nimport { from } from '../observable/from';\nimport { operate } from '../util/lift';\nexport function share(options) {\n options = options || {};\n const { connector = () => new Subject(), resetOnComplete = true, resetOnError = true, resetOnRefCountZero = true } = options;\n let connection = null;\n let subject = null;\n let refCount = 0;\n let hasCompleted = false;\n let hasErrored = false;\n const reset = () => {\n connection = subject = null;\n hasCompleted = hasErrored = false;\n };\n return operate((source, subscriber) => {\n refCount++;\n if (!subject) {\n subject = connector();\n }\n const castSubscription = subject.subscribe(subscriber);\n if (!connection) {\n connection = from(source).subscribe({\n next: (value) => subject.next(value),\n error: (err) => {\n hasErrored = true;\n const dest = subject;\n if (resetOnError) {\n reset();\n }\n dest.error(err);\n },\n complete: () => {\n hasCompleted = true;\n const dest = subject;\n if (resetOnComplete) {\n reset();\n }\n dest.complete();\n },\n });\n }\n return () => {\n refCount--;\n castSubscription.unsubscribe();\n if (!refCount && resetOnRefCountZero && !hasErrored && !hasCompleted) {\n const conn = connection;\n reset();\n conn === null || conn === void 0 ? void 0 : conn.unsubscribe();\n }\n };\n });\n}\n//# sourceMappingURL=share.js.map","import { ReplaySubject } from '../ReplaySubject';\nimport { share } from './share';\nexport function shareReplay(configOrBufferSize, windowTime, scheduler) {\n var _a, _b;\n let bufferSize;\n let refCount = false;\n if (configOrBufferSize && typeof configOrBufferSize === 'object') {\n bufferSize = (_a = configOrBufferSize.bufferSize) !== null && _a !== void 0 ? _a : Infinity;\n windowTime = (_b = configOrBufferSize.windowTime) !== null && _b !== void 0 ? _b : Infinity;\n refCount = !!configOrBufferSize.refCount;\n scheduler = configOrBufferSize.scheduler;\n }\n else {\n bufferSize = configOrBufferSize !== null && configOrBufferSize !== void 0 ? configOrBufferSize : Infinity;\n }\n return share({\n connector: () => new ReplaySubject(bufferSize, windowTime, scheduler),\n resetOnError: true,\n resetOnComplete: false,\n resetOnRefCountZero: refCount\n });\n}\n//# sourceMappingURL=shareReplay.js.map","import { isFunction } from '../util/isFunction';\nimport { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nimport { identity } from '../util/identity';\nexport function tap(observerOrNext, error, complete) {\n const tapObserver = isFunction(observerOrNext) || error || complete ? { next: observerOrNext, error, complete } : observerOrNext;\n return tapObserver\n ? operate((source, subscriber) => {\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n var _a;\n (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);\n subscriber.next(value);\n }, (err) => {\n var _a;\n (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);\n subscriber.error(err);\n }, () => {\n var _a;\n (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n subscriber.complete();\n }));\n })\n :\n identity;\n}\n//# sourceMappingURL=tap.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function filter(predicate, thisArg) {\n return operate((source, subscriber) => {\n let index = 0;\n source.subscribe(new OperatorSubscriber(subscriber, (value) => predicate.call(thisArg, value, index++) && subscriber.next(value)));\n });\n}\n//# sourceMappingURL=filter.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n of\n} from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(resize => NEVER.pipe(startWith(resize))\n .pipe(\n finalize(() => resize.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(el: HTMLElement): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/**\n * Retrieve element content size, i.e. including overflowing content\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementContentSize(el: HTMLElement): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ contentRect }) => ({\n width: contentRect.width,\n height: contentRect.height\n }))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n","import { Observable } from '../Observable';\nimport { innerFrom } from './from';\nexport function defer(observableFactory) {\n return new Observable((subscriber) => {\n innerFrom(observableFactory()).subscribe(subscriber);\n });\n}\n//# sourceMappingURL=defer.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport { distinctUntilChanged, map, startWith } from \"rxjs/operators\"\n\nimport { getElementContentSize, getElementSize } from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(el: HTMLElement): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n\n/**\n * Watch element threshold\n *\n * This function returns an observable which emits whether the bottom scroll\n * offset of an elements is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element threshold observable\n */\nexport function watchElementThreshold(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getElementOrThrow } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElementOrThrow(\"[data-md-toggle=drawer]\"),\n search: getElementOrThrow(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { BehaviorSubject, Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function will return a `URL` object (and not `Location`) in order to\n * normalize typings across the application. Furthermore, locations need to be\n * tracked without setting them and `Location` is a singleton which represents\n * the current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new BehaviorSubject(getLocation())\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, from } from \"rxjs\"\nimport {\n filter,\n map,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * @param url - Request URL\n * @param options - Request options\n *\n * @returns Response observable\n */\nexport function request(\n url: string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(url, options))\n .pipe(\n filter(res => res.status === 200),\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Request options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Request options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n","const { isArray } = Array;\nconst { getPrototypeOf, prototype: objectProto, keys: getKeys } = Object;\nexport function argsArgArrayOrObject(args) {\n if (args.length === 1) {\n const first = args[0];\n if (isArray(first)) {\n return { args: first, keys: null };\n }\n if (isPOJO(first)) {\n const keys = getKeys(first);\n return {\n args: keys.map((key) => first[key]),\n keys,\n };\n }\n }\n return { args: args, keys: null };\n}\nfunction isPOJO(obj) {\n return obj && typeof obj === 'object' && getPrototypeOf(obj) === objectProto;\n}\n//# sourceMappingURL=argsArgArrayOrObject.js.map","import { Observable } from '../Observable';\nimport { argsArgArrayOrObject } from '../util/argsArgArrayOrObject';\nimport { Subscriber } from '../Subscriber';\nimport { from } from './from';\nimport { identity } from '../util/identity';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { popResultSelector, popScheduler } from '../util/args';\nexport function combineLatest(...args) {\n const scheduler = popScheduler(args);\n const resultSelector = popResultSelector(args);\n const { args: observables, keys } = argsArgArrayOrObject(args);\n if (observables.length === 0) {\n return from([], scheduler);\n }\n const result = new Observable(combineLatestInit(observables, scheduler, keys\n ?\n (values) => {\n const value = {};\n for (let i = 0; i < values.length; i++) {\n value[keys[i]] = values[i];\n }\n return value;\n }\n :\n identity));\n if (resultSelector) {\n return result.pipe(mapOneOrManyArgs(resultSelector));\n }\n return result;\n}\nclass CombineLatestSubscriber extends Subscriber {\n constructor(destination, _next, shouldComplete) {\n super(destination);\n this._next = _next;\n this.shouldComplete = shouldComplete;\n }\n _complete() {\n if (this.shouldComplete()) {\n super._complete();\n }\n else {\n this.unsubscribe();\n }\n }\n}\nexport function combineLatestInit(observables, scheduler, valueTransform = identity) {\n return (subscriber) => {\n const primarySubscribe = () => {\n const { length } = observables;\n const values = new Array(length);\n let active = length;\n const hasValues = observables.map(() => false);\n let waitingForFirstValues = true;\n const emit = () => subscriber.next(valueTransform(values.slice()));\n for (let i = 0; i < length; i++) {\n const subscribe = () => {\n const source = from(observables[i], scheduler);\n source.subscribe(new CombineLatestSubscriber(subscriber, (value) => {\n values[i] = value;\n if (waitingForFirstValues) {\n hasValues[i] = true;\n waitingForFirstValues = !hasValues.every(identity);\n }\n if (!waitingForFirstValues) {\n emit();\n }\n }, () => --active === 0));\n };\n maybeSchedule(scheduler, subscribe, subscriber);\n }\n };\n maybeSchedule(scheduler, primarySubscribe, subscriber);\n };\n}\nfunction maybeSchedule(scheduler, execute, subscription) {\n if (scheduler) {\n subscription.add(scheduler.schedule(execute));\n }\n else {\n execute();\n }\n}\n//# sourceMappingURL=combineLatest.js.map","import { distinctUntilChanged } from './distinctUntilChanged';\nexport function distinctUntilKeyChanged(key, compare) {\n return distinctUntilChanged((x, y) => compare ? compare(x[key], y[key]) : x[key] === y[key]);\n}\n//# sourceMappingURL=distinctUntilKeyChanged.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElementOrThrow, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component\n */\nexport type ComponentType =\n | \"icon-search\" /* Icon search */\n | \"icon-search-query\" /* Icon search input */\n | \"icon-search-result\" /* Icon search results */\n\n/**\n * A component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: ComponentType, node: ParentNode = document\n): T {\n return getElementOrThrow(`[data-mdx-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: ComponentType, node: ParentNode = document\n): T[] {\n return getElements(`[data-mdx-component=${type}]`, node)\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElementOrThrow, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Sections navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElementOrThrow(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = new URL(config.base, getLocation())\n .toString()\n .replace(/\\/$/, \"\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Value to be replaced\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n","import { Subscription } from '../Subscription';\nexport class Action extends Subscription {\n constructor(scheduler, work) {\n super();\n }\n schedule(state, delay = 0) {\n return this;\n }\n}\n//# sourceMappingURL=Action.js.map","export const intervalProvider = {\n setInterval(...args) {\n const { delegate } = intervalProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.setInterval) || setInterval)(...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearInterval) || clearInterval)(handle);\n },\n delegate: undefined,\n};\n//# sourceMappingURL=intervalProvider.js.map","import { Action } from './Action';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nexport class AsyncAction extends Action {\n constructor(scheduler, work) {\n super(scheduler, work);\n this.scheduler = scheduler;\n this.work = work;\n this.pending = false;\n }\n schedule(state, delay = 0) {\n if (this.closed) {\n return this;\n }\n this.state = state;\n const id = this.id;\n const scheduler = this.scheduler;\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n this.pending = true;\n this.delay = delay;\n this.id = this.id || this.requestAsyncId(scheduler, this.id, delay);\n return this;\n }\n requestAsyncId(scheduler, _id, delay = 0) {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n recycleAsyncId(_scheduler, id, delay = 0) {\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n intervalProvider.clearInterval(id);\n return undefined;\n }\n execute(state, delay) {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n }\n else if (this.pending === false && this.id != null) {\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n _execute(state, _delay) {\n let errored = false;\n let errorValue;\n try {\n this.work(state);\n }\n catch (e) {\n errored = true;\n errorValue = (!!e && e) || new Error(e);\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n this.work = this.state = this.scheduler = null;\n this.pending = false;\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n this.delay = null;\n super.unsubscribe();\n }\n }\n}\n//# sourceMappingURL=AsyncAction.js.map","import { dateTimestampProvider } from \"./scheduler/dateTimestampProvider\";\nexport class Scheduler {\n constructor(schedulerActionCtor, now = Scheduler.now) {\n this.schedulerActionCtor = schedulerActionCtor;\n this.now = now;\n }\n schedule(work, delay = 0, state) {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\nScheduler.now = dateTimestampProvider.now;\n//# sourceMappingURL=Scheduler.js.map","import { Scheduler } from '../Scheduler';\nexport class AsyncScheduler extends Scheduler {\n constructor(SchedulerAction, now = Scheduler.now) {\n super(SchedulerAction, now);\n this.actions = [];\n this.active = false;\n this.scheduled = undefined;\n }\n flush(action) {\n const { actions } = this;\n if (this.active) {\n actions.push(action);\n return;\n }\n let error;\n this.active = true;\n do {\n if (error = action.execute(action.state, action.delay)) {\n break;\n }\n } while (action = actions.shift());\n this.active = false;\n if (error) {\n while (action = actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n//# sourceMappingURL=AsyncScheduler.js.map","import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\nexport const async = asyncScheduler;\n//# sourceMappingURL=async.js.map","import { EMPTY } from '../observable/empty';\nimport { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function take(count) {\n return count <= 0\n ?\n () => EMPTY\n : operate((source, subscriber) => {\n let seen = 0;\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n if (++seen <= count) {\n subscriber.next(value);\n if (count <= seen) {\n subscriber.complete();\n }\n }\n }));\n });\n}\n//# sourceMappingURL=take.js.map","import { concat } from '../observable/concat';\nimport { take } from './take';\nimport { ignoreElements } from './ignoreElements';\nimport { mapTo } from './mapTo';\nimport { mergeMap } from './mergeMap';\nexport function delayWhen(delayDurationSelector, subscriptionDelay) {\n if (subscriptionDelay) {\n return (source) => concat(subscriptionDelay.pipe(take(1), ignoreElements()), source.pipe(delayWhen(delayDurationSelector)));\n }\n return mergeMap((value, index) => delayDurationSelector(value, index).pipe(take(1), mapTo(value)));\n}\n//# sourceMappingURL=delayWhen.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nexport function ignoreElements() {\n return operate((source, subscriber) => {\n source.subscribe(new OperatorSubscriber(subscriber, noop));\n });\n}\n//# sourceMappingURL=ignoreElements.js.map","import { Observable } from '../Observable';\nimport { async as asyncScheduler } from '../scheduler/async';\nimport { isScheduler } from '../util/isScheduler';\nimport { isValidDate } from '../util/isDate';\nexport function timer(dueTime = 0, intervalOrScheduler, scheduler = asyncScheduler) {\n let intervalDuration = -1;\n if (intervalOrScheduler != null) {\n if (isScheduler(intervalOrScheduler)) {\n scheduler = intervalOrScheduler;\n }\n else {\n intervalDuration = intervalOrScheduler;\n }\n }\n return new Observable((subscriber) => {\n let due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime;\n if (due < 0) {\n due = 0;\n }\n let n = 0;\n return scheduler.schedule(function () {\n if (!subscriber.closed) {\n subscriber.next(n++);\n if (0 <= intervalDuration) {\n this.schedule(undefined, intervalDuration);\n }\n else {\n subscriber.complete();\n }\n }\n }, due);\n });\n}\n//# sourceMappingURL=timer.js.map","export function isValidDate(value) {\n return value instanceof Date && !isNaN(value);\n}\n//# sourceMappingURL=isDate.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/from';\nimport { identity } from '../util/identity';\nimport { noop } from '../util/noop';\nimport { popResultSelector } from '../util/args';\nexport function withLatestFrom(...inputs) {\n const project = popResultSelector(inputs);\n return operate((source, subscriber) => {\n const len = inputs.length;\n const otherValues = new Array(len);\n let hasValue = inputs.map(() => false);\n let ready = false;\n for (let i = 0; i < len; i++) {\n innerFrom(inputs[i]).subscribe(new OperatorSubscriber(subscriber, (value) => {\n otherValues[i] = value;\n if (!ready && !hasValue[i]) {\n hasValue[i] = true;\n (ready = hasValue.every(identity)) && (hasValue = null);\n }\n }, undefined, noop));\n }\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n if (ready) {\n const values = [value, ...otherValues];\n subscriber.next(project ? project(...values) : values);\n }\n }));\n });\n}\n//# sourceMappingURL=withLatestFrom.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, combineLatest, fromEvent, merge } from \"rxjs\"\nimport {\n delay,\n distinctUntilChanged,\n filter,\n map,\n startWith,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { watchElementFocus } from \"~/browser\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Icon search query\n */\nexport interface IconSearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount icon search query\n *\n * @param el - Icon search query element\n *\n * @returns Icon search query component observable\n */\nexport function mountIconSearchQuery(\n el: HTMLInputElement\n): Observable> {\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1))\n )\n .pipe(\n map(() => el.value),\n startWith(el.value),\n distinctUntilChanged()\n )\n\n /* Log search on blur */\n focus$\n .pipe(\n filter(active => !active),\n withLatestFrom(value$)\n )\n .subscribe(([, value]) => {\n const path = document.location.pathname\n ga(\"send\", \"pageview\", `${path}?q=[icon]+${value}`)\n })\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ ref: el, value, focus })),\n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set element focus\n *\n * @param el - Element\n * @param value - Whether the element should be focused\n */\nexport function setElementFocus(\n el: HTMLElement, value = true\n): void {\n if (value)\n el.focus()\n else\n el.blur()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"focus\"),\n fromEvent(el, \"blur\")\n )\n .pipe(\n map(({ type }) => type === \"focus\"),\n startWith(el === getActiveElement())\n )\n}\n","import { asyncScheduler } from '../scheduler/async';\nimport { delayWhen } from './delayWhen';\nimport { timer } from '../observable/timer';\nexport function delay(due, scheduler = asyncScheduler) {\n const duration = timer(due, scheduler);\n return delayWhen(() => duration);\n}\n//# sourceMappingURL=delay.js.map","import { Subscription } from '../Subscription';\nexport const animationFrameProvider = {\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel === null || cancel === void 0 ? void 0 : cancel(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.requestAnimationFrame) || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return ((delegate === null || delegate === void 0 ? void 0 : delegate.cancelAnimationFrame) || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n//# sourceMappingURL=animationFrameProvider.js.map","import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\nexport const animationFrame = animationFrameScheduler;\n//# sourceMappingURL=animationFrame.js.map","import { AsyncScheduler } from './AsyncScheduler';\nexport class AnimationFrameScheduler extends AsyncScheduler {\n flush(action) {\n this.active = true;\n this.scheduled = undefined;\n const { actions } = this;\n let error;\n let index = -1;\n action = action || actions.shift();\n const count = actions.length;\n do {\n if (error = action.execute(action.state, action.delay)) {\n break;\n }\n } while (++index < count && (action = actions.shift()));\n this.active = false;\n if (error) {\n while (++index < count && (action = actions.shift())) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n//# sourceMappingURL=AnimationFrameScheduler.js.map","import { AsyncAction } from './AsyncAction';\nimport { animationFrameProvider } from './animationFrameProvider';\nexport class AnimationFrameAction extends AsyncAction {\n constructor(scheduler, work) {\n super(scheduler, work);\n this.scheduler = scheduler;\n this.work = work;\n }\n requestAsyncId(scheduler, id, delay = 0) {\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n scheduler.actions.push(this);\n return scheduler.scheduled || (scheduler.scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n recycleAsyncId(scheduler, id, delay = 0) {\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n if (scheduler.actions.length === 0) {\n animationFrameProvider.cancelAnimationFrame(id);\n scheduler.scheduled = undefined;\n }\n return undefined;\n }\n}\n//# sourceMappingURL=AnimationFrameAction.js.map","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function observeOn(scheduler, delay = 0) {\n return operate((source, subscriber) => {\n source.subscribe(new OperatorSubscriber(subscriber, (value) => subscriber.add(scheduler.schedule(() => subscriber.next(value), delay)), (err) => subscriber.add(scheduler.schedule(() => subscriber.error(err), delay)), () => subscriber.add(scheduler.schedule(() => subscriber.complete(), delay))));\n });\n}\n//# sourceMappingURL=observeOn.js.map","import { zip as zipStatic } from '../observable/zip';\nimport { operate } from '../util/lift';\nexport function zip(...sources) {\n return operate((source, subscriber) => {\n zipStatic(source, ...sources).subscribe(subscriber);\n });\n}\nexport function zipWith(...otherInputs) {\n return zip(...otherInputs);\n}\n//# sourceMappingURL=zipWith.js.map","import { Observable } from '../Observable';\nimport { innerFrom } from './from';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { EMPTY } from './empty';\nimport { OperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { popResultSelector } from '../util/args';\nexport function zip(...args) {\n const resultSelector = popResultSelector(args);\n const sources = argsOrArgArray(args);\n return sources.length\n ? new Observable((subscriber) => {\n let buffers = sources.map(() => []);\n let completed = sources.map(() => false);\n subscriber.add(() => {\n buffers = completed = null;\n });\n for (let sourceIndex = 0; !subscriber.closed && sourceIndex < sources.length; sourceIndex++) {\n innerFrom(sources[sourceIndex]).subscribe(new OperatorSubscriber(subscriber, (value) => {\n buffers[sourceIndex].push(value);\n if (buffers.every((buffer) => buffer.length)) {\n const result = buffers.map((buffer) => buffer.shift());\n subscriber.next(resultSelector ? resultSelector(...result) : result);\n if (buffers.some((buffer, i) => !buffer.length && completed[i])) {\n subscriber.complete();\n }\n }\n }, undefined, () => {\n completed[sourceIndex] = true;\n !buffers[sourceIndex].length && subscriber.complete();\n }));\n }\n return () => {\n buffers = completed = null;\n };\n })\n : EMPTY;\n}\n//# sourceMappingURL=zip.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: string, attributes: Attributes | null, ...children: Child[]\n): HTMLElement {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes))\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else if (attributes[attr])\n el.setAttribute(attr, \"\")\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { wrap } from \"fuzzaldrin-plus\"\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Icon\n */\nexport interface Icon {\n shortcode: string /* Icon shortcode */\n url: string /* Icon URL */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Highlight an icon search result\n *\n * @param icon - Icon\n * @param query - Search query\n *\n * @returns Highlighted result\n */\nfunction highlight(icon: Icon, query: string) {\n return wrap(icon.shortcode, query, {\n wrap: {\n tagOpen: \"\",\n tagClose: \"\"\n }\n })\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an icon search result\n *\n * @param icon - Icon\n * @param query - Search query\n *\n * @returns Element\n */\nexport function renderIconSearchResult(\n icon: Icon, query: string\n): HTMLElement {\n return (\n
  • \n \n \n \n \n {`:${highlight(icon, query)}:`}\n \n
  • \n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { filter as search } from \"fuzzaldrin-plus\"\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n combineLatest,\n merge,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n observeOn,\n switchMap,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs/operators\"\n\nimport {\n addToSearchResultList,\n resetSearchResultList,\n resetSearchResultMeta,\n setSearchResultMeta\n} from \"~/actions\"\nimport {\n getElementOrThrow,\n watchElementThreshold\n} from \"~/browser\"\n\nimport { Icon, renderIconSearchResult } from \"../../../templates\"\nimport { Component } from \"../../_\"\nimport { IconSearchIndex } from \"../_\"\nimport { IconSearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Icon search result\n */\nexport interface IconSearchResult {\n data: Icon[] /* Search result data */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n index$: Observable /* Search index observable */\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: Observable /* Search index observable */\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch icon search result\n *\n * @param _el - Icon search result element\n * @param options - Options\n *\n * @returns Icon search result observable\n */\nexport function watchIconSearchResult(\n _el: HTMLElement, { index$, query$ }: WatchOptions\n): Observable {\n return combineLatest([\n query$.pipe(distinctUntilKeyChanged(\"value\")),\n index$\n .pipe(\n map(({ icons, emojis }) => [\n ...Object.keys(icons.data),\n ...Object.keys(emojis.data)\n ])\n )\n ])\n .pipe(\n map(([{ value }, data]) => search(data, value)),\n switchMap(shortcodes => index$.pipe(\n map(({ icons, emojis }) => ({\n data: shortcodes.map(shortcode => {\n const category =\n shortcode in icons.data\n ? icons\n : emojis\n return {\n shortcode,\n url: [\n category.base,\n category.data[shortcode]\n ].join(\"\")\n }\n })\n }))\n ))\n )\n}\n\n/**\n * Mount icon search result\n *\n * @param el - Icon search result element\n * @param options - Options\n *\n * @returns Icon search result component observable\n */\nexport function mountIconSearchResult(\n el: HTMLElement, { index$, query$ }: MountOptions\n): Observable> {\n const internal$ = new Subject()\n const boundary$ = watchElementThreshold(el)\n .pipe(\n filter(Boolean)\n )\n\n /* Update search result metadata */\n const meta = getElementOrThrow(\":scope > :first-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n withLatestFrom(query$)\n )\n .subscribe(([{ data }, { value }]) => {\n if (value)\n setSearchResultMeta(meta, data.length)\n else\n resetSearchResultMeta(meta)\n })\n\n /* Update icon search result list */\n const list = getElementOrThrow(\":scope > :last-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n tap(() => resetSearchResultList(list)),\n switchMap(({ data }) => merge(\n of(...data.slice(0, 10)),\n of(...data.slice(10))\n .pipe(\n bufferCount(10),\n zipWith(boundary$),\n switchMap(([chunk]) => of(...chunk))\n )\n )),\n withLatestFrom(query$)\n )\n .subscribe(([result, { value }]) => {\n addToSearchResultList(list, renderIconSearchResult(result, value))\n })\n\n /* Create and return component */\n return watchIconSearchResult(el, { query$, index$ })\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set number of search results\n *\n * @param el - Search result metadata element\n * @param value - Number of results\n */\nexport function setSearchResultMeta(\n el: HTMLElement, value: number\n): void {\n switch (value) {\n\n /* No results */\n case 0:\n el.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n el.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n el.textContent = translation(\"search.result.other\", round(value))\n }\n}\n\n/**\n * Reset number of search results\n *\n * @param el - Search result metadata element\n */\nexport function resetSearchResultMeta(\n el: HTMLElement\n): void {\n el.textContent = translation(\"search.result.placeholder\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Add an element to the search result list\n *\n * @param el - Search result list element\n * @param child - Search result element\n */\nexport function addToSearchResultList(\n el: HTMLElement, child: Element\n): void {\n el.appendChild(child)\n}\n\n/**\n * Reset search result list\n *\n * @param el - Search result list element\n */\nexport function resetSearchResultList(\n el: HTMLElement\n): void {\n el.innerHTML = \"\"\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n\n/**\n * Simple hash function\n *\n * @see https://bit.ly/2wsVjJ4 - Original source\n *\n * @param value - Value to be hashed\n *\n * @returns Hash as 32bit integer\n */\nexport function hash(value: string): number {\n let h = 0\n for (let i = 0, len = value.length; i < len; i++) {\n h = ((h << 5) - h) + value.charCodeAt(i)\n h |= 0 // Convert to 32bit integer\n }\n return h\n}\n","import { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nimport { arrRemove } from '../util/arrRemove';\nexport function bufferCount(bufferSize, startBufferEvery = null) {\n startBufferEvery = startBufferEvery !== null && startBufferEvery !== void 0 ? startBufferEvery : bufferSize;\n return operate((source, subscriber) => {\n let buffers = [];\n let count = 0;\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n let toEmit = null;\n if (count++ % startBufferEvery === 0) {\n buffers.push([]);\n }\n for (const buffer of buffers) {\n buffer.push(value);\n if (bufferSize <= buffer.length) {\n toEmit = toEmit !== null && toEmit !== void 0 ? toEmit : [];\n toEmit.push(buffer);\n }\n }\n if (toEmit) {\n for (const buffer of toEmit) {\n arrRemove(buffers, buffer);\n subscriber.next(buffer);\n }\n }\n }, undefined, () => {\n for (const buffer of buffers) {\n subscriber.next(buffer);\n }\n subscriber.complete();\n }, () => {\n buffers = null;\n }));\n });\n}\n//# sourceMappingURL=bufferCount.js.map","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { requestJSON } from \"~/browser\"\n\nimport { Component, getComponentElement } from \"../../_\"\nimport {\n IconSearchQuery,\n mountIconSearchQuery\n} from \"../query\"\nimport {\n IconSearchResult,\n mountIconSearchResult\n} from \"../result\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Icon category\n */\nexport interface IconCategory {\n base: string /* Category base URL */\n data: Record /* Category data */\n}\n\n/**\n * Icon search index\n */\nexport interface IconSearchIndex {\n icons: IconCategory /* Icons */\n emojis: IconCategory /* Emojis */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Icon search\n */\nexport type IconSearch =\n | IconSearchQuery\n | IconSearchResult\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount icon search\n *\n * @param el - Icon search element\n *\n * @returns Icon search component observable\n */\nexport function mountIconSearch(\n el: HTMLElement\n): Observable> {\n const config = configuration()\n const index$ = requestJSON(\n `${config.base}/overrides/assets/javascripts/icon_search_index.json`\n )\n\n /* Retrieve nested components */\n const query = getComponentElement(\"icon-search-query\", el)\n const result = getComponentElement(\"icon-search-result\", el)\n\n /* Create and return component */\n const query$ = mountIconSearchQuery(query as HTMLInputElement)\n return merge(\n query$,\n mountIconSearchResult(result, { index$, query$ })\n )\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { fromEvent } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up extra analytics events\n */\nexport function setupAnalytics(): void {\n fromEvent(document.body, \"click\")\n .subscribe(ev => {\n if (ev.target instanceof HTMLElement) {\n const el = ev.target.closest(\"a[href^=http]\")\n if (el instanceof HTMLLinkElement)\n ga(\"send\", \"event\", \"outbound\", \"click\", el.href)\n }\n })\n}\n","/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\nimport { switchMap } from \"rxjs/operators\"\n\nimport {\n getComponentElements,\n mountIconSearch\n} from \"./components\"\nimport { setupAnalytics } from \"./integrations\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Set up extra analytics events */\nsetupAnalytics()\n\n/* Set up extra component observables */\ndeclare const document$: Observable\ndocument$\n .pipe(\n switchMap(() => merge(\n\n /* Icon search */\n ...getComponentElements(\"icon-search\")\n .map(el => mountIconSearch(el))\n ))\n )\n .subscribe()\n"],"sourceRoot":""} \ No newline at end of file diff --git a/v2.0.2/overrides/assets/javascripts/icon_search_index.json b/v2.0.2/overrides/assets/javascripts/icon_search_index.json new file mode 100644 index 0000000..f87536d --- /dev/null +++ b/v2.0.2/overrides/assets/javascripts/icon_search_index.json @@ -0,0 +1 @@ +{"icons":{"base":"https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/","data":{"fontawesome-brands-500px":"fontawesome/brands/500px.svg","fontawesome-brands-accessible-icon":"fontawesome/brands/accessible-icon.svg","fontawesome-brands-accusoft":"fontawesome/brands/accusoft.svg","fontawesome-brands-acquisitions-incorporated":"fontawesome/brands/acquisitions-incorporated.svg","fontawesome-brands-adn":"fontawesome/brands/adn.svg","fontawesome-brands-adversal":"fontawesome/brands/adversal.svg","fontawesome-brands-affiliatetheme":"fontawesome/brands/affiliatetheme.svg","fontawesome-brands-airbnb":"fontawesome/brands/airbnb.svg","fontawesome-brands-algolia":"fontawesome/brands/algolia.svg","fontawesome-brands-alipay":"fontawesome/brands/alipay.svg","fontawesome-brands-amazon-pay":"fontawesome/brands/amazon-pay.svg","fontawesome-brands-amazon":"fontawesome/brands/amazon.svg","fontawesome-brands-amilia":"fontawesome/brands/amilia.svg","fontawesome-brands-android":"fontawesome/brands/android.svg","fontawesome-brands-angellist":"fontawesome/brands/angellist.svg","fontawesome-brands-angrycreative":"fontawesome/brands/angrycreative.svg","fontawesome-brands-angular":"fontawesome/brands/angular.svg","fontawesome-brands-app-store-ios":"fontawesome/brands/app-store-ios.svg","fontawesome-brands-app-store":"fontawesome/brands/app-store.svg","fontawesome-brands-apper":"fontawesome/brands/apper.svg","fontawesome-brands-apple-pay":"fontawesome/brands/apple-pay.svg","fontawesome-brands-apple":"fontawesome/brands/apple.svg","fontawesome-brands-artstation":"fontawesome/brands/artstation.svg","fontawesome-brands-asymmetrik":"fontawesome/brands/asymmetrik.svg","fontawesome-brands-atlassian":"fontawesome/brands/atlassian.svg","fontawesome-brands-audible":"fontawesome/brands/audible.svg","fontawesome-brands-autoprefixer":"fontawesome/brands/autoprefixer.svg","fontawesome-brands-avianex":"fontawesome/brands/avianex.svg","fontawesome-brands-aviato":"fontawesome/brands/aviato.svg","fontawesome-brands-aws":"fontawesome/brands/aws.svg","fontawesome-brands-bandcamp":"fontawesome/brands/bandcamp.svg","fontawesome-brands-battle-net":"fontawesome/brands/battle-net.svg","fontawesome-brands-behance-square":"fontawesome/brands/behance-square.svg","fontawesome-brands-behance":"fontawesome/brands/behance.svg","fontawesome-brands-bimobject":"fontawesome/brands/bimobject.svg","fontawesome-brands-bitbucket":"fontawesome/brands/bitbucket.svg","fontawesome-brands-bitcoin":"fontawesome/brands/bitcoin.svg","fontawesome-brands-bity":"fontawesome/brands/bity.svg","fontawesome-brands-black-tie":"fontawesome/brands/black-tie.svg","fontawesome-brands-blackberry":"fontawesome/brands/blackberry.svg","fontawesome-brands-blogger-b":"fontawesome/brands/blogger-b.svg","fontawesome-brands-blogger":"fontawesome/brands/blogger.svg","fontawesome-brands-bluetooth-b":"fontawesome/brands/bluetooth-b.svg","fontawesome-brands-bluetooth":"fontawesome/brands/bluetooth.svg","fontawesome-brands-bootstrap":"fontawesome/brands/bootstrap.svg","fontawesome-brands-btc":"fontawesome/brands/btc.svg","fontawesome-brands-buffer":"fontawesome/brands/buffer.svg","fontawesome-brands-buromobelexperte":"fontawesome/brands/buromobelexperte.svg","fontawesome-brands-buy-n-large":"fontawesome/brands/buy-n-large.svg","fontawesome-brands-buysellads":"fontawesome/brands/buysellads.svg","fontawesome-brands-canadian-maple-leaf":"fontawesome/brands/canadian-maple-leaf.svg","fontawesome-brands-cc-amazon-pay":"fontawesome/brands/cc-amazon-pay.svg","fontawesome-brands-cc-amex":"fontawesome/brands/cc-amex.svg","fontawesome-brands-cc-apple-pay":"fontawesome/brands/cc-apple-pay.svg","fontawesome-brands-cc-diners-club":"fontawesome/brands/cc-diners-club.svg","fontawesome-brands-cc-discover":"fontawesome/brands/cc-discover.svg","fontawesome-brands-cc-jcb":"fontawesome/brands/cc-jcb.svg","fontawesome-brands-cc-mastercard":"fontawesome/brands/cc-mastercard.svg","fontawesome-brands-cc-paypal":"fontawesome/brands/cc-paypal.svg","fontawesome-brands-cc-stripe":"fontawesome/brands/cc-stripe.svg","fontawesome-brands-cc-visa":"fontawesome/brands/cc-visa.svg","fontawesome-brands-centercode":"fontawesome/brands/centercode.svg","fontawesome-brands-centos":"fontawesome/brands/centos.svg","fontawesome-brands-chrome":"fontawesome/brands/chrome.svg","fontawesome-brands-chromecast":"fontawesome/brands/chromecast.svg","fontawesome-brands-cloudflare":"fontawesome/brands/cloudflare.svg","fontawesome-brands-cloudscale":"fontawesome/brands/cloudscale.svg","fontawesome-brands-cloudsmith":"fontawesome/brands/cloudsmith.svg","fontawesome-brands-cloudversify":"fontawesome/brands/cloudversify.svg","fontawesome-brands-codepen":"fontawesome/brands/codepen.svg","fontawesome-brands-codiepie":"fontawesome/brands/codiepie.svg","fontawesome-brands-confluence":"fontawesome/brands/confluence.svg","fontawesome-brands-connectdevelop":"fontawesome/brands/connectdevelop.svg","fontawesome-brands-contao":"fontawesome/brands/contao.svg","fontawesome-brands-cotton-bureau":"fontawesome/brands/cotton-bureau.svg","fontawesome-brands-cpanel":"fontawesome/brands/cpanel.svg","fontawesome-brands-creative-commons-by":"fontawesome/brands/creative-commons-by.svg","fontawesome-brands-creative-commons-nc-eu":"fontawesome/brands/creative-commons-nc-eu.svg","fontawesome-brands-creative-commons-nc-jp":"fontawesome/brands/creative-commons-nc-jp.svg","fontawesome-brands-creative-commons-nc":"fontawesome/brands/creative-commons-nc.svg","fontawesome-brands-creative-commons-nd":"fontawesome/brands/creative-commons-nd.svg","fontawesome-brands-creative-commons-pd-alt":"fontawesome/brands/creative-commons-pd-alt.svg","fontawesome-brands-creative-commons-pd":"fontawesome/brands/creative-commons-pd.svg","fontawesome-brands-creative-commons-remix":"fontawesome/brands/creative-commons-remix.svg","fontawesome-brands-creative-commons-sa":"fontawesome/brands/creative-commons-sa.svg","fontawesome-brands-creative-commons-sampling-plus":"fontawesome/brands/creative-commons-sampling-plus.svg","fontawesome-brands-creative-commons-sampling":"fontawesome/brands/creative-commons-sampling.svg","fontawesome-brands-creative-commons-share":"fontawesome/brands/creative-commons-share.svg","fontawesome-brands-creative-commons-zero":"fontawesome/brands/creative-commons-zero.svg","fontawesome-brands-creative-commons":"fontawesome/brands/creative-commons.svg","fontawesome-brands-critical-role":"fontawesome/brands/critical-role.svg","fontawesome-brands-css3-alt":"fontawesome/brands/css3-alt.svg","fontawesome-brands-css3":"fontawesome/brands/css3.svg","fontawesome-brands-cuttlefish":"fontawesome/brands/cuttlefish.svg","fontawesome-brands-d-and-d-beyond":"fontawesome/brands/d-and-d-beyond.svg","fontawesome-brands-d-and-d":"fontawesome/brands/d-and-d.svg","fontawesome-brands-dailymotion":"fontawesome/brands/dailymotion.svg","fontawesome-brands-dashcube":"fontawesome/brands/dashcube.svg","fontawesome-brands-deezer":"fontawesome/brands/deezer.svg","fontawesome-brands-delicious":"fontawesome/brands/delicious.svg","fontawesome-brands-deploydog":"fontawesome/brands/deploydog.svg","fontawesome-brands-deskpro":"fontawesome/brands/deskpro.svg","fontawesome-brands-dev":"fontawesome/brands/dev.svg","fontawesome-brands-deviantart":"fontawesome/brands/deviantart.svg","fontawesome-brands-dhl":"fontawesome/brands/dhl.svg","fontawesome-brands-diaspora":"fontawesome/brands/diaspora.svg","fontawesome-brands-digg":"fontawesome/brands/digg.svg","fontawesome-brands-digital-ocean":"fontawesome/brands/digital-ocean.svg","fontawesome-brands-discord":"fontawesome/brands/discord.svg","fontawesome-brands-discourse":"fontawesome/brands/discourse.svg","fontawesome-brands-dochub":"fontawesome/brands/dochub.svg","fontawesome-brands-docker":"fontawesome/brands/docker.svg","fontawesome-brands-draft2digital":"fontawesome/brands/draft2digital.svg","fontawesome-brands-dribbble-square":"fontawesome/brands/dribbble-square.svg","fontawesome-brands-dribbble":"fontawesome/brands/dribbble.svg","fontawesome-brands-dropbox":"fontawesome/brands/dropbox.svg","fontawesome-brands-drupal":"fontawesome/brands/drupal.svg","fontawesome-brands-dyalog":"fontawesome/brands/dyalog.svg","fontawesome-brands-earlybirds":"fontawesome/brands/earlybirds.svg","fontawesome-brands-ebay":"fontawesome/brands/ebay.svg","fontawesome-brands-edge-legacy":"fontawesome/brands/edge-legacy.svg","fontawesome-brands-edge":"fontawesome/brands/edge.svg","fontawesome-brands-elementor":"fontawesome/brands/elementor.svg","fontawesome-brands-ello":"fontawesome/brands/ello.svg","fontawesome-brands-ember":"fontawesome/brands/ember.svg","fontawesome-brands-empire":"fontawesome/brands/empire.svg","fontawesome-brands-envira":"fontawesome/brands/envira.svg","fontawesome-brands-erlang":"fontawesome/brands/erlang.svg","fontawesome-brands-ethereum":"fontawesome/brands/ethereum.svg","fontawesome-brands-etsy":"fontawesome/brands/etsy.svg","fontawesome-brands-evernote":"fontawesome/brands/evernote.svg","fontawesome-brands-expeditedssl":"fontawesome/brands/expeditedssl.svg","fontawesome-brands-facebook-f":"fontawesome/brands/facebook-f.svg","fontawesome-brands-facebook-messenger":"fontawesome/brands/facebook-messenger.svg","fontawesome-brands-facebook-square":"fontawesome/brands/facebook-square.svg","fontawesome-brands-facebook":"fontawesome/brands/facebook.svg","fontawesome-brands-fantasy-flight-games":"fontawesome/brands/fantasy-flight-games.svg","fontawesome-brands-fedex":"fontawesome/brands/fedex.svg","fontawesome-brands-fedora":"fontawesome/brands/fedora.svg","fontawesome-brands-figma":"fontawesome/brands/figma.svg","fontawesome-brands-firefox-browser":"fontawesome/brands/firefox-browser.svg","fontawesome-brands-firefox":"fontawesome/brands/firefox.svg","fontawesome-brands-first-order-alt":"fontawesome/brands/first-order-alt.svg","fontawesome-brands-first-order":"fontawesome/brands/first-order.svg","fontawesome-brands-firstdraft":"fontawesome/brands/firstdraft.svg","fontawesome-brands-flickr":"fontawesome/brands/flickr.svg","fontawesome-brands-flipboard":"fontawesome/brands/flipboard.svg","fontawesome-brands-fly":"fontawesome/brands/fly.svg","fontawesome-brands-font-awesome-alt":"fontawesome/brands/font-awesome-alt.svg","fontawesome-brands-font-awesome-flag":"fontawesome/brands/font-awesome-flag.svg","fontawesome-brands-font-awesome-logo-full":"fontawesome/brands/font-awesome-logo-full.svg","fontawesome-brands-font-awesome":"fontawesome/brands/font-awesome.svg","fontawesome-brands-fonticons-fi":"fontawesome/brands/fonticons-fi.svg","fontawesome-brands-fonticons":"fontawesome/brands/fonticons.svg","fontawesome-brands-fort-awesome-alt":"fontawesome/brands/fort-awesome-alt.svg","fontawesome-brands-fort-awesome":"fontawesome/brands/fort-awesome.svg","fontawesome-brands-forumbee":"fontawesome/brands/forumbee.svg","fontawesome-brands-foursquare":"fontawesome/brands/foursquare.svg","fontawesome-brands-free-code-camp":"fontawesome/brands/free-code-camp.svg","fontawesome-brands-freebsd":"fontawesome/brands/freebsd.svg","fontawesome-brands-fulcrum":"fontawesome/brands/fulcrum.svg","fontawesome-brands-galactic-republic":"fontawesome/brands/galactic-republic.svg","fontawesome-brands-galactic-senate":"fontawesome/brands/galactic-senate.svg","fontawesome-brands-get-pocket":"fontawesome/brands/get-pocket.svg","fontawesome-brands-gg-circle":"fontawesome/brands/gg-circle.svg","fontawesome-brands-gg":"fontawesome/brands/gg.svg","fontawesome-brands-git-alt":"fontawesome/brands/git-alt.svg","fontawesome-brands-git-square":"fontawesome/brands/git-square.svg","fontawesome-brands-git":"fontawesome/brands/git.svg","fontawesome-brands-github-alt":"fontawesome/brands/github-alt.svg","fontawesome-brands-github-square":"fontawesome/brands/github-square.svg","fontawesome-brands-github":"fontawesome/brands/github.svg","fontawesome-brands-gitkraken":"fontawesome/brands/gitkraken.svg","fontawesome-brands-gitlab":"fontawesome/brands/gitlab.svg","fontawesome-brands-gitter":"fontawesome/brands/gitter.svg","fontawesome-brands-glide-g":"fontawesome/brands/glide-g.svg","fontawesome-brands-glide":"fontawesome/brands/glide.svg","fontawesome-brands-gofore":"fontawesome/brands/gofore.svg","fontawesome-brands-goodreads-g":"fontawesome/brands/goodreads-g.svg","fontawesome-brands-goodreads":"fontawesome/brands/goodreads.svg","fontawesome-brands-google-drive":"fontawesome/brands/google-drive.svg","fontawesome-brands-google-pay":"fontawesome/brands/google-pay.svg","fontawesome-brands-google-play":"fontawesome/brands/google-play.svg","fontawesome-brands-google-plus-g":"fontawesome/brands/google-plus-g.svg","fontawesome-brands-google-plus-square":"fontawesome/brands/google-plus-square.svg","fontawesome-brands-google-plus":"fontawesome/brands/google-plus.svg","fontawesome-brands-google-wallet":"fontawesome/brands/google-wallet.svg","fontawesome-brands-google":"fontawesome/brands/google.svg","fontawesome-brands-gratipay":"fontawesome/brands/gratipay.svg","fontawesome-brands-grav":"fontawesome/brands/grav.svg","fontawesome-brands-gripfire":"fontawesome/brands/gripfire.svg","fontawesome-brands-grunt":"fontawesome/brands/grunt.svg","fontawesome-brands-guilded":"fontawesome/brands/guilded.svg","fontawesome-brands-gulp":"fontawesome/brands/gulp.svg","fontawesome-brands-hacker-news-square":"fontawesome/brands/hacker-news-square.svg","fontawesome-brands-hacker-news":"fontawesome/brands/hacker-news.svg","fontawesome-brands-hackerrank":"fontawesome/brands/hackerrank.svg","fontawesome-brands-hips":"fontawesome/brands/hips.svg","fontawesome-brands-hire-a-helper":"fontawesome/brands/hire-a-helper.svg","fontawesome-brands-hive":"fontawesome/brands/hive.svg","fontawesome-brands-hooli":"fontawesome/brands/hooli.svg","fontawesome-brands-hornbill":"fontawesome/brands/hornbill.svg","fontawesome-brands-hotjar":"fontawesome/brands/hotjar.svg","fontawesome-brands-houzz":"fontawesome/brands/houzz.svg","fontawesome-brands-html5":"fontawesome/brands/html5.svg","fontawesome-brands-hubspot":"fontawesome/brands/hubspot.svg","fontawesome-brands-ideal":"fontawesome/brands/ideal.svg","fontawesome-brands-imdb":"fontawesome/brands/imdb.svg","fontawesome-brands-innosoft":"fontawesome/brands/innosoft.svg","fontawesome-brands-instagram-square":"fontawesome/brands/instagram-square.svg","fontawesome-brands-instagram":"fontawesome/brands/instagram.svg","fontawesome-brands-instalod":"fontawesome/brands/instalod.svg","fontawesome-brands-intercom":"fontawesome/brands/intercom.svg","fontawesome-brands-internet-explorer":"fontawesome/brands/internet-explorer.svg","fontawesome-brands-invision":"fontawesome/brands/invision.svg","fontawesome-brands-ioxhost":"fontawesome/brands/ioxhost.svg","fontawesome-brands-itch-io":"fontawesome/brands/itch-io.svg","fontawesome-brands-itunes-note":"fontawesome/brands/itunes-note.svg","fontawesome-brands-itunes":"fontawesome/brands/itunes.svg","fontawesome-brands-java":"fontawesome/brands/java.svg","fontawesome-brands-jedi-order":"fontawesome/brands/jedi-order.svg","fontawesome-brands-jenkins":"fontawesome/brands/jenkins.svg","fontawesome-brands-jira":"fontawesome/brands/jira.svg","fontawesome-brands-joget":"fontawesome/brands/joget.svg","fontawesome-brands-joomla":"fontawesome/brands/joomla.svg","fontawesome-brands-js-square":"fontawesome/brands/js-square.svg","fontawesome-brands-js":"fontawesome/brands/js.svg","fontawesome-brands-jsfiddle":"fontawesome/brands/jsfiddle.svg","fontawesome-brands-kaggle":"fontawesome/brands/kaggle.svg","fontawesome-brands-keybase":"fontawesome/brands/keybase.svg","fontawesome-brands-keycdn":"fontawesome/brands/keycdn.svg","fontawesome-brands-kickstarter-k":"fontawesome/brands/kickstarter-k.svg","fontawesome-brands-kickstarter":"fontawesome/brands/kickstarter.svg","fontawesome-brands-korvue":"fontawesome/brands/korvue.svg","fontawesome-brands-laravel":"fontawesome/brands/laravel.svg","fontawesome-brands-lastfm-square":"fontawesome/brands/lastfm-square.svg","fontawesome-brands-lastfm":"fontawesome/brands/lastfm.svg","fontawesome-brands-leanpub":"fontawesome/brands/leanpub.svg","fontawesome-brands-less":"fontawesome/brands/less.svg","fontawesome-brands-line":"fontawesome/brands/line.svg","fontawesome-brands-linkedin-in":"fontawesome/brands/linkedin-in.svg","fontawesome-brands-linkedin":"fontawesome/brands/linkedin.svg","fontawesome-brands-linode":"fontawesome/brands/linode.svg","fontawesome-brands-linux":"fontawesome/brands/linux.svg","fontawesome-brands-lyft":"fontawesome/brands/lyft.svg","fontawesome-brands-magento":"fontawesome/brands/magento.svg","fontawesome-brands-mailchimp":"fontawesome/brands/mailchimp.svg","fontawesome-brands-mandalorian":"fontawesome/brands/mandalorian.svg","fontawesome-brands-markdown":"fontawesome/brands/markdown.svg","fontawesome-brands-mastodon":"fontawesome/brands/mastodon.svg","fontawesome-brands-maxcdn":"fontawesome/brands/maxcdn.svg","fontawesome-brands-mdb":"fontawesome/brands/mdb.svg","fontawesome-brands-medapps":"fontawesome/brands/medapps.svg","fontawesome-brands-medium-m":"fontawesome/brands/medium-m.svg","fontawesome-brands-medium":"fontawesome/brands/medium.svg","fontawesome-brands-medrt":"fontawesome/brands/medrt.svg","fontawesome-brands-meetup":"fontawesome/brands/meetup.svg","fontawesome-brands-megaport":"fontawesome/brands/megaport.svg","fontawesome-brands-mendeley":"fontawesome/brands/mendeley.svg","fontawesome-brands-microblog":"fontawesome/brands/microblog.svg","fontawesome-brands-microsoft":"fontawesome/brands/microsoft.svg","fontawesome-brands-mix":"fontawesome/brands/mix.svg","fontawesome-brands-mixcloud":"fontawesome/brands/mixcloud.svg","fontawesome-brands-mixer":"fontawesome/brands/mixer.svg","fontawesome-brands-mizuni":"fontawesome/brands/mizuni.svg","fontawesome-brands-modx":"fontawesome/brands/modx.svg","fontawesome-brands-monero":"fontawesome/brands/monero.svg","fontawesome-brands-napster":"fontawesome/brands/napster.svg","fontawesome-brands-neos":"fontawesome/brands/neos.svg","fontawesome-brands-nimblr":"fontawesome/brands/nimblr.svg","fontawesome-brands-node-js":"fontawesome/brands/node-js.svg","fontawesome-brands-node":"fontawesome/brands/node.svg","fontawesome-brands-npm":"fontawesome/brands/npm.svg","fontawesome-brands-ns8":"fontawesome/brands/ns8.svg","fontawesome-brands-nutritionix":"fontawesome/brands/nutritionix.svg","fontawesome-brands-octopus-deploy":"fontawesome/brands/octopus-deploy.svg","fontawesome-brands-odnoklassniki-square":"fontawesome/brands/odnoklassniki-square.svg","fontawesome-brands-odnoklassniki":"fontawesome/brands/odnoklassniki.svg","fontawesome-brands-old-republic":"fontawesome/brands/old-republic.svg","fontawesome-brands-opencart":"fontawesome/brands/opencart.svg","fontawesome-brands-openid":"fontawesome/brands/openid.svg","fontawesome-brands-opera":"fontawesome/brands/opera.svg","fontawesome-brands-optin-monster":"fontawesome/brands/optin-monster.svg","fontawesome-brands-orcid":"fontawesome/brands/orcid.svg","fontawesome-brands-osi":"fontawesome/brands/osi.svg","fontawesome-brands-page4":"fontawesome/brands/page4.svg","fontawesome-brands-pagelines":"fontawesome/brands/pagelines.svg","fontawesome-brands-palfed":"fontawesome/brands/palfed.svg","fontawesome-brands-patreon":"fontawesome/brands/patreon.svg","fontawesome-brands-paypal":"fontawesome/brands/paypal.svg","fontawesome-brands-penny-arcade":"fontawesome/brands/penny-arcade.svg","fontawesome-brands-perbyte":"fontawesome/brands/perbyte.svg","fontawesome-brands-periscope":"fontawesome/brands/periscope.svg","fontawesome-brands-phabricator":"fontawesome/brands/phabricator.svg","fontawesome-brands-phoenix-framework":"fontawesome/brands/phoenix-framework.svg","fontawesome-brands-phoenix-squadron":"fontawesome/brands/phoenix-squadron.svg","fontawesome-brands-php":"fontawesome/brands/php.svg","fontawesome-brands-pied-piper-alt":"fontawesome/brands/pied-piper-alt.svg","fontawesome-brands-pied-piper-hat":"fontawesome/brands/pied-piper-hat.svg","fontawesome-brands-pied-piper-pp":"fontawesome/brands/pied-piper-pp.svg","fontawesome-brands-pied-piper-square":"fontawesome/brands/pied-piper-square.svg","fontawesome-brands-pied-piper":"fontawesome/brands/pied-piper.svg","fontawesome-brands-pinterest-p":"fontawesome/brands/pinterest-p.svg","fontawesome-brands-pinterest-square":"fontawesome/brands/pinterest-square.svg","fontawesome-brands-pinterest":"fontawesome/brands/pinterest.svg","fontawesome-brands-playstation":"fontawesome/brands/playstation.svg","fontawesome-brands-product-hunt":"fontawesome/brands/product-hunt.svg","fontawesome-brands-pushed":"fontawesome/brands/pushed.svg","fontawesome-brands-python":"fontawesome/brands/python.svg","fontawesome-brands-qq":"fontawesome/brands/qq.svg","fontawesome-brands-quinscape":"fontawesome/brands/quinscape.svg","fontawesome-brands-quora":"fontawesome/brands/quora.svg","fontawesome-brands-r-project":"fontawesome/brands/r-project.svg","fontawesome-brands-raspberry-pi":"fontawesome/brands/raspberry-pi.svg","fontawesome-brands-ravelry":"fontawesome/brands/ravelry.svg","fontawesome-brands-react":"fontawesome/brands/react.svg","fontawesome-brands-reacteurope":"fontawesome/brands/reacteurope.svg","fontawesome-brands-readme":"fontawesome/brands/readme.svg","fontawesome-brands-rebel":"fontawesome/brands/rebel.svg","fontawesome-brands-red-river":"fontawesome/brands/red-river.svg","fontawesome-brands-reddit-alien":"fontawesome/brands/reddit-alien.svg","fontawesome-brands-reddit-square":"fontawesome/brands/reddit-square.svg","fontawesome-brands-reddit":"fontawesome/brands/reddit.svg","fontawesome-brands-redhat":"fontawesome/brands/redhat.svg","fontawesome-brands-renren":"fontawesome/brands/renren.svg","fontawesome-brands-replyd":"fontawesome/brands/replyd.svg","fontawesome-brands-researchgate":"fontawesome/brands/researchgate.svg","fontawesome-brands-resolving":"fontawesome/brands/resolving.svg","fontawesome-brands-rev":"fontawesome/brands/rev.svg","fontawesome-brands-rocketchat":"fontawesome/brands/rocketchat.svg","fontawesome-brands-rockrms":"fontawesome/brands/rockrms.svg","fontawesome-brands-rust":"fontawesome/brands/rust.svg","fontawesome-brands-safari":"fontawesome/brands/safari.svg","fontawesome-brands-salesforce":"fontawesome/brands/salesforce.svg","fontawesome-brands-sass":"fontawesome/brands/sass.svg","fontawesome-brands-schlix":"fontawesome/brands/schlix.svg","fontawesome-brands-scribd":"fontawesome/brands/scribd.svg","fontawesome-brands-searchengin":"fontawesome/brands/searchengin.svg","fontawesome-brands-sellcast":"fontawesome/brands/sellcast.svg","fontawesome-brands-sellsy":"fontawesome/brands/sellsy.svg","fontawesome-brands-servicestack":"fontawesome/brands/servicestack.svg","fontawesome-brands-shirtsinbulk":"fontawesome/brands/shirtsinbulk.svg","fontawesome-brands-shopify":"fontawesome/brands/shopify.svg","fontawesome-brands-shopware":"fontawesome/brands/shopware.svg","fontawesome-brands-simplybuilt":"fontawesome/brands/simplybuilt.svg","fontawesome-brands-sistrix":"fontawesome/brands/sistrix.svg","fontawesome-brands-sith":"fontawesome/brands/sith.svg","fontawesome-brands-sketch":"fontawesome/brands/sketch.svg","fontawesome-brands-skyatlas":"fontawesome/brands/skyatlas.svg","fontawesome-brands-skype":"fontawesome/brands/skype.svg","fontawesome-brands-slack-hash":"fontawesome/brands/slack-hash.svg","fontawesome-brands-slack":"fontawesome/brands/slack.svg","fontawesome-brands-slideshare":"fontawesome/brands/slideshare.svg","fontawesome-brands-snapchat-ghost":"fontawesome/brands/snapchat-ghost.svg","fontawesome-brands-snapchat-square":"fontawesome/brands/snapchat-square.svg","fontawesome-brands-snapchat":"fontawesome/brands/snapchat.svg","fontawesome-brands-soundcloud":"fontawesome/brands/soundcloud.svg","fontawesome-brands-sourcetree":"fontawesome/brands/sourcetree.svg","fontawesome-brands-speakap":"fontawesome/brands/speakap.svg","fontawesome-brands-speaker-deck":"fontawesome/brands/speaker-deck.svg","fontawesome-brands-spotify":"fontawesome/brands/spotify.svg","fontawesome-brands-squarespace":"fontawesome/brands/squarespace.svg","fontawesome-brands-stack-exchange":"fontawesome/brands/stack-exchange.svg","fontawesome-brands-stack-overflow":"fontawesome/brands/stack-overflow.svg","fontawesome-brands-stackpath":"fontawesome/brands/stackpath.svg","fontawesome-brands-staylinked":"fontawesome/brands/staylinked.svg","fontawesome-brands-steam-square":"fontawesome/brands/steam-square.svg","fontawesome-brands-steam-symbol":"fontawesome/brands/steam-symbol.svg","fontawesome-brands-steam":"fontawesome/brands/steam.svg","fontawesome-brands-sticker-mule":"fontawesome/brands/sticker-mule.svg","fontawesome-brands-strava":"fontawesome/brands/strava.svg","fontawesome-brands-stripe-s":"fontawesome/brands/stripe-s.svg","fontawesome-brands-stripe":"fontawesome/brands/stripe.svg","fontawesome-brands-studiovinari":"fontawesome/brands/studiovinari.svg","fontawesome-brands-stumbleupon-circle":"fontawesome/brands/stumbleupon-circle.svg","fontawesome-brands-stumbleupon":"fontawesome/brands/stumbleupon.svg","fontawesome-brands-superpowers":"fontawesome/brands/superpowers.svg","fontawesome-brands-supple":"fontawesome/brands/supple.svg","fontawesome-brands-suse":"fontawesome/brands/suse.svg","fontawesome-brands-swift":"fontawesome/brands/swift.svg","fontawesome-brands-symfony":"fontawesome/brands/symfony.svg","fontawesome-brands-teamspeak":"fontawesome/brands/teamspeak.svg","fontawesome-brands-telegram-plane":"fontawesome/brands/telegram-plane.svg","fontawesome-brands-telegram":"fontawesome/brands/telegram.svg","fontawesome-brands-tencent-weibo":"fontawesome/brands/tencent-weibo.svg","fontawesome-brands-the-red-yeti":"fontawesome/brands/the-red-yeti.svg","fontawesome-brands-themeco":"fontawesome/brands/themeco.svg","fontawesome-brands-themeisle":"fontawesome/brands/themeisle.svg","fontawesome-brands-think-peaks":"fontawesome/brands/think-peaks.svg","fontawesome-brands-tiktok":"fontawesome/brands/tiktok.svg","fontawesome-brands-trade-federation":"fontawesome/brands/trade-federation.svg","fontawesome-brands-trello":"fontawesome/brands/trello.svg","fontawesome-brands-tripadvisor":"fontawesome/brands/tripadvisor.svg","fontawesome-brands-tumblr-square":"fontawesome/brands/tumblr-square.svg","fontawesome-brands-tumblr":"fontawesome/brands/tumblr.svg","fontawesome-brands-twitch":"fontawesome/brands/twitch.svg","fontawesome-brands-twitter-square":"fontawesome/brands/twitter-square.svg","fontawesome-brands-twitter":"fontawesome/brands/twitter.svg","fontawesome-brands-typo3":"fontawesome/brands/typo3.svg","fontawesome-brands-uber":"fontawesome/brands/uber.svg","fontawesome-brands-ubuntu":"fontawesome/brands/ubuntu.svg","fontawesome-brands-uikit":"fontawesome/brands/uikit.svg","fontawesome-brands-umbraco":"fontawesome/brands/umbraco.svg","fontawesome-brands-uncharted":"fontawesome/brands/uncharted.svg","fontawesome-brands-uniregistry":"fontawesome/brands/uniregistry.svg","fontawesome-brands-unity":"fontawesome/brands/unity.svg","fontawesome-brands-unsplash":"fontawesome/brands/unsplash.svg","fontawesome-brands-untappd":"fontawesome/brands/untappd.svg","fontawesome-brands-ups":"fontawesome/brands/ups.svg","fontawesome-brands-usb":"fontawesome/brands/usb.svg","fontawesome-brands-usps":"fontawesome/brands/usps.svg","fontawesome-brands-ussunnah":"fontawesome/brands/ussunnah.svg","fontawesome-brands-vaadin":"fontawesome/brands/vaadin.svg","fontawesome-brands-viacoin":"fontawesome/brands/viacoin.svg","fontawesome-brands-viadeo-square":"fontawesome/brands/viadeo-square.svg","fontawesome-brands-viadeo":"fontawesome/brands/viadeo.svg","fontawesome-brands-viber":"fontawesome/brands/viber.svg","fontawesome-brands-vimeo-square":"fontawesome/brands/vimeo-square.svg","fontawesome-brands-vimeo-v":"fontawesome/brands/vimeo-v.svg","fontawesome-brands-vimeo":"fontawesome/brands/vimeo.svg","fontawesome-brands-vine":"fontawesome/brands/vine.svg","fontawesome-brands-vk":"fontawesome/brands/vk.svg","fontawesome-brands-vnv":"fontawesome/brands/vnv.svg","fontawesome-brands-vuejs":"fontawesome/brands/vuejs.svg","fontawesome-brands-watchman-monitoring":"fontawesome/brands/watchman-monitoring.svg","fontawesome-brands-waze":"fontawesome/brands/waze.svg","fontawesome-brands-weebly":"fontawesome/brands/weebly.svg","fontawesome-brands-weibo":"fontawesome/brands/weibo.svg","fontawesome-brands-weixin":"fontawesome/brands/weixin.svg","fontawesome-brands-whatsapp-square":"fontawesome/brands/whatsapp-square.svg","fontawesome-brands-whatsapp":"fontawesome/brands/whatsapp.svg","fontawesome-brands-whmcs":"fontawesome/brands/whmcs.svg","fontawesome-brands-wikipedia-w":"fontawesome/brands/wikipedia-w.svg","fontawesome-brands-windows":"fontawesome/brands/windows.svg","fontawesome-brands-wix":"fontawesome/brands/wix.svg","fontawesome-brands-wizards-of-the-coast":"fontawesome/brands/wizards-of-the-coast.svg","fontawesome-brands-wodu":"fontawesome/brands/wodu.svg","fontawesome-brands-wolf-pack-battalion":"fontawesome/brands/wolf-pack-battalion.svg","fontawesome-brands-wordpress-simple":"fontawesome/brands/wordpress-simple.svg","fontawesome-brands-wordpress":"fontawesome/brands/wordpress.svg","fontawesome-brands-wpbeginner":"fontawesome/brands/wpbeginner.svg","fontawesome-brands-wpexplorer":"fontawesome/brands/wpexplorer.svg","fontawesome-brands-wpforms":"fontawesome/brands/wpforms.svg","fontawesome-brands-wpressr":"fontawesome/brands/wpressr.svg","fontawesome-brands-xbox":"fontawesome/brands/xbox.svg","fontawesome-brands-xing-square":"fontawesome/brands/xing-square.svg","fontawesome-brands-xing":"fontawesome/brands/xing.svg","fontawesome-brands-y-combinator":"fontawesome/brands/y-combinator.svg","fontawesome-brands-yahoo":"fontawesome/brands/yahoo.svg","fontawesome-brands-yammer":"fontawesome/brands/yammer.svg","fontawesome-brands-yandex-international":"fontawesome/brands/yandex-international.svg","fontawesome-brands-yandex":"fontawesome/brands/yandex.svg","fontawesome-brands-yarn":"fontawesome/brands/yarn.svg","fontawesome-brands-yelp":"fontawesome/brands/yelp.svg","fontawesome-brands-yoast":"fontawesome/brands/yoast.svg","fontawesome-brands-youtube-square":"fontawesome/brands/youtube-square.svg","fontawesome-brands-youtube":"fontawesome/brands/youtube.svg","fontawesome-brands-zhihu":"fontawesome/brands/zhihu.svg","fontawesome-regular-address-book":"fontawesome/regular/address-book.svg","fontawesome-regular-address-card":"fontawesome/regular/address-card.svg","fontawesome-regular-angry":"fontawesome/regular/angry.svg","fontawesome-regular-arrow-alt-circle-down":"fontawesome/regular/arrow-alt-circle-down.svg","fontawesome-regular-arrow-alt-circle-left":"fontawesome/regular/arrow-alt-circle-left.svg","fontawesome-regular-arrow-alt-circle-right":"fontawesome/regular/arrow-alt-circle-right.svg","fontawesome-regular-arrow-alt-circle-up":"fontawesome/regular/arrow-alt-circle-up.svg","fontawesome-regular-bell-slash":"fontawesome/regular/bell-slash.svg","fontawesome-regular-bell":"fontawesome/regular/bell.svg","fontawesome-regular-bookmark":"fontawesome/regular/bookmark.svg","fontawesome-regular-building":"fontawesome/regular/building.svg","fontawesome-regular-calendar-alt":"fontawesome/regular/calendar-alt.svg","fontawesome-regular-calendar-check":"fontawesome/regular/calendar-check.svg","fontawesome-regular-calendar-minus":"fontawesome/regular/calendar-minus.svg","fontawesome-regular-calendar-plus":"fontawesome/regular/calendar-plus.svg","fontawesome-regular-calendar-times":"fontawesome/regular/calendar-times.svg","fontawesome-regular-calendar":"fontawesome/regular/calendar.svg","fontawesome-regular-caret-square-down":"fontawesome/regular/caret-square-down.svg","fontawesome-regular-caret-square-left":"fontawesome/regular/caret-square-left.svg","fontawesome-regular-caret-square-right":"fontawesome/regular/caret-square-right.svg","fontawesome-regular-caret-square-up":"fontawesome/regular/caret-square-up.svg","fontawesome-regular-chart-bar":"fontawesome/regular/chart-bar.svg","fontawesome-regular-check-circle":"fontawesome/regular/check-circle.svg","fontawesome-regular-check-square":"fontawesome/regular/check-square.svg","fontawesome-regular-circle":"fontawesome/regular/circle.svg","fontawesome-regular-clipboard":"fontawesome/regular/clipboard.svg","fontawesome-regular-clock":"fontawesome/regular/clock.svg","fontawesome-regular-clone":"fontawesome/regular/clone.svg","fontawesome-regular-closed-captioning":"fontawesome/regular/closed-captioning.svg","fontawesome-regular-comment-alt":"fontawesome/regular/comment-alt.svg","fontawesome-regular-comment-dots":"fontawesome/regular/comment-dots.svg","fontawesome-regular-comment":"fontawesome/regular/comment.svg","fontawesome-regular-comments":"fontawesome/regular/comments.svg","fontawesome-regular-compass":"fontawesome/regular/compass.svg","fontawesome-regular-copy":"fontawesome/regular/copy.svg","fontawesome-regular-copyright":"fontawesome/regular/copyright.svg","fontawesome-regular-credit-card":"fontawesome/regular/credit-card.svg","fontawesome-regular-dizzy":"fontawesome/regular/dizzy.svg","fontawesome-regular-dot-circle":"fontawesome/regular/dot-circle.svg","fontawesome-regular-edit":"fontawesome/regular/edit.svg","fontawesome-regular-envelope-open":"fontawesome/regular/envelope-open.svg","fontawesome-regular-envelope":"fontawesome/regular/envelope.svg","fontawesome-regular-eye-slash":"fontawesome/regular/eye-slash.svg","fontawesome-regular-eye":"fontawesome/regular/eye.svg","fontawesome-regular-file-alt":"fontawesome/regular/file-alt.svg","fontawesome-regular-file-archive":"fontawesome/regular/file-archive.svg","fontawesome-regular-file-audio":"fontawesome/regular/file-audio.svg","fontawesome-regular-file-code":"fontawesome/regular/file-code.svg","fontawesome-regular-file-excel":"fontawesome/regular/file-excel.svg","fontawesome-regular-file-image":"fontawesome/regular/file-image.svg","fontawesome-regular-file-pdf":"fontawesome/regular/file-pdf.svg","fontawesome-regular-file-powerpoint":"fontawesome/regular/file-powerpoint.svg","fontawesome-regular-file-video":"fontawesome/regular/file-video.svg","fontawesome-regular-file-word":"fontawesome/regular/file-word.svg","fontawesome-regular-file":"fontawesome/regular/file.svg","fontawesome-regular-flag":"fontawesome/regular/flag.svg","fontawesome-regular-flushed":"fontawesome/regular/flushed.svg","fontawesome-regular-folder-open":"fontawesome/regular/folder-open.svg","fontawesome-regular-folder":"fontawesome/regular/folder.svg","fontawesome-regular-font-awesome-logo-full":"fontawesome/regular/font-awesome-logo-full.svg","fontawesome-regular-frown-open":"fontawesome/regular/frown-open.svg","fontawesome-regular-frown":"fontawesome/regular/frown.svg","fontawesome-regular-futbol":"fontawesome/regular/futbol.svg","fontawesome-regular-gem":"fontawesome/regular/gem.svg","fontawesome-regular-grimace":"fontawesome/regular/grimace.svg","fontawesome-regular-grin-alt":"fontawesome/regular/grin-alt.svg","fontawesome-regular-grin-beam-sweat":"fontawesome/regular/grin-beam-sweat.svg","fontawesome-regular-grin-beam":"fontawesome/regular/grin-beam.svg","fontawesome-regular-grin-hearts":"fontawesome/regular/grin-hearts.svg","fontawesome-regular-grin-squint-tears":"fontawesome/regular/grin-squint-tears.svg","fontawesome-regular-grin-squint":"fontawesome/regular/grin-squint.svg","fontawesome-regular-grin-stars":"fontawesome/regular/grin-stars.svg","fontawesome-regular-grin-tears":"fontawesome/regular/grin-tears.svg","fontawesome-regular-grin-tongue-squint":"fontawesome/regular/grin-tongue-squint.svg","fontawesome-regular-grin-tongue-wink":"fontawesome/regular/grin-tongue-wink.svg","fontawesome-regular-grin-tongue":"fontawesome/regular/grin-tongue.svg","fontawesome-regular-grin-wink":"fontawesome/regular/grin-wink.svg","fontawesome-regular-grin":"fontawesome/regular/grin.svg","fontawesome-regular-hand-lizard":"fontawesome/regular/hand-lizard.svg","fontawesome-regular-hand-paper":"fontawesome/regular/hand-paper.svg","fontawesome-regular-hand-peace":"fontawesome/regular/hand-peace.svg","fontawesome-regular-hand-point-down":"fontawesome/regular/hand-point-down.svg","fontawesome-regular-hand-point-left":"fontawesome/regular/hand-point-left.svg","fontawesome-regular-hand-point-right":"fontawesome/regular/hand-point-right.svg","fontawesome-regular-hand-point-up":"fontawesome/regular/hand-point-up.svg","fontawesome-regular-hand-pointer":"fontawesome/regular/hand-pointer.svg","fontawesome-regular-hand-rock":"fontawesome/regular/hand-rock.svg","fontawesome-regular-hand-scissors":"fontawesome/regular/hand-scissors.svg","fontawesome-regular-hand-spock":"fontawesome/regular/hand-spock.svg","fontawesome-regular-handshake":"fontawesome/regular/handshake.svg","fontawesome-regular-hdd":"fontawesome/regular/hdd.svg","fontawesome-regular-heart":"fontawesome/regular/heart.svg","fontawesome-regular-hospital":"fontawesome/regular/hospital.svg","fontawesome-regular-hourglass":"fontawesome/regular/hourglass.svg","fontawesome-regular-id-badge":"fontawesome/regular/id-badge.svg","fontawesome-regular-id-card":"fontawesome/regular/id-card.svg","fontawesome-regular-image":"fontawesome/regular/image.svg","fontawesome-regular-images":"fontawesome/regular/images.svg","fontawesome-regular-keyboard":"fontawesome/regular/keyboard.svg","fontawesome-regular-kiss-beam":"fontawesome/regular/kiss-beam.svg","fontawesome-regular-kiss-wink-heart":"fontawesome/regular/kiss-wink-heart.svg","fontawesome-regular-kiss":"fontawesome/regular/kiss.svg","fontawesome-regular-laugh-beam":"fontawesome/regular/laugh-beam.svg","fontawesome-regular-laugh-squint":"fontawesome/regular/laugh-squint.svg","fontawesome-regular-laugh-wink":"fontawesome/regular/laugh-wink.svg","fontawesome-regular-laugh":"fontawesome/regular/laugh.svg","fontawesome-regular-lemon":"fontawesome/regular/lemon.svg","fontawesome-regular-life-ring":"fontawesome/regular/life-ring.svg","fontawesome-regular-lightbulb":"fontawesome/regular/lightbulb.svg","fontawesome-regular-list-alt":"fontawesome/regular/list-alt.svg","fontawesome-regular-map":"fontawesome/regular/map.svg","fontawesome-regular-meh-blank":"fontawesome/regular/meh-blank.svg","fontawesome-regular-meh-rolling-eyes":"fontawesome/regular/meh-rolling-eyes.svg","fontawesome-regular-meh":"fontawesome/regular/meh.svg","fontawesome-regular-minus-square":"fontawesome/regular/minus-square.svg","fontawesome-regular-money-bill-alt":"fontawesome/regular/money-bill-alt.svg","fontawesome-regular-moon":"fontawesome/regular/moon.svg","fontawesome-regular-newspaper":"fontawesome/regular/newspaper.svg","fontawesome-regular-object-group":"fontawesome/regular/object-group.svg","fontawesome-regular-object-ungroup":"fontawesome/regular/object-ungroup.svg","fontawesome-regular-paper-plane":"fontawesome/regular/paper-plane.svg","fontawesome-regular-pause-circle":"fontawesome/regular/pause-circle.svg","fontawesome-regular-play-circle":"fontawesome/regular/play-circle.svg","fontawesome-regular-plus-square":"fontawesome/regular/plus-square.svg","fontawesome-regular-question-circle":"fontawesome/regular/question-circle.svg","fontawesome-regular-registered":"fontawesome/regular/registered.svg","fontawesome-regular-sad-cry":"fontawesome/regular/sad-cry.svg","fontawesome-regular-sad-tear":"fontawesome/regular/sad-tear.svg","fontawesome-regular-save":"fontawesome/regular/save.svg","fontawesome-regular-share-square":"fontawesome/regular/share-square.svg","fontawesome-regular-smile-beam":"fontawesome/regular/smile-beam.svg","fontawesome-regular-smile-wink":"fontawesome/regular/smile-wink.svg","fontawesome-regular-smile":"fontawesome/regular/smile.svg","fontawesome-regular-snowflake":"fontawesome/regular/snowflake.svg","fontawesome-regular-square":"fontawesome/regular/square.svg","fontawesome-regular-star-half":"fontawesome/regular/star-half.svg","fontawesome-regular-star":"fontawesome/regular/star.svg","fontawesome-regular-sticky-note":"fontawesome/regular/sticky-note.svg","fontawesome-regular-stop-circle":"fontawesome/regular/stop-circle.svg","fontawesome-regular-sun":"fontawesome/regular/sun.svg","fontawesome-regular-surprise":"fontawesome/regular/surprise.svg","fontawesome-regular-thumbs-down":"fontawesome/regular/thumbs-down.svg","fontawesome-regular-thumbs-up":"fontawesome/regular/thumbs-up.svg","fontawesome-regular-times-circle":"fontawesome/regular/times-circle.svg","fontawesome-regular-tired":"fontawesome/regular/tired.svg","fontawesome-regular-trash-alt":"fontawesome/regular/trash-alt.svg","fontawesome-regular-user-circle":"fontawesome/regular/user-circle.svg","fontawesome-regular-user":"fontawesome/regular/user.svg","fontawesome-regular-window-close":"fontawesome/regular/window-close.svg","fontawesome-regular-window-maximize":"fontawesome/regular/window-maximize.svg","fontawesome-regular-window-minimize":"fontawesome/regular/window-minimize.svg","fontawesome-regular-window-restore":"fontawesome/regular/window-restore.svg","fontawesome-solid-ad":"fontawesome/solid/ad.svg","fontawesome-solid-address-book":"fontawesome/solid/address-book.svg","fontawesome-solid-address-card":"fontawesome/solid/address-card.svg","fontawesome-solid-adjust":"fontawesome/solid/adjust.svg","fontawesome-solid-air-freshener":"fontawesome/solid/air-freshener.svg","fontawesome-solid-align-center":"fontawesome/solid/align-center.svg","fontawesome-solid-align-justify":"fontawesome/solid/align-justify.svg","fontawesome-solid-align-left":"fontawesome/solid/align-left.svg","fontawesome-solid-align-right":"fontawesome/solid/align-right.svg","fontawesome-solid-allergies":"fontawesome/solid/allergies.svg","fontawesome-solid-ambulance":"fontawesome/solid/ambulance.svg","fontawesome-solid-american-sign-language-interpreting":"fontawesome/solid/american-sign-language-interpreting.svg","fontawesome-solid-anchor":"fontawesome/solid/anchor.svg","fontawesome-solid-angle-double-down":"fontawesome/solid/angle-double-down.svg","fontawesome-solid-angle-double-left":"fontawesome/solid/angle-double-left.svg","fontawesome-solid-angle-double-right":"fontawesome/solid/angle-double-right.svg","fontawesome-solid-angle-double-up":"fontawesome/solid/angle-double-up.svg","fontawesome-solid-angle-down":"fontawesome/solid/angle-down.svg","fontawesome-solid-angle-left":"fontawesome/solid/angle-left.svg","fontawesome-solid-angle-right":"fontawesome/solid/angle-right.svg","fontawesome-solid-angle-up":"fontawesome/solid/angle-up.svg","fontawesome-solid-angry":"fontawesome/solid/angry.svg","fontawesome-solid-ankh":"fontawesome/solid/ankh.svg","fontawesome-solid-apple-alt":"fontawesome/solid/apple-alt.svg","fontawesome-solid-archive":"fontawesome/solid/archive.svg","fontawesome-solid-archway":"fontawesome/solid/archway.svg","fontawesome-solid-arrow-alt-circle-down":"fontawesome/solid/arrow-alt-circle-down.svg","fontawesome-solid-arrow-alt-circle-left":"fontawesome/solid/arrow-alt-circle-left.svg","fontawesome-solid-arrow-alt-circle-right":"fontawesome/solid/arrow-alt-circle-right.svg","fontawesome-solid-arrow-alt-circle-up":"fontawesome/solid/arrow-alt-circle-up.svg","fontawesome-solid-arrow-circle-down":"fontawesome/solid/arrow-circle-down.svg","fontawesome-solid-arrow-circle-left":"fontawesome/solid/arrow-circle-left.svg","fontawesome-solid-arrow-circle-right":"fontawesome/solid/arrow-circle-right.svg","fontawesome-solid-arrow-circle-up":"fontawesome/solid/arrow-circle-up.svg","fontawesome-solid-arrow-down":"fontawesome/solid/arrow-down.svg","fontawesome-solid-arrow-left":"fontawesome/solid/arrow-left.svg","fontawesome-solid-arrow-right":"fontawesome/solid/arrow-right.svg","fontawesome-solid-arrow-up":"fontawesome/solid/arrow-up.svg","fontawesome-solid-arrows-alt-h":"fontawesome/solid/arrows-alt-h.svg","fontawesome-solid-arrows-alt-v":"fontawesome/solid/arrows-alt-v.svg","fontawesome-solid-arrows-alt":"fontawesome/solid/arrows-alt.svg","fontawesome-solid-assistive-listening-systems":"fontawesome/solid/assistive-listening-systems.svg","fontawesome-solid-asterisk":"fontawesome/solid/asterisk.svg","fontawesome-solid-at":"fontawesome/solid/at.svg","fontawesome-solid-atlas":"fontawesome/solid/atlas.svg","fontawesome-solid-atom":"fontawesome/solid/atom.svg","fontawesome-solid-audio-description":"fontawesome/solid/audio-description.svg","fontawesome-solid-award":"fontawesome/solid/award.svg","fontawesome-solid-baby-carriage":"fontawesome/solid/baby-carriage.svg","fontawesome-solid-baby":"fontawesome/solid/baby.svg","fontawesome-solid-backspace":"fontawesome/solid/backspace.svg","fontawesome-solid-backward":"fontawesome/solid/backward.svg","fontawesome-solid-bacon":"fontawesome/solid/bacon.svg","fontawesome-solid-bacteria":"fontawesome/solid/bacteria.svg","fontawesome-solid-bacterium":"fontawesome/solid/bacterium.svg","fontawesome-solid-bahai":"fontawesome/solid/bahai.svg","fontawesome-solid-balance-scale-left":"fontawesome/solid/balance-scale-left.svg","fontawesome-solid-balance-scale-right":"fontawesome/solid/balance-scale-right.svg","fontawesome-solid-balance-scale":"fontawesome/solid/balance-scale.svg","fontawesome-solid-ban":"fontawesome/solid/ban.svg","fontawesome-solid-band-aid":"fontawesome/solid/band-aid.svg","fontawesome-solid-barcode":"fontawesome/solid/barcode.svg","fontawesome-solid-bars":"fontawesome/solid/bars.svg","fontawesome-solid-baseball-ball":"fontawesome/solid/baseball-ball.svg","fontawesome-solid-basketball-ball":"fontawesome/solid/basketball-ball.svg","fontawesome-solid-bath":"fontawesome/solid/bath.svg","fontawesome-solid-battery-empty":"fontawesome/solid/battery-empty.svg","fontawesome-solid-battery-full":"fontawesome/solid/battery-full.svg","fontawesome-solid-battery-half":"fontawesome/solid/battery-half.svg","fontawesome-solid-battery-quarter":"fontawesome/solid/battery-quarter.svg","fontawesome-solid-battery-three-quarters":"fontawesome/solid/battery-three-quarters.svg","fontawesome-solid-bed":"fontawesome/solid/bed.svg","fontawesome-solid-beer":"fontawesome/solid/beer.svg","fontawesome-solid-bell-slash":"fontawesome/solid/bell-slash.svg","fontawesome-solid-bell":"fontawesome/solid/bell.svg","fontawesome-solid-bezier-curve":"fontawesome/solid/bezier-curve.svg","fontawesome-solid-bible":"fontawesome/solid/bible.svg","fontawesome-solid-bicycle":"fontawesome/solid/bicycle.svg","fontawesome-solid-biking":"fontawesome/solid/biking.svg","fontawesome-solid-binoculars":"fontawesome/solid/binoculars.svg","fontawesome-solid-biohazard":"fontawesome/solid/biohazard.svg","fontawesome-solid-birthday-cake":"fontawesome/solid/birthday-cake.svg","fontawesome-solid-blender-phone":"fontawesome/solid/blender-phone.svg","fontawesome-solid-blender":"fontawesome/solid/blender.svg","fontawesome-solid-blind":"fontawesome/solid/blind.svg","fontawesome-solid-blog":"fontawesome/solid/blog.svg","fontawesome-solid-bold":"fontawesome/solid/bold.svg","fontawesome-solid-bolt":"fontawesome/solid/bolt.svg","fontawesome-solid-bomb":"fontawesome/solid/bomb.svg","fontawesome-solid-bone":"fontawesome/solid/bone.svg","fontawesome-solid-bong":"fontawesome/solid/bong.svg","fontawesome-solid-book-dead":"fontawesome/solid/book-dead.svg","fontawesome-solid-book-medical":"fontawesome/solid/book-medical.svg","fontawesome-solid-book-open":"fontawesome/solid/book-open.svg","fontawesome-solid-book-reader":"fontawesome/solid/book-reader.svg","fontawesome-solid-book":"fontawesome/solid/book.svg","fontawesome-solid-bookmark":"fontawesome/solid/bookmark.svg","fontawesome-solid-border-all":"fontawesome/solid/border-all.svg","fontawesome-solid-border-none":"fontawesome/solid/border-none.svg","fontawesome-solid-border-style":"fontawesome/solid/border-style.svg","fontawesome-solid-bowling-ball":"fontawesome/solid/bowling-ball.svg","fontawesome-solid-box-open":"fontawesome/solid/box-open.svg","fontawesome-solid-box-tissue":"fontawesome/solid/box-tissue.svg","fontawesome-solid-box":"fontawesome/solid/box.svg","fontawesome-solid-boxes":"fontawesome/solid/boxes.svg","fontawesome-solid-braille":"fontawesome/solid/braille.svg","fontawesome-solid-brain":"fontawesome/solid/brain.svg","fontawesome-solid-bread-slice":"fontawesome/solid/bread-slice.svg","fontawesome-solid-briefcase-medical":"fontawesome/solid/briefcase-medical.svg","fontawesome-solid-briefcase":"fontawesome/solid/briefcase.svg","fontawesome-solid-broadcast-tower":"fontawesome/solid/broadcast-tower.svg","fontawesome-solid-broom":"fontawesome/solid/broom.svg","fontawesome-solid-brush":"fontawesome/solid/brush.svg","fontawesome-solid-bug":"fontawesome/solid/bug.svg","fontawesome-solid-building":"fontawesome/solid/building.svg","fontawesome-solid-bullhorn":"fontawesome/solid/bullhorn.svg","fontawesome-solid-bullseye":"fontawesome/solid/bullseye.svg","fontawesome-solid-burn":"fontawesome/solid/burn.svg","fontawesome-solid-bus-alt":"fontawesome/solid/bus-alt.svg","fontawesome-solid-bus":"fontawesome/solid/bus.svg","fontawesome-solid-business-time":"fontawesome/solid/business-time.svg","fontawesome-solid-calculator":"fontawesome/solid/calculator.svg","fontawesome-solid-calendar-alt":"fontawesome/solid/calendar-alt.svg","fontawesome-solid-calendar-check":"fontawesome/solid/calendar-check.svg","fontawesome-solid-calendar-day":"fontawesome/solid/calendar-day.svg","fontawesome-solid-calendar-minus":"fontawesome/solid/calendar-minus.svg","fontawesome-solid-calendar-plus":"fontawesome/solid/calendar-plus.svg","fontawesome-solid-calendar-times":"fontawesome/solid/calendar-times.svg","fontawesome-solid-calendar-week":"fontawesome/solid/calendar-week.svg","fontawesome-solid-calendar":"fontawesome/solid/calendar.svg","fontawesome-solid-camera-retro":"fontawesome/solid/camera-retro.svg","fontawesome-solid-camera":"fontawesome/solid/camera.svg","fontawesome-solid-campground":"fontawesome/solid/campground.svg","fontawesome-solid-candy-cane":"fontawesome/solid/candy-cane.svg","fontawesome-solid-cannabis":"fontawesome/solid/cannabis.svg","fontawesome-solid-capsules":"fontawesome/solid/capsules.svg","fontawesome-solid-car-alt":"fontawesome/solid/car-alt.svg","fontawesome-solid-car-battery":"fontawesome/solid/car-battery.svg","fontawesome-solid-car-crash":"fontawesome/solid/car-crash.svg","fontawesome-solid-car-side":"fontawesome/solid/car-side.svg","fontawesome-solid-car":"fontawesome/solid/car.svg","fontawesome-solid-caravan":"fontawesome/solid/caravan.svg","fontawesome-solid-caret-down":"fontawesome/solid/caret-down.svg","fontawesome-solid-caret-left":"fontawesome/solid/caret-left.svg","fontawesome-solid-caret-right":"fontawesome/solid/caret-right.svg","fontawesome-solid-caret-square-down":"fontawesome/solid/caret-square-down.svg","fontawesome-solid-caret-square-left":"fontawesome/solid/caret-square-left.svg","fontawesome-solid-caret-square-right":"fontawesome/solid/caret-square-right.svg","fontawesome-solid-caret-square-up":"fontawesome/solid/caret-square-up.svg","fontawesome-solid-caret-up":"fontawesome/solid/caret-up.svg","fontawesome-solid-carrot":"fontawesome/solid/carrot.svg","fontawesome-solid-cart-arrow-down":"fontawesome/solid/cart-arrow-down.svg","fontawesome-solid-cart-plus":"fontawesome/solid/cart-plus.svg","fontawesome-solid-cash-register":"fontawesome/solid/cash-register.svg","fontawesome-solid-cat":"fontawesome/solid/cat.svg","fontawesome-solid-certificate":"fontawesome/solid/certificate.svg","fontawesome-solid-chair":"fontawesome/solid/chair.svg","fontawesome-solid-chalkboard-teacher":"fontawesome/solid/chalkboard-teacher.svg","fontawesome-solid-chalkboard":"fontawesome/solid/chalkboard.svg","fontawesome-solid-charging-station":"fontawesome/solid/charging-station.svg","fontawesome-solid-chart-area":"fontawesome/solid/chart-area.svg","fontawesome-solid-chart-bar":"fontawesome/solid/chart-bar.svg","fontawesome-solid-chart-line":"fontawesome/solid/chart-line.svg","fontawesome-solid-chart-pie":"fontawesome/solid/chart-pie.svg","fontawesome-solid-check-circle":"fontawesome/solid/check-circle.svg","fontawesome-solid-check-double":"fontawesome/solid/check-double.svg","fontawesome-solid-check-square":"fontawesome/solid/check-square.svg","fontawesome-solid-check":"fontawesome/solid/check.svg","fontawesome-solid-cheese":"fontawesome/solid/cheese.svg","fontawesome-solid-chess-bishop":"fontawesome/solid/chess-bishop.svg","fontawesome-solid-chess-board":"fontawesome/solid/chess-board.svg","fontawesome-solid-chess-king":"fontawesome/solid/chess-king.svg","fontawesome-solid-chess-knight":"fontawesome/solid/chess-knight.svg","fontawesome-solid-chess-pawn":"fontawesome/solid/chess-pawn.svg","fontawesome-solid-chess-queen":"fontawesome/solid/chess-queen.svg","fontawesome-solid-chess-rook":"fontawesome/solid/chess-rook.svg","fontawesome-solid-chess":"fontawesome/solid/chess.svg","fontawesome-solid-chevron-circle-down":"fontawesome/solid/chevron-circle-down.svg","fontawesome-solid-chevron-circle-left":"fontawesome/solid/chevron-circle-left.svg","fontawesome-solid-chevron-circle-right":"fontawesome/solid/chevron-circle-right.svg","fontawesome-solid-chevron-circle-up":"fontawesome/solid/chevron-circle-up.svg","fontawesome-solid-chevron-down":"fontawesome/solid/chevron-down.svg","fontawesome-solid-chevron-left":"fontawesome/solid/chevron-left.svg","fontawesome-solid-chevron-right":"fontawesome/solid/chevron-right.svg","fontawesome-solid-chevron-up":"fontawesome/solid/chevron-up.svg","fontawesome-solid-child":"fontawesome/solid/child.svg","fontawesome-solid-church":"fontawesome/solid/church.svg","fontawesome-solid-circle-notch":"fontawesome/solid/circle-notch.svg","fontawesome-solid-circle":"fontawesome/solid/circle.svg","fontawesome-solid-city":"fontawesome/solid/city.svg","fontawesome-solid-clinic-medical":"fontawesome/solid/clinic-medical.svg","fontawesome-solid-clipboard-check":"fontawesome/solid/clipboard-check.svg","fontawesome-solid-clipboard-list":"fontawesome/solid/clipboard-list.svg","fontawesome-solid-clipboard":"fontawesome/solid/clipboard.svg","fontawesome-solid-clock":"fontawesome/solid/clock.svg","fontawesome-solid-clone":"fontawesome/solid/clone.svg","fontawesome-solid-closed-captioning":"fontawesome/solid/closed-captioning.svg","fontawesome-solid-cloud-download-alt":"fontawesome/solid/cloud-download-alt.svg","fontawesome-solid-cloud-meatball":"fontawesome/solid/cloud-meatball.svg","fontawesome-solid-cloud-moon-rain":"fontawesome/solid/cloud-moon-rain.svg","fontawesome-solid-cloud-moon":"fontawesome/solid/cloud-moon.svg","fontawesome-solid-cloud-rain":"fontawesome/solid/cloud-rain.svg","fontawesome-solid-cloud-showers-heavy":"fontawesome/solid/cloud-showers-heavy.svg","fontawesome-solid-cloud-sun-rain":"fontawesome/solid/cloud-sun-rain.svg","fontawesome-solid-cloud-sun":"fontawesome/solid/cloud-sun.svg","fontawesome-solid-cloud-upload-alt":"fontawesome/solid/cloud-upload-alt.svg","fontawesome-solid-cloud":"fontawesome/solid/cloud.svg","fontawesome-solid-cocktail":"fontawesome/solid/cocktail.svg","fontawesome-solid-code-branch":"fontawesome/solid/code-branch.svg","fontawesome-solid-code":"fontawesome/solid/code.svg","fontawesome-solid-coffee":"fontawesome/solid/coffee.svg","fontawesome-solid-cog":"fontawesome/solid/cog.svg","fontawesome-solid-cogs":"fontawesome/solid/cogs.svg","fontawesome-solid-coins":"fontawesome/solid/coins.svg","fontawesome-solid-columns":"fontawesome/solid/columns.svg","fontawesome-solid-comment-alt":"fontawesome/solid/comment-alt.svg","fontawesome-solid-comment-dollar":"fontawesome/solid/comment-dollar.svg","fontawesome-solid-comment-dots":"fontawesome/solid/comment-dots.svg","fontawesome-solid-comment-medical":"fontawesome/solid/comment-medical.svg","fontawesome-solid-comment-slash":"fontawesome/solid/comment-slash.svg","fontawesome-solid-comment":"fontawesome/solid/comment.svg","fontawesome-solid-comments-dollar":"fontawesome/solid/comments-dollar.svg","fontawesome-solid-comments":"fontawesome/solid/comments.svg","fontawesome-solid-compact-disc":"fontawesome/solid/compact-disc.svg","fontawesome-solid-compass":"fontawesome/solid/compass.svg","fontawesome-solid-compress-alt":"fontawesome/solid/compress-alt.svg","fontawesome-solid-compress-arrows-alt":"fontawesome/solid/compress-arrows-alt.svg","fontawesome-solid-compress":"fontawesome/solid/compress.svg","fontawesome-solid-concierge-bell":"fontawesome/solid/concierge-bell.svg","fontawesome-solid-cookie-bite":"fontawesome/solid/cookie-bite.svg","fontawesome-solid-cookie":"fontawesome/solid/cookie.svg","fontawesome-solid-copy":"fontawesome/solid/copy.svg","fontawesome-solid-copyright":"fontawesome/solid/copyright.svg","fontawesome-solid-couch":"fontawesome/solid/couch.svg","fontawesome-solid-credit-card":"fontawesome/solid/credit-card.svg","fontawesome-solid-crop-alt":"fontawesome/solid/crop-alt.svg","fontawesome-solid-crop":"fontawesome/solid/crop.svg","fontawesome-solid-cross":"fontawesome/solid/cross.svg","fontawesome-solid-crosshairs":"fontawesome/solid/crosshairs.svg","fontawesome-solid-crow":"fontawesome/solid/crow.svg","fontawesome-solid-crown":"fontawesome/solid/crown.svg","fontawesome-solid-crutch":"fontawesome/solid/crutch.svg","fontawesome-solid-cube":"fontawesome/solid/cube.svg","fontawesome-solid-cubes":"fontawesome/solid/cubes.svg","fontawesome-solid-cut":"fontawesome/solid/cut.svg","fontawesome-solid-database":"fontawesome/solid/database.svg","fontawesome-solid-deaf":"fontawesome/solid/deaf.svg","fontawesome-solid-democrat":"fontawesome/solid/democrat.svg","fontawesome-solid-desktop":"fontawesome/solid/desktop.svg","fontawesome-solid-dharmachakra":"fontawesome/solid/dharmachakra.svg","fontawesome-solid-diagnoses":"fontawesome/solid/diagnoses.svg","fontawesome-solid-dice-d20":"fontawesome/solid/dice-d20.svg","fontawesome-solid-dice-d6":"fontawesome/solid/dice-d6.svg","fontawesome-solid-dice-five":"fontawesome/solid/dice-five.svg","fontawesome-solid-dice-four":"fontawesome/solid/dice-four.svg","fontawesome-solid-dice-one":"fontawesome/solid/dice-one.svg","fontawesome-solid-dice-six":"fontawesome/solid/dice-six.svg","fontawesome-solid-dice-three":"fontawesome/solid/dice-three.svg","fontawesome-solid-dice-two":"fontawesome/solid/dice-two.svg","fontawesome-solid-dice":"fontawesome/solid/dice.svg","fontawesome-solid-digital-tachograph":"fontawesome/solid/digital-tachograph.svg","fontawesome-solid-directions":"fontawesome/solid/directions.svg","fontawesome-solid-disease":"fontawesome/solid/disease.svg","fontawesome-solid-divide":"fontawesome/solid/divide.svg","fontawesome-solid-dizzy":"fontawesome/solid/dizzy.svg","fontawesome-solid-dna":"fontawesome/solid/dna.svg","fontawesome-solid-dog":"fontawesome/solid/dog.svg","fontawesome-solid-dollar-sign":"fontawesome/solid/dollar-sign.svg","fontawesome-solid-dolly-flatbed":"fontawesome/solid/dolly-flatbed.svg","fontawesome-solid-dolly":"fontawesome/solid/dolly.svg","fontawesome-solid-donate":"fontawesome/solid/donate.svg","fontawesome-solid-door-closed":"fontawesome/solid/door-closed.svg","fontawesome-solid-door-open":"fontawesome/solid/door-open.svg","fontawesome-solid-dot-circle":"fontawesome/solid/dot-circle.svg","fontawesome-solid-dove":"fontawesome/solid/dove.svg","fontawesome-solid-download":"fontawesome/solid/download.svg","fontawesome-solid-drafting-compass":"fontawesome/solid/drafting-compass.svg","fontawesome-solid-dragon":"fontawesome/solid/dragon.svg","fontawesome-solid-draw-polygon":"fontawesome/solid/draw-polygon.svg","fontawesome-solid-drum-steelpan":"fontawesome/solid/drum-steelpan.svg","fontawesome-solid-drum":"fontawesome/solid/drum.svg","fontawesome-solid-drumstick-bite":"fontawesome/solid/drumstick-bite.svg","fontawesome-solid-dumbbell":"fontawesome/solid/dumbbell.svg","fontawesome-solid-dumpster-fire":"fontawesome/solid/dumpster-fire.svg","fontawesome-solid-dumpster":"fontawesome/solid/dumpster.svg","fontawesome-solid-dungeon":"fontawesome/solid/dungeon.svg","fontawesome-solid-edit":"fontawesome/solid/edit.svg","fontawesome-solid-egg":"fontawesome/solid/egg.svg","fontawesome-solid-eject":"fontawesome/solid/eject.svg","fontawesome-solid-ellipsis-h":"fontawesome/solid/ellipsis-h.svg","fontawesome-solid-ellipsis-v":"fontawesome/solid/ellipsis-v.svg","fontawesome-solid-envelope-open-text":"fontawesome/solid/envelope-open-text.svg","fontawesome-solid-envelope-open":"fontawesome/solid/envelope-open.svg","fontawesome-solid-envelope-square":"fontawesome/solid/envelope-square.svg","fontawesome-solid-envelope":"fontawesome/solid/envelope.svg","fontawesome-solid-equals":"fontawesome/solid/equals.svg","fontawesome-solid-eraser":"fontawesome/solid/eraser.svg","fontawesome-solid-ethernet":"fontawesome/solid/ethernet.svg","fontawesome-solid-euro-sign":"fontawesome/solid/euro-sign.svg","fontawesome-solid-exchange-alt":"fontawesome/solid/exchange-alt.svg","fontawesome-solid-exclamation-circle":"fontawesome/solid/exclamation-circle.svg","fontawesome-solid-exclamation-triangle":"fontawesome/solid/exclamation-triangle.svg","fontawesome-solid-exclamation":"fontawesome/solid/exclamation.svg","fontawesome-solid-expand-alt":"fontawesome/solid/expand-alt.svg","fontawesome-solid-expand-arrows-alt":"fontawesome/solid/expand-arrows-alt.svg","fontawesome-solid-expand":"fontawesome/solid/expand.svg","fontawesome-solid-external-link-alt":"fontawesome/solid/external-link-alt.svg","fontawesome-solid-external-link-square-alt":"fontawesome/solid/external-link-square-alt.svg","fontawesome-solid-eye-dropper":"fontawesome/solid/eye-dropper.svg","fontawesome-solid-eye-slash":"fontawesome/solid/eye-slash.svg","fontawesome-solid-eye":"fontawesome/solid/eye.svg","fontawesome-solid-fan":"fontawesome/solid/fan.svg","fontawesome-solid-fast-backward":"fontawesome/solid/fast-backward.svg","fontawesome-solid-fast-forward":"fontawesome/solid/fast-forward.svg","fontawesome-solid-faucet":"fontawesome/solid/faucet.svg","fontawesome-solid-fax":"fontawesome/solid/fax.svg","fontawesome-solid-feather-alt":"fontawesome/solid/feather-alt.svg","fontawesome-solid-feather":"fontawesome/solid/feather.svg","fontawesome-solid-female":"fontawesome/solid/female.svg","fontawesome-solid-fighter-jet":"fontawesome/solid/fighter-jet.svg","fontawesome-solid-file-alt":"fontawesome/solid/file-alt.svg","fontawesome-solid-file-archive":"fontawesome/solid/file-archive.svg","fontawesome-solid-file-audio":"fontawesome/solid/file-audio.svg","fontawesome-solid-file-code":"fontawesome/solid/file-code.svg","fontawesome-solid-file-contract":"fontawesome/solid/file-contract.svg","fontawesome-solid-file-csv":"fontawesome/solid/file-csv.svg","fontawesome-solid-file-download":"fontawesome/solid/file-download.svg","fontawesome-solid-file-excel":"fontawesome/solid/file-excel.svg","fontawesome-solid-file-export":"fontawesome/solid/file-export.svg","fontawesome-solid-file-image":"fontawesome/solid/file-image.svg","fontawesome-solid-file-import":"fontawesome/solid/file-import.svg","fontawesome-solid-file-invoice-dollar":"fontawesome/solid/file-invoice-dollar.svg","fontawesome-solid-file-invoice":"fontawesome/solid/file-invoice.svg","fontawesome-solid-file-medical-alt":"fontawesome/solid/file-medical-alt.svg","fontawesome-solid-file-medical":"fontawesome/solid/file-medical.svg","fontawesome-solid-file-pdf":"fontawesome/solid/file-pdf.svg","fontawesome-solid-file-powerpoint":"fontawesome/solid/file-powerpoint.svg","fontawesome-solid-file-prescription":"fontawesome/solid/file-prescription.svg","fontawesome-solid-file-signature":"fontawesome/solid/file-signature.svg","fontawesome-solid-file-upload":"fontawesome/solid/file-upload.svg","fontawesome-solid-file-video":"fontawesome/solid/file-video.svg","fontawesome-solid-file-word":"fontawesome/solid/file-word.svg","fontawesome-solid-file":"fontawesome/solid/file.svg","fontawesome-solid-fill-drip":"fontawesome/solid/fill-drip.svg","fontawesome-solid-fill":"fontawesome/solid/fill.svg","fontawesome-solid-film":"fontawesome/solid/film.svg","fontawesome-solid-filter":"fontawesome/solid/filter.svg","fontawesome-solid-fingerprint":"fontawesome/solid/fingerprint.svg","fontawesome-solid-fire-alt":"fontawesome/solid/fire-alt.svg","fontawesome-solid-fire-extinguisher":"fontawesome/solid/fire-extinguisher.svg","fontawesome-solid-fire":"fontawesome/solid/fire.svg","fontawesome-solid-first-aid":"fontawesome/solid/first-aid.svg","fontawesome-solid-fish":"fontawesome/solid/fish.svg","fontawesome-solid-fist-raised":"fontawesome/solid/fist-raised.svg","fontawesome-solid-flag-checkered":"fontawesome/solid/flag-checkered.svg","fontawesome-solid-flag-usa":"fontawesome/solid/flag-usa.svg","fontawesome-solid-flag":"fontawesome/solid/flag.svg","fontawesome-solid-flask":"fontawesome/solid/flask.svg","fontawesome-solid-flushed":"fontawesome/solid/flushed.svg","fontawesome-solid-folder-minus":"fontawesome/solid/folder-minus.svg","fontawesome-solid-folder-open":"fontawesome/solid/folder-open.svg","fontawesome-solid-folder-plus":"fontawesome/solid/folder-plus.svg","fontawesome-solid-folder":"fontawesome/solid/folder.svg","fontawesome-solid-font-awesome-logo-full":"fontawesome/solid/font-awesome-logo-full.svg","fontawesome-solid-font":"fontawesome/solid/font.svg","fontawesome-solid-football-ball":"fontawesome/solid/football-ball.svg","fontawesome-solid-forward":"fontawesome/solid/forward.svg","fontawesome-solid-frog":"fontawesome/solid/frog.svg","fontawesome-solid-frown-open":"fontawesome/solid/frown-open.svg","fontawesome-solid-frown":"fontawesome/solid/frown.svg","fontawesome-solid-funnel-dollar":"fontawesome/solid/funnel-dollar.svg","fontawesome-solid-futbol":"fontawesome/solid/futbol.svg","fontawesome-solid-gamepad":"fontawesome/solid/gamepad.svg","fontawesome-solid-gas-pump":"fontawesome/solid/gas-pump.svg","fontawesome-solid-gavel":"fontawesome/solid/gavel.svg","fontawesome-solid-gem":"fontawesome/solid/gem.svg","fontawesome-solid-genderless":"fontawesome/solid/genderless.svg","fontawesome-solid-ghost":"fontawesome/solid/ghost.svg","fontawesome-solid-gift":"fontawesome/solid/gift.svg","fontawesome-solid-gifts":"fontawesome/solid/gifts.svg","fontawesome-solid-glass-cheers":"fontawesome/solid/glass-cheers.svg","fontawesome-solid-glass-martini-alt":"fontawesome/solid/glass-martini-alt.svg","fontawesome-solid-glass-martini":"fontawesome/solid/glass-martini.svg","fontawesome-solid-glass-whiskey":"fontawesome/solid/glass-whiskey.svg","fontawesome-solid-glasses":"fontawesome/solid/glasses.svg","fontawesome-solid-globe-africa":"fontawesome/solid/globe-africa.svg","fontawesome-solid-globe-americas":"fontawesome/solid/globe-americas.svg","fontawesome-solid-globe-asia":"fontawesome/solid/globe-asia.svg","fontawesome-solid-globe-europe":"fontawesome/solid/globe-europe.svg","fontawesome-solid-globe":"fontawesome/solid/globe.svg","fontawesome-solid-golf-ball":"fontawesome/solid/golf-ball.svg","fontawesome-solid-gopuram":"fontawesome/solid/gopuram.svg","fontawesome-solid-graduation-cap":"fontawesome/solid/graduation-cap.svg","fontawesome-solid-greater-than-equal":"fontawesome/solid/greater-than-equal.svg","fontawesome-solid-greater-than":"fontawesome/solid/greater-than.svg","fontawesome-solid-grimace":"fontawesome/solid/grimace.svg","fontawesome-solid-grin-alt":"fontawesome/solid/grin-alt.svg","fontawesome-solid-grin-beam-sweat":"fontawesome/solid/grin-beam-sweat.svg","fontawesome-solid-grin-beam":"fontawesome/solid/grin-beam.svg","fontawesome-solid-grin-hearts":"fontawesome/solid/grin-hearts.svg","fontawesome-solid-grin-squint-tears":"fontawesome/solid/grin-squint-tears.svg","fontawesome-solid-grin-squint":"fontawesome/solid/grin-squint.svg","fontawesome-solid-grin-stars":"fontawesome/solid/grin-stars.svg","fontawesome-solid-grin-tears":"fontawesome/solid/grin-tears.svg","fontawesome-solid-grin-tongue-squint":"fontawesome/solid/grin-tongue-squint.svg","fontawesome-solid-grin-tongue-wink":"fontawesome/solid/grin-tongue-wink.svg","fontawesome-solid-grin-tongue":"fontawesome/solid/grin-tongue.svg","fontawesome-solid-grin-wink":"fontawesome/solid/grin-wink.svg","fontawesome-solid-grin":"fontawesome/solid/grin.svg","fontawesome-solid-grip-horizontal":"fontawesome/solid/grip-horizontal.svg","fontawesome-solid-grip-lines-vertical":"fontawesome/solid/grip-lines-vertical.svg","fontawesome-solid-grip-lines":"fontawesome/solid/grip-lines.svg","fontawesome-solid-grip-vertical":"fontawesome/solid/grip-vertical.svg","fontawesome-solid-guitar":"fontawesome/solid/guitar.svg","fontawesome-solid-h-square":"fontawesome/solid/h-square.svg","fontawesome-solid-hamburger":"fontawesome/solid/hamburger.svg","fontawesome-solid-hammer":"fontawesome/solid/hammer.svg","fontawesome-solid-hamsa":"fontawesome/solid/hamsa.svg","fontawesome-solid-hand-holding-heart":"fontawesome/solid/hand-holding-heart.svg","fontawesome-solid-hand-holding-medical":"fontawesome/solid/hand-holding-medical.svg","fontawesome-solid-hand-holding-usd":"fontawesome/solid/hand-holding-usd.svg","fontawesome-solid-hand-holding-water":"fontawesome/solid/hand-holding-water.svg","fontawesome-solid-hand-holding":"fontawesome/solid/hand-holding.svg","fontawesome-solid-hand-lizard":"fontawesome/solid/hand-lizard.svg","fontawesome-solid-hand-middle-finger":"fontawesome/solid/hand-middle-finger.svg","fontawesome-solid-hand-paper":"fontawesome/solid/hand-paper.svg","fontawesome-solid-hand-peace":"fontawesome/solid/hand-peace.svg","fontawesome-solid-hand-point-down":"fontawesome/solid/hand-point-down.svg","fontawesome-solid-hand-point-left":"fontawesome/solid/hand-point-left.svg","fontawesome-solid-hand-point-right":"fontawesome/solid/hand-point-right.svg","fontawesome-solid-hand-point-up":"fontawesome/solid/hand-point-up.svg","fontawesome-solid-hand-pointer":"fontawesome/solid/hand-pointer.svg","fontawesome-solid-hand-rock":"fontawesome/solid/hand-rock.svg","fontawesome-solid-hand-scissors":"fontawesome/solid/hand-scissors.svg","fontawesome-solid-hand-sparkles":"fontawesome/solid/hand-sparkles.svg","fontawesome-solid-hand-spock":"fontawesome/solid/hand-spock.svg","fontawesome-solid-hands-helping":"fontawesome/solid/hands-helping.svg","fontawesome-solid-hands-wash":"fontawesome/solid/hands-wash.svg","fontawesome-solid-hands":"fontawesome/solid/hands.svg","fontawesome-solid-handshake-alt-slash":"fontawesome/solid/handshake-alt-slash.svg","fontawesome-solid-handshake-slash":"fontawesome/solid/handshake-slash.svg","fontawesome-solid-handshake":"fontawesome/solid/handshake.svg","fontawesome-solid-hanukiah":"fontawesome/solid/hanukiah.svg","fontawesome-solid-hard-hat":"fontawesome/solid/hard-hat.svg","fontawesome-solid-hashtag":"fontawesome/solid/hashtag.svg","fontawesome-solid-hat-cowboy-side":"fontawesome/solid/hat-cowboy-side.svg","fontawesome-solid-hat-cowboy":"fontawesome/solid/hat-cowboy.svg","fontawesome-solid-hat-wizard":"fontawesome/solid/hat-wizard.svg","fontawesome-solid-hdd":"fontawesome/solid/hdd.svg","fontawesome-solid-head-side-cough-slash":"fontawesome/solid/head-side-cough-slash.svg","fontawesome-solid-head-side-cough":"fontawesome/solid/head-side-cough.svg","fontawesome-solid-head-side-mask":"fontawesome/solid/head-side-mask.svg","fontawesome-solid-head-side-virus":"fontawesome/solid/head-side-virus.svg","fontawesome-solid-heading":"fontawesome/solid/heading.svg","fontawesome-solid-headphones-alt":"fontawesome/solid/headphones-alt.svg","fontawesome-solid-headphones":"fontawesome/solid/headphones.svg","fontawesome-solid-headset":"fontawesome/solid/headset.svg","fontawesome-solid-heart-broken":"fontawesome/solid/heart-broken.svg","fontawesome-solid-heart":"fontawesome/solid/heart.svg","fontawesome-solid-heartbeat":"fontawesome/solid/heartbeat.svg","fontawesome-solid-helicopter":"fontawesome/solid/helicopter.svg","fontawesome-solid-highlighter":"fontawesome/solid/highlighter.svg","fontawesome-solid-hiking":"fontawesome/solid/hiking.svg","fontawesome-solid-hippo":"fontawesome/solid/hippo.svg","fontawesome-solid-history":"fontawesome/solid/history.svg","fontawesome-solid-hockey-puck":"fontawesome/solid/hockey-puck.svg","fontawesome-solid-holly-berry":"fontawesome/solid/holly-berry.svg","fontawesome-solid-home":"fontawesome/solid/home.svg","fontawesome-solid-horse-head":"fontawesome/solid/horse-head.svg","fontawesome-solid-horse":"fontawesome/solid/horse.svg","fontawesome-solid-hospital-alt":"fontawesome/solid/hospital-alt.svg","fontawesome-solid-hospital-symbol":"fontawesome/solid/hospital-symbol.svg","fontawesome-solid-hospital-user":"fontawesome/solid/hospital-user.svg","fontawesome-solid-hospital":"fontawesome/solid/hospital.svg","fontawesome-solid-hot-tub":"fontawesome/solid/hot-tub.svg","fontawesome-solid-hotdog":"fontawesome/solid/hotdog.svg","fontawesome-solid-hotel":"fontawesome/solid/hotel.svg","fontawesome-solid-hourglass-end":"fontawesome/solid/hourglass-end.svg","fontawesome-solid-hourglass-half":"fontawesome/solid/hourglass-half.svg","fontawesome-solid-hourglass-start":"fontawesome/solid/hourglass-start.svg","fontawesome-solid-hourglass":"fontawesome/solid/hourglass.svg","fontawesome-solid-house-damage":"fontawesome/solid/house-damage.svg","fontawesome-solid-house-user":"fontawesome/solid/house-user.svg","fontawesome-solid-hryvnia":"fontawesome/solid/hryvnia.svg","fontawesome-solid-i-cursor":"fontawesome/solid/i-cursor.svg","fontawesome-solid-ice-cream":"fontawesome/solid/ice-cream.svg","fontawesome-solid-icicles":"fontawesome/solid/icicles.svg","fontawesome-solid-icons":"fontawesome/solid/icons.svg","fontawesome-solid-id-badge":"fontawesome/solid/id-badge.svg","fontawesome-solid-id-card-alt":"fontawesome/solid/id-card-alt.svg","fontawesome-solid-id-card":"fontawesome/solid/id-card.svg","fontawesome-solid-igloo":"fontawesome/solid/igloo.svg","fontawesome-solid-image":"fontawesome/solid/image.svg","fontawesome-solid-images":"fontawesome/solid/images.svg","fontawesome-solid-inbox":"fontawesome/solid/inbox.svg","fontawesome-solid-indent":"fontawesome/solid/indent.svg","fontawesome-solid-industry":"fontawesome/solid/industry.svg","fontawesome-solid-infinity":"fontawesome/solid/infinity.svg","fontawesome-solid-info-circle":"fontawesome/solid/info-circle.svg","fontawesome-solid-info":"fontawesome/solid/info.svg","fontawesome-solid-italic":"fontawesome/solid/italic.svg","fontawesome-solid-jedi":"fontawesome/solid/jedi.svg","fontawesome-solid-joint":"fontawesome/solid/joint.svg","fontawesome-solid-journal-whills":"fontawesome/solid/journal-whills.svg","fontawesome-solid-kaaba":"fontawesome/solid/kaaba.svg","fontawesome-solid-key":"fontawesome/solid/key.svg","fontawesome-solid-keyboard":"fontawesome/solid/keyboard.svg","fontawesome-solid-khanda":"fontawesome/solid/khanda.svg","fontawesome-solid-kiss-beam":"fontawesome/solid/kiss-beam.svg","fontawesome-solid-kiss-wink-heart":"fontawesome/solid/kiss-wink-heart.svg","fontawesome-solid-kiss":"fontawesome/solid/kiss.svg","fontawesome-solid-kiwi-bird":"fontawesome/solid/kiwi-bird.svg","fontawesome-solid-landmark":"fontawesome/solid/landmark.svg","fontawesome-solid-language":"fontawesome/solid/language.svg","fontawesome-solid-laptop-code":"fontawesome/solid/laptop-code.svg","fontawesome-solid-laptop-house":"fontawesome/solid/laptop-house.svg","fontawesome-solid-laptop-medical":"fontawesome/solid/laptop-medical.svg","fontawesome-solid-laptop":"fontawesome/solid/laptop.svg","fontawesome-solid-laugh-beam":"fontawesome/solid/laugh-beam.svg","fontawesome-solid-laugh-squint":"fontawesome/solid/laugh-squint.svg","fontawesome-solid-laugh-wink":"fontawesome/solid/laugh-wink.svg","fontawesome-solid-laugh":"fontawesome/solid/laugh.svg","fontawesome-solid-layer-group":"fontawesome/solid/layer-group.svg","fontawesome-solid-leaf":"fontawesome/solid/leaf.svg","fontawesome-solid-lemon":"fontawesome/solid/lemon.svg","fontawesome-solid-less-than-equal":"fontawesome/solid/less-than-equal.svg","fontawesome-solid-less-than":"fontawesome/solid/less-than.svg","fontawesome-solid-level-down-alt":"fontawesome/solid/level-down-alt.svg","fontawesome-solid-level-up-alt":"fontawesome/solid/level-up-alt.svg","fontawesome-solid-life-ring":"fontawesome/solid/life-ring.svg","fontawesome-solid-lightbulb":"fontawesome/solid/lightbulb.svg","fontawesome-solid-link":"fontawesome/solid/link.svg","fontawesome-solid-lira-sign":"fontawesome/solid/lira-sign.svg","fontawesome-solid-list-alt":"fontawesome/solid/list-alt.svg","fontawesome-solid-list-ol":"fontawesome/solid/list-ol.svg","fontawesome-solid-list-ul":"fontawesome/solid/list-ul.svg","fontawesome-solid-list":"fontawesome/solid/list.svg","fontawesome-solid-location-arrow":"fontawesome/solid/location-arrow.svg","fontawesome-solid-lock-open":"fontawesome/solid/lock-open.svg","fontawesome-solid-lock":"fontawesome/solid/lock.svg","fontawesome-solid-long-arrow-alt-down":"fontawesome/solid/long-arrow-alt-down.svg","fontawesome-solid-long-arrow-alt-left":"fontawesome/solid/long-arrow-alt-left.svg","fontawesome-solid-long-arrow-alt-right":"fontawesome/solid/long-arrow-alt-right.svg","fontawesome-solid-long-arrow-alt-up":"fontawesome/solid/long-arrow-alt-up.svg","fontawesome-solid-low-vision":"fontawesome/solid/low-vision.svg","fontawesome-solid-luggage-cart":"fontawesome/solid/luggage-cart.svg","fontawesome-solid-lungs-virus":"fontawesome/solid/lungs-virus.svg","fontawesome-solid-lungs":"fontawesome/solid/lungs.svg","fontawesome-solid-magic":"fontawesome/solid/magic.svg","fontawesome-solid-magnet":"fontawesome/solid/magnet.svg","fontawesome-solid-mail-bulk":"fontawesome/solid/mail-bulk.svg","fontawesome-solid-male":"fontawesome/solid/male.svg","fontawesome-solid-map-marked-alt":"fontawesome/solid/map-marked-alt.svg","fontawesome-solid-map-marked":"fontawesome/solid/map-marked.svg","fontawesome-solid-map-marker-alt":"fontawesome/solid/map-marker-alt.svg","fontawesome-solid-map-marker":"fontawesome/solid/map-marker.svg","fontawesome-solid-map-pin":"fontawesome/solid/map-pin.svg","fontawesome-solid-map-signs":"fontawesome/solid/map-signs.svg","fontawesome-solid-map":"fontawesome/solid/map.svg","fontawesome-solid-marker":"fontawesome/solid/marker.svg","fontawesome-solid-mars-double":"fontawesome/solid/mars-double.svg","fontawesome-solid-mars-stroke-h":"fontawesome/solid/mars-stroke-h.svg","fontawesome-solid-mars-stroke-v":"fontawesome/solid/mars-stroke-v.svg","fontawesome-solid-mars-stroke":"fontawesome/solid/mars-stroke.svg","fontawesome-solid-mars":"fontawesome/solid/mars.svg","fontawesome-solid-mask":"fontawesome/solid/mask.svg","fontawesome-solid-medal":"fontawesome/solid/medal.svg","fontawesome-solid-medkit":"fontawesome/solid/medkit.svg","fontawesome-solid-meh-blank":"fontawesome/solid/meh-blank.svg","fontawesome-solid-meh-rolling-eyes":"fontawesome/solid/meh-rolling-eyes.svg","fontawesome-solid-meh":"fontawesome/solid/meh.svg","fontawesome-solid-memory":"fontawesome/solid/memory.svg","fontawesome-solid-menorah":"fontawesome/solid/menorah.svg","fontawesome-solid-mercury":"fontawesome/solid/mercury.svg","fontawesome-solid-meteor":"fontawesome/solid/meteor.svg","fontawesome-solid-microchip":"fontawesome/solid/microchip.svg","fontawesome-solid-microphone-alt-slash":"fontawesome/solid/microphone-alt-slash.svg","fontawesome-solid-microphone-alt":"fontawesome/solid/microphone-alt.svg","fontawesome-solid-microphone-slash":"fontawesome/solid/microphone-slash.svg","fontawesome-solid-microphone":"fontawesome/solid/microphone.svg","fontawesome-solid-microscope":"fontawesome/solid/microscope.svg","fontawesome-solid-minus-circle":"fontawesome/solid/minus-circle.svg","fontawesome-solid-minus-square":"fontawesome/solid/minus-square.svg","fontawesome-solid-minus":"fontawesome/solid/minus.svg","fontawesome-solid-mitten":"fontawesome/solid/mitten.svg","fontawesome-solid-mobile-alt":"fontawesome/solid/mobile-alt.svg","fontawesome-solid-mobile":"fontawesome/solid/mobile.svg","fontawesome-solid-money-bill-alt":"fontawesome/solid/money-bill-alt.svg","fontawesome-solid-money-bill-wave-alt":"fontawesome/solid/money-bill-wave-alt.svg","fontawesome-solid-money-bill-wave":"fontawesome/solid/money-bill-wave.svg","fontawesome-solid-money-bill":"fontawesome/solid/money-bill.svg","fontawesome-solid-money-check-alt":"fontawesome/solid/money-check-alt.svg","fontawesome-solid-money-check":"fontawesome/solid/money-check.svg","fontawesome-solid-monument":"fontawesome/solid/monument.svg","fontawesome-solid-moon":"fontawesome/solid/moon.svg","fontawesome-solid-mortar-pestle":"fontawesome/solid/mortar-pestle.svg","fontawesome-solid-mosque":"fontawesome/solid/mosque.svg","fontawesome-solid-motorcycle":"fontawesome/solid/motorcycle.svg","fontawesome-solid-mountain":"fontawesome/solid/mountain.svg","fontawesome-solid-mouse-pointer":"fontawesome/solid/mouse-pointer.svg","fontawesome-solid-mouse":"fontawesome/solid/mouse.svg","fontawesome-solid-mug-hot":"fontawesome/solid/mug-hot.svg","fontawesome-solid-music":"fontawesome/solid/music.svg","fontawesome-solid-network-wired":"fontawesome/solid/network-wired.svg","fontawesome-solid-neuter":"fontawesome/solid/neuter.svg","fontawesome-solid-newspaper":"fontawesome/solid/newspaper.svg","fontawesome-solid-not-equal":"fontawesome/solid/not-equal.svg","fontawesome-solid-notes-medical":"fontawesome/solid/notes-medical.svg","fontawesome-solid-object-group":"fontawesome/solid/object-group.svg","fontawesome-solid-object-ungroup":"fontawesome/solid/object-ungroup.svg","fontawesome-solid-oil-can":"fontawesome/solid/oil-can.svg","fontawesome-solid-om":"fontawesome/solid/om.svg","fontawesome-solid-otter":"fontawesome/solid/otter.svg","fontawesome-solid-outdent":"fontawesome/solid/outdent.svg","fontawesome-solid-pager":"fontawesome/solid/pager.svg","fontawesome-solid-paint-brush":"fontawesome/solid/paint-brush.svg","fontawesome-solid-paint-roller":"fontawesome/solid/paint-roller.svg","fontawesome-solid-palette":"fontawesome/solid/palette.svg","fontawesome-solid-pallet":"fontawesome/solid/pallet.svg","fontawesome-solid-paper-plane":"fontawesome/solid/paper-plane.svg","fontawesome-solid-paperclip":"fontawesome/solid/paperclip.svg","fontawesome-solid-parachute-box":"fontawesome/solid/parachute-box.svg","fontawesome-solid-paragraph":"fontawesome/solid/paragraph.svg","fontawesome-solid-parking":"fontawesome/solid/parking.svg","fontawesome-solid-passport":"fontawesome/solid/passport.svg","fontawesome-solid-pastafarianism":"fontawesome/solid/pastafarianism.svg","fontawesome-solid-paste":"fontawesome/solid/paste.svg","fontawesome-solid-pause-circle":"fontawesome/solid/pause-circle.svg","fontawesome-solid-pause":"fontawesome/solid/pause.svg","fontawesome-solid-paw":"fontawesome/solid/paw.svg","fontawesome-solid-peace":"fontawesome/solid/peace.svg","fontawesome-solid-pen-alt":"fontawesome/solid/pen-alt.svg","fontawesome-solid-pen-fancy":"fontawesome/solid/pen-fancy.svg","fontawesome-solid-pen-nib":"fontawesome/solid/pen-nib.svg","fontawesome-solid-pen-square":"fontawesome/solid/pen-square.svg","fontawesome-solid-pen":"fontawesome/solid/pen.svg","fontawesome-solid-pencil-alt":"fontawesome/solid/pencil-alt.svg","fontawesome-solid-pencil-ruler":"fontawesome/solid/pencil-ruler.svg","fontawesome-solid-people-arrows":"fontawesome/solid/people-arrows.svg","fontawesome-solid-people-carry":"fontawesome/solid/people-carry.svg","fontawesome-solid-pepper-hot":"fontawesome/solid/pepper-hot.svg","fontawesome-solid-percent":"fontawesome/solid/percent.svg","fontawesome-solid-percentage":"fontawesome/solid/percentage.svg","fontawesome-solid-person-booth":"fontawesome/solid/person-booth.svg","fontawesome-solid-phone-alt":"fontawesome/solid/phone-alt.svg","fontawesome-solid-phone-slash":"fontawesome/solid/phone-slash.svg","fontawesome-solid-phone-square-alt":"fontawesome/solid/phone-square-alt.svg","fontawesome-solid-phone-square":"fontawesome/solid/phone-square.svg","fontawesome-solid-phone-volume":"fontawesome/solid/phone-volume.svg","fontawesome-solid-phone":"fontawesome/solid/phone.svg","fontawesome-solid-photo-video":"fontawesome/solid/photo-video.svg","fontawesome-solid-piggy-bank":"fontawesome/solid/piggy-bank.svg","fontawesome-solid-pills":"fontawesome/solid/pills.svg","fontawesome-solid-pizza-slice":"fontawesome/solid/pizza-slice.svg","fontawesome-solid-place-of-worship":"fontawesome/solid/place-of-worship.svg","fontawesome-solid-plane-arrival":"fontawesome/solid/plane-arrival.svg","fontawesome-solid-plane-departure":"fontawesome/solid/plane-departure.svg","fontawesome-solid-plane-slash":"fontawesome/solid/plane-slash.svg","fontawesome-solid-plane":"fontawesome/solid/plane.svg","fontawesome-solid-play-circle":"fontawesome/solid/play-circle.svg","fontawesome-solid-play":"fontawesome/solid/play.svg","fontawesome-solid-plug":"fontawesome/solid/plug.svg","fontawesome-solid-plus-circle":"fontawesome/solid/plus-circle.svg","fontawesome-solid-plus-square":"fontawesome/solid/plus-square.svg","fontawesome-solid-plus":"fontawesome/solid/plus.svg","fontawesome-solid-podcast":"fontawesome/solid/podcast.svg","fontawesome-solid-poll-h":"fontawesome/solid/poll-h.svg","fontawesome-solid-poll":"fontawesome/solid/poll.svg","fontawesome-solid-poo-storm":"fontawesome/solid/poo-storm.svg","fontawesome-solid-poo":"fontawesome/solid/poo.svg","fontawesome-solid-poop":"fontawesome/solid/poop.svg","fontawesome-solid-portrait":"fontawesome/solid/portrait.svg","fontawesome-solid-pound-sign":"fontawesome/solid/pound-sign.svg","fontawesome-solid-power-off":"fontawesome/solid/power-off.svg","fontawesome-solid-pray":"fontawesome/solid/pray.svg","fontawesome-solid-praying-hands":"fontawesome/solid/praying-hands.svg","fontawesome-solid-prescription-bottle-alt":"fontawesome/solid/prescription-bottle-alt.svg","fontawesome-solid-prescription-bottle":"fontawesome/solid/prescription-bottle.svg","fontawesome-solid-prescription":"fontawesome/solid/prescription.svg","fontawesome-solid-print":"fontawesome/solid/print.svg","fontawesome-solid-procedures":"fontawesome/solid/procedures.svg","fontawesome-solid-project-diagram":"fontawesome/solid/project-diagram.svg","fontawesome-solid-pump-medical":"fontawesome/solid/pump-medical.svg","fontawesome-solid-pump-soap":"fontawesome/solid/pump-soap.svg","fontawesome-solid-puzzle-piece":"fontawesome/solid/puzzle-piece.svg","fontawesome-solid-qrcode":"fontawesome/solid/qrcode.svg","fontawesome-solid-question-circle":"fontawesome/solid/question-circle.svg","fontawesome-solid-question":"fontawesome/solid/question.svg","fontawesome-solid-quidditch":"fontawesome/solid/quidditch.svg","fontawesome-solid-quote-left":"fontawesome/solid/quote-left.svg","fontawesome-solid-quote-right":"fontawesome/solid/quote-right.svg","fontawesome-solid-quran":"fontawesome/solid/quran.svg","fontawesome-solid-radiation-alt":"fontawesome/solid/radiation-alt.svg","fontawesome-solid-radiation":"fontawesome/solid/radiation.svg","fontawesome-solid-rainbow":"fontawesome/solid/rainbow.svg","fontawesome-solid-random":"fontawesome/solid/random.svg","fontawesome-solid-receipt":"fontawesome/solid/receipt.svg","fontawesome-solid-record-vinyl":"fontawesome/solid/record-vinyl.svg","fontawesome-solid-recycle":"fontawesome/solid/recycle.svg","fontawesome-solid-redo-alt":"fontawesome/solid/redo-alt.svg","fontawesome-solid-redo":"fontawesome/solid/redo.svg","fontawesome-solid-registered":"fontawesome/solid/registered.svg","fontawesome-solid-remove-format":"fontawesome/solid/remove-format.svg","fontawesome-solid-reply-all":"fontawesome/solid/reply-all.svg","fontawesome-solid-reply":"fontawesome/solid/reply.svg","fontawesome-solid-republican":"fontawesome/solid/republican.svg","fontawesome-solid-restroom":"fontawesome/solid/restroom.svg","fontawesome-solid-retweet":"fontawesome/solid/retweet.svg","fontawesome-solid-ribbon":"fontawesome/solid/ribbon.svg","fontawesome-solid-ring":"fontawesome/solid/ring.svg","fontawesome-solid-road":"fontawesome/solid/road.svg","fontawesome-solid-robot":"fontawesome/solid/robot.svg","fontawesome-solid-rocket":"fontawesome/solid/rocket.svg","fontawesome-solid-route":"fontawesome/solid/route.svg","fontawesome-solid-rss-square":"fontawesome/solid/rss-square.svg","fontawesome-solid-rss":"fontawesome/solid/rss.svg","fontawesome-solid-ruble-sign":"fontawesome/solid/ruble-sign.svg","fontawesome-solid-ruler-combined":"fontawesome/solid/ruler-combined.svg","fontawesome-solid-ruler-horizontal":"fontawesome/solid/ruler-horizontal.svg","fontawesome-solid-ruler-vertical":"fontawesome/solid/ruler-vertical.svg","fontawesome-solid-ruler":"fontawesome/solid/ruler.svg","fontawesome-solid-running":"fontawesome/solid/running.svg","fontawesome-solid-rupee-sign":"fontawesome/solid/rupee-sign.svg","fontawesome-solid-sad-cry":"fontawesome/solid/sad-cry.svg","fontawesome-solid-sad-tear":"fontawesome/solid/sad-tear.svg","fontawesome-solid-satellite-dish":"fontawesome/solid/satellite-dish.svg","fontawesome-solid-satellite":"fontawesome/solid/satellite.svg","fontawesome-solid-save":"fontawesome/solid/save.svg","fontawesome-solid-school":"fontawesome/solid/school.svg","fontawesome-solid-screwdriver":"fontawesome/solid/screwdriver.svg","fontawesome-solid-scroll":"fontawesome/solid/scroll.svg","fontawesome-solid-sd-card":"fontawesome/solid/sd-card.svg","fontawesome-solid-search-dollar":"fontawesome/solid/search-dollar.svg","fontawesome-solid-search-location":"fontawesome/solid/search-location.svg","fontawesome-solid-search-minus":"fontawesome/solid/search-minus.svg","fontawesome-solid-search-plus":"fontawesome/solid/search-plus.svg","fontawesome-solid-search":"fontawesome/solid/search.svg","fontawesome-solid-seedling":"fontawesome/solid/seedling.svg","fontawesome-solid-server":"fontawesome/solid/server.svg","fontawesome-solid-shapes":"fontawesome/solid/shapes.svg","fontawesome-solid-share-alt-square":"fontawesome/solid/share-alt-square.svg","fontawesome-solid-share-alt":"fontawesome/solid/share-alt.svg","fontawesome-solid-share-square":"fontawesome/solid/share-square.svg","fontawesome-solid-share":"fontawesome/solid/share.svg","fontawesome-solid-shekel-sign":"fontawesome/solid/shekel-sign.svg","fontawesome-solid-shield-alt":"fontawesome/solid/shield-alt.svg","fontawesome-solid-shield-virus":"fontawesome/solid/shield-virus.svg","fontawesome-solid-ship":"fontawesome/solid/ship.svg","fontawesome-solid-shipping-fast":"fontawesome/solid/shipping-fast.svg","fontawesome-solid-shoe-prints":"fontawesome/solid/shoe-prints.svg","fontawesome-solid-shopping-bag":"fontawesome/solid/shopping-bag.svg","fontawesome-solid-shopping-basket":"fontawesome/solid/shopping-basket.svg","fontawesome-solid-shopping-cart":"fontawesome/solid/shopping-cart.svg","fontawesome-solid-shower":"fontawesome/solid/shower.svg","fontawesome-solid-shuttle-van":"fontawesome/solid/shuttle-van.svg","fontawesome-solid-sign-in-alt":"fontawesome/solid/sign-in-alt.svg","fontawesome-solid-sign-language":"fontawesome/solid/sign-language.svg","fontawesome-solid-sign-out-alt":"fontawesome/solid/sign-out-alt.svg","fontawesome-solid-sign":"fontawesome/solid/sign.svg","fontawesome-solid-signal":"fontawesome/solid/signal.svg","fontawesome-solid-signature":"fontawesome/solid/signature.svg","fontawesome-solid-sim-card":"fontawesome/solid/sim-card.svg","fontawesome-solid-sink":"fontawesome/solid/sink.svg","fontawesome-solid-sitemap":"fontawesome/solid/sitemap.svg","fontawesome-solid-skating":"fontawesome/solid/skating.svg","fontawesome-solid-skiing-nordic":"fontawesome/solid/skiing-nordic.svg","fontawesome-solid-skiing":"fontawesome/solid/skiing.svg","fontawesome-solid-skull-crossbones":"fontawesome/solid/skull-crossbones.svg","fontawesome-solid-skull":"fontawesome/solid/skull.svg","fontawesome-solid-slash":"fontawesome/solid/slash.svg","fontawesome-solid-sleigh":"fontawesome/solid/sleigh.svg","fontawesome-solid-sliders-h":"fontawesome/solid/sliders-h.svg","fontawesome-solid-smile-beam":"fontawesome/solid/smile-beam.svg","fontawesome-solid-smile-wink":"fontawesome/solid/smile-wink.svg","fontawesome-solid-smile":"fontawesome/solid/smile.svg","fontawesome-solid-smog":"fontawesome/solid/smog.svg","fontawesome-solid-smoking-ban":"fontawesome/solid/smoking-ban.svg","fontawesome-solid-smoking":"fontawesome/solid/smoking.svg","fontawesome-solid-sms":"fontawesome/solid/sms.svg","fontawesome-solid-snowboarding":"fontawesome/solid/snowboarding.svg","fontawesome-solid-snowflake":"fontawesome/solid/snowflake.svg","fontawesome-solid-snowman":"fontawesome/solid/snowman.svg","fontawesome-solid-snowplow":"fontawesome/solid/snowplow.svg","fontawesome-solid-soap":"fontawesome/solid/soap.svg","fontawesome-solid-socks":"fontawesome/solid/socks.svg","fontawesome-solid-solar-panel":"fontawesome/solid/solar-panel.svg","fontawesome-solid-sort-alpha-down-alt":"fontawesome/solid/sort-alpha-down-alt.svg","fontawesome-solid-sort-alpha-down":"fontawesome/solid/sort-alpha-down.svg","fontawesome-solid-sort-alpha-up-alt":"fontawesome/solid/sort-alpha-up-alt.svg","fontawesome-solid-sort-alpha-up":"fontawesome/solid/sort-alpha-up.svg","fontawesome-solid-sort-amount-down-alt":"fontawesome/solid/sort-amount-down-alt.svg","fontawesome-solid-sort-amount-down":"fontawesome/solid/sort-amount-down.svg","fontawesome-solid-sort-amount-up-alt":"fontawesome/solid/sort-amount-up-alt.svg","fontawesome-solid-sort-amount-up":"fontawesome/solid/sort-amount-up.svg","fontawesome-solid-sort-down":"fontawesome/solid/sort-down.svg","fontawesome-solid-sort-numeric-down-alt":"fontawesome/solid/sort-numeric-down-alt.svg","fontawesome-solid-sort-numeric-down":"fontawesome/solid/sort-numeric-down.svg","fontawesome-solid-sort-numeric-up-alt":"fontawesome/solid/sort-numeric-up-alt.svg","fontawesome-solid-sort-numeric-up":"fontawesome/solid/sort-numeric-up.svg","fontawesome-solid-sort-up":"fontawesome/solid/sort-up.svg","fontawesome-solid-sort":"fontawesome/solid/sort.svg","fontawesome-solid-spa":"fontawesome/solid/spa.svg","fontawesome-solid-space-shuttle":"fontawesome/solid/space-shuttle.svg","fontawesome-solid-spell-check":"fontawesome/solid/spell-check.svg","fontawesome-solid-spider":"fontawesome/solid/spider.svg","fontawesome-solid-spinner":"fontawesome/solid/spinner.svg","fontawesome-solid-splotch":"fontawesome/solid/splotch.svg","fontawesome-solid-spray-can":"fontawesome/solid/spray-can.svg","fontawesome-solid-square-full":"fontawesome/solid/square-full.svg","fontawesome-solid-square-root-alt":"fontawesome/solid/square-root-alt.svg","fontawesome-solid-square":"fontawesome/solid/square.svg","fontawesome-solid-stamp":"fontawesome/solid/stamp.svg","fontawesome-solid-star-and-crescent":"fontawesome/solid/star-and-crescent.svg","fontawesome-solid-star-half-alt":"fontawesome/solid/star-half-alt.svg","fontawesome-solid-star-half":"fontawesome/solid/star-half.svg","fontawesome-solid-star-of-david":"fontawesome/solid/star-of-david.svg","fontawesome-solid-star-of-life":"fontawesome/solid/star-of-life.svg","fontawesome-solid-star":"fontawesome/solid/star.svg","fontawesome-solid-step-backward":"fontawesome/solid/step-backward.svg","fontawesome-solid-step-forward":"fontawesome/solid/step-forward.svg","fontawesome-solid-stethoscope":"fontawesome/solid/stethoscope.svg","fontawesome-solid-sticky-note":"fontawesome/solid/sticky-note.svg","fontawesome-solid-stop-circle":"fontawesome/solid/stop-circle.svg","fontawesome-solid-stop":"fontawesome/solid/stop.svg","fontawesome-solid-stopwatch-20":"fontawesome/solid/stopwatch-20.svg","fontawesome-solid-stopwatch":"fontawesome/solid/stopwatch.svg","fontawesome-solid-store-alt-slash":"fontawesome/solid/store-alt-slash.svg","fontawesome-solid-store-alt":"fontawesome/solid/store-alt.svg","fontawesome-solid-store-slash":"fontawesome/solid/store-slash.svg","fontawesome-solid-store":"fontawesome/solid/store.svg","fontawesome-solid-stream":"fontawesome/solid/stream.svg","fontawesome-solid-street-view":"fontawesome/solid/street-view.svg","fontawesome-solid-strikethrough":"fontawesome/solid/strikethrough.svg","fontawesome-solid-stroopwafel":"fontawesome/solid/stroopwafel.svg","fontawesome-solid-subscript":"fontawesome/solid/subscript.svg","fontawesome-solid-subway":"fontawesome/solid/subway.svg","fontawesome-solid-suitcase-rolling":"fontawesome/solid/suitcase-rolling.svg","fontawesome-solid-suitcase":"fontawesome/solid/suitcase.svg","fontawesome-solid-sun":"fontawesome/solid/sun.svg","fontawesome-solid-superscript":"fontawesome/solid/superscript.svg","fontawesome-solid-surprise":"fontawesome/solid/surprise.svg","fontawesome-solid-swatchbook":"fontawesome/solid/swatchbook.svg","fontawesome-solid-swimmer":"fontawesome/solid/swimmer.svg","fontawesome-solid-swimming-pool":"fontawesome/solid/swimming-pool.svg","fontawesome-solid-synagogue":"fontawesome/solid/synagogue.svg","fontawesome-solid-sync-alt":"fontawesome/solid/sync-alt.svg","fontawesome-solid-sync":"fontawesome/solid/sync.svg","fontawesome-solid-syringe":"fontawesome/solid/syringe.svg","fontawesome-solid-table-tennis":"fontawesome/solid/table-tennis.svg","fontawesome-solid-table":"fontawesome/solid/table.svg","fontawesome-solid-tablet-alt":"fontawesome/solid/tablet-alt.svg","fontawesome-solid-tablet":"fontawesome/solid/tablet.svg","fontawesome-solid-tablets":"fontawesome/solid/tablets.svg","fontawesome-solid-tachometer-alt":"fontawesome/solid/tachometer-alt.svg","fontawesome-solid-tag":"fontawesome/solid/tag.svg","fontawesome-solid-tags":"fontawesome/solid/tags.svg","fontawesome-solid-tape":"fontawesome/solid/tape.svg","fontawesome-solid-tasks":"fontawesome/solid/tasks.svg","fontawesome-solid-taxi":"fontawesome/solid/taxi.svg","fontawesome-solid-teeth-open":"fontawesome/solid/teeth-open.svg","fontawesome-solid-teeth":"fontawesome/solid/teeth.svg","fontawesome-solid-temperature-high":"fontawesome/solid/temperature-high.svg","fontawesome-solid-temperature-low":"fontawesome/solid/temperature-low.svg","fontawesome-solid-tenge":"fontawesome/solid/tenge.svg","fontawesome-solid-terminal":"fontawesome/solid/terminal.svg","fontawesome-solid-text-height":"fontawesome/solid/text-height.svg","fontawesome-solid-text-width":"fontawesome/solid/text-width.svg","fontawesome-solid-th-large":"fontawesome/solid/th-large.svg","fontawesome-solid-th-list":"fontawesome/solid/th-list.svg","fontawesome-solid-th":"fontawesome/solid/th.svg","fontawesome-solid-theater-masks":"fontawesome/solid/theater-masks.svg","fontawesome-solid-thermometer-empty":"fontawesome/solid/thermometer-empty.svg","fontawesome-solid-thermometer-full":"fontawesome/solid/thermometer-full.svg","fontawesome-solid-thermometer-half":"fontawesome/solid/thermometer-half.svg","fontawesome-solid-thermometer-quarter":"fontawesome/solid/thermometer-quarter.svg","fontawesome-solid-thermometer-three-quarters":"fontawesome/solid/thermometer-three-quarters.svg","fontawesome-solid-thermometer":"fontawesome/solid/thermometer.svg","fontawesome-solid-thumbs-down":"fontawesome/solid/thumbs-down.svg","fontawesome-solid-thumbs-up":"fontawesome/solid/thumbs-up.svg","fontawesome-solid-thumbtack":"fontawesome/solid/thumbtack.svg","fontawesome-solid-ticket-alt":"fontawesome/solid/ticket-alt.svg","fontawesome-solid-times-circle":"fontawesome/solid/times-circle.svg","fontawesome-solid-times":"fontawesome/solid/times.svg","fontawesome-solid-tint-slash":"fontawesome/solid/tint-slash.svg","fontawesome-solid-tint":"fontawesome/solid/tint.svg","fontawesome-solid-tired":"fontawesome/solid/tired.svg","fontawesome-solid-toggle-off":"fontawesome/solid/toggle-off.svg","fontawesome-solid-toggle-on":"fontawesome/solid/toggle-on.svg","fontawesome-solid-toilet-paper-slash":"fontawesome/solid/toilet-paper-slash.svg","fontawesome-solid-toilet-paper":"fontawesome/solid/toilet-paper.svg","fontawesome-solid-toilet":"fontawesome/solid/toilet.svg","fontawesome-solid-toolbox":"fontawesome/solid/toolbox.svg","fontawesome-solid-tools":"fontawesome/solid/tools.svg","fontawesome-solid-tooth":"fontawesome/solid/tooth.svg","fontawesome-solid-torah":"fontawesome/solid/torah.svg","fontawesome-solid-torii-gate":"fontawesome/solid/torii-gate.svg","fontawesome-solid-tractor":"fontawesome/solid/tractor.svg","fontawesome-solid-trademark":"fontawesome/solid/trademark.svg","fontawesome-solid-traffic-light":"fontawesome/solid/traffic-light.svg","fontawesome-solid-trailer":"fontawesome/solid/trailer.svg","fontawesome-solid-train":"fontawesome/solid/train.svg","fontawesome-solid-tram":"fontawesome/solid/tram.svg","fontawesome-solid-transgender-alt":"fontawesome/solid/transgender-alt.svg","fontawesome-solid-transgender":"fontawesome/solid/transgender.svg","fontawesome-solid-trash-alt":"fontawesome/solid/trash-alt.svg","fontawesome-solid-trash-restore-alt":"fontawesome/solid/trash-restore-alt.svg","fontawesome-solid-trash-restore":"fontawesome/solid/trash-restore.svg","fontawesome-solid-trash":"fontawesome/solid/trash.svg","fontawesome-solid-tree":"fontawesome/solid/tree.svg","fontawesome-solid-trophy":"fontawesome/solid/trophy.svg","fontawesome-solid-truck-loading":"fontawesome/solid/truck-loading.svg","fontawesome-solid-truck-monster":"fontawesome/solid/truck-monster.svg","fontawesome-solid-truck-moving":"fontawesome/solid/truck-moving.svg","fontawesome-solid-truck-pickup":"fontawesome/solid/truck-pickup.svg","fontawesome-solid-truck":"fontawesome/solid/truck.svg","fontawesome-solid-tshirt":"fontawesome/solid/tshirt.svg","fontawesome-solid-tty":"fontawesome/solid/tty.svg","fontawesome-solid-tv":"fontawesome/solid/tv.svg","fontawesome-solid-umbrella-beach":"fontawesome/solid/umbrella-beach.svg","fontawesome-solid-umbrella":"fontawesome/solid/umbrella.svg","fontawesome-solid-underline":"fontawesome/solid/underline.svg","fontawesome-solid-undo-alt":"fontawesome/solid/undo-alt.svg","fontawesome-solid-undo":"fontawesome/solid/undo.svg","fontawesome-solid-universal-access":"fontawesome/solid/universal-access.svg","fontawesome-solid-university":"fontawesome/solid/university.svg","fontawesome-solid-unlink":"fontawesome/solid/unlink.svg","fontawesome-solid-unlock-alt":"fontawesome/solid/unlock-alt.svg","fontawesome-solid-unlock":"fontawesome/solid/unlock.svg","fontawesome-solid-upload":"fontawesome/solid/upload.svg","fontawesome-solid-user-alt-slash":"fontawesome/solid/user-alt-slash.svg","fontawesome-solid-user-alt":"fontawesome/solid/user-alt.svg","fontawesome-solid-user-astronaut":"fontawesome/solid/user-astronaut.svg","fontawesome-solid-user-check":"fontawesome/solid/user-check.svg","fontawesome-solid-user-circle":"fontawesome/solid/user-circle.svg","fontawesome-solid-user-clock":"fontawesome/solid/user-clock.svg","fontawesome-solid-user-cog":"fontawesome/solid/user-cog.svg","fontawesome-solid-user-edit":"fontawesome/solid/user-edit.svg","fontawesome-solid-user-friends":"fontawesome/solid/user-friends.svg","fontawesome-solid-user-graduate":"fontawesome/solid/user-graduate.svg","fontawesome-solid-user-injured":"fontawesome/solid/user-injured.svg","fontawesome-solid-user-lock":"fontawesome/solid/user-lock.svg","fontawesome-solid-user-md":"fontawesome/solid/user-md.svg","fontawesome-solid-user-minus":"fontawesome/solid/user-minus.svg","fontawesome-solid-user-ninja":"fontawesome/solid/user-ninja.svg","fontawesome-solid-user-nurse":"fontawesome/solid/user-nurse.svg","fontawesome-solid-user-plus":"fontawesome/solid/user-plus.svg","fontawesome-solid-user-secret":"fontawesome/solid/user-secret.svg","fontawesome-solid-user-shield":"fontawesome/solid/user-shield.svg","fontawesome-solid-user-slash":"fontawesome/solid/user-slash.svg","fontawesome-solid-user-tag":"fontawesome/solid/user-tag.svg","fontawesome-solid-user-tie":"fontawesome/solid/user-tie.svg","fontawesome-solid-user-times":"fontawesome/solid/user-times.svg","fontawesome-solid-user":"fontawesome/solid/user.svg","fontawesome-solid-users-cog":"fontawesome/solid/users-cog.svg","fontawesome-solid-users-slash":"fontawesome/solid/users-slash.svg","fontawesome-solid-users":"fontawesome/solid/users.svg","fontawesome-solid-utensil-spoon":"fontawesome/solid/utensil-spoon.svg","fontawesome-solid-utensils":"fontawesome/solid/utensils.svg","fontawesome-solid-vector-square":"fontawesome/solid/vector-square.svg","fontawesome-solid-venus-double":"fontawesome/solid/venus-double.svg","fontawesome-solid-venus-mars":"fontawesome/solid/venus-mars.svg","fontawesome-solid-venus":"fontawesome/solid/venus.svg","fontawesome-solid-vest-patches":"fontawesome/solid/vest-patches.svg","fontawesome-solid-vest":"fontawesome/solid/vest.svg","fontawesome-solid-vial":"fontawesome/solid/vial.svg","fontawesome-solid-vials":"fontawesome/solid/vials.svg","fontawesome-solid-video-slash":"fontawesome/solid/video-slash.svg","fontawesome-solid-video":"fontawesome/solid/video.svg","fontawesome-solid-vihara":"fontawesome/solid/vihara.svg","fontawesome-solid-virus-slash":"fontawesome/solid/virus-slash.svg","fontawesome-solid-virus":"fontawesome/solid/virus.svg","fontawesome-solid-viruses":"fontawesome/solid/viruses.svg","fontawesome-solid-voicemail":"fontawesome/solid/voicemail.svg","fontawesome-solid-volleyball-ball":"fontawesome/solid/volleyball-ball.svg","fontawesome-solid-volume-down":"fontawesome/solid/volume-down.svg","fontawesome-solid-volume-mute":"fontawesome/solid/volume-mute.svg","fontawesome-solid-volume-off":"fontawesome/solid/volume-off.svg","fontawesome-solid-volume-up":"fontawesome/solid/volume-up.svg","fontawesome-solid-vote-yea":"fontawesome/solid/vote-yea.svg","fontawesome-solid-vr-cardboard":"fontawesome/solid/vr-cardboard.svg","fontawesome-solid-walking":"fontawesome/solid/walking.svg","fontawesome-solid-wallet":"fontawesome/solid/wallet.svg","fontawesome-solid-warehouse":"fontawesome/solid/warehouse.svg","fontawesome-solid-water":"fontawesome/solid/water.svg","fontawesome-solid-wave-square":"fontawesome/solid/wave-square.svg","fontawesome-solid-weight-hanging":"fontawesome/solid/weight-hanging.svg","fontawesome-solid-weight":"fontawesome/solid/weight.svg","fontawesome-solid-wheelchair":"fontawesome/solid/wheelchair.svg","fontawesome-solid-wifi":"fontawesome/solid/wifi.svg","fontawesome-solid-wind":"fontawesome/solid/wind.svg","fontawesome-solid-window-close":"fontawesome/solid/window-close.svg","fontawesome-solid-window-maximize":"fontawesome/solid/window-maximize.svg","fontawesome-solid-window-minimize":"fontawesome/solid/window-minimize.svg","fontawesome-solid-window-restore":"fontawesome/solid/window-restore.svg","fontawesome-solid-wine-bottle":"fontawesome/solid/wine-bottle.svg","fontawesome-solid-wine-glass-alt":"fontawesome/solid/wine-glass-alt.svg","fontawesome-solid-wine-glass":"fontawesome/solid/wine-glass.svg","fontawesome-solid-won-sign":"fontawesome/solid/won-sign.svg","fontawesome-solid-wrench":"fontawesome/solid/wrench.svg","fontawesome-solid-x-ray":"fontawesome/solid/x-ray.svg","fontawesome-solid-yen-sign":"fontawesome/solid/yen-sign.svg","fontawesome-solid-yin-yang":"fontawesome/solid/yin-yang.svg","logo":"logo.svg","material-ab-testing":"material/ab-testing.svg","material-abacus":"material/abacus.svg","material-abjad-arabic":"material/abjad-arabic.svg","material-abjad-hebrew":"material/abjad-hebrew.svg","material-abugida-devanagari":"material/abugida-devanagari.svg","material-abugida-thai":"material/abugida-thai.svg","material-access-point-check":"material/access-point-check.svg","material-access-point-minus":"material/access-point-minus.svg","material-access-point-network-off":"material/access-point-network-off.svg","material-access-point-network":"material/access-point-network.svg","material-access-point-off":"material/access-point-off.svg","material-access-point-plus":"material/access-point-plus.svg","material-access-point-remove":"material/access-point-remove.svg","material-access-point":"material/access-point.svg","material-account-alert-outline":"material/account-alert-outline.svg","material-account-alert":"material/account-alert.svg","material-account-arrow-left-outline":"material/account-arrow-left-outline.svg","material-account-arrow-left":"material/account-arrow-left.svg","material-account-arrow-right-outline":"material/account-arrow-right-outline.svg","material-account-arrow-right":"material/account-arrow-right.svg","material-account-box-multiple-outline":"material/account-box-multiple-outline.svg","material-account-box-multiple":"material/account-box-multiple.svg","material-account-box-outline":"material/account-box-outline.svg","material-account-box":"material/account-box.svg","material-account-cancel-outline":"material/account-cancel-outline.svg","material-account-cancel":"material/account-cancel.svg","material-account-cash-outline":"material/account-cash-outline.svg","material-account-cash":"material/account-cash.svg","material-account-check-outline":"material/account-check-outline.svg","material-account-check":"material/account-check.svg","material-account-child-circle":"material/account-child-circle.svg","material-account-child-outline":"material/account-child-outline.svg","material-account-child":"material/account-child.svg","material-account-circle-outline":"material/account-circle-outline.svg","material-account-circle":"material/account-circle.svg","material-account-clock-outline":"material/account-clock-outline.svg","material-account-clock":"material/account-clock.svg","material-account-cog-outline":"material/account-cog-outline.svg","material-account-cog":"material/account-cog.svg","material-account-convert-outline":"material/account-convert-outline.svg","material-account-convert":"material/account-convert.svg","material-account-cowboy-hat":"material/account-cowboy-hat.svg","material-account-details-outline":"material/account-details-outline.svg","material-account-details":"material/account-details.svg","material-account-edit-outline":"material/account-edit-outline.svg","material-account-edit":"material/account-edit.svg","material-account-group-outline":"material/account-group-outline.svg","material-account-group":"material/account-group.svg","material-account-hard-hat":"material/account-hard-hat.svg","material-account-heart-outline":"material/account-heart-outline.svg","material-account-heart":"material/account-heart.svg","material-account-key-outline":"material/account-key-outline.svg","material-account-key":"material/account-key.svg","material-account-lock-outline":"material/account-lock-outline.svg","material-account-lock":"material/account-lock.svg","material-account-minus-outline":"material/account-minus-outline.svg","material-account-minus":"material/account-minus.svg","material-account-multiple-check-outline":"material/account-multiple-check-outline.svg","material-account-multiple-check":"material/account-multiple-check.svg","material-account-multiple-minus-outline":"material/account-multiple-minus-outline.svg","material-account-multiple-minus":"material/account-multiple-minus.svg","material-account-multiple-outline":"material/account-multiple-outline.svg","material-account-multiple-plus-outline":"material/account-multiple-plus-outline.svg","material-account-multiple-plus":"material/account-multiple-plus.svg","material-account-multiple-remove-outline":"material/account-multiple-remove-outline.svg","material-account-multiple-remove":"material/account-multiple-remove.svg","material-account-multiple":"material/account-multiple.svg","material-account-music-outline":"material/account-music-outline.svg","material-account-music":"material/account-music.svg","material-account-network-outline":"material/account-network-outline.svg","material-account-network":"material/account-network.svg","material-account-off-outline":"material/account-off-outline.svg","material-account-off":"material/account-off.svg","material-account-outline":"material/account-outline.svg","material-account-plus-outline":"material/account-plus-outline.svg","material-account-plus":"material/account-plus.svg","material-account-question-outline":"material/account-question-outline.svg","material-account-question":"material/account-question.svg","material-account-reactivate-outline":"material/account-reactivate-outline.svg","material-account-reactivate":"material/account-reactivate.svg","material-account-remove-outline":"material/account-remove-outline.svg","material-account-remove":"material/account-remove.svg","material-account-search-outline":"material/account-search-outline.svg","material-account-search":"material/account-search.svg","material-account-settings-outline":"material/account-settings-outline.svg","material-account-settings":"material/account-settings.svg","material-account-star-outline":"material/account-star-outline.svg","material-account-star":"material/account-star.svg","material-account-supervisor-circle-outline":"material/account-supervisor-circle-outline.svg","material-account-supervisor-circle":"material/account-supervisor-circle.svg","material-account-supervisor-outline":"material/account-supervisor-outline.svg","material-account-supervisor":"material/account-supervisor.svg","material-account-switch-outline":"material/account-switch-outline.svg","material-account-switch":"material/account-switch.svg","material-account-tie-outline":"material/account-tie-outline.svg","material-account-tie-voice-off-outline":"material/account-tie-voice-off-outline.svg","material-account-tie-voice-off":"material/account-tie-voice-off.svg","material-account-tie-voice-outline":"material/account-tie-voice-outline.svg","material-account-tie-voice":"material/account-tie-voice.svg","material-account-tie":"material/account-tie.svg","material-account-voice":"material/account-voice.svg","material-account":"material/account.svg","material-adjust":"material/adjust.svg","material-adobe-acrobat":"material/adobe-acrobat.svg","material-adobe":"material/adobe.svg","material-air-conditioner":"material/air-conditioner.svg","material-air-filter":"material/air-filter.svg","material-air-horn":"material/air-horn.svg","material-air-humidifier-off":"material/air-humidifier-off.svg","material-air-humidifier":"material/air-humidifier.svg","material-air-purifier":"material/air-purifier.svg","material-airbag":"material/airbag.svg","material-airballoon-outline":"material/airballoon-outline.svg","material-airballoon":"material/airballoon.svg","material-airplane-landing":"material/airplane-landing.svg","material-airplane-off":"material/airplane-off.svg","material-airplane-takeoff":"material/airplane-takeoff.svg","material-airplane":"material/airplane.svg","material-airport":"material/airport.svg","material-alarm-bell":"material/alarm-bell.svg","material-alarm-check":"material/alarm-check.svg","material-alarm-light-off-outline":"material/alarm-light-off-outline.svg","material-alarm-light-off":"material/alarm-light-off.svg","material-alarm-light-outline":"material/alarm-light-outline.svg","material-alarm-light":"material/alarm-light.svg","material-alarm-multiple":"material/alarm-multiple.svg","material-alarm-note-off":"material/alarm-note-off.svg","material-alarm-note":"material/alarm-note.svg","material-alarm-off":"material/alarm-off.svg","material-alarm-panel-outline":"material/alarm-panel-outline.svg","material-alarm-panel":"material/alarm-panel.svg","material-alarm-plus":"material/alarm-plus.svg","material-alarm-snooze":"material/alarm-snooze.svg","material-alarm":"material/alarm.svg","material-album":"material/album.svg","material-alert-box-outline":"material/alert-box-outline.svg","material-alert-box":"material/alert-box.svg","material-alert-circle-check-outline":"material/alert-circle-check-outline.svg","material-alert-circle-check":"material/alert-circle-check.svg","material-alert-circle-outline":"material/alert-circle-outline.svg","material-alert-circle":"material/alert-circle.svg","material-alert-decagram-outline":"material/alert-decagram-outline.svg","material-alert-decagram":"material/alert-decagram.svg","material-alert-minus-outline":"material/alert-minus-outline.svg","material-alert-minus":"material/alert-minus.svg","material-alert-octagon-outline":"material/alert-octagon-outline.svg","material-alert-octagon":"material/alert-octagon.svg","material-alert-octagram-outline":"material/alert-octagram-outline.svg","material-alert-octagram":"material/alert-octagram.svg","material-alert-outline":"material/alert-outline.svg","material-alert-plus-outline":"material/alert-plus-outline.svg","material-alert-plus":"material/alert-plus.svg","material-alert-remove-outline":"material/alert-remove-outline.svg","material-alert-remove":"material/alert-remove.svg","material-alert-rhombus-outline":"material/alert-rhombus-outline.svg","material-alert-rhombus":"material/alert-rhombus.svg","material-alert":"material/alert.svg","material-alien-outline":"material/alien-outline.svg","material-alien":"material/alien.svg","material-align-horizontal-center":"material/align-horizontal-center.svg","material-align-horizontal-left":"material/align-horizontal-left.svg","material-align-horizontal-right":"material/align-horizontal-right.svg","material-align-vertical-bottom":"material/align-vertical-bottom.svg","material-align-vertical-center":"material/align-vertical-center.svg","material-align-vertical-top":"material/align-vertical-top.svg","material-all-inclusive":"material/all-inclusive.svg","material-allergy":"material/allergy.svg","material-alpha-a-box-outline":"material/alpha-a-box-outline.svg","material-alpha-a-box":"material/alpha-a-box.svg","material-alpha-a-circle-outline":"material/alpha-a-circle-outline.svg","material-alpha-a-circle":"material/alpha-a-circle.svg","material-alpha-a":"material/alpha-a.svg","material-alpha-b-box-outline":"material/alpha-b-box-outline.svg","material-alpha-b-box":"material/alpha-b-box.svg","material-alpha-b-circle-outline":"material/alpha-b-circle-outline.svg","material-alpha-b-circle":"material/alpha-b-circle.svg","material-alpha-b":"material/alpha-b.svg","material-alpha-c-box-outline":"material/alpha-c-box-outline.svg","material-alpha-c-box":"material/alpha-c-box.svg","material-alpha-c-circle-outline":"material/alpha-c-circle-outline.svg","material-alpha-c-circle":"material/alpha-c-circle.svg","material-alpha-c":"material/alpha-c.svg","material-alpha-d-box-outline":"material/alpha-d-box-outline.svg","material-alpha-d-box":"material/alpha-d-box.svg","material-alpha-d-circle-outline":"material/alpha-d-circle-outline.svg","material-alpha-d-circle":"material/alpha-d-circle.svg","material-alpha-d":"material/alpha-d.svg","material-alpha-e-box-outline":"material/alpha-e-box-outline.svg","material-alpha-e-box":"material/alpha-e-box.svg","material-alpha-e-circle-outline":"material/alpha-e-circle-outline.svg","material-alpha-e-circle":"material/alpha-e-circle.svg","material-alpha-e":"material/alpha-e.svg","material-alpha-f-box-outline":"material/alpha-f-box-outline.svg","material-alpha-f-box":"material/alpha-f-box.svg","material-alpha-f-circle-outline":"material/alpha-f-circle-outline.svg","material-alpha-f-circle":"material/alpha-f-circle.svg","material-alpha-f":"material/alpha-f.svg","material-alpha-g-box-outline":"material/alpha-g-box-outline.svg","material-alpha-g-box":"material/alpha-g-box.svg","material-alpha-g-circle-outline":"material/alpha-g-circle-outline.svg","material-alpha-g-circle":"material/alpha-g-circle.svg","material-alpha-g":"material/alpha-g.svg","material-alpha-h-box-outline":"material/alpha-h-box-outline.svg","material-alpha-h-box":"material/alpha-h-box.svg","material-alpha-h-circle-outline":"material/alpha-h-circle-outline.svg","material-alpha-h-circle":"material/alpha-h-circle.svg","material-alpha-h":"material/alpha-h.svg","material-alpha-i-box-outline":"material/alpha-i-box-outline.svg","material-alpha-i-box":"material/alpha-i-box.svg","material-alpha-i-circle-outline":"material/alpha-i-circle-outline.svg","material-alpha-i-circle":"material/alpha-i-circle.svg","material-alpha-i":"material/alpha-i.svg","material-alpha-j-box-outline":"material/alpha-j-box-outline.svg","material-alpha-j-box":"material/alpha-j-box.svg","material-alpha-j-circle-outline":"material/alpha-j-circle-outline.svg","material-alpha-j-circle":"material/alpha-j-circle.svg","material-alpha-j":"material/alpha-j.svg","material-alpha-k-box-outline":"material/alpha-k-box-outline.svg","material-alpha-k-box":"material/alpha-k-box.svg","material-alpha-k-circle-outline":"material/alpha-k-circle-outline.svg","material-alpha-k-circle":"material/alpha-k-circle.svg","material-alpha-k":"material/alpha-k.svg","material-alpha-l-box-outline":"material/alpha-l-box-outline.svg","material-alpha-l-box":"material/alpha-l-box.svg","material-alpha-l-circle-outline":"material/alpha-l-circle-outline.svg","material-alpha-l-circle":"material/alpha-l-circle.svg","material-alpha-l":"material/alpha-l.svg","material-alpha-m-box-outline":"material/alpha-m-box-outline.svg","material-alpha-m-box":"material/alpha-m-box.svg","material-alpha-m-circle-outline":"material/alpha-m-circle-outline.svg","material-alpha-m-circle":"material/alpha-m-circle.svg","material-alpha-m":"material/alpha-m.svg","material-alpha-n-box-outline":"material/alpha-n-box-outline.svg","material-alpha-n-box":"material/alpha-n-box.svg","material-alpha-n-circle-outline":"material/alpha-n-circle-outline.svg","material-alpha-n-circle":"material/alpha-n-circle.svg","material-alpha-n":"material/alpha-n.svg","material-alpha-o-box-outline":"material/alpha-o-box-outline.svg","material-alpha-o-box":"material/alpha-o-box.svg","material-alpha-o-circle-outline":"material/alpha-o-circle-outline.svg","material-alpha-o-circle":"material/alpha-o-circle.svg","material-alpha-o":"material/alpha-o.svg","material-alpha-p-box-outline":"material/alpha-p-box-outline.svg","material-alpha-p-box":"material/alpha-p-box.svg","material-alpha-p-circle-outline":"material/alpha-p-circle-outline.svg","material-alpha-p-circle":"material/alpha-p-circle.svg","material-alpha-p":"material/alpha-p.svg","material-alpha-q-box-outline":"material/alpha-q-box-outline.svg","material-alpha-q-box":"material/alpha-q-box.svg","material-alpha-q-circle-outline":"material/alpha-q-circle-outline.svg","material-alpha-q-circle":"material/alpha-q-circle.svg","material-alpha-q":"material/alpha-q.svg","material-alpha-r-box-outline":"material/alpha-r-box-outline.svg","material-alpha-r-box":"material/alpha-r-box.svg","material-alpha-r-circle-outline":"material/alpha-r-circle-outline.svg","material-alpha-r-circle":"material/alpha-r-circle.svg","material-alpha-r":"material/alpha-r.svg","material-alpha-s-box-outline":"material/alpha-s-box-outline.svg","material-alpha-s-box":"material/alpha-s-box.svg","material-alpha-s-circle-outline":"material/alpha-s-circle-outline.svg","material-alpha-s-circle":"material/alpha-s-circle.svg","material-alpha-s":"material/alpha-s.svg","material-alpha-t-box-outline":"material/alpha-t-box-outline.svg","material-alpha-t-box":"material/alpha-t-box.svg","material-alpha-t-circle-outline":"material/alpha-t-circle-outline.svg","material-alpha-t-circle":"material/alpha-t-circle.svg","material-alpha-t":"material/alpha-t.svg","material-alpha-u-box-outline":"material/alpha-u-box-outline.svg","material-alpha-u-box":"material/alpha-u-box.svg","material-alpha-u-circle-outline":"material/alpha-u-circle-outline.svg","material-alpha-u-circle":"material/alpha-u-circle.svg","material-alpha-u":"material/alpha-u.svg","material-alpha-v-box-outline":"material/alpha-v-box-outline.svg","material-alpha-v-box":"material/alpha-v-box.svg","material-alpha-v-circle-outline":"material/alpha-v-circle-outline.svg","material-alpha-v-circle":"material/alpha-v-circle.svg","material-alpha-v":"material/alpha-v.svg","material-alpha-w-box-outline":"material/alpha-w-box-outline.svg","material-alpha-w-box":"material/alpha-w-box.svg","material-alpha-w-circle-outline":"material/alpha-w-circle-outline.svg","material-alpha-w-circle":"material/alpha-w-circle.svg","material-alpha-w":"material/alpha-w.svg","material-alpha-x-box-outline":"material/alpha-x-box-outline.svg","material-alpha-x-box":"material/alpha-x-box.svg","material-alpha-x-circle-outline":"material/alpha-x-circle-outline.svg","material-alpha-x-circle":"material/alpha-x-circle.svg","material-alpha-x":"material/alpha-x.svg","material-alpha-y-box-outline":"material/alpha-y-box-outline.svg","material-alpha-y-box":"material/alpha-y-box.svg","material-alpha-y-circle-outline":"material/alpha-y-circle-outline.svg","material-alpha-y-circle":"material/alpha-y-circle.svg","material-alpha-y":"material/alpha-y.svg","material-alpha-z-box-outline":"material/alpha-z-box-outline.svg","material-alpha-z-box":"material/alpha-z-box.svg","material-alpha-z-circle-outline":"material/alpha-z-circle-outline.svg","material-alpha-z-circle":"material/alpha-z-circle.svg","material-alpha-z":"material/alpha-z.svg","material-alpha":"material/alpha.svg","material-alphabet-aurebesh":"material/alphabet-aurebesh.svg","material-alphabet-cyrillic":"material/alphabet-cyrillic.svg","material-alphabet-greek":"material/alphabet-greek.svg","material-alphabet-latin":"material/alphabet-latin.svg","material-alphabet-piqad":"material/alphabet-piqad.svg","material-alphabet-tengwar":"material/alphabet-tengwar.svg","material-alphabetical-off":"material/alphabetical-off.svg","material-alphabetical-variant-off":"material/alphabetical-variant-off.svg","material-alphabetical-variant":"material/alphabetical-variant.svg","material-alphabetical":"material/alphabetical.svg","material-altimeter":"material/altimeter.svg","material-amazon-alexa":"material/amazon-alexa.svg","material-amazon":"material/amazon.svg","material-ambulance":"material/ambulance.svg","material-ammunition":"material/ammunition.svg","material-ampersand":"material/ampersand.svg","material-amplifier-off":"material/amplifier-off.svg","material-amplifier":"material/amplifier.svg","material-anchor":"material/anchor.svg","material-android-auto":"material/android-auto.svg","material-android-debug-bridge":"material/android-debug-bridge.svg","material-android-messages":"material/android-messages.svg","material-android-studio":"material/android-studio.svg","material-android":"material/android.svg","material-angle-acute":"material/angle-acute.svg","material-angle-obtuse":"material/angle-obtuse.svg","material-angle-right":"material/angle-right.svg","material-angular":"material/angular.svg","material-angularjs":"material/angularjs.svg","material-animation-outline":"material/animation-outline.svg","material-animation-play-outline":"material/animation-play-outline.svg","material-animation-play":"material/animation-play.svg","material-animation":"material/animation.svg","material-ansible":"material/ansible.svg","material-antenna":"material/antenna.svg","material-anvil":"material/anvil.svg","material-apache-kafka":"material/apache-kafka.svg","material-api-off":"material/api-off.svg","material-api":"material/api.svg","material-apple-airplay":"material/apple-airplay.svg","material-apple-finder":"material/apple-finder.svg","material-apple-icloud":"material/apple-icloud.svg","material-apple-ios":"material/apple-ios.svg","material-apple-keyboard-caps":"material/apple-keyboard-caps.svg","material-apple-keyboard-command":"material/apple-keyboard-command.svg","material-apple-keyboard-control":"material/apple-keyboard-control.svg","material-apple-keyboard-option":"material/apple-keyboard-option.svg","material-apple-keyboard-shift":"material/apple-keyboard-shift.svg","material-apple-safari":"material/apple-safari.svg","material-apple":"material/apple.svg","material-application-cog":"material/application-cog.svg","material-application-export":"material/application-export.svg","material-application-import":"material/application-import.svg","material-application-settings":"material/application-settings.svg","material-application":"material/application.svg","material-approximately-equal-box":"material/approximately-equal-box.svg","material-approximately-equal":"material/approximately-equal.svg","material-apps-box":"material/apps-box.svg","material-apps":"material/apps.svg","material-arch":"material/arch.svg","material-archive-alert-outline":"material/archive-alert-outline.svg","material-archive-alert":"material/archive-alert.svg","material-archive-arrow-down-outline":"material/archive-arrow-down-outline.svg","material-archive-arrow-down":"material/archive-arrow-down.svg","material-archive-arrow-up-outline":"material/archive-arrow-up-outline.svg","material-archive-arrow-up":"material/archive-arrow-up.svg","material-archive-outline":"material/archive-outline.svg","material-archive":"material/archive.svg","material-arm-flex-outline":"material/arm-flex-outline.svg","material-arm-flex":"material/arm-flex.svg","material-arrange-bring-forward":"material/arrange-bring-forward.svg","material-arrange-bring-to-front":"material/arrange-bring-to-front.svg","material-arrange-send-backward":"material/arrange-send-backward.svg","material-arrange-send-to-back":"material/arrange-send-to-back.svg","material-arrow-all":"material/arrow-all.svg","material-arrow-bottom-left-bold-outline":"material/arrow-bottom-left-bold-outline.svg","material-arrow-bottom-left-thick":"material/arrow-bottom-left-thick.svg","material-arrow-bottom-left-thin-circle-outline":"material/arrow-bottom-left-thin-circle-outline.svg","material-arrow-bottom-left":"material/arrow-bottom-left.svg","material-arrow-bottom-right-bold-outline":"material/arrow-bottom-right-bold-outline.svg","material-arrow-bottom-right-thick":"material/arrow-bottom-right-thick.svg","material-arrow-bottom-right-thin-circle-outline":"material/arrow-bottom-right-thin-circle-outline.svg","material-arrow-bottom-right":"material/arrow-bottom-right.svg","material-arrow-collapse-all":"material/arrow-collapse-all.svg","material-arrow-collapse-down":"material/arrow-collapse-down.svg","material-arrow-collapse-horizontal":"material/arrow-collapse-horizontal.svg","material-arrow-collapse-left":"material/arrow-collapse-left.svg","material-arrow-collapse-right":"material/arrow-collapse-right.svg","material-arrow-collapse-up":"material/arrow-collapse-up.svg","material-arrow-collapse-vertical":"material/arrow-collapse-vertical.svg","material-arrow-collapse":"material/arrow-collapse.svg","material-arrow-decision-auto-outline":"material/arrow-decision-auto-outline.svg","material-arrow-decision-auto":"material/arrow-decision-auto.svg","material-arrow-decision-outline":"material/arrow-decision-outline.svg","material-arrow-decision":"material/arrow-decision.svg","material-arrow-down-bold-box-outline":"material/arrow-down-bold-box-outline.svg","material-arrow-down-bold-box":"material/arrow-down-bold-box.svg","material-arrow-down-bold-circle-outline":"material/arrow-down-bold-circle-outline.svg","material-arrow-down-bold-circle":"material/arrow-down-bold-circle.svg","material-arrow-down-bold-hexagon-outline":"material/arrow-down-bold-hexagon-outline.svg","material-arrow-down-bold-outline":"material/arrow-down-bold-outline.svg","material-arrow-down-bold":"material/arrow-down-bold.svg","material-arrow-down-box":"material/arrow-down-box.svg","material-arrow-down-circle-outline":"material/arrow-down-circle-outline.svg","material-arrow-down-circle":"material/arrow-down-circle.svg","material-arrow-down-drop-circle-outline":"material/arrow-down-drop-circle-outline.svg","material-arrow-down-drop-circle":"material/arrow-down-drop-circle.svg","material-arrow-down-thick":"material/arrow-down-thick.svg","material-arrow-down-thin-circle-outline":"material/arrow-down-thin-circle-outline.svg","material-arrow-down":"material/arrow-down.svg","material-arrow-expand-all":"material/arrow-expand-all.svg","material-arrow-expand-down":"material/arrow-expand-down.svg","material-arrow-expand-horizontal":"material/arrow-expand-horizontal.svg","material-arrow-expand-left":"material/arrow-expand-left.svg","material-arrow-expand-right":"material/arrow-expand-right.svg","material-arrow-expand-up":"material/arrow-expand-up.svg","material-arrow-expand-vertical":"material/arrow-expand-vertical.svg","material-arrow-expand":"material/arrow-expand.svg","material-arrow-horizontal-lock":"material/arrow-horizontal-lock.svg","material-arrow-left-bold-box-outline":"material/arrow-left-bold-box-outline.svg","material-arrow-left-bold-box":"material/arrow-left-bold-box.svg","material-arrow-left-bold-circle-outline":"material/arrow-left-bold-circle-outline.svg","material-arrow-left-bold-circle":"material/arrow-left-bold-circle.svg","material-arrow-left-bold-hexagon-outline":"material/arrow-left-bold-hexagon-outline.svg","material-arrow-left-bold-outline":"material/arrow-left-bold-outline.svg","material-arrow-left-bold":"material/arrow-left-bold.svg","material-arrow-left-box":"material/arrow-left-box.svg","material-arrow-left-circle-outline":"material/arrow-left-circle-outline.svg","material-arrow-left-circle":"material/arrow-left-circle.svg","material-arrow-left-drop-circle-outline":"material/arrow-left-drop-circle-outline.svg","material-arrow-left-drop-circle":"material/arrow-left-drop-circle.svg","material-arrow-left-right-bold-outline":"material/arrow-left-right-bold-outline.svg","material-arrow-left-right-bold":"material/arrow-left-right-bold.svg","material-arrow-left-right":"material/arrow-left-right.svg","material-arrow-left-thick":"material/arrow-left-thick.svg","material-arrow-left-thin-circle-outline":"material/arrow-left-thin-circle-outline.svg","material-arrow-left":"material/arrow-left.svg","material-arrow-right-bold-box-outline":"material/arrow-right-bold-box-outline.svg","material-arrow-right-bold-box":"material/arrow-right-bold-box.svg","material-arrow-right-bold-circle-outline":"material/arrow-right-bold-circle-outline.svg","material-arrow-right-bold-circle":"material/arrow-right-bold-circle.svg","material-arrow-right-bold-hexagon-outline":"material/arrow-right-bold-hexagon-outline.svg","material-arrow-right-bold-outline":"material/arrow-right-bold-outline.svg","material-arrow-right-bold":"material/arrow-right-bold.svg","material-arrow-right-box":"material/arrow-right-box.svg","material-arrow-right-circle-outline":"material/arrow-right-circle-outline.svg","material-arrow-right-circle":"material/arrow-right-circle.svg","material-arrow-right-drop-circle-outline":"material/arrow-right-drop-circle-outline.svg","material-arrow-right-drop-circle":"material/arrow-right-drop-circle.svg","material-arrow-right-thick":"material/arrow-right-thick.svg","material-arrow-right-thin-circle-outline":"material/arrow-right-thin-circle-outline.svg","material-arrow-right":"material/arrow-right.svg","material-arrow-split-horizontal":"material/arrow-split-horizontal.svg","material-arrow-split-vertical":"material/arrow-split-vertical.svg","material-arrow-top-left-bold-outline":"material/arrow-top-left-bold-outline.svg","material-arrow-top-left-bottom-right-bold":"material/arrow-top-left-bottom-right-bold.svg","material-arrow-top-left-bottom-right":"material/arrow-top-left-bottom-right.svg","material-arrow-top-left-thick":"material/arrow-top-left-thick.svg","material-arrow-top-left-thin-circle-outline":"material/arrow-top-left-thin-circle-outline.svg","material-arrow-top-left":"material/arrow-top-left.svg","material-arrow-top-right-bold-outline":"material/arrow-top-right-bold-outline.svg","material-arrow-top-right-bottom-left-bold":"material/arrow-top-right-bottom-left-bold.svg","material-arrow-top-right-bottom-left":"material/arrow-top-right-bottom-left.svg","material-arrow-top-right-thick":"material/arrow-top-right-thick.svg","material-arrow-top-right-thin-circle-outline":"material/arrow-top-right-thin-circle-outline.svg","material-arrow-top-right":"material/arrow-top-right.svg","material-arrow-up-bold-box-outline":"material/arrow-up-bold-box-outline.svg","material-arrow-up-bold-box":"material/arrow-up-bold-box.svg","material-arrow-up-bold-circle-outline":"material/arrow-up-bold-circle-outline.svg","material-arrow-up-bold-circle":"material/arrow-up-bold-circle.svg","material-arrow-up-bold-hexagon-outline":"material/arrow-up-bold-hexagon-outline.svg","material-arrow-up-bold-outline":"material/arrow-up-bold-outline.svg","material-arrow-up-bold":"material/arrow-up-bold.svg","material-arrow-up-box":"material/arrow-up-box.svg","material-arrow-up-circle-outline":"material/arrow-up-circle-outline.svg","material-arrow-up-circle":"material/arrow-up-circle.svg","material-arrow-up-down-bold-outline":"material/arrow-up-down-bold-outline.svg","material-arrow-up-down-bold":"material/arrow-up-down-bold.svg","material-arrow-up-down":"material/arrow-up-down.svg","material-arrow-up-drop-circle-outline":"material/arrow-up-drop-circle-outline.svg","material-arrow-up-drop-circle":"material/arrow-up-drop-circle.svg","material-arrow-up-thick":"material/arrow-up-thick.svg","material-arrow-up-thin-circle-outline":"material/arrow-up-thin-circle-outline.svg","material-arrow-up":"material/arrow-up.svg","material-arrow-vertical-lock":"material/arrow-vertical-lock.svg","material-artstation":"material/artstation.svg","material-aspect-ratio":"material/aspect-ratio.svg","material-assistant":"material/assistant.svg","material-asterisk":"material/asterisk.svg","material-at":"material/at.svg","material-atlassian":"material/atlassian.svg","material-atm":"material/atm.svg","material-atom-variant":"material/atom-variant.svg","material-atom":"material/atom.svg","material-attachment":"material/attachment.svg","material-audio-video-off":"material/audio-video-off.svg","material-audio-video":"material/audio-video.svg","material-augmented-reality":"material/augmented-reality.svg","material-auto-download":"material/auto-download.svg","material-auto-fix":"material/auto-fix.svg","material-auto-upload":"material/auto-upload.svg","material-autorenew":"material/autorenew.svg","material-av-timer":"material/av-timer.svg","material-aws":"material/aws.svg","material-axe":"material/axe.svg","material-axis-arrow-info":"material/axis-arrow-info.svg","material-axis-arrow-lock":"material/axis-arrow-lock.svg","material-axis-arrow":"material/axis-arrow.svg","material-axis-lock":"material/axis-lock.svg","material-axis-x-arrow-lock":"material/axis-x-arrow-lock.svg","material-axis-x-arrow":"material/axis-x-arrow.svg","material-axis-x-rotate-clockwise":"material/axis-x-rotate-clockwise.svg","material-axis-x-rotate-counterclockwise":"material/axis-x-rotate-counterclockwise.svg","material-axis-x-y-arrow-lock":"material/axis-x-y-arrow-lock.svg","material-axis-y-arrow-lock":"material/axis-y-arrow-lock.svg","material-axis-y-arrow":"material/axis-y-arrow.svg","material-axis-y-rotate-clockwise":"material/axis-y-rotate-clockwise.svg","material-axis-y-rotate-counterclockwise":"material/axis-y-rotate-counterclockwise.svg","material-axis-z-arrow-lock":"material/axis-z-arrow-lock.svg","material-axis-z-arrow":"material/axis-z-arrow.svg","material-axis-z-rotate-clockwise":"material/axis-z-rotate-clockwise.svg","material-axis-z-rotate-counterclockwise":"material/axis-z-rotate-counterclockwise.svg","material-axis":"material/axis.svg","material-babel":"material/babel.svg","material-baby-bottle-outline":"material/baby-bottle-outline.svg","material-baby-bottle":"material/baby-bottle.svg","material-baby-buggy":"material/baby-buggy.svg","material-baby-carriage-off":"material/baby-carriage-off.svg","material-baby-carriage":"material/baby-carriage.svg","material-baby-face-outline":"material/baby-face-outline.svg","material-baby-face":"material/baby-face.svg","material-baby":"material/baby.svg","material-backburger":"material/backburger.svg","material-backspace-outline":"material/backspace-outline.svg","material-backspace-reverse-outline":"material/backspace-reverse-outline.svg","material-backspace-reverse":"material/backspace-reverse.svg","material-backspace":"material/backspace.svg","material-backup-restore":"material/backup-restore.svg","material-bacteria-outline":"material/bacteria-outline.svg","material-bacteria":"material/bacteria.svg","material-badge-account-alert-outline":"material/badge-account-alert-outline.svg","material-badge-account-alert":"material/badge-account-alert.svg","material-badge-account-horizontal-outline":"material/badge-account-horizontal-outline.svg","material-badge-account-horizontal":"material/badge-account-horizontal.svg","material-badge-account-outline":"material/badge-account-outline.svg","material-badge-account":"material/badge-account.svg","material-badminton":"material/badminton.svg","material-bag-carry-on-check":"material/bag-carry-on-check.svg","material-bag-carry-on-off":"material/bag-carry-on-off.svg","material-bag-carry-on":"material/bag-carry-on.svg","material-bag-checked":"material/bag-checked.svg","material-bag-personal-off-outline":"material/bag-personal-off-outline.svg","material-bag-personal-off":"material/bag-personal-off.svg","material-bag-personal-outline":"material/bag-personal-outline.svg","material-bag-personal":"material/bag-personal.svg","material-bag-suitcase-off-outline":"material/bag-suitcase-off-outline.svg","material-bag-suitcase-off":"material/bag-suitcase-off.svg","material-bag-suitcase-outline":"material/bag-suitcase-outline.svg","material-bag-suitcase":"material/bag-suitcase.svg","material-baguette":"material/baguette.svg","material-balloon":"material/balloon.svg","material-ballot-outline":"material/ballot-outline.svg","material-ballot-recount-outline":"material/ballot-recount-outline.svg","material-ballot-recount":"material/ballot-recount.svg","material-ballot":"material/ballot.svg","material-bandage":"material/bandage.svg","material-bandcamp":"material/bandcamp.svg","material-bank-check":"material/bank-check.svg","material-bank-minus":"material/bank-minus.svg","material-bank-off-outline":"material/bank-off-outline.svg","material-bank-off":"material/bank-off.svg","material-bank-outline":"material/bank-outline.svg","material-bank-plus":"material/bank-plus.svg","material-bank-remove":"material/bank-remove.svg","material-bank-transfer-in":"material/bank-transfer-in.svg","material-bank-transfer-out":"material/bank-transfer-out.svg","material-bank-transfer":"material/bank-transfer.svg","material-bank":"material/bank.svg","material-barcode-off":"material/barcode-off.svg","material-barcode-scan":"material/barcode-scan.svg","material-barcode":"material/barcode.svg","material-barley-off":"material/barley-off.svg","material-barley":"material/barley.svg","material-barn":"material/barn.svg","material-barrel":"material/barrel.svg","material-baseball-bat":"material/baseball-bat.svg","material-baseball-diamond-outline":"material/baseball-diamond-outline.svg","material-baseball-diamond":"material/baseball-diamond.svg","material-baseball":"material/baseball.svg","material-bash":"material/bash.svg","material-basket-fill":"material/basket-fill.svg","material-basket-minus-outline":"material/basket-minus-outline.svg","material-basket-minus":"material/basket-minus.svg","material-basket-off-outline":"material/basket-off-outline.svg","material-basket-off":"material/basket-off.svg","material-basket-outline":"material/basket-outline.svg","material-basket-plus-outline":"material/basket-plus-outline.svg","material-basket-plus":"material/basket-plus.svg","material-basket-remove-outline":"material/basket-remove-outline.svg","material-basket-remove":"material/basket-remove.svg","material-basket-unfill":"material/basket-unfill.svg","material-basket":"material/basket.svg","material-basketball-hoop-outline":"material/basketball-hoop-outline.svg","material-basketball-hoop":"material/basketball-hoop.svg","material-basketball":"material/basketball.svg","material-bat":"material/bat.svg","material-battery-10-bluetooth":"material/battery-10-bluetooth.svg","material-battery-10":"material/battery-10.svg","material-battery-20-bluetooth":"material/battery-20-bluetooth.svg","material-battery-20":"material/battery-20.svg","material-battery-30-bluetooth":"material/battery-30-bluetooth.svg","material-battery-30":"material/battery-30.svg","material-battery-40-bluetooth":"material/battery-40-bluetooth.svg","material-battery-40":"material/battery-40.svg","material-battery-50-bluetooth":"material/battery-50-bluetooth.svg","material-battery-50":"material/battery-50.svg","material-battery-60-bluetooth":"material/battery-60-bluetooth.svg","material-battery-60":"material/battery-60.svg","material-battery-70-bluetooth":"material/battery-70-bluetooth.svg","material-battery-70":"material/battery-70.svg","material-battery-80-bluetooth":"material/battery-80-bluetooth.svg","material-battery-80":"material/battery-80.svg","material-battery-90-bluetooth":"material/battery-90-bluetooth.svg","material-battery-90":"material/battery-90.svg","material-battery-alert-bluetooth":"material/battery-alert-bluetooth.svg","material-battery-alert-variant-outline":"material/battery-alert-variant-outline.svg","material-battery-alert-variant":"material/battery-alert-variant.svg","material-battery-alert":"material/battery-alert.svg","material-battery-bluetooth-variant":"material/battery-bluetooth-variant.svg","material-battery-bluetooth":"material/battery-bluetooth.svg","material-battery-charging-10":"material/battery-charging-10.svg","material-battery-charging-100":"material/battery-charging-100.svg","material-battery-charging-20":"material/battery-charging-20.svg","material-battery-charging-30":"material/battery-charging-30.svg","material-battery-charging-40":"material/battery-charging-40.svg","material-battery-charging-50":"material/battery-charging-50.svg","material-battery-charging-60":"material/battery-charging-60.svg","material-battery-charging-70":"material/battery-charging-70.svg","material-battery-charging-80":"material/battery-charging-80.svg","material-battery-charging-90":"material/battery-charging-90.svg","material-battery-charging-high":"material/battery-charging-high.svg","material-battery-charging-low":"material/battery-charging-low.svg","material-battery-charging-medium":"material/battery-charging-medium.svg","material-battery-charging-outline":"material/battery-charging-outline.svg","material-battery-charging-wireless-10":"material/battery-charging-wireless-10.svg","material-battery-charging-wireless-20":"material/battery-charging-wireless-20.svg","material-battery-charging-wireless-30":"material/battery-charging-wireless-30.svg","material-battery-charging-wireless-40":"material/battery-charging-wireless-40.svg","material-battery-charging-wireless-50":"material/battery-charging-wireless-50.svg","material-battery-charging-wireless-60":"material/battery-charging-wireless-60.svg","material-battery-charging-wireless-70":"material/battery-charging-wireless-70.svg","material-battery-charging-wireless-80":"material/battery-charging-wireless-80.svg","material-battery-charging-wireless-90":"material/battery-charging-wireless-90.svg","material-battery-charging-wireless-alert":"material/battery-charging-wireless-alert.svg","material-battery-charging-wireless-outline":"material/battery-charging-wireless-outline.svg","material-battery-charging-wireless":"material/battery-charging-wireless.svg","material-battery-charging":"material/battery-charging.svg","material-battery-heart-outline":"material/battery-heart-outline.svg","material-battery-heart-variant":"material/battery-heart-variant.svg","material-battery-heart":"material/battery-heart.svg","material-battery-high":"material/battery-high.svg","material-battery-low":"material/battery-low.svg","material-battery-medium":"material/battery-medium.svg","material-battery-minus":"material/battery-minus.svg","material-battery-negative":"material/battery-negative.svg","material-battery-off-outline":"material/battery-off-outline.svg","material-battery-off":"material/battery-off.svg","material-battery-outline":"material/battery-outline.svg","material-battery-plus":"material/battery-plus.svg","material-battery-positive":"material/battery-positive.svg","material-battery-unknown-bluetooth":"material/battery-unknown-bluetooth.svg","material-battery-unknown":"material/battery-unknown.svg","material-battery":"material/battery.svg","material-battlenet":"material/battlenet.svg","material-beach":"material/beach.svg","material-beaker-alert-outline":"material/beaker-alert-outline.svg","material-beaker-alert":"material/beaker-alert.svg","material-beaker-check-outline":"material/beaker-check-outline.svg","material-beaker-check":"material/beaker-check.svg","material-beaker-minus-outline":"material/beaker-minus-outline.svg","material-beaker-minus":"material/beaker-minus.svg","material-beaker-outline":"material/beaker-outline.svg","material-beaker-plus-outline":"material/beaker-plus-outline.svg","material-beaker-plus":"material/beaker-plus.svg","material-beaker-question-outline":"material/beaker-question-outline.svg","material-beaker-question":"material/beaker-question.svg","material-beaker-remove-outline":"material/beaker-remove-outline.svg","material-beaker-remove":"material/beaker-remove.svg","material-beaker":"material/beaker.svg","material-bed-double-outline":"material/bed-double-outline.svg","material-bed-double":"material/bed-double.svg","material-bed-empty":"material/bed-empty.svg","material-bed-king-outline":"material/bed-king-outline.svg","material-bed-king":"material/bed-king.svg","material-bed-outline":"material/bed-outline.svg","material-bed-queen-outline":"material/bed-queen-outline.svg","material-bed-queen":"material/bed-queen.svg","material-bed-single-outline":"material/bed-single-outline.svg","material-bed-single":"material/bed-single.svg","material-bed":"material/bed.svg","material-bee-flower":"material/bee-flower.svg","material-bee":"material/bee.svg","material-beehive-off-outline":"material/beehive-off-outline.svg","material-beehive-outline":"material/beehive-outline.svg","material-beekeeper":"material/beekeeper.svg","material-beer-outline":"material/beer-outline.svg","material-beer":"material/beer.svg","material-bell-alert-outline":"material/bell-alert-outline.svg","material-bell-alert":"material/bell-alert.svg","material-bell-cancel-outline":"material/bell-cancel-outline.svg","material-bell-cancel":"material/bell-cancel.svg","material-bell-check-outline":"material/bell-check-outline.svg","material-bell-check":"material/bell-check.svg","material-bell-circle-outline":"material/bell-circle-outline.svg","material-bell-circle":"material/bell-circle.svg","material-bell-minus-outline":"material/bell-minus-outline.svg","material-bell-minus":"material/bell-minus.svg","material-bell-off-outline":"material/bell-off-outline.svg","material-bell-off":"material/bell-off.svg","material-bell-outline":"material/bell-outline.svg","material-bell-plus-outline":"material/bell-plus-outline.svg","material-bell-plus":"material/bell-plus.svg","material-bell-remove-outline":"material/bell-remove-outline.svg","material-bell-remove":"material/bell-remove.svg","material-bell-ring-outline":"material/bell-ring-outline.svg","material-bell-ring":"material/bell-ring.svg","material-bell-sleep-outline":"material/bell-sleep-outline.svg","material-bell-sleep":"material/bell-sleep.svg","material-bell":"material/bell.svg","material-beta":"material/beta.svg","material-betamax":"material/betamax.svg","material-biathlon":"material/biathlon.svg","material-bicycle-basket":"material/bicycle-basket.svg","material-bicycle-electric":"material/bicycle-electric.svg","material-bicycle-penny-farthing":"material/bicycle-penny-farthing.svg","material-bicycle":"material/bicycle.svg","material-bike-fast":"material/bike-fast.svg","material-bike":"material/bike.svg","material-billboard":"material/billboard.svg","material-billiards-rack":"material/billiards-rack.svg","material-billiards":"material/billiards.svg","material-binoculars":"material/binoculars.svg","material-bio":"material/bio.svg","material-biohazard":"material/biohazard.svg","material-bird":"material/bird.svg","material-bitbucket":"material/bitbucket.svg","material-bitcoin":"material/bitcoin.svg","material-black-mesa":"material/black-mesa.svg","material-blender-software":"material/blender-software.svg","material-blender":"material/blender.svg","material-blinds-open":"material/blinds-open.svg","material-blinds":"material/blinds.svg","material-block-helper":"material/block-helper.svg","material-blogger":"material/blogger.svg","material-blood-bag":"material/blood-bag.svg","material-bluetooth-audio":"material/bluetooth-audio.svg","material-bluetooth-connect":"material/bluetooth-connect.svg","material-bluetooth-off":"material/bluetooth-off.svg","material-bluetooth-settings":"material/bluetooth-settings.svg","material-bluetooth-transfer":"material/bluetooth-transfer.svg","material-bluetooth":"material/bluetooth.svg","material-blur-linear":"material/blur-linear.svg","material-blur-off":"material/blur-off.svg","material-blur-radial":"material/blur-radial.svg","material-blur":"material/blur.svg","material-bolnisi-cross":"material/bolnisi-cross.svg","material-bolt":"material/bolt.svg","material-bomb-off":"material/bomb-off.svg","material-bomb":"material/bomb.svg","material-bone":"material/bone.svg","material-book-account-outline":"material/book-account-outline.svg","material-book-account":"material/book-account.svg","material-book-alert-outline":"material/book-alert-outline.svg","material-book-alert":"material/book-alert.svg","material-book-alphabet":"material/book-alphabet.svg","material-book-arrow-down-outline":"material/book-arrow-down-outline.svg","material-book-arrow-down":"material/book-arrow-down.svg","material-book-arrow-left-outline":"material/book-arrow-left-outline.svg","material-book-arrow-left":"material/book-arrow-left.svg","material-book-arrow-right-outline":"material/book-arrow-right-outline.svg","material-book-arrow-right":"material/book-arrow-right.svg","material-book-arrow-up-outline":"material/book-arrow-up-outline.svg","material-book-arrow-up":"material/book-arrow-up.svg","material-book-cancel-outline":"material/book-cancel-outline.svg","material-book-cancel":"material/book-cancel.svg","material-book-check-outline":"material/book-check-outline.svg","material-book-check":"material/book-check.svg","material-book-clock-outline":"material/book-clock-outline.svg","material-book-clock":"material/book-clock.svg","material-book-cog-outline":"material/book-cog-outline.svg","material-book-cog":"material/book-cog.svg","material-book-cross":"material/book-cross.svg","material-book-edit-outline":"material/book-edit-outline.svg","material-book-edit":"material/book-edit.svg","material-book-education-outline":"material/book-education-outline.svg","material-book-education":"material/book-education.svg","material-book-information-variant":"material/book-information-variant.svg","material-book-lock-open-outline":"material/book-lock-open-outline.svg","material-book-lock-open":"material/book-lock-open.svg","material-book-lock-outline":"material/book-lock-outline.svg","material-book-lock":"material/book-lock.svg","material-book-marker-outline":"material/book-marker-outline.svg","material-book-marker":"material/book-marker.svg","material-book-minus-multiple-outline":"material/book-minus-multiple-outline.svg","material-book-minus-multiple":"material/book-minus-multiple.svg","material-book-minus-outline":"material/book-minus-outline.svg","material-book-minus":"material/book-minus.svg","material-book-multiple-outline":"material/book-multiple-outline.svg","material-book-multiple":"material/book-multiple.svg","material-book-music-outline":"material/book-music-outline.svg","material-book-music":"material/book-music.svg","material-book-off-outline":"material/book-off-outline.svg","material-book-off":"material/book-off.svg","material-book-open-blank-variant":"material/book-open-blank-variant.svg","material-book-open-outline":"material/book-open-outline.svg","material-book-open-page-variant-outline":"material/book-open-page-variant-outline.svg","material-book-open-page-variant":"material/book-open-page-variant.svg","material-book-open-variant":"material/book-open-variant.svg","material-book-open":"material/book-open.svg","material-book-outline":"material/book-outline.svg","material-book-play-outline":"material/book-play-outline.svg","material-book-play":"material/book-play.svg","material-book-plus-multiple-outline":"material/book-plus-multiple-outline.svg","material-book-plus-multiple":"material/book-plus-multiple.svg","material-book-plus-outline":"material/book-plus-outline.svg","material-book-plus":"material/book-plus.svg","material-book-refresh-outline":"material/book-refresh-outline.svg","material-book-refresh":"material/book-refresh.svg","material-book-remove-multiple-outline":"material/book-remove-multiple-outline.svg","material-book-remove-multiple":"material/book-remove-multiple.svg","material-book-remove-outline":"material/book-remove-outline.svg","material-book-remove":"material/book-remove.svg","material-book-search-outline":"material/book-search-outline.svg","material-book-search":"material/book-search.svg","material-book-settings-outline":"material/book-settings-outline.svg","material-book-settings":"material/book-settings.svg","material-book-sync-outline":"material/book-sync-outline.svg","material-book-sync":"material/book-sync.svg","material-book-variant-multiple":"material/book-variant-multiple.svg","material-book-variant":"material/book-variant.svg","material-book":"material/book.svg","material-bookmark-check-outline":"material/bookmark-check-outline.svg","material-bookmark-check":"material/bookmark-check.svg","material-bookmark-minus-outline":"material/bookmark-minus-outline.svg","material-bookmark-minus":"material/bookmark-minus.svg","material-bookmark-multiple-outline":"material/bookmark-multiple-outline.svg","material-bookmark-multiple":"material/bookmark-multiple.svg","material-bookmark-music-outline":"material/bookmark-music-outline.svg","material-bookmark-music":"material/bookmark-music.svg","material-bookmark-off-outline":"material/bookmark-off-outline.svg","material-bookmark-off":"material/bookmark-off.svg","material-bookmark-outline":"material/bookmark-outline.svg","material-bookmark-plus-outline":"material/bookmark-plus-outline.svg","material-bookmark-plus":"material/bookmark-plus.svg","material-bookmark-remove-outline":"material/bookmark-remove-outline.svg","material-bookmark-remove":"material/bookmark-remove.svg","material-bookmark":"material/bookmark.svg","material-bookshelf":"material/bookshelf.svg","material-boom-gate-alert-outline":"material/boom-gate-alert-outline.svg","material-boom-gate-alert":"material/boom-gate-alert.svg","material-boom-gate-down-outline":"material/boom-gate-down-outline.svg","material-boom-gate-down":"material/boom-gate-down.svg","material-boom-gate-outline":"material/boom-gate-outline.svg","material-boom-gate-up-outline":"material/boom-gate-up-outline.svg","material-boom-gate-up":"material/boom-gate-up.svg","material-boom-gate":"material/boom-gate.svg","material-boombox":"material/boombox.svg","material-boomerang":"material/boomerang.svg","material-bootstrap":"material/bootstrap.svg","material-border-all-variant":"material/border-all-variant.svg","material-border-all":"material/border-all.svg","material-border-bottom-variant":"material/border-bottom-variant.svg","material-border-bottom":"material/border-bottom.svg","material-border-color":"material/border-color.svg","material-border-horizontal":"material/border-horizontal.svg","material-border-inside":"material/border-inside.svg","material-border-left-variant":"material/border-left-variant.svg","material-border-left":"material/border-left.svg","material-border-none-variant":"material/border-none-variant.svg","material-border-none":"material/border-none.svg","material-border-outside":"material/border-outside.svg","material-border-right-variant":"material/border-right-variant.svg","material-border-right":"material/border-right.svg","material-border-style":"material/border-style.svg","material-border-top-variant":"material/border-top-variant.svg","material-border-top":"material/border-top.svg","material-border-vertical":"material/border-vertical.svg","material-bottle-soda-classic-outline":"material/bottle-soda-classic-outline.svg","material-bottle-soda-classic":"material/bottle-soda-classic.svg","material-bottle-soda-outline":"material/bottle-soda-outline.svg","material-bottle-soda":"material/bottle-soda.svg","material-bottle-tonic-outline":"material/bottle-tonic-outline.svg","material-bottle-tonic-plus-outline":"material/bottle-tonic-plus-outline.svg","material-bottle-tonic-plus":"material/bottle-tonic-plus.svg","material-bottle-tonic-skull-outline":"material/bottle-tonic-skull-outline.svg","material-bottle-tonic-skull":"material/bottle-tonic-skull.svg","material-bottle-tonic":"material/bottle-tonic.svg","material-bottle-wine-outline":"material/bottle-wine-outline.svg","material-bottle-wine":"material/bottle-wine.svg","material-bow-tie":"material/bow-tie.svg","material-bowl-mix-outline":"material/bowl-mix-outline.svg","material-bowl-mix":"material/bowl-mix.svg","material-bowl-outline":"material/bowl-outline.svg","material-bowl":"material/bowl.svg","material-bowling":"material/bowling.svg","material-box-cutter-off":"material/box-cutter-off.svg","material-box-cutter":"material/box-cutter.svg","material-box-shadow":"material/box-shadow.svg","material-box":"material/box.svg","material-boxing-glove":"material/boxing-glove.svg","material-braille":"material/braille.svg","material-brain":"material/brain.svg","material-bread-slice-outline":"material/bread-slice-outline.svg","material-bread-slice":"material/bread-slice.svg","material-bridge":"material/bridge.svg","material-briefcase-account-outline":"material/briefcase-account-outline.svg","material-briefcase-account":"material/briefcase-account.svg","material-briefcase-check-outline":"material/briefcase-check-outline.svg","material-briefcase-check":"material/briefcase-check.svg","material-briefcase-clock-outline":"material/briefcase-clock-outline.svg","material-briefcase-clock":"material/briefcase-clock.svg","material-briefcase-download-outline":"material/briefcase-download-outline.svg","material-briefcase-download":"material/briefcase-download.svg","material-briefcase-edit-outline":"material/briefcase-edit-outline.svg","material-briefcase-edit":"material/briefcase-edit.svg","material-briefcase-minus-outline":"material/briefcase-minus-outline.svg","material-briefcase-minus":"material/briefcase-minus.svg","material-briefcase-off-outline":"material/briefcase-off-outline.svg","material-briefcase-off":"material/briefcase-off.svg","material-briefcase-outline":"material/briefcase-outline.svg","material-briefcase-plus-outline":"material/briefcase-plus-outline.svg","material-briefcase-plus":"material/briefcase-plus.svg","material-briefcase-remove-outline":"material/briefcase-remove-outline.svg","material-briefcase-remove":"material/briefcase-remove.svg","material-briefcase-search-outline":"material/briefcase-search-outline.svg","material-briefcase-search":"material/briefcase-search.svg","material-briefcase-upload-outline":"material/briefcase-upload-outline.svg","material-briefcase-upload":"material/briefcase-upload.svg","material-briefcase-variant-off-outline":"material/briefcase-variant-off-outline.svg","material-briefcase-variant-off":"material/briefcase-variant-off.svg","material-briefcase-variant-outline":"material/briefcase-variant-outline.svg","material-briefcase-variant":"material/briefcase-variant.svg","material-briefcase":"material/briefcase.svg","material-brightness-1":"material/brightness-1.svg","material-brightness-2":"material/brightness-2.svg","material-brightness-3":"material/brightness-3.svg","material-brightness-4":"material/brightness-4.svg","material-brightness-5":"material/brightness-5.svg","material-brightness-6":"material/brightness-6.svg","material-brightness-7":"material/brightness-7.svg","material-brightness-auto":"material/brightness-auto.svg","material-brightness-percent":"material/brightness-percent.svg","material-broadcast-off":"material/broadcast-off.svg","material-broadcast":"material/broadcast.svg","material-broom":"material/broom.svg","material-brush":"material/brush.svg","material-bucket-outline":"material/bucket-outline.svg","material-bucket":"material/bucket.svg","material-buddhism":"material/buddhism.svg","material-buffer":"material/buffer.svg","material-buffet":"material/buffet.svg","material-bug-check-outline":"material/bug-check-outline.svg","material-bug-check":"material/bug-check.svg","material-bug-outline":"material/bug-outline.svg","material-bug":"material/bug.svg","material-bugle":"material/bugle.svg","material-bulldozer":"material/bulldozer.svg","material-bullet":"material/bullet.svg","material-bulletin-board":"material/bulletin-board.svg","material-bullhorn-outline":"material/bullhorn-outline.svg","material-bullhorn":"material/bullhorn.svg","material-bullseye-arrow":"material/bullseye-arrow.svg","material-bullseye":"material/bullseye.svg","material-bulma":"material/bulma.svg","material-bunk-bed-outline":"material/bunk-bed-outline.svg","material-bunk-bed":"material/bunk-bed.svg","material-bus-alert":"material/bus-alert.svg","material-bus-articulated-end":"material/bus-articulated-end.svg","material-bus-articulated-front":"material/bus-articulated-front.svg","material-bus-clock":"material/bus-clock.svg","material-bus-double-decker":"material/bus-double-decker.svg","material-bus-marker":"material/bus-marker.svg","material-bus-multiple":"material/bus-multiple.svg","material-bus-school":"material/bus-school.svg","material-bus-side":"material/bus-side.svg","material-bus-stop-covered":"material/bus-stop-covered.svg","material-bus-stop-uncovered":"material/bus-stop-uncovered.svg","material-bus-stop":"material/bus-stop.svg","material-bus":"material/bus.svg","material-butterfly-outline":"material/butterfly-outline.svg","material-butterfly":"material/butterfly.svg","material-cable-data":"material/cable-data.svg","material-cached":"material/cached.svg","material-cactus":"material/cactus.svg","material-cake-layered":"material/cake-layered.svg","material-cake-variant":"material/cake-variant.svg","material-cake":"material/cake.svg","material-calculator-variant-outline":"material/calculator-variant-outline.svg","material-calculator-variant":"material/calculator-variant.svg","material-calculator":"material/calculator.svg","material-calendar-account-outline":"material/calendar-account-outline.svg","material-calendar-account":"material/calendar-account.svg","material-calendar-alert":"material/calendar-alert.svg","material-calendar-arrow-left":"material/calendar-arrow-left.svg","material-calendar-arrow-right":"material/calendar-arrow-right.svg","material-calendar-blank-multiple":"material/calendar-blank-multiple.svg","material-calendar-blank-outline":"material/calendar-blank-outline.svg","material-calendar-blank":"material/calendar-blank.svg","material-calendar-check-outline":"material/calendar-check-outline.svg","material-calendar-check":"material/calendar-check.svg","material-calendar-clock-outline":"material/calendar-clock-outline.svg","material-calendar-clock":"material/calendar-clock.svg","material-calendar-cursor":"material/calendar-cursor.svg","material-calendar-edit":"material/calendar-edit.svg","material-calendar-end":"material/calendar-end.svg","material-calendar-export":"material/calendar-export.svg","material-calendar-heart":"material/calendar-heart.svg","material-calendar-import":"material/calendar-import.svg","material-calendar-lock-outline":"material/calendar-lock-outline.svg","material-calendar-lock":"material/calendar-lock.svg","material-calendar-minus":"material/calendar-minus.svg","material-calendar-month-outline":"material/calendar-month-outline.svg","material-calendar-month":"material/calendar-month.svg","material-calendar-multiple-check":"material/calendar-multiple-check.svg","material-calendar-multiple":"material/calendar-multiple.svg","material-calendar-multiselect":"material/calendar-multiselect.svg","material-calendar-outline":"material/calendar-outline.svg","material-calendar-plus":"material/calendar-plus.svg","material-calendar-question":"material/calendar-question.svg","material-calendar-range-outline":"material/calendar-range-outline.svg","material-calendar-range":"material/calendar-range.svg","material-calendar-refresh-outline":"material/calendar-refresh-outline.svg","material-calendar-refresh":"material/calendar-refresh.svg","material-calendar-remove-outline":"material/calendar-remove-outline.svg","material-calendar-remove":"material/calendar-remove.svg","material-calendar-search":"material/calendar-search.svg","material-calendar-star":"material/calendar-star.svg","material-calendar-start":"material/calendar-start.svg","material-calendar-sync-outline":"material/calendar-sync-outline.svg","material-calendar-sync":"material/calendar-sync.svg","material-calendar-text-outline":"material/calendar-text-outline.svg","material-calendar-text":"material/calendar-text.svg","material-calendar-today":"material/calendar-today.svg","material-calendar-week-begin":"material/calendar-week-begin.svg","material-calendar-week":"material/calendar-week.svg","material-calendar-weekend-outline":"material/calendar-weekend-outline.svg","material-calendar-weekend":"material/calendar-weekend.svg","material-calendar":"material/calendar.svg","material-call-made":"material/call-made.svg","material-call-merge":"material/call-merge.svg","material-call-missed":"material/call-missed.svg","material-call-received":"material/call-received.svg","material-call-split":"material/call-split.svg","material-camcorder-off":"material/camcorder-off.svg","material-camcorder":"material/camcorder.svg","material-camera-account":"material/camera-account.svg","material-camera-burst":"material/camera-burst.svg","material-camera-control":"material/camera-control.svg","material-camera-enhance-outline":"material/camera-enhance-outline.svg","material-camera-enhance":"material/camera-enhance.svg","material-camera-flip-outline":"material/camera-flip-outline.svg","material-camera-flip":"material/camera-flip.svg","material-camera-front-variant":"material/camera-front-variant.svg","material-camera-front":"material/camera-front.svg","material-camera-gopro":"material/camera-gopro.svg","material-camera-image":"material/camera-image.svg","material-camera-iris":"material/camera-iris.svg","material-camera-metering-center":"material/camera-metering-center.svg","material-camera-metering-matrix":"material/camera-metering-matrix.svg","material-camera-metering-partial":"material/camera-metering-partial.svg","material-camera-metering-spot":"material/camera-metering-spot.svg","material-camera-off":"material/camera-off.svg","material-camera-outline":"material/camera-outline.svg","material-camera-party-mode":"material/camera-party-mode.svg","material-camera-plus-outline":"material/camera-plus-outline.svg","material-camera-plus":"material/camera-plus.svg","material-camera-rear-variant":"material/camera-rear-variant.svg","material-camera-rear":"material/camera-rear.svg","material-camera-retake-outline":"material/camera-retake-outline.svg","material-camera-retake":"material/camera-retake.svg","material-camera-switch-outline":"material/camera-switch-outline.svg","material-camera-switch":"material/camera-switch.svg","material-camera-timer":"material/camera-timer.svg","material-camera-wireless-outline":"material/camera-wireless-outline.svg","material-camera-wireless":"material/camera-wireless.svg","material-camera":"material/camera.svg","material-campfire":"material/campfire.svg","material-cancel":"material/cancel.svg","material-candle":"material/candle.svg","material-candycane":"material/candycane.svg","material-cannabis-off":"material/cannabis-off.svg","material-cannabis":"material/cannabis.svg","material-caps-lock":"material/caps-lock.svg","material-car-2-plus":"material/car-2-plus.svg","material-car-3-plus":"material/car-3-plus.svg","material-car-arrow-left":"material/car-arrow-left.svg","material-car-arrow-right":"material/car-arrow-right.svg","material-car-back":"material/car-back.svg","material-car-battery":"material/car-battery.svg","material-car-brake-abs":"material/car-brake-abs.svg","material-car-brake-alert":"material/car-brake-alert.svg","material-car-brake-hold":"material/car-brake-hold.svg","material-car-brake-parking":"material/car-brake-parking.svg","material-car-brake-retarder":"material/car-brake-retarder.svg","material-car-child-seat":"material/car-child-seat.svg","material-car-clutch":"material/car-clutch.svg","material-car-cog":"material/car-cog.svg","material-car-connected":"material/car-connected.svg","material-car-convertible":"material/car-convertible.svg","material-car-coolant-level":"material/car-coolant-level.svg","material-car-cruise-control":"material/car-cruise-control.svg","material-car-defrost-front":"material/car-defrost-front.svg","material-car-defrost-rear":"material/car-defrost-rear.svg","material-car-door-lock":"material/car-door-lock.svg","material-car-door":"material/car-door.svg","material-car-electric-outline":"material/car-electric-outline.svg","material-car-electric":"material/car-electric.svg","material-car-emergency":"material/car-emergency.svg","material-car-esp":"material/car-esp.svg","material-car-estate":"material/car-estate.svg","material-car-hatchback":"material/car-hatchback.svg","material-car-info":"material/car-info.svg","material-car-key":"material/car-key.svg","material-car-lifted-pickup":"material/car-lifted-pickup.svg","material-car-light-dimmed":"material/car-light-dimmed.svg","material-car-light-fog":"material/car-light-fog.svg","material-car-light-high":"material/car-light-high.svg","material-car-limousine":"material/car-limousine.svg","material-car-multiple":"material/car-multiple.svg","material-car-off":"material/car-off.svg","material-car-outline":"material/car-outline.svg","material-car-parking-lights":"material/car-parking-lights.svg","material-car-pickup":"material/car-pickup.svg","material-car-seat-cooler":"material/car-seat-cooler.svg","material-car-seat-heater":"material/car-seat-heater.svg","material-car-seat":"material/car-seat.svg","material-car-settings":"material/car-settings.svg","material-car-shift-pattern":"material/car-shift-pattern.svg","material-car-side":"material/car-side.svg","material-car-sports":"material/car-sports.svg","material-car-tire-alert":"material/car-tire-alert.svg","material-car-traction-control":"material/car-traction-control.svg","material-car-turbocharger":"material/car-turbocharger.svg","material-car-wash":"material/car-wash.svg","material-car-windshield-outline":"material/car-windshield-outline.svg","material-car-windshield":"material/car-windshield.svg","material-car":"material/car.svg","material-carabiner":"material/carabiner.svg","material-caravan":"material/caravan.svg","material-card-account-details-outline":"material/card-account-details-outline.svg","material-card-account-details-star-outline":"material/card-account-details-star-outline.svg","material-card-account-details-star":"material/card-account-details-star.svg","material-card-account-details":"material/card-account-details.svg","material-card-account-mail-outline":"material/card-account-mail-outline.svg","material-card-account-mail":"material/card-account-mail.svg","material-card-account-phone-outline":"material/card-account-phone-outline.svg","material-card-account-phone":"material/card-account-phone.svg","material-card-bulleted-off-outline":"material/card-bulleted-off-outline.svg","material-card-bulleted-off":"material/card-bulleted-off.svg","material-card-bulleted-outline":"material/card-bulleted-outline.svg","material-card-bulleted-settings-outline":"material/card-bulleted-settings-outline.svg","material-card-bulleted-settings":"material/card-bulleted-settings.svg","material-card-bulleted":"material/card-bulleted.svg","material-card-minus-outline":"material/card-minus-outline.svg","material-card-minus":"material/card-minus.svg","material-card-off-outline":"material/card-off-outline.svg","material-card-off":"material/card-off.svg","material-card-outline":"material/card-outline.svg","material-card-plus-outline":"material/card-plus-outline.svg","material-card-plus":"material/card-plus.svg","material-card-remove-outline":"material/card-remove-outline.svg","material-card-remove":"material/card-remove.svg","material-card-search-outline":"material/card-search-outline.svg","material-card-search":"material/card-search.svg","material-card-text-outline":"material/card-text-outline.svg","material-card-text":"material/card-text.svg","material-card":"material/card.svg","material-cards-club":"material/cards-club.svg","material-cards-diamond-outline":"material/cards-diamond-outline.svg","material-cards-diamond":"material/cards-diamond.svg","material-cards-heart":"material/cards-heart.svg","material-cards-outline":"material/cards-outline.svg","material-cards-playing-outline":"material/cards-playing-outline.svg","material-cards-spade":"material/cards-spade.svg","material-cards-variant":"material/cards-variant.svg","material-cards":"material/cards.svg","material-carrot":"material/carrot.svg","material-cart-arrow-down":"material/cart-arrow-down.svg","material-cart-arrow-right":"material/cart-arrow-right.svg","material-cart-arrow-up":"material/cart-arrow-up.svg","material-cart-check":"material/cart-check.svg","material-cart-minus":"material/cart-minus.svg","material-cart-off":"material/cart-off.svg","material-cart-outline":"material/cart-outline.svg","material-cart-plus":"material/cart-plus.svg","material-cart-remove":"material/cart-remove.svg","material-cart-variant":"material/cart-variant.svg","material-cart":"material/cart.svg","material-case-sensitive-alt":"material/case-sensitive-alt.svg","material-cash-100":"material/cash-100.svg","material-cash-check":"material/cash-check.svg","material-cash-lock-open":"material/cash-lock-open.svg","material-cash-lock":"material/cash-lock.svg","material-cash-marker":"material/cash-marker.svg","material-cash-minus":"material/cash-minus.svg","material-cash-multiple":"material/cash-multiple.svg","material-cash-plus":"material/cash-plus.svg","material-cash-refund":"material/cash-refund.svg","material-cash-register":"material/cash-register.svg","material-cash-remove":"material/cash-remove.svg","material-cash-usd-outline":"material/cash-usd-outline.svg","material-cash-usd":"material/cash-usd.svg","material-cash":"material/cash.svg","material-cassette":"material/cassette.svg","material-cast-audio":"material/cast-audio.svg","material-cast-connected":"material/cast-connected.svg","material-cast-education":"material/cast-education.svg","material-cast-off":"material/cast-off.svg","material-cast":"material/cast.svg","material-castle":"material/castle.svg","material-cat":"material/cat.svg","material-cctv":"material/cctv.svg","material-ceiling-light":"material/ceiling-light.svg","material-cellphone-android":"material/cellphone-android.svg","material-cellphone-arrow-down":"material/cellphone-arrow-down.svg","material-cellphone-basic":"material/cellphone-basic.svg","material-cellphone-charging":"material/cellphone-charging.svg","material-cellphone-cog":"material/cellphone-cog.svg","material-cellphone-dock":"material/cellphone-dock.svg","material-cellphone-erase":"material/cellphone-erase.svg","material-cellphone-information":"material/cellphone-information.svg","material-cellphone-iphone":"material/cellphone-iphone.svg","material-cellphone-key":"material/cellphone-key.svg","material-cellphone-link-off":"material/cellphone-link-off.svg","material-cellphone-link":"material/cellphone-link.svg","material-cellphone-lock":"material/cellphone-lock.svg","material-cellphone-message-off":"material/cellphone-message-off.svg","material-cellphone-message":"material/cellphone-message.svg","material-cellphone-nfc-off":"material/cellphone-nfc-off.svg","material-cellphone-nfc":"material/cellphone-nfc.svg","material-cellphone-off":"material/cellphone-off.svg","material-cellphone-play":"material/cellphone-play.svg","material-cellphone-screenshot":"material/cellphone-screenshot.svg","material-cellphone-settings":"material/cellphone-settings.svg","material-cellphone-sound":"material/cellphone-sound.svg","material-cellphone-text":"material/cellphone-text.svg","material-cellphone-wireless":"material/cellphone-wireless.svg","material-cellphone":"material/cellphone.svg","material-celtic-cross":"material/celtic-cross.svg","material-centos":"material/centos.svg","material-certificate-outline":"material/certificate-outline.svg","material-certificate":"material/certificate.svg","material-chair-rolling":"material/chair-rolling.svg","material-chair-school":"material/chair-school.svg","material-charity":"material/charity.svg","material-chart-arc":"material/chart-arc.svg","material-chart-areaspline-variant":"material/chart-areaspline-variant.svg","material-chart-areaspline":"material/chart-areaspline.svg","material-chart-bar-stacked":"material/chart-bar-stacked.svg","material-chart-bar":"material/chart-bar.svg","material-chart-bell-curve-cumulative":"material/chart-bell-curve-cumulative.svg","material-chart-bell-curve":"material/chart-bell-curve.svg","material-chart-box-outline":"material/chart-box-outline.svg","material-chart-box-plus-outline":"material/chart-box-plus-outline.svg","material-chart-box":"material/chart-box.svg","material-chart-bubble":"material/chart-bubble.svg","material-chart-donut-variant":"material/chart-donut-variant.svg","material-chart-donut":"material/chart-donut.svg","material-chart-gantt":"material/chart-gantt.svg","material-chart-histogram":"material/chart-histogram.svg","material-chart-line-stacked":"material/chart-line-stacked.svg","material-chart-line-variant":"material/chart-line-variant.svg","material-chart-line":"material/chart-line.svg","material-chart-multiline":"material/chart-multiline.svg","material-chart-multiple":"material/chart-multiple.svg","material-chart-pie":"material/chart-pie.svg","material-chart-ppf":"material/chart-ppf.svg","material-chart-sankey-variant":"material/chart-sankey-variant.svg","material-chart-sankey":"material/chart-sankey.svg","material-chart-scatter-plot-hexbin":"material/chart-scatter-plot-hexbin.svg","material-chart-scatter-plot":"material/chart-scatter-plot.svg","material-chart-timeline-variant-shimmer":"material/chart-timeline-variant-shimmer.svg","material-chart-timeline-variant":"material/chart-timeline-variant.svg","material-chart-timeline":"material/chart-timeline.svg","material-chart-tree":"material/chart-tree.svg","material-chat-alert-outline":"material/chat-alert-outline.svg","material-chat-alert":"material/chat-alert.svg","material-chat-minus-outline":"material/chat-minus-outline.svg","material-chat-minus":"material/chat-minus.svg","material-chat-outline":"material/chat-outline.svg","material-chat-plus-outline":"material/chat-plus-outline.svg","material-chat-plus":"material/chat-plus.svg","material-chat-processing-outline":"material/chat-processing-outline.svg","material-chat-processing":"material/chat-processing.svg","material-chat-question-outline":"material/chat-question-outline.svg","material-chat-question":"material/chat-question.svg","material-chat-remove-outline":"material/chat-remove-outline.svg","material-chat-remove":"material/chat-remove.svg","material-chat-sleep-outline":"material/chat-sleep-outline.svg","material-chat-sleep":"material/chat-sleep.svg","material-chat":"material/chat.svg","material-check-all":"material/check-all.svg","material-check-bold":"material/check-bold.svg","material-check-box-multiple-outline":"material/check-box-multiple-outline.svg","material-check-box-outline":"material/check-box-outline.svg","material-check-circle-outline":"material/check-circle-outline.svg","material-check-circle":"material/check-circle.svg","material-check-decagram-outline":"material/check-decagram-outline.svg","material-check-decagram":"material/check-decagram.svg","material-check-network-outline":"material/check-network-outline.svg","material-check-network":"material/check-network.svg","material-check-outline":"material/check-outline.svg","material-check-underline-circle-outline":"material/check-underline-circle-outline.svg","material-check-underline-circle":"material/check-underline-circle.svg","material-check-underline":"material/check-underline.svg","material-check":"material/check.svg","material-checkbook":"material/checkbook.svg","material-checkbox-blank-circle-outline":"material/checkbox-blank-circle-outline.svg","material-checkbox-blank-circle":"material/checkbox-blank-circle.svg","material-checkbox-blank-off-outline":"material/checkbox-blank-off-outline.svg","material-checkbox-blank-off":"material/checkbox-blank-off.svg","material-checkbox-blank-outline":"material/checkbox-blank-outline.svg","material-checkbox-blank":"material/checkbox-blank.svg","material-checkbox-intermediate":"material/checkbox-intermediate.svg","material-checkbox-marked-circle-outline":"material/checkbox-marked-circle-outline.svg","material-checkbox-marked-circle":"material/checkbox-marked-circle.svg","material-checkbox-marked-outline":"material/checkbox-marked-outline.svg","material-checkbox-marked":"material/checkbox-marked.svg","material-checkbox-multiple-blank-circle-outline":"material/checkbox-multiple-blank-circle-outline.svg","material-checkbox-multiple-blank-circle":"material/checkbox-multiple-blank-circle.svg","material-checkbox-multiple-blank-outline":"material/checkbox-multiple-blank-outline.svg","material-checkbox-multiple-blank":"material/checkbox-multiple-blank.svg","material-checkbox-multiple-marked-circle-outline":"material/checkbox-multiple-marked-circle-outline.svg","material-checkbox-multiple-marked-circle":"material/checkbox-multiple-marked-circle.svg","material-checkbox-multiple-marked-outline":"material/checkbox-multiple-marked-outline.svg","material-checkbox-multiple-marked":"material/checkbox-multiple-marked.svg","material-checkerboard-minus":"material/checkerboard-minus.svg","material-checkerboard-plus":"material/checkerboard-plus.svg","material-checkerboard-remove":"material/checkerboard-remove.svg","material-checkerboard":"material/checkerboard.svg","material-cheese-off":"material/cheese-off.svg","material-cheese":"material/cheese.svg","material-chef-hat":"material/chef-hat.svg","material-chemical-weapon":"material/chemical-weapon.svg","material-chess-bishop":"material/chess-bishop.svg","material-chess-king":"material/chess-king.svg","material-chess-knight":"material/chess-knight.svg","material-chess-pawn":"material/chess-pawn.svg","material-chess-queen":"material/chess-queen.svg","material-chess-rook":"material/chess-rook.svg","material-chevron-double-down":"material/chevron-double-down.svg","material-chevron-double-left":"material/chevron-double-left.svg","material-chevron-double-right":"material/chevron-double-right.svg","material-chevron-double-up":"material/chevron-double-up.svg","material-chevron-down-box-outline":"material/chevron-down-box-outline.svg","material-chevron-down-box":"material/chevron-down-box.svg","material-chevron-down-circle-outline":"material/chevron-down-circle-outline.svg","material-chevron-down-circle":"material/chevron-down-circle.svg","material-chevron-down":"material/chevron-down.svg","material-chevron-left-box-outline":"material/chevron-left-box-outline.svg","material-chevron-left-box":"material/chevron-left-box.svg","material-chevron-left-circle-outline":"material/chevron-left-circle-outline.svg","material-chevron-left-circle":"material/chevron-left-circle.svg","material-chevron-left":"material/chevron-left.svg","material-chevron-right-box-outline":"material/chevron-right-box-outline.svg","material-chevron-right-box":"material/chevron-right-box.svg","material-chevron-right-circle-outline":"material/chevron-right-circle-outline.svg","material-chevron-right-circle":"material/chevron-right-circle.svg","material-chevron-right":"material/chevron-right.svg","material-chevron-triple-down":"material/chevron-triple-down.svg","material-chevron-triple-left":"material/chevron-triple-left.svg","material-chevron-triple-right":"material/chevron-triple-right.svg","material-chevron-triple-up":"material/chevron-triple-up.svg","material-chevron-up-box-outline":"material/chevron-up-box-outline.svg","material-chevron-up-box":"material/chevron-up-box.svg","material-chevron-up-circle-outline":"material/chevron-up-circle-outline.svg","material-chevron-up-circle":"material/chevron-up-circle.svg","material-chevron-up":"material/chevron-up.svg","material-chili-hot":"material/chili-hot.svg","material-chili-medium":"material/chili-medium.svg","material-chili-mild":"material/chili-mild.svg","material-chili-off":"material/chili-off.svg","material-chip":"material/chip.svg","material-christianity-outline":"material/christianity-outline.svg","material-christianity":"material/christianity.svg","material-church":"material/church.svg","material-cigar-off":"material/cigar-off.svg","material-cigar":"material/cigar.svg","material-circle-box-outline":"material/circle-box-outline.svg","material-circle-box":"material/circle-box.svg","material-circle-double":"material/circle-double.svg","material-circle-edit-outline":"material/circle-edit-outline.svg","material-circle-expand":"material/circle-expand.svg","material-circle-half-full":"material/circle-half-full.svg","material-circle-half":"material/circle-half.svg","material-circle-medium":"material/circle-medium.svg","material-circle-multiple-outline":"material/circle-multiple-outline.svg","material-circle-multiple":"material/circle-multiple.svg","material-circle-off-outline":"material/circle-off-outline.svg","material-circle-outline":"material/circle-outline.svg","material-circle-slice-1":"material/circle-slice-1.svg","material-circle-slice-2":"material/circle-slice-2.svg","material-circle-slice-3":"material/circle-slice-3.svg","material-circle-slice-4":"material/circle-slice-4.svg","material-circle-slice-5":"material/circle-slice-5.svg","material-circle-slice-6":"material/circle-slice-6.svg","material-circle-slice-7":"material/circle-slice-7.svg","material-circle-slice-8":"material/circle-slice-8.svg","material-circle-small":"material/circle-small.svg","material-circle":"material/circle.svg","material-circular-saw":"material/circular-saw.svg","material-city-variant-outline":"material/city-variant-outline.svg","material-city-variant":"material/city-variant.svg","material-city":"material/city.svg","material-clipboard-account-outline":"material/clipboard-account-outline.svg","material-clipboard-account":"material/clipboard-account.svg","material-clipboard-alert-outline":"material/clipboard-alert-outline.svg","material-clipboard-alert":"material/clipboard-alert.svg","material-clipboard-arrow-down-outline":"material/clipboard-arrow-down-outline.svg","material-clipboard-arrow-down":"material/clipboard-arrow-down.svg","material-clipboard-arrow-left-outline":"material/clipboard-arrow-left-outline.svg","material-clipboard-arrow-left":"material/clipboard-arrow-left.svg","material-clipboard-arrow-right-outline":"material/clipboard-arrow-right-outline.svg","material-clipboard-arrow-right":"material/clipboard-arrow-right.svg","material-clipboard-arrow-up-outline":"material/clipboard-arrow-up-outline.svg","material-clipboard-arrow-up":"material/clipboard-arrow-up.svg","material-clipboard-check-multiple-outline":"material/clipboard-check-multiple-outline.svg","material-clipboard-check-multiple":"material/clipboard-check-multiple.svg","material-clipboard-check-outline":"material/clipboard-check-outline.svg","material-clipboard-check":"material/clipboard-check.svg","material-clipboard-clock-outline":"material/clipboard-clock-outline.svg","material-clipboard-clock":"material/clipboard-clock.svg","material-clipboard-edit-outline":"material/clipboard-edit-outline.svg","material-clipboard-edit":"material/clipboard-edit.svg","material-clipboard-file-outline":"material/clipboard-file-outline.svg","material-clipboard-file":"material/clipboard-file.svg","material-clipboard-flow-outline":"material/clipboard-flow-outline.svg","material-clipboard-flow":"material/clipboard-flow.svg","material-clipboard-list-outline":"material/clipboard-list-outline.svg","material-clipboard-list":"material/clipboard-list.svg","material-clipboard-minus-outline":"material/clipboard-minus-outline.svg","material-clipboard-minus":"material/clipboard-minus.svg","material-clipboard-multiple-outline":"material/clipboard-multiple-outline.svg","material-clipboard-multiple":"material/clipboard-multiple.svg","material-clipboard-off-outline":"material/clipboard-off-outline.svg","material-clipboard-off":"material/clipboard-off.svg","material-clipboard-outline":"material/clipboard-outline.svg","material-clipboard-play-multiple-outline":"material/clipboard-play-multiple-outline.svg","material-clipboard-play-multiple":"material/clipboard-play-multiple.svg","material-clipboard-play-outline":"material/clipboard-play-outline.svg","material-clipboard-play":"material/clipboard-play.svg","material-clipboard-plus-outline":"material/clipboard-plus-outline.svg","material-clipboard-plus":"material/clipboard-plus.svg","material-clipboard-pulse-outline":"material/clipboard-pulse-outline.svg","material-clipboard-pulse":"material/clipboard-pulse.svg","material-clipboard-remove-outline":"material/clipboard-remove-outline.svg","material-clipboard-remove":"material/clipboard-remove.svg","material-clipboard-search-outline":"material/clipboard-search-outline.svg","material-clipboard-search":"material/clipboard-search.svg","material-clipboard-text-multiple-outline":"material/clipboard-text-multiple-outline.svg","material-clipboard-text-multiple":"material/clipboard-text-multiple.svg","material-clipboard-text-off-outline":"material/clipboard-text-off-outline.svg","material-clipboard-text-off":"material/clipboard-text-off.svg","material-clipboard-text-outline":"material/clipboard-text-outline.svg","material-clipboard-text-play-outline":"material/clipboard-text-play-outline.svg","material-clipboard-text-play":"material/clipboard-text-play.svg","material-clipboard-text-search-outline":"material/clipboard-text-search-outline.svg","material-clipboard-text-search":"material/clipboard-text-search.svg","material-clipboard-text":"material/clipboard-text.svg","material-clipboard":"material/clipboard.svg","material-clippy":"material/clippy.svg","material-clock-alert-outline":"material/clock-alert-outline.svg","material-clock-alert":"material/clock-alert.svg","material-clock-check-outline":"material/clock-check-outline.svg","material-clock-check":"material/clock-check.svg","material-clock-digital":"material/clock-digital.svg","material-clock-end":"material/clock-end.svg","material-clock-fast":"material/clock-fast.svg","material-clock-in":"material/clock-in.svg","material-clock-out":"material/clock-out.svg","material-clock-outline":"material/clock-outline.svg","material-clock-start":"material/clock-start.svg","material-clock-time-eight-outline":"material/clock-time-eight-outline.svg","material-clock-time-eight":"material/clock-time-eight.svg","material-clock-time-eleven-outline":"material/clock-time-eleven-outline.svg","material-clock-time-eleven":"material/clock-time-eleven.svg","material-clock-time-five-outline":"material/clock-time-five-outline.svg","material-clock-time-five":"material/clock-time-five.svg","material-clock-time-four-outline":"material/clock-time-four-outline.svg","material-clock-time-four":"material/clock-time-four.svg","material-clock-time-nine-outline":"material/clock-time-nine-outline.svg","material-clock-time-nine":"material/clock-time-nine.svg","material-clock-time-one-outline":"material/clock-time-one-outline.svg","material-clock-time-one":"material/clock-time-one.svg","material-clock-time-seven-outline":"material/clock-time-seven-outline.svg","material-clock-time-seven":"material/clock-time-seven.svg","material-clock-time-six-outline":"material/clock-time-six-outline.svg","material-clock-time-six":"material/clock-time-six.svg","material-clock-time-ten-outline":"material/clock-time-ten-outline.svg","material-clock-time-ten":"material/clock-time-ten.svg","material-clock-time-three-outline":"material/clock-time-three-outline.svg","material-clock-time-three":"material/clock-time-three.svg","material-clock-time-twelve-outline":"material/clock-time-twelve-outline.svg","material-clock-time-twelve":"material/clock-time-twelve.svg","material-clock-time-two-outline":"material/clock-time-two-outline.svg","material-clock-time-two":"material/clock-time-two.svg","material-clock":"material/clock.svg","material-close-box-multiple-outline":"material/close-box-multiple-outline.svg","material-close-box-multiple":"material/close-box-multiple.svg","material-close-box-outline":"material/close-box-outline.svg","material-close-box":"material/close-box.svg","material-close-circle-multiple-outline":"material/close-circle-multiple-outline.svg","material-close-circle-multiple":"material/close-circle-multiple.svg","material-close-circle-outline":"material/close-circle-outline.svg","material-close-circle":"material/close-circle.svg","material-close-network-outline":"material/close-network-outline.svg","material-close-network":"material/close-network.svg","material-close-octagon-outline":"material/close-octagon-outline.svg","material-close-octagon":"material/close-octagon.svg","material-close-outline":"material/close-outline.svg","material-close-thick":"material/close-thick.svg","material-close":"material/close.svg","material-closed-caption-outline":"material/closed-caption-outline.svg","material-closed-caption":"material/closed-caption.svg","material-cloud-alert":"material/cloud-alert.svg","material-cloud-braces":"material/cloud-braces.svg","material-cloud-check-outline":"material/cloud-check-outline.svg","material-cloud-check":"material/cloud-check.svg","material-cloud-circle":"material/cloud-circle.svg","material-cloud-download-outline":"material/cloud-download-outline.svg","material-cloud-download":"material/cloud-download.svg","material-cloud-lock-outline":"material/cloud-lock-outline.svg","material-cloud-lock":"material/cloud-lock.svg","material-cloud-off-outline":"material/cloud-off-outline.svg","material-cloud-outline":"material/cloud-outline.svg","material-cloud-print-outline":"material/cloud-print-outline.svg","material-cloud-print":"material/cloud-print.svg","material-cloud-question":"material/cloud-question.svg","material-cloud-refresh":"material/cloud-refresh.svg","material-cloud-search-outline":"material/cloud-search-outline.svg","material-cloud-search":"material/cloud-search.svg","material-cloud-sync-outline":"material/cloud-sync-outline.svg","material-cloud-sync":"material/cloud-sync.svg","material-cloud-tags":"material/cloud-tags.svg","material-cloud-upload-outline":"material/cloud-upload-outline.svg","material-cloud-upload":"material/cloud-upload.svg","material-cloud":"material/cloud.svg","material-clover":"material/clover.svg","material-coach-lamp":"material/coach-lamp.svg","material-coat-rack":"material/coat-rack.svg","material-code-array":"material/code-array.svg","material-code-braces-box":"material/code-braces-box.svg","material-code-braces":"material/code-braces.svg","material-code-brackets":"material/code-brackets.svg","material-code-equal":"material/code-equal.svg","material-code-greater-than-or-equal":"material/code-greater-than-or-equal.svg","material-code-greater-than":"material/code-greater-than.svg","material-code-json":"material/code-json.svg","material-code-less-than-or-equal":"material/code-less-than-or-equal.svg","material-code-less-than":"material/code-less-than.svg","material-code-not-equal-variant":"material/code-not-equal-variant.svg","material-code-not-equal":"material/code-not-equal.svg","material-code-parentheses-box":"material/code-parentheses-box.svg","material-code-parentheses":"material/code-parentheses.svg","material-code-string":"material/code-string.svg","material-code-tags-check":"material/code-tags-check.svg","material-code-tags":"material/code-tags.svg","material-codepen":"material/codepen.svg","material-coffee-maker":"material/coffee-maker.svg","material-coffee-off-outline":"material/coffee-off-outline.svg","material-coffee-off":"material/coffee-off.svg","material-coffee-outline":"material/coffee-outline.svg","material-coffee-to-go-outline":"material/coffee-to-go-outline.svg","material-coffee-to-go":"material/coffee-to-go.svg","material-coffee":"material/coffee.svg","material-coffin":"material/coffin.svg","material-cog-box":"material/cog-box.svg","material-cog-clockwise":"material/cog-clockwise.svg","material-cog-counterclockwise":"material/cog-counterclockwise.svg","material-cog-off-outline":"material/cog-off-outline.svg","material-cog-off":"material/cog-off.svg","material-cog-outline":"material/cog-outline.svg","material-cog-refresh-outline":"material/cog-refresh-outline.svg","material-cog-refresh":"material/cog-refresh.svg","material-cog-sync-outline":"material/cog-sync-outline.svg","material-cog-sync":"material/cog-sync.svg","material-cog-transfer-outline":"material/cog-transfer-outline.svg","material-cog-transfer":"material/cog-transfer.svg","material-cog":"material/cog.svg","material-cogs":"material/cogs.svg","material-collage":"material/collage.svg","material-collapse-all-outline":"material/collapse-all-outline.svg","material-collapse-all":"material/collapse-all.svg","material-color-helper":"material/color-helper.svg","material-comma-box-outline":"material/comma-box-outline.svg","material-comma-box":"material/comma-box.svg","material-comma-circle-outline":"material/comma-circle-outline.svg","material-comma-circle":"material/comma-circle.svg","material-comma":"material/comma.svg","material-comment-account-outline":"material/comment-account-outline.svg","material-comment-account":"material/comment-account.svg","material-comment-alert-outline":"material/comment-alert-outline.svg","material-comment-alert":"material/comment-alert.svg","material-comment-arrow-left-outline":"material/comment-arrow-left-outline.svg","material-comment-arrow-left":"material/comment-arrow-left.svg","material-comment-arrow-right-outline":"material/comment-arrow-right-outline.svg","material-comment-arrow-right":"material/comment-arrow-right.svg","material-comment-bookmark-outline":"material/comment-bookmark-outline.svg","material-comment-bookmark":"material/comment-bookmark.svg","material-comment-check-outline":"material/comment-check-outline.svg","material-comment-check":"material/comment-check.svg","material-comment-edit-outline":"material/comment-edit-outline.svg","material-comment-edit":"material/comment-edit.svg","material-comment-eye-outline":"material/comment-eye-outline.svg","material-comment-eye":"material/comment-eye.svg","material-comment-flash-outline":"material/comment-flash-outline.svg","material-comment-flash":"material/comment-flash.svg","material-comment-minus-outline":"material/comment-minus-outline.svg","material-comment-minus":"material/comment-minus.svg","material-comment-multiple-outline":"material/comment-multiple-outline.svg","material-comment-multiple":"material/comment-multiple.svg","material-comment-off-outline":"material/comment-off-outline.svg","material-comment-off":"material/comment-off.svg","material-comment-outline":"material/comment-outline.svg","material-comment-plus-outline":"material/comment-plus-outline.svg","material-comment-plus":"material/comment-plus.svg","material-comment-processing-outline":"material/comment-processing-outline.svg","material-comment-processing":"material/comment-processing.svg","material-comment-question-outline":"material/comment-question-outline.svg","material-comment-question":"material/comment-question.svg","material-comment-quote-outline":"material/comment-quote-outline.svg","material-comment-quote":"material/comment-quote.svg","material-comment-remove-outline":"material/comment-remove-outline.svg","material-comment-remove":"material/comment-remove.svg","material-comment-search-outline":"material/comment-search-outline.svg","material-comment-search":"material/comment-search.svg","material-comment-text-multiple-outline":"material/comment-text-multiple-outline.svg","material-comment-text-multiple":"material/comment-text-multiple.svg","material-comment-text-outline":"material/comment-text-outline.svg","material-comment-text":"material/comment-text.svg","material-comment":"material/comment.svg","material-compare-horizontal":"material/compare-horizontal.svg","material-compare-vertical":"material/compare-vertical.svg","material-compare":"material/compare.svg","material-compass-off-outline":"material/compass-off-outline.svg","material-compass-off":"material/compass-off.svg","material-compass-outline":"material/compass-outline.svg","material-compass-rose":"material/compass-rose.svg","material-compass":"material/compass.svg","material-concourse-ci":"material/concourse-ci.svg","material-connection":"material/connection.svg","material-console-line":"material/console-line.svg","material-console-network-outline":"material/console-network-outline.svg","material-console-network":"material/console-network.svg","material-console":"material/console.svg","material-consolidate":"material/consolidate.svg","material-contactless-payment-circle-outline":"material/contactless-payment-circle-outline.svg","material-contactless-payment-circle":"material/contactless-payment-circle.svg","material-contactless-payment":"material/contactless-payment.svg","material-contacts-outline":"material/contacts-outline.svg","material-contacts":"material/contacts.svg","material-contain-end":"material/contain-end.svg","material-contain-start":"material/contain-start.svg","material-contain":"material/contain.svg","material-content-copy":"material/content-copy.svg","material-content-cut":"material/content-cut.svg","material-content-duplicate":"material/content-duplicate.svg","material-content-paste":"material/content-paste.svg","material-content-save-alert-outline":"material/content-save-alert-outline.svg","material-content-save-alert":"material/content-save-alert.svg","material-content-save-all-outline":"material/content-save-all-outline.svg","material-content-save-all":"material/content-save-all.svg","material-content-save-cog-outline":"material/content-save-cog-outline.svg","material-content-save-cog":"material/content-save-cog.svg","material-content-save-edit-outline":"material/content-save-edit-outline.svg","material-content-save-edit":"material/content-save-edit.svg","material-content-save-move-outline":"material/content-save-move-outline.svg","material-content-save-move":"material/content-save-move.svg","material-content-save-off-outline":"material/content-save-off-outline.svg","material-content-save-off":"material/content-save-off.svg","material-content-save-outline":"material/content-save-outline.svg","material-content-save-settings-outline":"material/content-save-settings-outline.svg","material-content-save-settings":"material/content-save-settings.svg","material-content-save":"material/content-save.svg","material-contrast-box":"material/contrast-box.svg","material-contrast-circle":"material/contrast-circle.svg","material-contrast":"material/contrast.svg","material-controller-classic-outline":"material/controller-classic-outline.svg","material-controller-classic":"material/controller-classic.svg","material-cookie-alert-outline":"material/cookie-alert-outline.svg","material-cookie-alert":"material/cookie-alert.svg","material-cookie-check-outline":"material/cookie-check-outline.svg","material-cookie-check":"material/cookie-check.svg","material-cookie-clock-outline":"material/cookie-clock-outline.svg","material-cookie-clock":"material/cookie-clock.svg","material-cookie-cog-outline":"material/cookie-cog-outline.svg","material-cookie-cog":"material/cookie-cog.svg","material-cookie-edit-outline":"material/cookie-edit-outline.svg","material-cookie-edit":"material/cookie-edit.svg","material-cookie-lock-outline":"material/cookie-lock-outline.svg","material-cookie-lock":"material/cookie-lock.svg","material-cookie-minus-outline":"material/cookie-minus-outline.svg","material-cookie-minus":"material/cookie-minus.svg","material-cookie-off-outline":"material/cookie-off-outline.svg","material-cookie-off":"material/cookie-off.svg","material-cookie-outline":"material/cookie-outline.svg","material-cookie-plus-outline":"material/cookie-plus-outline.svg","material-cookie-plus":"material/cookie-plus.svg","material-cookie-refresh-outline":"material/cookie-refresh-outline.svg","material-cookie-refresh":"material/cookie-refresh.svg","material-cookie-remove-outline":"material/cookie-remove-outline.svg","material-cookie-remove":"material/cookie-remove.svg","material-cookie-settings-outline":"material/cookie-settings-outline.svg","material-cookie-settings":"material/cookie-settings.svg","material-cookie":"material/cookie.svg","material-coolant-temperature":"material/coolant-temperature.svg","material-copyright":"material/copyright.svg","material-cordova":"material/cordova.svg","material-corn-off":"material/corn-off.svg","material-corn":"material/corn.svg","material-cosine-wave":"material/cosine-wave.svg","material-counter":"material/counter.svg","material-cow":"material/cow.svg","material-cpu-32-bit":"material/cpu-32-bit.svg","material-cpu-64-bit":"material/cpu-64-bit.svg","material-crane":"material/crane.svg","material-creation":"material/creation.svg","material-creative-commons":"material/creative-commons.svg","material-credit-card-check-outline":"material/credit-card-check-outline.svg","material-credit-card-check":"material/credit-card-check.svg","material-credit-card-clock-outline":"material/credit-card-clock-outline.svg","material-credit-card-clock":"material/credit-card-clock.svg","material-credit-card-marker-outline":"material/credit-card-marker-outline.svg","material-credit-card-marker":"material/credit-card-marker.svg","material-credit-card-minus-outline":"material/credit-card-minus-outline.svg","material-credit-card-minus":"material/credit-card-minus.svg","material-credit-card-multiple-outline":"material/credit-card-multiple-outline.svg","material-credit-card-multiple":"material/credit-card-multiple.svg","material-credit-card-off-outline":"material/credit-card-off-outline.svg","material-credit-card-off":"material/credit-card-off.svg","material-credit-card-outline":"material/credit-card-outline.svg","material-credit-card-plus-outline":"material/credit-card-plus-outline.svg","material-credit-card-plus":"material/credit-card-plus.svg","material-credit-card-refresh-outline":"material/credit-card-refresh-outline.svg","material-credit-card-refresh":"material/credit-card-refresh.svg","material-credit-card-refund-outline":"material/credit-card-refund-outline.svg","material-credit-card-refund":"material/credit-card-refund.svg","material-credit-card-remove-outline":"material/credit-card-remove-outline.svg","material-credit-card-remove":"material/credit-card-remove.svg","material-credit-card-scan-outline":"material/credit-card-scan-outline.svg","material-credit-card-scan":"material/credit-card-scan.svg","material-credit-card-search-outline":"material/credit-card-search-outline.svg","material-credit-card-search":"material/credit-card-search.svg","material-credit-card-settings-outline":"material/credit-card-settings-outline.svg","material-credit-card-settings":"material/credit-card-settings.svg","material-credit-card-sync-outline":"material/credit-card-sync-outline.svg","material-credit-card-sync":"material/credit-card-sync.svg","material-credit-card-wireless-off-outline":"material/credit-card-wireless-off-outline.svg","material-credit-card-wireless-off":"material/credit-card-wireless-off.svg","material-credit-card-wireless-outline":"material/credit-card-wireless-outline.svg","material-credit-card-wireless":"material/credit-card-wireless.svg","material-credit-card":"material/credit-card.svg","material-cricket":"material/cricket.svg","material-crop-free":"material/crop-free.svg","material-crop-landscape":"material/crop-landscape.svg","material-crop-portrait":"material/crop-portrait.svg","material-crop-rotate":"material/crop-rotate.svg","material-crop-square":"material/crop-square.svg","material-crop":"material/crop.svg","material-crosshairs-gps":"material/crosshairs-gps.svg","material-crosshairs-off":"material/crosshairs-off.svg","material-crosshairs-question":"material/crosshairs-question.svg","material-crosshairs":"material/crosshairs.svg","material-crown-outline":"material/crown-outline.svg","material-crown":"material/crown.svg","material-cryengine":"material/cryengine.svg","material-crystal-ball":"material/crystal-ball.svg","material-cube-off-outline":"material/cube-off-outline.svg","material-cube-off":"material/cube-off.svg","material-cube-outline":"material/cube-outline.svg","material-cube-scan":"material/cube-scan.svg","material-cube-send":"material/cube-send.svg","material-cube-unfolded":"material/cube-unfolded.svg","material-cube":"material/cube.svg","material-cup-off-outline":"material/cup-off-outline.svg","material-cup-off":"material/cup-off.svg","material-cup-outline":"material/cup-outline.svg","material-cup-water":"material/cup-water.svg","material-cup":"material/cup.svg","material-cupboard-outline":"material/cupboard-outline.svg","material-cupboard":"material/cupboard.svg","material-cupcake":"material/cupcake.svg","material-curling":"material/curling.svg","material-currency-bdt":"material/currency-bdt.svg","material-currency-brl":"material/currency-brl.svg","material-currency-btc":"material/currency-btc.svg","material-currency-cny":"material/currency-cny.svg","material-currency-eth":"material/currency-eth.svg","material-currency-eur-off":"material/currency-eur-off.svg","material-currency-eur":"material/currency-eur.svg","material-currency-gbp":"material/currency-gbp.svg","material-currency-ils":"material/currency-ils.svg","material-currency-inr":"material/currency-inr.svg","material-currency-jpy":"material/currency-jpy.svg","material-currency-krw":"material/currency-krw.svg","material-currency-kzt":"material/currency-kzt.svg","material-currency-mnt":"material/currency-mnt.svg","material-currency-ngn":"material/currency-ngn.svg","material-currency-php":"material/currency-php.svg","material-currency-rial":"material/currency-rial.svg","material-currency-rub":"material/currency-rub.svg","material-currency-sign":"material/currency-sign.svg","material-currency-try":"material/currency-try.svg","material-currency-twd":"material/currency-twd.svg","material-currency-usd-circle-outline":"material/currency-usd-circle-outline.svg","material-currency-usd-circle":"material/currency-usd-circle.svg","material-currency-usd-off":"material/currency-usd-off.svg","material-currency-usd":"material/currency-usd.svg","material-current-ac":"material/current-ac.svg","material-current-dc":"material/current-dc.svg","material-cursor-default-click-outline":"material/cursor-default-click-outline.svg","material-cursor-default-click":"material/cursor-default-click.svg","material-cursor-default-gesture-outline":"material/cursor-default-gesture-outline.svg","material-cursor-default-gesture":"material/cursor-default-gesture.svg","material-cursor-default-outline":"material/cursor-default-outline.svg","material-cursor-default":"material/cursor-default.svg","material-cursor-move":"material/cursor-move.svg","material-cursor-pointer":"material/cursor-pointer.svg","material-cursor-text":"material/cursor-text.svg","material-dance-ballroom":"material/dance-ballroom.svg","material-dance-pole":"material/dance-pole.svg","material-data-matrix-edit":"material/data-matrix-edit.svg","material-data-matrix-minus":"material/data-matrix-minus.svg","material-data-matrix-plus":"material/data-matrix-plus.svg","material-data-matrix-remove":"material/data-matrix-remove.svg","material-data-matrix-scan":"material/data-matrix-scan.svg","material-data-matrix":"material/data-matrix.svg","material-database-alert-outline":"material/database-alert-outline.svg","material-database-alert":"material/database-alert.svg","material-database-arrow-down-outline":"material/database-arrow-down-outline.svg","material-database-arrow-down":"material/database-arrow-down.svg","material-database-arrow-left-outline":"material/database-arrow-left-outline.svg","material-database-arrow-left":"material/database-arrow-left.svg","material-database-arrow-right-outline":"material/database-arrow-right-outline.svg","material-database-arrow-right":"material/database-arrow-right.svg","material-database-arrow-up-outline":"material/database-arrow-up-outline.svg","material-database-arrow-up":"material/database-arrow-up.svg","material-database-check-outline":"material/database-check-outline.svg","material-database-check":"material/database-check.svg","material-database-clock-outline":"material/database-clock-outline.svg","material-database-clock":"material/database-clock.svg","material-database-cog-outline":"material/database-cog-outline.svg","material-database-cog":"material/database-cog.svg","material-database-edit-outline":"material/database-edit-outline.svg","material-database-edit":"material/database-edit.svg","material-database-export-outline":"material/database-export-outline.svg","material-database-export":"material/database-export.svg","material-database-import-outline":"material/database-import-outline.svg","material-database-import":"material/database-import.svg","material-database-lock-outline":"material/database-lock-outline.svg","material-database-lock":"material/database-lock.svg","material-database-marker-outline":"material/database-marker-outline.svg","material-database-marker":"material/database-marker.svg","material-database-minus-outline":"material/database-minus-outline.svg","material-database-minus":"material/database-minus.svg","material-database-off-outline":"material/database-off-outline.svg","material-database-off":"material/database-off.svg","material-database-outline":"material/database-outline.svg","material-database-plus-outline":"material/database-plus-outline.svg","material-database-plus":"material/database-plus.svg","material-database-refresh-outline":"material/database-refresh-outline.svg","material-database-refresh":"material/database-refresh.svg","material-database-remove-outline":"material/database-remove-outline.svg","material-database-remove":"material/database-remove.svg","material-database-search-outline":"material/database-search-outline.svg","material-database-search":"material/database-search.svg","material-database-settings-outline":"material/database-settings-outline.svg","material-database-settings":"material/database-settings.svg","material-database-sync-outline":"material/database-sync-outline.svg","material-database-sync":"material/database-sync.svg","material-database":"material/database.svg","material-death-star-variant":"material/death-star-variant.svg","material-death-star":"material/death-star.svg","material-deathly-hallows":"material/deathly-hallows.svg","material-debian":"material/debian.svg","material-debug-step-into":"material/debug-step-into.svg","material-debug-step-out":"material/debug-step-out.svg","material-debug-step-over":"material/debug-step-over.svg","material-decagram-outline":"material/decagram-outline.svg","material-decagram":"material/decagram.svg","material-decimal-comma-decrease":"material/decimal-comma-decrease.svg","material-decimal-comma-increase":"material/decimal-comma-increase.svg","material-decimal-comma":"material/decimal-comma.svg","material-decimal-decrease":"material/decimal-decrease.svg","material-decimal-increase":"material/decimal-increase.svg","material-decimal":"material/decimal.svg","material-delete-alert-outline":"material/delete-alert-outline.svg","material-delete-alert":"material/delete-alert.svg","material-delete-circle-outline":"material/delete-circle-outline.svg","material-delete-circle":"material/delete-circle.svg","material-delete-clock-outline":"material/delete-clock-outline.svg","material-delete-clock":"material/delete-clock.svg","material-delete-empty-outline":"material/delete-empty-outline.svg","material-delete-empty":"material/delete-empty.svg","material-delete-forever-outline":"material/delete-forever-outline.svg","material-delete-forever":"material/delete-forever.svg","material-delete-off-outline":"material/delete-off-outline.svg","material-delete-off":"material/delete-off.svg","material-delete-outline":"material/delete-outline.svg","material-delete-restore":"material/delete-restore.svg","material-delete-sweep-outline":"material/delete-sweep-outline.svg","material-delete-sweep":"material/delete-sweep.svg","material-delete-variant":"material/delete-variant.svg","material-delete":"material/delete.svg","material-delta":"material/delta.svg","material-desk-lamp":"material/desk-lamp.svg","material-desk":"material/desk.svg","material-deskphone":"material/deskphone.svg","material-desktop-classic":"material/desktop-classic.svg","material-desktop-mac-dashboard":"material/desktop-mac-dashboard.svg","material-desktop-mac":"material/desktop-mac.svg","material-desktop-tower-monitor":"material/desktop-tower-monitor.svg","material-desktop-tower":"material/desktop-tower.svg","material-details":"material/details.svg","material-dev-to":"material/dev-to.svg","material-developer-board":"material/developer-board.svg","material-deviantart":"material/deviantart.svg","material-devices":"material/devices.svg","material-diabetes":"material/diabetes.svg","material-dialpad":"material/dialpad.svg","material-diameter-outline":"material/diameter-outline.svg","material-diameter-variant":"material/diameter-variant.svg","material-diameter":"material/diameter.svg","material-diamond-outline":"material/diamond-outline.svg","material-diamond-stone":"material/diamond-stone.svg","material-diamond":"material/diamond.svg","material-dice-1-outline":"material/dice-1-outline.svg","material-dice-1":"material/dice-1.svg","material-dice-2-outline":"material/dice-2-outline.svg","material-dice-2":"material/dice-2.svg","material-dice-3-outline":"material/dice-3-outline.svg","material-dice-3":"material/dice-3.svg","material-dice-4-outline":"material/dice-4-outline.svg","material-dice-4":"material/dice-4.svg","material-dice-5-outline":"material/dice-5-outline.svg","material-dice-5":"material/dice-5.svg","material-dice-6-outline":"material/dice-6-outline.svg","material-dice-6":"material/dice-6.svg","material-dice-d10-outline":"material/dice-d10-outline.svg","material-dice-d10":"material/dice-d10.svg","material-dice-d12-outline":"material/dice-d12-outline.svg","material-dice-d12":"material/dice-d12.svg","material-dice-d20-outline":"material/dice-d20-outline.svg","material-dice-d20":"material/dice-d20.svg","material-dice-d4-outline":"material/dice-d4-outline.svg","material-dice-d4":"material/dice-d4.svg","material-dice-d6-outline":"material/dice-d6-outline.svg","material-dice-d6":"material/dice-d6.svg","material-dice-d8-outline":"material/dice-d8-outline.svg","material-dice-d8":"material/dice-d8.svg","material-dice-multiple-outline":"material/dice-multiple-outline.svg","material-dice-multiple":"material/dice-multiple.svg","material-digital-ocean":"material/digital-ocean.svg","material-dip-switch":"material/dip-switch.svg","material-directions-fork":"material/directions-fork.svg","material-directions":"material/directions.svg","material-disc-alert":"material/disc-alert.svg","material-disc-player":"material/disc-player.svg","material-disc":"material/disc.svg","material-discord":"material/discord.svg","material-dishwasher-alert":"material/dishwasher-alert.svg","material-dishwasher-off":"material/dishwasher-off.svg","material-dishwasher":"material/dishwasher.svg","material-disqus":"material/disqus.svg","material-distribute-horizontal-center":"material/distribute-horizontal-center.svg","material-distribute-horizontal-left":"material/distribute-horizontal-left.svg","material-distribute-horizontal-right":"material/distribute-horizontal-right.svg","material-distribute-vertical-bottom":"material/distribute-vertical-bottom.svg","material-distribute-vertical-center":"material/distribute-vertical-center.svg","material-distribute-vertical-top":"material/distribute-vertical-top.svg","material-diving-flippers":"material/diving-flippers.svg","material-diving-helmet":"material/diving-helmet.svg","material-diving-scuba-flag":"material/diving-scuba-flag.svg","material-diving-scuba-tank-multiple":"material/diving-scuba-tank-multiple.svg","material-diving-scuba-tank":"material/diving-scuba-tank.svg","material-diving-scuba":"material/diving-scuba.svg","material-diving-snorkel":"material/diving-snorkel.svg","material-division-box":"material/division-box.svg","material-division":"material/division.svg","material-dlna":"material/dlna.svg","material-dna":"material/dna.svg","material-dns-outline":"material/dns-outline.svg","material-dns":"material/dns.svg","material-do-not-disturb-off":"material/do-not-disturb-off.svg","material-do-not-disturb":"material/do-not-disturb.svg","material-dock-bottom":"material/dock-bottom.svg","material-dock-left":"material/dock-left.svg","material-dock-right":"material/dock-right.svg","material-dock-top":"material/dock-top.svg","material-dock-window":"material/dock-window.svg","material-docker":"material/docker.svg","material-doctor":"material/doctor.svg","material-dog-service":"material/dog-service.svg","material-dog-side-off":"material/dog-side-off.svg","material-dog-side":"material/dog-side.svg","material-dog":"material/dog.svg","material-dolby":"material/dolby.svg","material-dolly":"material/dolly.svg","material-domain-off":"material/domain-off.svg","material-domain-plus":"material/domain-plus.svg","material-domain-remove":"material/domain-remove.svg","material-domain":"material/domain.svg","material-dome-light":"material/dome-light.svg","material-domino-mask":"material/domino-mask.svg","material-donkey":"material/donkey.svg","material-door-closed-lock":"material/door-closed-lock.svg","material-door-closed":"material/door-closed.svg","material-door-open":"material/door-open.svg","material-door":"material/door.svg","material-doorbell-video":"material/doorbell-video.svg","material-doorbell":"material/doorbell.svg","material-dot-net":"material/dot-net.svg","material-dots-grid":"material/dots-grid.svg","material-dots-hexagon":"material/dots-hexagon.svg","material-dots-horizontal-circle-outline":"material/dots-horizontal-circle-outline.svg","material-dots-horizontal-circle":"material/dots-horizontal-circle.svg","material-dots-horizontal":"material/dots-horizontal.svg","material-dots-square":"material/dots-square.svg","material-dots-triangle":"material/dots-triangle.svg","material-dots-vertical-circle-outline":"material/dots-vertical-circle-outline.svg","material-dots-vertical-circle":"material/dots-vertical-circle.svg","material-dots-vertical":"material/dots-vertical.svg","material-douban":"material/douban.svg","material-download-box-outline":"material/download-box-outline.svg","material-download-box":"material/download-box.svg","material-download-circle-outline":"material/download-circle-outline.svg","material-download-circle":"material/download-circle.svg","material-download-lock-outline":"material/download-lock-outline.svg","material-download-lock":"material/download-lock.svg","material-download-multiple":"material/download-multiple.svg","material-download-network-outline":"material/download-network-outline.svg","material-download-network":"material/download-network.svg","material-download-off-outline":"material/download-off-outline.svg","material-download-off":"material/download-off.svg","material-download-outline":"material/download-outline.svg","material-download":"material/download.svg","material-drag-horizontal-variant":"material/drag-horizontal-variant.svg","material-drag-horizontal":"material/drag-horizontal.svg","material-drag-variant":"material/drag-variant.svg","material-drag-vertical-variant":"material/drag-vertical-variant.svg","material-drag-vertical":"material/drag-vertical.svg","material-drag":"material/drag.svg","material-drama-masks":"material/drama-masks.svg","material-draw":"material/draw.svg","material-drawing-box":"material/drawing-box.svg","material-drawing":"material/drawing.svg","material-dresser-outline":"material/dresser-outline.svg","material-dresser":"material/dresser.svg","material-drone":"material/drone.svg","material-dropbox":"material/dropbox.svg","material-drupal":"material/drupal.svg","material-duck":"material/duck.svg","material-dumbbell":"material/dumbbell.svg","material-dump-truck":"material/dump-truck.svg","material-ear-hearing-off":"material/ear-hearing-off.svg","material-ear-hearing":"material/ear-hearing.svg","material-earth-arrow-right":"material/earth-arrow-right.svg","material-earth-box-minus":"material/earth-box-minus.svg","material-earth-box-off":"material/earth-box-off.svg","material-earth-box-plus":"material/earth-box-plus.svg","material-earth-box-remove":"material/earth-box-remove.svg","material-earth-box":"material/earth-box.svg","material-earth-minus":"material/earth-minus.svg","material-earth-off":"material/earth-off.svg","material-earth-plus":"material/earth-plus.svg","material-earth-remove":"material/earth-remove.svg","material-earth":"material/earth.svg","material-egg-easter":"material/egg-easter.svg","material-egg-off-outline":"material/egg-off-outline.svg","material-egg-off":"material/egg-off.svg","material-egg-outline":"material/egg-outline.svg","material-egg":"material/egg.svg","material-eiffel-tower":"material/eiffel-tower.svg","material-eight-track":"material/eight-track.svg","material-eject-outline":"material/eject-outline.svg","material-eject":"material/eject.svg","material-electric-switch-closed":"material/electric-switch-closed.svg","material-electric-switch":"material/electric-switch.svg","material-electron-framework":"material/electron-framework.svg","material-elephant":"material/elephant.svg","material-elevation-decline":"material/elevation-decline.svg","material-elevation-rise":"material/elevation-rise.svg","material-elevator-down":"material/elevator-down.svg","material-elevator-passenger":"material/elevator-passenger.svg","material-elevator-up":"material/elevator-up.svg","material-elevator":"material/elevator.svg","material-ellipse-outline":"material/ellipse-outline.svg","material-ellipse":"material/ellipse.svg","material-email-alert-outline":"material/email-alert-outline.svg","material-email-alert":"material/email-alert.svg","material-email-box":"material/email-box.svg","material-email-check-outline":"material/email-check-outline.svg","material-email-check":"material/email-check.svg","material-email-edit-outline":"material/email-edit-outline.svg","material-email-edit":"material/email-edit.svg","material-email-lock":"material/email-lock.svg","material-email-mark-as-unread":"material/email-mark-as-unread.svg","material-email-minus-outline":"material/email-minus-outline.svg","material-email-minus":"material/email-minus.svg","material-email-multiple-outline":"material/email-multiple-outline.svg","material-email-multiple":"material/email-multiple.svg","material-email-newsletter":"material/email-newsletter.svg","material-email-off-outline":"material/email-off-outline.svg","material-email-off":"material/email-off.svg","material-email-open-multiple-outline":"material/email-open-multiple-outline.svg","material-email-open-multiple":"material/email-open-multiple.svg","material-email-open-outline":"material/email-open-outline.svg","material-email-open":"material/email-open.svg","material-email-outline":"material/email-outline.svg","material-email-plus-outline":"material/email-plus-outline.svg","material-email-plus":"material/email-plus.svg","material-email-receive-outline":"material/email-receive-outline.svg","material-email-receive":"material/email-receive.svg","material-email-remove-outline":"material/email-remove-outline.svg","material-email-remove":"material/email-remove.svg","material-email-search-outline":"material/email-search-outline.svg","material-email-search":"material/email-search.svg","material-email-send-outline":"material/email-send-outline.svg","material-email-send":"material/email-send.svg","material-email-sync-outline":"material/email-sync-outline.svg","material-email-sync":"material/email-sync.svg","material-email-variant":"material/email-variant.svg","material-email":"material/email.svg","material-ember":"material/ember.svg","material-emby":"material/emby.svg","material-emoticon-angry-outline":"material/emoticon-angry-outline.svg","material-emoticon-angry":"material/emoticon-angry.svg","material-emoticon-confused-outline":"material/emoticon-confused-outline.svg","material-emoticon-confused":"material/emoticon-confused.svg","material-emoticon-cool-outline":"material/emoticon-cool-outline.svg","material-emoticon-cool":"material/emoticon-cool.svg","material-emoticon-cry-outline":"material/emoticon-cry-outline.svg","material-emoticon-cry":"material/emoticon-cry.svg","material-emoticon-dead-outline":"material/emoticon-dead-outline.svg","material-emoticon-dead":"material/emoticon-dead.svg","material-emoticon-devil-outline":"material/emoticon-devil-outline.svg","material-emoticon-devil":"material/emoticon-devil.svg","material-emoticon-excited-outline":"material/emoticon-excited-outline.svg","material-emoticon-excited":"material/emoticon-excited.svg","material-emoticon-frown-outline":"material/emoticon-frown-outline.svg","material-emoticon-frown":"material/emoticon-frown.svg","material-emoticon-happy-outline":"material/emoticon-happy-outline.svg","material-emoticon-happy":"material/emoticon-happy.svg","material-emoticon-kiss-outline":"material/emoticon-kiss-outline.svg","material-emoticon-kiss":"material/emoticon-kiss.svg","material-emoticon-lol-outline":"material/emoticon-lol-outline.svg","material-emoticon-lol":"material/emoticon-lol.svg","material-emoticon-neutral-outline":"material/emoticon-neutral-outline.svg","material-emoticon-neutral":"material/emoticon-neutral.svg","material-emoticon-outline":"material/emoticon-outline.svg","material-emoticon-poop-outline":"material/emoticon-poop-outline.svg","material-emoticon-poop":"material/emoticon-poop.svg","material-emoticon-sad-outline":"material/emoticon-sad-outline.svg","material-emoticon-sad":"material/emoticon-sad.svg","material-emoticon-sick-outline":"material/emoticon-sick-outline.svg","material-emoticon-sick":"material/emoticon-sick.svg","material-emoticon-tongue-outline":"material/emoticon-tongue-outline.svg","material-emoticon-tongue":"material/emoticon-tongue.svg","material-emoticon-wink-outline":"material/emoticon-wink-outline.svg","material-emoticon-wink":"material/emoticon-wink.svg","material-emoticon":"material/emoticon.svg","material-engine-off-outline":"material/engine-off-outline.svg","material-engine-off":"material/engine-off.svg","material-engine-outline":"material/engine-outline.svg","material-engine":"material/engine.svg","material-epsilon":"material/epsilon.svg","material-equal-box":"material/equal-box.svg","material-equal":"material/equal.svg","material-equalizer-outline":"material/equalizer-outline.svg","material-equalizer":"material/equalizer.svg","material-eraser-variant":"material/eraser-variant.svg","material-eraser":"material/eraser.svg","material-escalator-box":"material/escalator-box.svg","material-escalator-down":"material/escalator-down.svg","material-escalator-up":"material/escalator-up.svg","material-escalator":"material/escalator.svg","material-eslint":"material/eslint.svg","material-et":"material/et.svg","material-ethereum":"material/ethereum.svg","material-ethernet-cable-off":"material/ethernet-cable-off.svg","material-ethernet-cable":"material/ethernet-cable.svg","material-ethernet":"material/ethernet.svg","material-ev-plug-ccs1":"material/ev-plug-ccs1.svg","material-ev-plug-ccs2":"material/ev-plug-ccs2.svg","material-ev-plug-chademo":"material/ev-plug-chademo.svg","material-ev-plug-tesla":"material/ev-plug-tesla.svg","material-ev-plug-type1":"material/ev-plug-type1.svg","material-ev-plug-type2":"material/ev-plug-type2.svg","material-ev-station":"material/ev-station.svg","material-evernote":"material/evernote.svg","material-excavator":"material/excavator.svg","material-exclamation-thick":"material/exclamation-thick.svg","material-exclamation":"material/exclamation.svg","material-exit-run":"material/exit-run.svg","material-exit-to-app":"material/exit-to-app.svg","material-expand-all-outline":"material/expand-all-outline.svg","material-expand-all":"material/expand-all.svg","material-expansion-card-variant":"material/expansion-card-variant.svg","material-expansion-card":"material/expansion-card.svg","material-exponent-box":"material/exponent-box.svg","material-exponent":"material/exponent.svg","material-export-variant":"material/export-variant.svg","material-export":"material/export.svg","material-eye-check-outline":"material/eye-check-outline.svg","material-eye-check":"material/eye-check.svg","material-eye-circle-outline":"material/eye-circle-outline.svg","material-eye-circle":"material/eye-circle.svg","material-eye-minus-outline":"material/eye-minus-outline.svg","material-eye-minus":"material/eye-minus.svg","material-eye-off-outline":"material/eye-off-outline.svg","material-eye-off":"material/eye-off.svg","material-eye-outline":"material/eye-outline.svg","material-eye-plus-outline":"material/eye-plus-outline.svg","material-eye-plus":"material/eye-plus.svg","material-eye-remove-outline":"material/eye-remove-outline.svg","material-eye-remove":"material/eye-remove.svg","material-eye-settings-outline":"material/eye-settings-outline.svg","material-eye-settings":"material/eye-settings.svg","material-eye":"material/eye.svg","material-eyedropper-minus":"material/eyedropper-minus.svg","material-eyedropper-off":"material/eyedropper-off.svg","material-eyedropper-plus":"material/eyedropper-plus.svg","material-eyedropper-remove":"material/eyedropper-remove.svg","material-eyedropper-variant":"material/eyedropper-variant.svg","material-eyedropper":"material/eyedropper.svg","material-face-agent":"material/face-agent.svg","material-face-mask-outline":"material/face-mask-outline.svg","material-face-mask":"material/face-mask.svg","material-face-outline":"material/face-outline.svg","material-face-profile-woman":"material/face-profile-woman.svg","material-face-profile":"material/face-profile.svg","material-face-recognition":"material/face-recognition.svg","material-face-shimmer-outline":"material/face-shimmer-outline.svg","material-face-shimmer":"material/face-shimmer.svg","material-face-woman-outline":"material/face-woman-outline.svg","material-face-woman-shimmer-outline":"material/face-woman-shimmer-outline.svg","material-face-woman-shimmer":"material/face-woman-shimmer.svg","material-face-woman":"material/face-woman.svg","material-face":"material/face.svg","material-facebook-gaming":"material/facebook-gaming.svg","material-facebook-messenger":"material/facebook-messenger.svg","material-facebook-workplace":"material/facebook-workplace.svg","material-facebook":"material/facebook.svg","material-factory":"material/factory.svg","material-family-tree":"material/family-tree.svg","material-fan-alert":"material/fan-alert.svg","material-fan-auto":"material/fan-auto.svg","material-fan-chevron-down":"material/fan-chevron-down.svg","material-fan-chevron-up":"material/fan-chevron-up.svg","material-fan-minus":"material/fan-minus.svg","material-fan-off":"material/fan-off.svg","material-fan-plus":"material/fan-plus.svg","material-fan-remove":"material/fan-remove.svg","material-fan-speed-1":"material/fan-speed-1.svg","material-fan-speed-2":"material/fan-speed-2.svg","material-fan-speed-3":"material/fan-speed-3.svg","material-fan":"material/fan.svg","material-fast-forward-10":"material/fast-forward-10.svg","material-fast-forward-30":"material/fast-forward-30.svg","material-fast-forward-5":"material/fast-forward-5.svg","material-fast-forward-60":"material/fast-forward-60.svg","material-fast-forward-outline":"material/fast-forward-outline.svg","material-fast-forward":"material/fast-forward.svg","material-fax":"material/fax.svg","material-feather":"material/feather.svg","material-feature-search-outline":"material/feature-search-outline.svg","material-feature-search":"material/feature-search.svg","material-fedora":"material/fedora.svg","material-fencing":"material/fencing.svg","material-ferris-wheel":"material/ferris-wheel.svg","material-ferry":"material/ferry.svg","material-file-account-outline":"material/file-account-outline.svg","material-file-account":"material/file-account.svg","material-file-alert-outline":"material/file-alert-outline.svg","material-file-alert":"material/file-alert.svg","material-file-cabinet":"material/file-cabinet.svg","material-file-cad-box":"material/file-cad-box.svg","material-file-cad":"material/file-cad.svg","material-file-cancel-outline":"material/file-cancel-outline.svg","material-file-cancel":"material/file-cancel.svg","material-file-certificate-outline":"material/file-certificate-outline.svg","material-file-certificate":"material/file-certificate.svg","material-file-chart-outline":"material/file-chart-outline.svg","material-file-chart":"material/file-chart.svg","material-file-check-outline":"material/file-check-outline.svg","material-file-check":"material/file-check.svg","material-file-clock-outline":"material/file-clock-outline.svg","material-file-clock":"material/file-clock.svg","material-file-cloud-outline":"material/file-cloud-outline.svg","material-file-cloud":"material/file-cloud.svg","material-file-code-outline":"material/file-code-outline.svg","material-file-code":"material/file-code.svg","material-file-cog-outline":"material/file-cog-outline.svg","material-file-cog":"material/file-cog.svg","material-file-compare":"material/file-compare.svg","material-file-delimited-outline":"material/file-delimited-outline.svg","material-file-delimited":"material/file-delimited.svg","material-file-document-edit-outline":"material/file-document-edit-outline.svg","material-file-document-edit":"material/file-document-edit.svg","material-file-document-multiple-outline":"material/file-document-multiple-outline.svg","material-file-document-multiple":"material/file-document-multiple.svg","material-file-document-outline":"material/file-document-outline.svg","material-file-document":"material/file-document.svg","material-file-download-outline":"material/file-download-outline.svg","material-file-download":"material/file-download.svg","material-file-edit-outline":"material/file-edit-outline.svg","material-file-edit":"material/file-edit.svg","material-file-excel-box-outline":"material/file-excel-box-outline.svg","material-file-excel-box":"material/file-excel-box.svg","material-file-excel-outline":"material/file-excel-outline.svg","material-file-excel":"material/file-excel.svg","material-file-export-outline":"material/file-export-outline.svg","material-file-export":"material/file-export.svg","material-file-eye-outline":"material/file-eye-outline.svg","material-file-eye":"material/file-eye.svg","material-file-find-outline":"material/file-find-outline.svg","material-file-find":"material/file-find.svg","material-file-hidden":"material/file-hidden.svg","material-file-image-outline":"material/file-image-outline.svg","material-file-image":"material/file-image.svg","material-file-import-outline":"material/file-import-outline.svg","material-file-import":"material/file-import.svg","material-file-key-outline":"material/file-key-outline.svg","material-file-key":"material/file-key.svg","material-file-link-outline":"material/file-link-outline.svg","material-file-link":"material/file-link.svg","material-file-lock-outline":"material/file-lock-outline.svg","material-file-lock":"material/file-lock.svg","material-file-move-outline":"material/file-move-outline.svg","material-file-move":"material/file-move.svg","material-file-multiple-outline":"material/file-multiple-outline.svg","material-file-multiple":"material/file-multiple.svg","material-file-music-outline":"material/file-music-outline.svg","material-file-music":"material/file-music.svg","material-file-outline":"material/file-outline.svg","material-file-pdf-box-outline":"material/file-pdf-box-outline.svg","material-file-pdf-box":"material/file-pdf-box.svg","material-file-pdf-outline":"material/file-pdf-outline.svg","material-file-pdf":"material/file-pdf.svg","material-file-percent-outline":"material/file-percent-outline.svg","material-file-percent":"material/file-percent.svg","material-file-phone-outline":"material/file-phone-outline.svg","material-file-phone":"material/file-phone.svg","material-file-plus-outline":"material/file-plus-outline.svg","material-file-plus":"material/file-plus.svg","material-file-powerpoint-box-outline":"material/file-powerpoint-box-outline.svg","material-file-powerpoint-box":"material/file-powerpoint-box.svg","material-file-powerpoint-outline":"material/file-powerpoint-outline.svg","material-file-powerpoint":"material/file-powerpoint.svg","material-file-presentation-box":"material/file-presentation-box.svg","material-file-question-outline":"material/file-question-outline.svg","material-file-question":"material/file-question.svg","material-file-refresh-outline":"material/file-refresh-outline.svg","material-file-refresh":"material/file-refresh.svg","material-file-remove-outline":"material/file-remove-outline.svg","material-file-remove":"material/file-remove.svg","material-file-replace-outline":"material/file-replace-outline.svg","material-file-replace":"material/file-replace.svg","material-file-restore-outline":"material/file-restore-outline.svg","material-file-restore":"material/file-restore.svg","material-file-search-outline":"material/file-search-outline.svg","material-file-search":"material/file-search.svg","material-file-send-outline":"material/file-send-outline.svg","material-file-send":"material/file-send.svg","material-file-settings-outline":"material/file-settings-outline.svg","material-file-settings":"material/file-settings.svg","material-file-star-outline":"material/file-star-outline.svg","material-file-star":"material/file-star.svg","material-file-swap-outline":"material/file-swap-outline.svg","material-file-swap":"material/file-swap.svg","material-file-sync-outline":"material/file-sync-outline.svg","material-file-sync":"material/file-sync.svg","material-file-table-box-multiple-outline":"material/file-table-box-multiple-outline.svg","material-file-table-box-multiple":"material/file-table-box-multiple.svg","material-file-table-box-outline":"material/file-table-box-outline.svg","material-file-table-box":"material/file-table-box.svg","material-file-table-outline":"material/file-table-outline.svg","material-file-table":"material/file-table.svg","material-file-tree-outline":"material/file-tree-outline.svg","material-file-tree":"material/file-tree.svg","material-file-undo-outline":"material/file-undo-outline.svg","material-file-undo":"material/file-undo.svg","material-file-upload-outline":"material/file-upload-outline.svg","material-file-upload":"material/file-upload.svg","material-file-video-outline":"material/file-video-outline.svg","material-file-video":"material/file-video.svg","material-file-word-box-outline":"material/file-word-box-outline.svg","material-file-word-box":"material/file-word-box.svg","material-file-word-outline":"material/file-word-outline.svg","material-file-word":"material/file-word.svg","material-file":"material/file.svg","material-film":"material/film.svg","material-filmstrip-box-multiple":"material/filmstrip-box-multiple.svg","material-filmstrip-box":"material/filmstrip-box.svg","material-filmstrip-off":"material/filmstrip-off.svg","material-filmstrip":"material/filmstrip.svg","material-filter-menu-outline":"material/filter-menu-outline.svg","material-filter-menu":"material/filter-menu.svg","material-filter-minus-outline":"material/filter-minus-outline.svg","material-filter-minus":"material/filter-minus.svg","material-filter-off-outline":"material/filter-off-outline.svg","material-filter-off":"material/filter-off.svg","material-filter-outline":"material/filter-outline.svg","material-filter-plus-outline":"material/filter-plus-outline.svg","material-filter-plus":"material/filter-plus.svg","material-filter-remove-outline":"material/filter-remove-outline.svg","material-filter-remove":"material/filter-remove.svg","material-filter-variant-minus":"material/filter-variant-minus.svg","material-filter-variant-plus":"material/filter-variant-plus.svg","material-filter-variant-remove":"material/filter-variant-remove.svg","material-filter-variant":"material/filter-variant.svg","material-filter":"material/filter.svg","material-finance":"material/finance.svg","material-find-replace":"material/find-replace.svg","material-fingerprint-off":"material/fingerprint-off.svg","material-fingerprint":"material/fingerprint.svg","material-fire-alert":"material/fire-alert.svg","material-fire-extinguisher":"material/fire-extinguisher.svg","material-fire-hydrant-alert":"material/fire-hydrant-alert.svg","material-fire-hydrant-off":"material/fire-hydrant-off.svg","material-fire-hydrant":"material/fire-hydrant.svg","material-fire-off":"material/fire-off.svg","material-fire-truck":"material/fire-truck.svg","material-fire":"material/fire.svg","material-firebase":"material/firebase.svg","material-firefox":"material/firefox.svg","material-fireplace-off":"material/fireplace-off.svg","material-fireplace":"material/fireplace.svg","material-firework-off":"material/firework-off.svg","material-firework":"material/firework.svg","material-fish-off":"material/fish-off.svg","material-fish":"material/fish.svg","material-fishbowl-outline":"material/fishbowl-outline.svg","material-fishbowl":"material/fishbowl.svg","material-fit-to-page-outline":"material/fit-to-page-outline.svg","material-fit-to-page":"material/fit-to-page.svg","material-flag-checkered":"material/flag-checkered.svg","material-flag-minus-outline":"material/flag-minus-outline.svg","material-flag-minus":"material/flag-minus.svg","material-flag-outline":"material/flag-outline.svg","material-flag-plus-outline":"material/flag-plus-outline.svg","material-flag-plus":"material/flag-plus.svg","material-flag-remove-outline":"material/flag-remove-outline.svg","material-flag-remove":"material/flag-remove.svg","material-flag-triangle":"material/flag-triangle.svg","material-flag-variant-outline":"material/flag-variant-outline.svg","material-flag-variant":"material/flag-variant.svg","material-flag":"material/flag.svg","material-flare":"material/flare.svg","material-flash-alert-outline":"material/flash-alert-outline.svg","material-flash-alert":"material/flash-alert.svg","material-flash-auto":"material/flash-auto.svg","material-flash-circle":"material/flash-circle.svg","material-flash-off":"material/flash-off.svg","material-flash-outline":"material/flash-outline.svg","material-flash-red-eye":"material/flash-red-eye.svg","material-flash":"material/flash.svg","material-flashlight-off":"material/flashlight-off.svg","material-flashlight":"material/flashlight.svg","material-flask-empty-minus-outline":"material/flask-empty-minus-outline.svg","material-flask-empty-minus":"material/flask-empty-minus.svg","material-flask-empty-off-outline":"material/flask-empty-off-outline.svg","material-flask-empty-off":"material/flask-empty-off.svg","material-flask-empty-outline":"material/flask-empty-outline.svg","material-flask-empty-plus-outline":"material/flask-empty-plus-outline.svg","material-flask-empty-plus":"material/flask-empty-plus.svg","material-flask-empty-remove-outline":"material/flask-empty-remove-outline.svg","material-flask-empty-remove":"material/flask-empty-remove.svg","material-flask-empty":"material/flask-empty.svg","material-flask-minus-outline":"material/flask-minus-outline.svg","material-flask-minus":"material/flask-minus.svg","material-flask-off-outline":"material/flask-off-outline.svg","material-flask-off":"material/flask-off.svg","material-flask-outline":"material/flask-outline.svg","material-flask-plus-outline":"material/flask-plus-outline.svg","material-flask-plus":"material/flask-plus.svg","material-flask-remove-outline":"material/flask-remove-outline.svg","material-flask-remove":"material/flask-remove.svg","material-flask-round-bottom-empty-outline":"material/flask-round-bottom-empty-outline.svg","material-flask-round-bottom-empty":"material/flask-round-bottom-empty.svg","material-flask-round-bottom-outline":"material/flask-round-bottom-outline.svg","material-flask-round-bottom":"material/flask-round-bottom.svg","material-flask":"material/flask.svg","material-fleur-de-lis":"material/fleur-de-lis.svg","material-flip-horizontal":"material/flip-horizontal.svg","material-flip-to-back":"material/flip-to-back.svg","material-flip-to-front":"material/flip-to-front.svg","material-flip-vertical":"material/flip-vertical.svg","material-floor-lamp-dual":"material/floor-lamp-dual.svg","material-floor-lamp-variant":"material/floor-lamp-variant.svg","material-floor-lamp":"material/floor-lamp.svg","material-floor-plan":"material/floor-plan.svg","material-floppy-variant":"material/floppy-variant.svg","material-floppy":"material/floppy.svg","material-flower-outline":"material/flower-outline.svg","material-flower-poppy":"material/flower-poppy.svg","material-flower-tulip-outline":"material/flower-tulip-outline.svg","material-flower-tulip":"material/flower-tulip.svg","material-flower":"material/flower.svg","material-focus-auto":"material/focus-auto.svg","material-focus-field-horizontal":"material/focus-field-horizontal.svg","material-focus-field-vertical":"material/focus-field-vertical.svg","material-focus-field":"material/focus-field.svg","material-folder-account-outline":"material/folder-account-outline.svg","material-folder-account":"material/folder-account.svg","material-folder-alert-outline":"material/folder-alert-outline.svg","material-folder-alert":"material/folder-alert.svg","material-folder-clock-outline":"material/folder-clock-outline.svg","material-folder-clock":"material/folder-clock.svg","material-folder-cog-outline":"material/folder-cog-outline.svg","material-folder-cog":"material/folder-cog.svg","material-folder-download-outline":"material/folder-download-outline.svg","material-folder-download":"material/folder-download.svg","material-folder-edit-outline":"material/folder-edit-outline.svg","material-folder-edit":"material/folder-edit.svg","material-folder-google-drive":"material/folder-google-drive.svg","material-folder-heart-outline":"material/folder-heart-outline.svg","material-folder-heart":"material/folder-heart.svg","material-folder-home-outline":"material/folder-home-outline.svg","material-folder-home":"material/folder-home.svg","material-folder-image":"material/folder-image.svg","material-folder-information-outline":"material/folder-information-outline.svg","material-folder-information":"material/folder-information.svg","material-folder-key-network-outline":"material/folder-key-network-outline.svg","material-folder-key-network":"material/folder-key-network.svg","material-folder-key-outline":"material/folder-key-outline.svg","material-folder-key":"material/folder-key.svg","material-folder-lock-open":"material/folder-lock-open.svg","material-folder-lock":"material/folder-lock.svg","material-folder-marker-outline":"material/folder-marker-outline.svg","material-folder-marker":"material/folder-marker.svg","material-folder-move-outline":"material/folder-move-outline.svg","material-folder-move":"material/folder-move.svg","material-folder-multiple-image":"material/folder-multiple-image.svg","material-folder-multiple-outline":"material/folder-multiple-outline.svg","material-folder-multiple-plus-outline":"material/folder-multiple-plus-outline.svg","material-folder-multiple-plus":"material/folder-multiple-plus.svg","material-folder-multiple":"material/folder-multiple.svg","material-folder-music-outline":"material/folder-music-outline.svg","material-folder-music":"material/folder-music.svg","material-folder-network-outline":"material/folder-network-outline.svg","material-folder-network":"material/folder-network.svg","material-folder-open-outline":"material/folder-open-outline.svg","material-folder-open":"material/folder-open.svg","material-folder-outline":"material/folder-outline.svg","material-folder-plus-outline":"material/folder-plus-outline.svg","material-folder-plus":"material/folder-plus.svg","material-folder-pound-outline":"material/folder-pound-outline.svg","material-folder-pound":"material/folder-pound.svg","material-folder-refresh-outline":"material/folder-refresh-outline.svg","material-folder-refresh":"material/folder-refresh.svg","material-folder-remove-outline":"material/folder-remove-outline.svg","material-folder-remove":"material/folder-remove.svg","material-folder-search-outline":"material/folder-search-outline.svg","material-folder-search":"material/folder-search.svg","material-folder-settings-outline":"material/folder-settings-outline.svg","material-folder-settings":"material/folder-settings.svg","material-folder-star-multiple-outline":"material/folder-star-multiple-outline.svg","material-folder-star-multiple":"material/folder-star-multiple.svg","material-folder-star-outline":"material/folder-star-outline.svg","material-folder-star":"material/folder-star.svg","material-folder-swap-outline":"material/folder-swap-outline.svg","material-folder-swap":"material/folder-swap.svg","material-folder-sync-outline":"material/folder-sync-outline.svg","material-folder-sync":"material/folder-sync.svg","material-folder-table-outline":"material/folder-table-outline.svg","material-folder-table":"material/folder-table.svg","material-folder-text-outline":"material/folder-text-outline.svg","material-folder-text":"material/folder-text.svg","material-folder-upload-outline":"material/folder-upload-outline.svg","material-folder-upload":"material/folder-upload.svg","material-folder-zip-outline":"material/folder-zip-outline.svg","material-folder-zip":"material/folder-zip.svg","material-folder":"material/folder.svg","material-font-awesome":"material/font-awesome.svg","material-food-apple-outline":"material/food-apple-outline.svg","material-food-apple":"material/food-apple.svg","material-food-croissant":"material/food-croissant.svg","material-food-drumstick-off-outline":"material/food-drumstick-off-outline.svg","material-food-drumstick-off":"material/food-drumstick-off.svg","material-food-drumstick-outline":"material/food-drumstick-outline.svg","material-food-drumstick":"material/food-drumstick.svg","material-food-fork-drink":"material/food-fork-drink.svg","material-food-halal":"material/food-halal.svg","material-food-kosher":"material/food-kosher.svg","material-food-off":"material/food-off.svg","material-food-steak-off":"material/food-steak-off.svg","material-food-steak":"material/food-steak.svg","material-food-turkey":"material/food-turkey.svg","material-food-variant-off":"material/food-variant-off.svg","material-food-variant":"material/food-variant.svg","material-food":"material/food.svg","material-foot-print":"material/foot-print.svg","material-football-australian":"material/football-australian.svg","material-football-helmet":"material/football-helmet.svg","material-football":"material/football.svg","material-forklift":"material/forklift.svg","material-form-dropdown":"material/form-dropdown.svg","material-form-select":"material/form-select.svg","material-form-textarea":"material/form-textarea.svg","material-form-textbox-lock":"material/form-textbox-lock.svg","material-form-textbox-password":"material/form-textbox-password.svg","material-form-textbox":"material/form-textbox.svg","material-format-align-bottom":"material/format-align-bottom.svg","material-format-align-center":"material/format-align-center.svg","material-format-align-justify":"material/format-align-justify.svg","material-format-align-left":"material/format-align-left.svg","material-format-align-middle":"material/format-align-middle.svg","material-format-align-right":"material/format-align-right.svg","material-format-align-top":"material/format-align-top.svg","material-format-annotation-minus":"material/format-annotation-minus.svg","material-format-annotation-plus":"material/format-annotation-plus.svg","material-format-bold":"material/format-bold.svg","material-format-clear":"material/format-clear.svg","material-format-color-fill":"material/format-color-fill.svg","material-format-color-highlight":"material/format-color-highlight.svg","material-format-color-marker-cancel":"material/format-color-marker-cancel.svg","material-format-color-text":"material/format-color-text.svg","material-format-columns":"material/format-columns.svg","material-format-float-center":"material/format-float-center.svg","material-format-float-left":"material/format-float-left.svg","material-format-float-none":"material/format-float-none.svg","material-format-float-right":"material/format-float-right.svg","material-format-font-size-decrease":"material/format-font-size-decrease.svg","material-format-font-size-increase":"material/format-font-size-increase.svg","material-format-font":"material/format-font.svg","material-format-header-1":"material/format-header-1.svg","material-format-header-2":"material/format-header-2.svg","material-format-header-3":"material/format-header-3.svg","material-format-header-4":"material/format-header-4.svg","material-format-header-5":"material/format-header-5.svg","material-format-header-6":"material/format-header-6.svg","material-format-header-decrease":"material/format-header-decrease.svg","material-format-header-equal":"material/format-header-equal.svg","material-format-header-increase":"material/format-header-increase.svg","material-format-header-pound":"material/format-header-pound.svg","material-format-horizontal-align-center":"material/format-horizontal-align-center.svg","material-format-horizontal-align-left":"material/format-horizontal-align-left.svg","material-format-horizontal-align-right":"material/format-horizontal-align-right.svg","material-format-indent-decrease":"material/format-indent-decrease.svg","material-format-indent-increase":"material/format-indent-increase.svg","material-format-italic":"material/format-italic.svg","material-format-letter-case-lower":"material/format-letter-case-lower.svg","material-format-letter-case-upper":"material/format-letter-case-upper.svg","material-format-letter-case":"material/format-letter-case.svg","material-format-letter-ends-with":"material/format-letter-ends-with.svg","material-format-letter-matches":"material/format-letter-matches.svg","material-format-letter-starts-with":"material/format-letter-starts-with.svg","material-format-line-spacing":"material/format-line-spacing.svg","material-format-line-style":"material/format-line-style.svg","material-format-line-weight":"material/format-line-weight.svg","material-format-list-bulleted-square":"material/format-list-bulleted-square.svg","material-format-list-bulleted-triangle":"material/format-list-bulleted-triangle.svg","material-format-list-bulleted-type":"material/format-list-bulleted-type.svg","material-format-list-bulleted":"material/format-list-bulleted.svg","material-format-list-checkbox":"material/format-list-checkbox.svg","material-format-list-checks":"material/format-list-checks.svg","material-format-list-numbered-rtl":"material/format-list-numbered-rtl.svg","material-format-list-numbered":"material/format-list-numbered.svg","material-format-list-text":"material/format-list-text.svg","material-format-overline":"material/format-overline.svg","material-format-page-break":"material/format-page-break.svg","material-format-paint":"material/format-paint.svg","material-format-paragraph":"material/format-paragraph.svg","material-format-pilcrow":"material/format-pilcrow.svg","material-format-quote-close-outline":"material/format-quote-close-outline.svg","material-format-quote-close":"material/format-quote-close.svg","material-format-quote-open-outline":"material/format-quote-open-outline.svg","material-format-quote-open":"material/format-quote-open.svg","material-format-rotate-90":"material/format-rotate-90.svg","material-format-section":"material/format-section.svg","material-format-size":"material/format-size.svg","material-format-strikethrough-variant":"material/format-strikethrough-variant.svg","material-format-strikethrough":"material/format-strikethrough.svg","material-format-subscript":"material/format-subscript.svg","material-format-superscript":"material/format-superscript.svg","material-format-text-rotation-angle-down":"material/format-text-rotation-angle-down.svg","material-format-text-rotation-angle-up":"material/format-text-rotation-angle-up.svg","material-format-text-rotation-down-vertical":"material/format-text-rotation-down-vertical.svg","material-format-text-rotation-down":"material/format-text-rotation-down.svg","material-format-text-rotation-none":"material/format-text-rotation-none.svg","material-format-text-rotation-up":"material/format-text-rotation-up.svg","material-format-text-rotation-vertical":"material/format-text-rotation-vertical.svg","material-format-text-variant-outline":"material/format-text-variant-outline.svg","material-format-text-variant":"material/format-text-variant.svg","material-format-text-wrapping-clip":"material/format-text-wrapping-clip.svg","material-format-text-wrapping-overflow":"material/format-text-wrapping-overflow.svg","material-format-text-wrapping-wrap":"material/format-text-wrapping-wrap.svg","material-format-text":"material/format-text.svg","material-format-textbox":"material/format-textbox.svg","material-format-textdirection-l-to-r":"material/format-textdirection-l-to-r.svg","material-format-textdirection-r-to-l":"material/format-textdirection-r-to-l.svg","material-format-title":"material/format-title.svg","material-format-underline":"material/format-underline.svg","material-format-vertical-align-bottom":"material/format-vertical-align-bottom.svg","material-format-vertical-align-center":"material/format-vertical-align-center.svg","material-format-vertical-align-top":"material/format-vertical-align-top.svg","material-format-wrap-inline":"material/format-wrap-inline.svg","material-format-wrap-square":"material/format-wrap-square.svg","material-format-wrap-tight":"material/format-wrap-tight.svg","material-format-wrap-top-bottom":"material/format-wrap-top-bottom.svg","material-forum-outline":"material/forum-outline.svg","material-forum":"material/forum.svg","material-forward":"material/forward.svg","material-forwardburger":"material/forwardburger.svg","material-fountain-pen-tip":"material/fountain-pen-tip.svg","material-fountain-pen":"material/fountain-pen.svg","material-fountain":"material/fountain.svg","material-freebsd":"material/freebsd.svg","material-frequently-asked-questions":"material/frequently-asked-questions.svg","material-fridge-alert-outline":"material/fridge-alert-outline.svg","material-fridge-alert":"material/fridge-alert.svg","material-fridge-bottom":"material/fridge-bottom.svg","material-fridge-industrial-alert-outline":"material/fridge-industrial-alert-outline.svg","material-fridge-industrial-alert":"material/fridge-industrial-alert.svg","material-fridge-industrial-off-outline":"material/fridge-industrial-off-outline.svg","material-fridge-industrial-off":"material/fridge-industrial-off.svg","material-fridge-industrial-outline":"material/fridge-industrial-outline.svg","material-fridge-industrial":"material/fridge-industrial.svg","material-fridge-off-outline":"material/fridge-off-outline.svg","material-fridge-off":"material/fridge-off.svg","material-fridge-outline":"material/fridge-outline.svg","material-fridge-top":"material/fridge-top.svg","material-fridge-variant-alert-outline":"material/fridge-variant-alert-outline.svg","material-fridge-variant-alert":"material/fridge-variant-alert.svg","material-fridge-variant-off-outline":"material/fridge-variant-off-outline.svg","material-fridge-variant-off":"material/fridge-variant-off.svg","material-fridge-variant-outline":"material/fridge-variant-outline.svg","material-fridge-variant":"material/fridge-variant.svg","material-fridge":"material/fridge.svg","material-fruit-cherries-off":"material/fruit-cherries-off.svg","material-fruit-cherries":"material/fruit-cherries.svg","material-fruit-citrus-off":"material/fruit-citrus-off.svg","material-fruit-citrus":"material/fruit-citrus.svg","material-fruit-grapes-outline":"material/fruit-grapes-outline.svg","material-fruit-grapes":"material/fruit-grapes.svg","material-fruit-pineapple":"material/fruit-pineapple.svg","material-fruit-watermelon":"material/fruit-watermelon.svg","material-fuel":"material/fuel.svg","material-fullscreen-exit":"material/fullscreen-exit.svg","material-fullscreen":"material/fullscreen.svg","material-function-variant":"material/function-variant.svg","material-function":"material/function.svg","material-furigana-horizontal":"material/furigana-horizontal.svg","material-furigana-vertical":"material/furigana-vertical.svg","material-fuse-alert":"material/fuse-alert.svg","material-fuse-blade":"material/fuse-blade.svg","material-fuse-off":"material/fuse-off.svg","material-fuse":"material/fuse.svg","material-gamepad-circle-down":"material/gamepad-circle-down.svg","material-gamepad-circle-left":"material/gamepad-circle-left.svg","material-gamepad-circle-outline":"material/gamepad-circle-outline.svg","material-gamepad-circle-right":"material/gamepad-circle-right.svg","material-gamepad-circle-up":"material/gamepad-circle-up.svg","material-gamepad-circle":"material/gamepad-circle.svg","material-gamepad-down":"material/gamepad-down.svg","material-gamepad-left":"material/gamepad-left.svg","material-gamepad-right":"material/gamepad-right.svg","material-gamepad-round-down":"material/gamepad-round-down.svg","material-gamepad-round-left":"material/gamepad-round-left.svg","material-gamepad-round-outline":"material/gamepad-round-outline.svg","material-gamepad-round-right":"material/gamepad-round-right.svg","material-gamepad-round-up":"material/gamepad-round-up.svg","material-gamepad-round":"material/gamepad-round.svg","material-gamepad-square-outline":"material/gamepad-square-outline.svg","material-gamepad-square":"material/gamepad-square.svg","material-gamepad-up":"material/gamepad-up.svg","material-gamepad-variant-outline":"material/gamepad-variant-outline.svg","material-gamepad-variant":"material/gamepad-variant.svg","material-gamepad":"material/gamepad.svg","material-gamma":"material/gamma.svg","material-gantry-crane":"material/gantry-crane.svg","material-garage-alert-variant":"material/garage-alert-variant.svg","material-garage-alert":"material/garage-alert.svg","material-garage-open-variant":"material/garage-open-variant.svg","material-garage-open":"material/garage-open.svg","material-garage-variant":"material/garage-variant.svg","material-garage":"material/garage.svg","material-gas-cylinder":"material/gas-cylinder.svg","material-gas-station-off-outline":"material/gas-station-off-outline.svg","material-gas-station-off":"material/gas-station-off.svg","material-gas-station-outline":"material/gas-station-outline.svg","material-gas-station":"material/gas-station.svg","material-gate-and":"material/gate-and.svg","material-gate-arrow-right":"material/gate-arrow-right.svg","material-gate-nand":"material/gate-nand.svg","material-gate-nor":"material/gate-nor.svg","material-gate-not":"material/gate-not.svg","material-gate-open":"material/gate-open.svg","material-gate-or":"material/gate-or.svg","material-gate-xnor":"material/gate-xnor.svg","material-gate-xor":"material/gate-xor.svg","material-gate":"material/gate.svg","material-gatsby":"material/gatsby.svg","material-gauge-empty":"material/gauge-empty.svg","material-gauge-full":"material/gauge-full.svg","material-gauge-low":"material/gauge-low.svg","material-gauge":"material/gauge.svg","material-gavel":"material/gavel.svg","material-gender-female":"material/gender-female.svg","material-gender-male-female-variant":"material/gender-male-female-variant.svg","material-gender-male-female":"material/gender-male-female.svg","material-gender-male":"material/gender-male.svg","material-gender-non-binary":"material/gender-non-binary.svg","material-gender-transgender":"material/gender-transgender.svg","material-gentoo":"material/gentoo.svg","material-gesture-double-tap":"material/gesture-double-tap.svg","material-gesture-pinch":"material/gesture-pinch.svg","material-gesture-spread":"material/gesture-spread.svg","material-gesture-swipe-down":"material/gesture-swipe-down.svg","material-gesture-swipe-horizontal":"material/gesture-swipe-horizontal.svg","material-gesture-swipe-left":"material/gesture-swipe-left.svg","material-gesture-swipe-right":"material/gesture-swipe-right.svg","material-gesture-swipe-up":"material/gesture-swipe-up.svg","material-gesture-swipe-vertical":"material/gesture-swipe-vertical.svg","material-gesture-swipe":"material/gesture-swipe.svg","material-gesture-tap-box":"material/gesture-tap-box.svg","material-gesture-tap-button":"material/gesture-tap-button.svg","material-gesture-tap-hold":"material/gesture-tap-hold.svg","material-gesture-tap":"material/gesture-tap.svg","material-gesture-two-double-tap":"material/gesture-two-double-tap.svg","material-gesture-two-tap":"material/gesture-two-tap.svg","material-gesture":"material/gesture.svg","material-ghost-off-outline":"material/ghost-off-outline.svg","material-ghost-off":"material/ghost-off.svg","material-ghost-outline":"material/ghost-outline.svg","material-ghost":"material/ghost.svg","material-gif":"material/gif.svg","material-gift-off-outline":"material/gift-off-outline.svg","material-gift-off":"material/gift-off.svg","material-gift-open-outline":"material/gift-open-outline.svg","material-gift-open":"material/gift-open.svg","material-gift-outline":"material/gift-outline.svg","material-gift":"material/gift.svg","material-git":"material/git.svg","material-github":"material/github.svg","material-gitlab":"material/gitlab.svg","material-glass-cocktail-off":"material/glass-cocktail-off.svg","material-glass-cocktail":"material/glass-cocktail.svg","material-glass-flute":"material/glass-flute.svg","material-glass-mug-off":"material/glass-mug-off.svg","material-glass-mug-variant-off":"material/glass-mug-variant-off.svg","material-glass-mug-variant":"material/glass-mug-variant.svg","material-glass-mug":"material/glass-mug.svg","material-glass-pint-outline":"material/glass-pint-outline.svg","material-glass-stange":"material/glass-stange.svg","material-glass-tulip":"material/glass-tulip.svg","material-glass-wine":"material/glass-wine.svg","material-glasses":"material/glasses.svg","material-globe-light":"material/globe-light.svg","material-globe-model":"material/globe-model.svg","material-gmail":"material/gmail.svg","material-gnome":"material/gnome.svg","material-go-kart-track":"material/go-kart-track.svg","material-go-kart":"material/go-kart.svg","material-gog":"material/gog.svg","material-gold":"material/gold.svg","material-golf-cart":"material/golf-cart.svg","material-golf-tee":"material/golf-tee.svg","material-golf":"material/golf.svg","material-gondola":"material/gondola.svg","material-goodreads":"material/goodreads.svg","material-google-ads":"material/google-ads.svg","material-google-analytics":"material/google-analytics.svg","material-google-assistant":"material/google-assistant.svg","material-google-cardboard":"material/google-cardboard.svg","material-google-chrome":"material/google-chrome.svg","material-google-circles-communities":"material/google-circles-communities.svg","material-google-circles-extended":"material/google-circles-extended.svg","material-google-circles-group":"material/google-circles-group.svg","material-google-circles":"material/google-circles.svg","material-google-classroom":"material/google-classroom.svg","material-google-cloud":"material/google-cloud.svg","material-google-controller-off":"material/google-controller-off.svg","material-google-controller":"material/google-controller.svg","material-google-downasaur":"material/google-downasaur.svg","material-google-drive":"material/google-drive.svg","material-google-earth":"material/google-earth.svg","material-google-fit":"material/google-fit.svg","material-google-glass":"material/google-glass.svg","material-google-hangouts":"material/google-hangouts.svg","material-google-home":"material/google-home.svg","material-google-keep":"material/google-keep.svg","material-google-lens":"material/google-lens.svg","material-google-maps":"material/google-maps.svg","material-google-my-business":"material/google-my-business.svg","material-google-nearby":"material/google-nearby.svg","material-google-photos":"material/google-photos.svg","material-google-play":"material/google-play.svg","material-google-plus":"material/google-plus.svg","material-google-podcast":"material/google-podcast.svg","material-google-spreadsheet":"material/google-spreadsheet.svg","material-google-street-view":"material/google-street-view.svg","material-google-translate":"material/google-translate.svg","material-google":"material/google.svg","material-gradient":"material/gradient.svg","material-grain":"material/grain.svg","material-graph-outline":"material/graph-outline.svg","material-graph":"material/graph.svg","material-graphql":"material/graphql.svg","material-grass":"material/grass.svg","material-grave-stone":"material/grave-stone.svg","material-grease-pencil":"material/grease-pencil.svg","material-greater-than-or-equal":"material/greater-than-or-equal.svg","material-greater-than":"material/greater-than.svg","material-grid-large":"material/grid-large.svg","material-grid-off":"material/grid-off.svg","material-grid":"material/grid.svg","material-grill-outline":"material/grill-outline.svg","material-grill":"material/grill.svg","material-group":"material/group.svg","material-guitar-acoustic":"material/guitar-acoustic.svg","material-guitar-electric":"material/guitar-electric.svg","material-guitar-pick-outline":"material/guitar-pick-outline.svg","material-guitar-pick":"material/guitar-pick.svg","material-guy-fawkes-mask":"material/guy-fawkes-mask.svg","material-hail":"material/hail.svg","material-hair-dryer-outline":"material/hair-dryer-outline.svg","material-hair-dryer":"material/hair-dryer.svg","material-halloween":"material/halloween.svg","material-hamburger":"material/hamburger.svg","material-hammer-screwdriver":"material/hammer-screwdriver.svg","material-hammer-wrench":"material/hammer-wrench.svg","material-hammer":"material/hammer.svg","material-hand-heart-outline":"material/hand-heart-outline.svg","material-hand-heart":"material/hand-heart.svg","material-hand-left":"material/hand-left.svg","material-hand-okay":"material/hand-okay.svg","material-hand-peace-variant":"material/hand-peace-variant.svg","material-hand-peace":"material/hand-peace.svg","material-hand-pointing-down":"material/hand-pointing-down.svg","material-hand-pointing-left":"material/hand-pointing-left.svg","material-hand-pointing-right":"material/hand-pointing-right.svg","material-hand-pointing-up":"material/hand-pointing-up.svg","material-hand-right":"material/hand-right.svg","material-hand-saw":"material/hand-saw.svg","material-hand-wash-outline":"material/hand-wash-outline.svg","material-hand-wash":"material/hand-wash.svg","material-hand-water":"material/hand-water.svg","material-hand":"material/hand.svg","material-handball":"material/handball.svg","material-handcuffs":"material/handcuffs.svg","material-handshake-outline":"material/handshake-outline.svg","material-handshake":"material/handshake.svg","material-hanger":"material/hanger.svg","material-hard-hat":"material/hard-hat.svg","material-harddisk-plus":"material/harddisk-plus.svg","material-harddisk-remove":"material/harddisk-remove.svg","material-harddisk":"material/harddisk.svg","material-hat-fedora":"material/hat-fedora.svg","material-hazard-lights":"material/hazard-lights.svg","material-hdr-off":"material/hdr-off.svg","material-hdr":"material/hdr.svg","material-head-alert-outline":"material/head-alert-outline.svg","material-head-alert":"material/head-alert.svg","material-head-check-outline":"material/head-check-outline.svg","material-head-check":"material/head-check.svg","material-head-cog-outline":"material/head-cog-outline.svg","material-head-cog":"material/head-cog.svg","material-head-dots-horizontal-outline":"material/head-dots-horizontal-outline.svg","material-head-dots-horizontal":"material/head-dots-horizontal.svg","material-head-flash-outline":"material/head-flash-outline.svg","material-head-flash":"material/head-flash.svg","material-head-heart-outline":"material/head-heart-outline.svg","material-head-heart":"material/head-heart.svg","material-head-lightbulb-outline":"material/head-lightbulb-outline.svg","material-head-lightbulb":"material/head-lightbulb.svg","material-head-minus-outline":"material/head-minus-outline.svg","material-head-minus":"material/head-minus.svg","material-head-outline":"material/head-outline.svg","material-head-plus-outline":"material/head-plus-outline.svg","material-head-plus":"material/head-plus.svg","material-head-question-outline":"material/head-question-outline.svg","material-head-question":"material/head-question.svg","material-head-remove-outline":"material/head-remove-outline.svg","material-head-remove":"material/head-remove.svg","material-head-snowflake-outline":"material/head-snowflake-outline.svg","material-head-snowflake":"material/head-snowflake.svg","material-head-sync-outline":"material/head-sync-outline.svg","material-head-sync":"material/head-sync.svg","material-head":"material/head.svg","material-headphones-bluetooth":"material/headphones-bluetooth.svg","material-headphones-box":"material/headphones-box.svg","material-headphones-off":"material/headphones-off.svg","material-headphones-settings":"material/headphones-settings.svg","material-headphones":"material/headphones.svg","material-headset-dock":"material/headset-dock.svg","material-headset-off":"material/headset-off.svg","material-headset":"material/headset.svg","material-heart-box-outline":"material/heart-box-outline.svg","material-heart-box":"material/heart-box.svg","material-heart-broken-outline":"material/heart-broken-outline.svg","material-heart-broken":"material/heart-broken.svg","material-heart-circle-outline":"material/heart-circle-outline.svg","material-heart-circle":"material/heart-circle.svg","material-heart-cog-outline":"material/heart-cog-outline.svg","material-heart-cog":"material/heart-cog.svg","material-heart-flash":"material/heart-flash.svg","material-heart-half-full":"material/heart-half-full.svg","material-heart-half-outline":"material/heart-half-outline.svg","material-heart-half":"material/heart-half.svg","material-heart-minus-outline":"material/heart-minus-outline.svg","material-heart-minus":"material/heart-minus.svg","material-heart-multiple-outline":"material/heart-multiple-outline.svg","material-heart-multiple":"material/heart-multiple.svg","material-heart-off-outline":"material/heart-off-outline.svg","material-heart-off":"material/heart-off.svg","material-heart-outline":"material/heart-outline.svg","material-heart-plus-outline":"material/heart-plus-outline.svg","material-heart-plus":"material/heart-plus.svg","material-heart-pulse":"material/heart-pulse.svg","material-heart-remove-outline":"material/heart-remove-outline.svg","material-heart-remove":"material/heart-remove.svg","material-heart-settings-outline":"material/heart-settings-outline.svg","material-heart-settings":"material/heart-settings.svg","material-heart":"material/heart.svg","material-helicopter":"material/helicopter.svg","material-help-box":"material/help-box.svg","material-help-circle-outline":"material/help-circle-outline.svg","material-help-circle":"material/help-circle.svg","material-help-network-outline":"material/help-network-outline.svg","material-help-network":"material/help-network.svg","material-help-rhombus-outline":"material/help-rhombus-outline.svg","material-help-rhombus":"material/help-rhombus.svg","material-help":"material/help.svg","material-hexadecimal":"material/hexadecimal.svg","material-hexagon-multiple-outline":"material/hexagon-multiple-outline.svg","material-hexagon-multiple":"material/hexagon-multiple.svg","material-hexagon-outline":"material/hexagon-outline.svg","material-hexagon-slice-1":"material/hexagon-slice-1.svg","material-hexagon-slice-2":"material/hexagon-slice-2.svg","material-hexagon-slice-3":"material/hexagon-slice-3.svg","material-hexagon-slice-4":"material/hexagon-slice-4.svg","material-hexagon-slice-5":"material/hexagon-slice-5.svg","material-hexagon-slice-6":"material/hexagon-slice-6.svg","material-hexagon":"material/hexagon.svg","material-hexagram-outline":"material/hexagram-outline.svg","material-hexagram":"material/hexagram.svg","material-high-definition-box":"material/high-definition-box.svg","material-high-definition":"material/high-definition.svg","material-highway":"material/highway.svg","material-hiking":"material/hiking.svg","material-hinduism":"material/hinduism.svg","material-history":"material/history.svg","material-hockey-puck":"material/hockey-puck.svg","material-hockey-sticks":"material/hockey-sticks.svg","material-hololens":"material/hololens.svg","material-home-account":"material/home-account.svg","material-home-alert-outline":"material/home-alert-outline.svg","material-home-alert":"material/home-alert.svg","material-home-analytics":"material/home-analytics.svg","material-home-assistant":"material/home-assistant.svg","material-home-automation":"material/home-automation.svg","material-home-circle-outline":"material/home-circle-outline.svg","material-home-circle":"material/home-circle.svg","material-home-city-outline":"material/home-city-outline.svg","material-home-city":"material/home-city.svg","material-home-currency-usd":"material/home-currency-usd.svg","material-home-edit-outline":"material/home-edit-outline.svg","material-home-edit":"material/home-edit.svg","material-home-export-outline":"material/home-export-outline.svg","material-home-flood":"material/home-flood.svg","material-home-floor-0":"material/home-floor-0.svg","material-home-floor-1":"material/home-floor-1.svg","material-home-floor-2":"material/home-floor-2.svg","material-home-floor-3":"material/home-floor-3.svg","material-home-floor-a":"material/home-floor-a.svg","material-home-floor-b":"material/home-floor-b.svg","material-home-floor-g":"material/home-floor-g.svg","material-home-floor-l":"material/home-floor-l.svg","material-home-floor-negative-1":"material/home-floor-negative-1.svg","material-home-group":"material/home-group.svg","material-home-heart":"material/home-heart.svg","material-home-import-outline":"material/home-import-outline.svg","material-home-lightbulb-outline":"material/home-lightbulb-outline.svg","material-home-lightbulb":"material/home-lightbulb.svg","material-home-lock-open":"material/home-lock-open.svg","material-home-lock":"material/home-lock.svg","material-home-map-marker":"material/home-map-marker.svg","material-home-minus-outline":"material/home-minus-outline.svg","material-home-minus":"material/home-minus.svg","material-home-modern":"material/home-modern.svg","material-home-outline":"material/home-outline.svg","material-home-plus-outline":"material/home-plus-outline.svg","material-home-plus":"material/home-plus.svg","material-home-remove-outline":"material/home-remove-outline.svg","material-home-remove":"material/home-remove.svg","material-home-roof":"material/home-roof.svg","material-home-search-outline":"material/home-search-outline.svg","material-home-search":"material/home-search.svg","material-home-thermometer-outline":"material/home-thermometer-outline.svg","material-home-thermometer":"material/home-thermometer.svg","material-home-variant-outline":"material/home-variant-outline.svg","material-home-variant":"material/home-variant.svg","material-home":"material/home.svg","material-hook-off":"material/hook-off.svg","material-hook":"material/hook.svg","material-hops":"material/hops.svg","material-horizontal-rotate-clockwise":"material/horizontal-rotate-clockwise.svg","material-horizontal-rotate-counterclockwise":"material/horizontal-rotate-counterclockwise.svg","material-horse-human":"material/horse-human.svg","material-horse-variant":"material/horse-variant.svg","material-horse":"material/horse.svg","material-horseshoe":"material/horseshoe.svg","material-hospital-box-outline":"material/hospital-box-outline.svg","material-hospital-box":"material/hospital-box.svg","material-hospital-building":"material/hospital-building.svg","material-hospital-marker":"material/hospital-marker.svg","material-hospital":"material/hospital.svg","material-hot-tub":"material/hot-tub.svg","material-hours-24":"material/hours-24.svg","material-hubspot":"material/hubspot.svg","material-hulu":"material/hulu.svg","material-human-baby-changing-table":"material/human-baby-changing-table.svg","material-human-cane":"material/human-cane.svg","material-human-capacity-decrease":"material/human-capacity-decrease.svg","material-human-capacity-increase":"material/human-capacity-increase.svg","material-human-child":"material/human-child.svg","material-human-edit":"material/human-edit.svg","material-human-female-boy":"material/human-female-boy.svg","material-human-female-dance":"material/human-female-dance.svg","material-human-female-female":"material/human-female-female.svg","material-human-female-girl":"material/human-female-girl.svg","material-human-female":"material/human-female.svg","material-human-greeting-proximity":"material/human-greeting-proximity.svg","material-human-greeting":"material/human-greeting.svg","material-human-handsdown":"material/human-handsdown.svg","material-human-handsup":"material/human-handsup.svg","material-human-male-boy":"material/human-male-boy.svg","material-human-male-child":"material/human-male-child.svg","material-human-male-female":"material/human-male-female.svg","material-human-male-girl":"material/human-male-girl.svg","material-human-male-height-variant":"material/human-male-height-variant.svg","material-human-male-height":"material/human-male-height.svg","material-human-male-male":"material/human-male-male.svg","material-human-male":"material/human-male.svg","material-human-pregnant":"material/human-pregnant.svg","material-human-queue":"material/human-queue.svg","material-human-scooter":"material/human-scooter.svg","material-human-wheelchair":"material/human-wheelchair.svg","material-human":"material/human.svg","material-humble-bundle":"material/humble-bundle.svg","material-hvac-off":"material/hvac-off.svg","material-hvac":"material/hvac.svg","material-hydraulic-oil-level":"material/hydraulic-oil-level.svg","material-hydraulic-oil-temperature":"material/hydraulic-oil-temperature.svg","material-hydro-power":"material/hydro-power.svg","material-ice-cream-off":"material/ice-cream-off.svg","material-ice-cream":"material/ice-cream.svg","material-ice-pop":"material/ice-pop.svg","material-id-card":"material/id-card.svg","material-identifier":"material/identifier.svg","material-ideogram-cjk-variant":"material/ideogram-cjk-variant.svg","material-ideogram-cjk":"material/ideogram-cjk.svg","material-iframe-array-outline":"material/iframe-array-outline.svg","material-iframe-array":"material/iframe-array.svg","material-iframe-braces-outline":"material/iframe-braces-outline.svg","material-iframe-braces":"material/iframe-braces.svg","material-iframe-outline":"material/iframe-outline.svg","material-iframe-parentheses-outline":"material/iframe-parentheses-outline.svg","material-iframe-parentheses":"material/iframe-parentheses.svg","material-iframe-variable-outline":"material/iframe-variable-outline.svg","material-iframe-variable":"material/iframe-variable.svg","material-iframe":"material/iframe.svg","material-image-album":"material/image-album.svg","material-image-area-close":"material/image-area-close.svg","material-image-area":"material/image-area.svg","material-image-auto-adjust":"material/image-auto-adjust.svg","material-image-broken-variant":"material/image-broken-variant.svg","material-image-broken":"material/image-broken.svg","material-image-edit-outline":"material/image-edit-outline.svg","material-image-edit":"material/image-edit.svg","material-image-filter-black-white":"material/image-filter-black-white.svg","material-image-filter-center-focus-strong-outline":"material/image-filter-center-focus-strong-outline.svg","material-image-filter-center-focus-strong":"material/image-filter-center-focus-strong.svg","material-image-filter-center-focus-weak":"material/image-filter-center-focus-weak.svg","material-image-filter-center-focus":"material/image-filter-center-focus.svg","material-image-filter-drama":"material/image-filter-drama.svg","material-image-filter-frames":"material/image-filter-frames.svg","material-image-filter-hdr":"material/image-filter-hdr.svg","material-image-filter-none":"material/image-filter-none.svg","material-image-filter-tilt-shift":"material/image-filter-tilt-shift.svg","material-image-filter-vintage":"material/image-filter-vintage.svg","material-image-frame":"material/image-frame.svg","material-image-minus":"material/image-minus.svg","material-image-move":"material/image-move.svg","material-image-multiple-outline":"material/image-multiple-outline.svg","material-image-multiple":"material/image-multiple.svg","material-image-off-outline":"material/image-off-outline.svg","material-image-off":"material/image-off.svg","material-image-outline":"material/image-outline.svg","material-image-plus":"material/image-plus.svg","material-image-remove":"material/image-remove.svg","material-image-search-outline":"material/image-search-outline.svg","material-image-search":"material/image-search.svg","material-image-size-select-actual":"material/image-size-select-actual.svg","material-image-size-select-large":"material/image-size-select-large.svg","material-image-size-select-small":"material/image-size-select-small.svg","material-image-text":"material/image-text.svg","material-image":"material/image.svg","material-import":"material/import.svg","material-inbox-arrow-down-outline":"material/inbox-arrow-down-outline.svg","material-inbox-arrow-down":"material/inbox-arrow-down.svg","material-inbox-arrow-up-outline":"material/inbox-arrow-up-outline.svg","material-inbox-arrow-up":"material/inbox-arrow-up.svg","material-inbox-full-outline":"material/inbox-full-outline.svg","material-inbox-full":"material/inbox-full.svg","material-inbox-multiple-outline":"material/inbox-multiple-outline.svg","material-inbox-multiple":"material/inbox-multiple.svg","material-inbox-outline":"material/inbox-outline.svg","material-inbox-remove-outline":"material/inbox-remove-outline.svg","material-inbox-remove":"material/inbox-remove.svg","material-inbox":"material/inbox.svg","material-incognito-circle-off":"material/incognito-circle-off.svg","material-incognito-circle":"material/incognito-circle.svg","material-incognito-off":"material/incognito-off.svg","material-incognito":"material/incognito.svg","material-infinity":"material/infinity.svg","material-information-outline":"material/information-outline.svg","material-information-variant":"material/information-variant.svg","material-information":"material/information.svg","material-instagram":"material/instagram.svg","material-instrument-triangle":"material/instrument-triangle.svg","material-invert-colors-off":"material/invert-colors-off.svg","material-invert-colors":"material/invert-colors.svg","material-iobroker":"material/iobroker.svg","material-ip-network-outline":"material/ip-network-outline.svg","material-ip-network":"material/ip-network.svg","material-ip":"material/ip.svg","material-ipod":"material/ipod.svg","material-islam":"material/islam.svg","material-island":"material/island.svg","material-iv-bag":"material/iv-bag.svg","material-jabber":"material/jabber.svg","material-jeepney":"material/jeepney.svg","material-jellyfish-outline":"material/jellyfish-outline.svg","material-jellyfish":"material/jellyfish.svg","material-jira":"material/jira.svg","material-jquery":"material/jquery.svg","material-jsfiddle":"material/jsfiddle.svg","material-judaism":"material/judaism.svg","material-jump-rope":"material/jump-rope.svg","material-kabaddi":"material/kabaddi.svg","material-kangaroo":"material/kangaroo.svg","material-karate":"material/karate.svg","material-keg":"material/keg.svg","material-kettle-alert-outline":"material/kettle-alert-outline.svg","material-kettle-alert":"material/kettle-alert.svg","material-kettle-off-outline":"material/kettle-off-outline.svg","material-kettle-off":"material/kettle-off.svg","material-kettle-outline":"material/kettle-outline.svg","material-kettle-pour-over":"material/kettle-pour-over.svg","material-kettle-steam-outline":"material/kettle-steam-outline.svg","material-kettle-steam":"material/kettle-steam.svg","material-kettle":"material/kettle.svg","material-kettlebell":"material/kettlebell.svg","material-key-arrow-right":"material/key-arrow-right.svg","material-key-chain-variant":"material/key-chain-variant.svg","material-key-chain":"material/key-chain.svg","material-key-change":"material/key-change.svg","material-key-link":"material/key-link.svg","material-key-minus":"material/key-minus.svg","material-key-outline":"material/key-outline.svg","material-key-plus":"material/key-plus.svg","material-key-remove":"material/key-remove.svg","material-key-star":"material/key-star.svg","material-key-variant":"material/key-variant.svg","material-key-wireless":"material/key-wireless.svg","material-key":"material/key.svg","material-keyboard-backspace":"material/keyboard-backspace.svg","material-keyboard-caps":"material/keyboard-caps.svg","material-keyboard-close":"material/keyboard-close.svg","material-keyboard-esc":"material/keyboard-esc.svg","material-keyboard-f1":"material/keyboard-f1.svg","material-keyboard-f10":"material/keyboard-f10.svg","material-keyboard-f11":"material/keyboard-f11.svg","material-keyboard-f12":"material/keyboard-f12.svg","material-keyboard-f2":"material/keyboard-f2.svg","material-keyboard-f3":"material/keyboard-f3.svg","material-keyboard-f4":"material/keyboard-f4.svg","material-keyboard-f5":"material/keyboard-f5.svg","material-keyboard-f6":"material/keyboard-f6.svg","material-keyboard-f7":"material/keyboard-f7.svg","material-keyboard-f8":"material/keyboard-f8.svg","material-keyboard-f9":"material/keyboard-f9.svg","material-keyboard-off-outline":"material/keyboard-off-outline.svg","material-keyboard-off":"material/keyboard-off.svg","material-keyboard-outline":"material/keyboard-outline.svg","material-keyboard-return":"material/keyboard-return.svg","material-keyboard-settings-outline":"material/keyboard-settings-outline.svg","material-keyboard-settings":"material/keyboard-settings.svg","material-keyboard-space":"material/keyboard-space.svg","material-keyboard-tab":"material/keyboard-tab.svg","material-keyboard-variant":"material/keyboard-variant.svg","material-keyboard":"material/keyboard.svg","material-khanda":"material/khanda.svg","material-kickstarter":"material/kickstarter.svg","material-klingon":"material/klingon.svg","material-knife-military":"material/knife-military.svg","material-knife":"material/knife.svg","material-koala":"material/koala.svg","material-kodi":"material/kodi.svg","material-kubernetes":"material/kubernetes.svg","material-label-multiple-outline":"material/label-multiple-outline.svg","material-label-multiple":"material/label-multiple.svg","material-label-off-outline":"material/label-off-outline.svg","material-label-off":"material/label-off.svg","material-label-outline":"material/label-outline.svg","material-label-percent-outline":"material/label-percent-outline.svg","material-label-percent":"material/label-percent.svg","material-label-variant-outline":"material/label-variant-outline.svg","material-label-variant":"material/label-variant.svg","material-label":"material/label.svg","material-ladder":"material/ladder.svg","material-ladybug":"material/ladybug.svg","material-lambda":"material/lambda.svg","material-lamp":"material/lamp.svg","material-lamps":"material/lamps.svg","material-lan-check":"material/lan-check.svg","material-lan-connect":"material/lan-connect.svg","material-lan-disconnect":"material/lan-disconnect.svg","material-lan-pending":"material/lan-pending.svg","material-lan":"material/lan.svg","material-language-c":"material/language-c.svg","material-language-cpp":"material/language-cpp.svg","material-language-csharp":"material/language-csharp.svg","material-language-css3":"material/language-css3.svg","material-language-fortran":"material/language-fortran.svg","material-language-go":"material/language-go.svg","material-language-haskell":"material/language-haskell.svg","material-language-html5":"material/language-html5.svg","material-language-java":"material/language-java.svg","material-language-javascript":"material/language-javascript.svg","material-language-kotlin":"material/language-kotlin.svg","material-language-lua":"material/language-lua.svg","material-language-markdown-outline":"material/language-markdown-outline.svg","material-language-markdown":"material/language-markdown.svg","material-language-php":"material/language-php.svg","material-language-python":"material/language-python.svg","material-language-r":"material/language-r.svg","material-language-ruby-on-rails":"material/language-ruby-on-rails.svg","material-language-ruby":"material/language-ruby.svg","material-language-rust":"material/language-rust.svg","material-language-swift":"material/language-swift.svg","material-language-typescript":"material/language-typescript.svg","material-language-xaml":"material/language-xaml.svg","material-laptop-chromebook":"material/laptop-chromebook.svg","material-laptop-mac":"material/laptop-mac.svg","material-laptop-off":"material/laptop-off.svg","material-laptop-windows":"material/laptop-windows.svg","material-laptop":"material/laptop.svg","material-laravel":"material/laravel.svg","material-laser-pointer":"material/laser-pointer.svg","material-lasso":"material/lasso.svg","material-lastpass":"material/lastpass.svg","material-latitude":"material/latitude.svg","material-launch":"material/launch.svg","material-lava-lamp":"material/lava-lamp.svg","material-layers-minus":"material/layers-minus.svg","material-layers-off-outline":"material/layers-off-outline.svg","material-layers-off":"material/layers-off.svg","material-layers-outline":"material/layers-outline.svg","material-layers-plus":"material/layers-plus.svg","material-layers-remove":"material/layers-remove.svg","material-layers-search-outline":"material/layers-search-outline.svg","material-layers-search":"material/layers-search.svg","material-layers-triple-outline":"material/layers-triple-outline.svg","material-layers-triple":"material/layers-triple.svg","material-layers":"material/layers.svg","material-lead-pencil":"material/lead-pencil.svg","material-leaf-maple-off":"material/leaf-maple-off.svg","material-leaf-maple":"material/leaf-maple.svg","material-leaf-off":"material/leaf-off.svg","material-leaf":"material/leaf.svg","material-leak-off":"material/leak-off.svg","material-leak":"material/leak.svg","material-led-off":"material/led-off.svg","material-led-on":"material/led-on.svg","material-led-outline":"material/led-outline.svg","material-led-strip-variant":"material/led-strip-variant.svg","material-led-strip":"material/led-strip.svg","material-led-variant-off":"material/led-variant-off.svg","material-led-variant-on":"material/led-variant-on.svg","material-led-variant-outline":"material/led-variant-outline.svg","material-leek":"material/leek.svg","material-less-than-or-equal":"material/less-than-or-equal.svg","material-less-than":"material/less-than.svg","material-library-shelves":"material/library-shelves.svg","material-library":"material/library.svg","material-license":"material/license.svg","material-lifebuoy":"material/lifebuoy.svg","material-light-switch":"material/light-switch.svg","material-lightbulb-cfl-off":"material/lightbulb-cfl-off.svg","material-lightbulb-cfl-spiral-off":"material/lightbulb-cfl-spiral-off.svg","material-lightbulb-cfl-spiral":"material/lightbulb-cfl-spiral.svg","material-lightbulb-cfl":"material/lightbulb-cfl.svg","material-lightbulb-group-off-outline":"material/lightbulb-group-off-outline.svg","material-lightbulb-group-off":"material/lightbulb-group-off.svg","material-lightbulb-group-outline":"material/lightbulb-group-outline.svg","material-lightbulb-group":"material/lightbulb-group.svg","material-lightbulb-multiple-off-outline":"material/lightbulb-multiple-off-outline.svg","material-lightbulb-multiple-off":"material/lightbulb-multiple-off.svg","material-lightbulb-multiple-outline":"material/lightbulb-multiple-outline.svg","material-lightbulb-multiple":"material/lightbulb-multiple.svg","material-lightbulb-off-outline":"material/lightbulb-off-outline.svg","material-lightbulb-off":"material/lightbulb-off.svg","material-lightbulb-on-outline":"material/lightbulb-on-outline.svg","material-lightbulb-on":"material/lightbulb-on.svg","material-lightbulb-outline":"material/lightbulb-outline.svg","material-lightbulb":"material/lightbulb.svg","material-lighthouse-on":"material/lighthouse-on.svg","material-lighthouse":"material/lighthouse.svg","material-lightning-bolt-outline":"material/lightning-bolt-outline.svg","material-lightning-bolt":"material/lightning-bolt.svg","material-lingerie":"material/lingerie.svg","material-link-box-outline":"material/link-box-outline.svg","material-link-box-variant-outline":"material/link-box-variant-outline.svg","material-link-box-variant":"material/link-box-variant.svg","material-link-box":"material/link-box.svg","material-link-lock":"material/link-lock.svg","material-link-off":"material/link-off.svg","material-link-plus":"material/link-plus.svg","material-link-variant-minus":"material/link-variant-minus.svg","material-link-variant-off":"material/link-variant-off.svg","material-link-variant-plus":"material/link-variant-plus.svg","material-link-variant-remove":"material/link-variant-remove.svg","material-link-variant":"material/link-variant.svg","material-link":"material/link.svg","material-linkedin":"material/linkedin.svg","material-linux-mint":"material/linux-mint.svg","material-linux":"material/linux.svg","material-lipstick":"material/lipstick.svg","material-list-status":"material/list-status.svg","material-litecoin":"material/litecoin.svg","material-loading":"material/loading.svg","material-location-enter":"material/location-enter.svg","material-location-exit":"material/location-exit.svg","material-lock-alert-outline":"material/lock-alert-outline.svg","material-lock-alert":"material/lock-alert.svg","material-lock-check-outline":"material/lock-check-outline.svg","material-lock-check":"material/lock-check.svg","material-lock-clock":"material/lock-clock.svg","material-lock-minus-outline":"material/lock-minus-outline.svg","material-lock-minus":"material/lock-minus.svg","material-lock-off-outline":"material/lock-off-outline.svg","material-lock-off":"material/lock-off.svg","material-lock-open-alert-outline":"material/lock-open-alert-outline.svg","material-lock-open-alert":"material/lock-open-alert.svg","material-lock-open-check-outline":"material/lock-open-check-outline.svg","material-lock-open-check":"material/lock-open-check.svg","material-lock-open-minus-outline":"material/lock-open-minus-outline.svg","material-lock-open-minus":"material/lock-open-minus.svg","material-lock-open-outline":"material/lock-open-outline.svg","material-lock-open-plus-outline":"material/lock-open-plus-outline.svg","material-lock-open-plus":"material/lock-open-plus.svg","material-lock-open-remove-outline":"material/lock-open-remove-outline.svg","material-lock-open-remove":"material/lock-open-remove.svg","material-lock-open-variant-outline":"material/lock-open-variant-outline.svg","material-lock-open-variant":"material/lock-open-variant.svg","material-lock-open":"material/lock-open.svg","material-lock-outline":"material/lock-outline.svg","material-lock-pattern":"material/lock-pattern.svg","material-lock-plus-outline":"material/lock-plus-outline.svg","material-lock-plus":"material/lock-plus.svg","material-lock-question":"material/lock-question.svg","material-lock-remove-outline":"material/lock-remove-outline.svg","material-lock-remove":"material/lock-remove.svg","material-lock-reset":"material/lock-reset.svg","material-lock-smart":"material/lock-smart.svg","material-lock":"material/lock.svg","material-locker-multiple":"material/locker-multiple.svg","material-locker":"material/locker.svg","material-login-variant":"material/login-variant.svg","material-login":"material/login.svg","material-logout-variant":"material/logout-variant.svg","material-logout":"material/logout.svg","material-longitude":"material/longitude.svg","material-looks":"material/looks.svg","material-lotion-outline":"material/lotion-outline.svg","material-lotion-plus-outline":"material/lotion-plus-outline.svg","material-lotion-plus":"material/lotion-plus.svg","material-lotion":"material/lotion.svg","material-loupe":"material/loupe.svg","material-lumx":"material/lumx.svg","material-lungs":"material/lungs.svg","material-magnet-on":"material/magnet-on.svg","material-magnet":"material/magnet.svg","material-magnify-close":"material/magnify-close.svg","material-magnify-minus-cursor":"material/magnify-minus-cursor.svg","material-magnify-minus-outline":"material/magnify-minus-outline.svg","material-magnify-minus":"material/magnify-minus.svg","material-magnify-plus-cursor":"material/magnify-plus-cursor.svg","material-magnify-plus-outline":"material/magnify-plus-outline.svg","material-magnify-plus":"material/magnify-plus.svg","material-magnify-remove-cursor":"material/magnify-remove-cursor.svg","material-magnify-remove-outline":"material/magnify-remove-outline.svg","material-magnify-scan":"material/magnify-scan.svg","material-magnify":"material/magnify.svg","material-mail":"material/mail.svg","material-mailbox-open-outline":"material/mailbox-open-outline.svg","material-mailbox-open-up-outline":"material/mailbox-open-up-outline.svg","material-mailbox-open-up":"material/mailbox-open-up.svg","material-mailbox-open":"material/mailbox-open.svg","material-mailbox-outline":"material/mailbox-outline.svg","material-mailbox-up-outline":"material/mailbox-up-outline.svg","material-mailbox-up":"material/mailbox-up.svg","material-mailbox":"material/mailbox.svg","material-manjaro":"material/manjaro.svg","material-map-check-outline":"material/map-check-outline.svg","material-map-check":"material/map-check.svg","material-map-clock-outline":"material/map-clock-outline.svg","material-map-clock":"material/map-clock.svg","material-map-legend":"material/map-legend.svg","material-map-marker-alert-outline":"material/map-marker-alert-outline.svg","material-map-marker-alert":"material/map-marker-alert.svg","material-map-marker-check-outline":"material/map-marker-check-outline.svg","material-map-marker-check":"material/map-marker-check.svg","material-map-marker-circle":"material/map-marker-circle.svg","material-map-marker-distance":"material/map-marker-distance.svg","material-map-marker-down":"material/map-marker-down.svg","material-map-marker-left-outline":"material/map-marker-left-outline.svg","material-map-marker-left":"material/map-marker-left.svg","material-map-marker-minus-outline":"material/map-marker-minus-outline.svg","material-map-marker-minus":"material/map-marker-minus.svg","material-map-marker-multiple-outline":"material/map-marker-multiple-outline.svg","material-map-marker-multiple":"material/map-marker-multiple.svg","material-map-marker-off-outline":"material/map-marker-off-outline.svg","material-map-marker-off":"material/map-marker-off.svg","material-map-marker-outline":"material/map-marker-outline.svg","material-map-marker-path":"material/map-marker-path.svg","material-map-marker-plus-outline":"material/map-marker-plus-outline.svg","material-map-marker-plus":"material/map-marker-plus.svg","material-map-marker-question-outline":"material/map-marker-question-outline.svg","material-map-marker-question":"material/map-marker-question.svg","material-map-marker-radius-outline":"material/map-marker-radius-outline.svg","material-map-marker-radius":"material/map-marker-radius.svg","material-map-marker-remove-outline":"material/map-marker-remove-outline.svg","material-map-marker-remove-variant":"material/map-marker-remove-variant.svg","material-map-marker-remove":"material/map-marker-remove.svg","material-map-marker-right-outline":"material/map-marker-right-outline.svg","material-map-marker-right":"material/map-marker-right.svg","material-map-marker-star-outline":"material/map-marker-star-outline.svg","material-map-marker-star":"material/map-marker-star.svg","material-map-marker-up":"material/map-marker-up.svg","material-map-marker":"material/map-marker.svg","material-map-minus":"material/map-minus.svg","material-map-outline":"material/map-outline.svg","material-map-plus":"material/map-plus.svg","material-map-search-outline":"material/map-search-outline.svg","material-map-search":"material/map-search.svg","material-map":"material/map.svg","material-mapbox":"material/mapbox.svg","material-margin":"material/margin.svg","material-marker-cancel":"material/marker-cancel.svg","material-marker-check":"material/marker-check.svg","material-marker":"material/marker.svg","material-mastodon":"material/mastodon.svg","material-material-design":"material/material-design.svg","material-material-ui":"material/material-ui.svg","material-math-compass":"material/math-compass.svg","material-math-cos":"material/math-cos.svg","material-math-integral-box":"material/math-integral-box.svg","material-math-integral":"material/math-integral.svg","material-math-log":"material/math-log.svg","material-math-norm-box":"material/math-norm-box.svg","material-math-norm":"material/math-norm.svg","material-math-sin":"material/math-sin.svg","material-math-tan":"material/math-tan.svg","material-matrix":"material/matrix.svg","material-medal-outline":"material/medal-outline.svg","material-medal":"material/medal.svg","material-medical-bag":"material/medical-bag.svg","material-meditation":"material/meditation.svg","material-memory":"material/memory.svg","material-menu-down-outline":"material/menu-down-outline.svg","material-menu-down":"material/menu-down.svg","material-menu-left-outline":"material/menu-left-outline.svg","material-menu-left":"material/menu-left.svg","material-menu-open":"material/menu-open.svg","material-menu-right-outline":"material/menu-right-outline.svg","material-menu-right":"material/menu-right.svg","material-menu-swap-outline":"material/menu-swap-outline.svg","material-menu-swap":"material/menu-swap.svg","material-menu-up-outline":"material/menu-up-outline.svg","material-menu-up":"material/menu-up.svg","material-menu":"material/menu.svg","material-merge":"material/merge.svg","material-message-alert-outline":"material/message-alert-outline.svg","material-message-alert":"material/message-alert.svg","material-message-arrow-left-outline":"material/message-arrow-left-outline.svg","material-message-arrow-left":"material/message-arrow-left.svg","material-message-arrow-right-outline":"material/message-arrow-right-outline.svg","material-message-arrow-right":"material/message-arrow-right.svg","material-message-bookmark-outline":"material/message-bookmark-outline.svg","material-message-bookmark":"material/message-bookmark.svg","material-message-bulleted-off":"material/message-bulleted-off.svg","material-message-bulleted":"material/message-bulleted.svg","material-message-cog-outline":"material/message-cog-outline.svg","material-message-cog":"material/message-cog.svg","material-message-draw":"material/message-draw.svg","material-message-flash-outline":"material/message-flash-outline.svg","material-message-flash":"material/message-flash.svg","material-message-image-outline":"material/message-image-outline.svg","material-message-image":"material/message-image.svg","material-message-lock-outline":"material/message-lock-outline.svg","material-message-lock":"material/message-lock.svg","material-message-minus-outline":"material/message-minus-outline.svg","material-message-minus":"material/message-minus.svg","material-message-off-outline":"material/message-off-outline.svg","material-message-off":"material/message-off.svg","material-message-outline":"material/message-outline.svg","material-message-plus-outline":"material/message-plus-outline.svg","material-message-plus":"material/message-plus.svg","material-message-processing-outline":"material/message-processing-outline.svg","material-message-processing":"material/message-processing.svg","material-message-question-outline":"material/message-question-outline.svg","material-message-question":"material/message-question.svg","material-message-reply-outline":"material/message-reply-outline.svg","material-message-reply-text-outline":"material/message-reply-text-outline.svg","material-message-reply-text":"material/message-reply-text.svg","material-message-reply":"material/message-reply.svg","material-message-settings-outline":"material/message-settings-outline.svg","material-message-settings":"material/message-settings.svg","material-message-text-clock-outline":"material/message-text-clock-outline.svg","material-message-text-clock":"material/message-text-clock.svg","material-message-text-lock-outline":"material/message-text-lock-outline.svg","material-message-text-lock":"material/message-text-lock.svg","material-message-text-outline":"material/message-text-outline.svg","material-message-text":"material/message-text.svg","material-message-video":"material/message-video.svg","material-message":"material/message.svg","material-meteor":"material/meteor.svg","material-metronome-tick":"material/metronome-tick.svg","material-metronome":"material/metronome.svg","material-micro-sd":"material/micro-sd.svg","material-microphone-minus":"material/microphone-minus.svg","material-microphone-off":"material/microphone-off.svg","material-microphone-outline":"material/microphone-outline.svg","material-microphone-plus":"material/microphone-plus.svg","material-microphone-settings":"material/microphone-settings.svg","material-microphone-variant-off":"material/microphone-variant-off.svg","material-microphone-variant":"material/microphone-variant.svg","material-microphone":"material/microphone.svg","material-microscope":"material/microscope.svg","material-microsoft-access":"material/microsoft-access.svg","material-microsoft-azure-devops":"material/microsoft-azure-devops.svg","material-microsoft-azure":"material/microsoft-azure.svg","material-microsoft-bing":"material/microsoft-bing.svg","material-microsoft-dynamics-365":"material/microsoft-dynamics-365.svg","material-microsoft-edge-legacy":"material/microsoft-edge-legacy.svg","material-microsoft-edge":"material/microsoft-edge.svg","material-microsoft-excel":"material/microsoft-excel.svg","material-microsoft-internet-explorer":"material/microsoft-internet-explorer.svg","material-microsoft-office":"material/microsoft-office.svg","material-microsoft-onedrive":"material/microsoft-onedrive.svg","material-microsoft-onenote":"material/microsoft-onenote.svg","material-microsoft-outlook":"material/microsoft-outlook.svg","material-microsoft-powerpoint":"material/microsoft-powerpoint.svg","material-microsoft-sharepoint":"material/microsoft-sharepoint.svg","material-microsoft-teams":"material/microsoft-teams.svg","material-microsoft-visual-studio-code":"material/microsoft-visual-studio-code.svg","material-microsoft-visual-studio":"material/microsoft-visual-studio.svg","material-microsoft-windows-classic":"material/microsoft-windows-classic.svg","material-microsoft-windows":"material/microsoft-windows.svg","material-microsoft-word":"material/microsoft-word.svg","material-microsoft-xbox-controller-battery-alert":"material/microsoft-xbox-controller-battery-alert.svg","material-microsoft-xbox-controller-battery-charging":"material/microsoft-xbox-controller-battery-charging.svg","material-microsoft-xbox-controller-battery-empty":"material/microsoft-xbox-controller-battery-empty.svg","material-microsoft-xbox-controller-battery-full":"material/microsoft-xbox-controller-battery-full.svg","material-microsoft-xbox-controller-battery-low":"material/microsoft-xbox-controller-battery-low.svg","material-microsoft-xbox-controller-battery-medium":"material/microsoft-xbox-controller-battery-medium.svg","material-microsoft-xbox-controller-battery-unknown":"material/microsoft-xbox-controller-battery-unknown.svg","material-microsoft-xbox-controller-menu":"material/microsoft-xbox-controller-menu.svg","material-microsoft-xbox-controller-off":"material/microsoft-xbox-controller-off.svg","material-microsoft-xbox-controller-view":"material/microsoft-xbox-controller-view.svg","material-microsoft-xbox-controller":"material/microsoft-xbox-controller.svg","material-microsoft-xbox":"material/microsoft-xbox.svg","material-microsoft-yammer":"material/microsoft-yammer.svg","material-microsoft":"material/microsoft.svg","material-microwave-off":"material/microwave-off.svg","material-microwave":"material/microwave.svg","material-middleware-outline":"material/middleware-outline.svg","material-middleware":"material/middleware.svg","material-midi-port":"material/midi-port.svg","material-midi":"material/midi.svg","material-mine":"material/mine.svg","material-minecraft":"material/minecraft.svg","material-mini-sd":"material/mini-sd.svg","material-minidisc":"material/minidisc.svg","material-minus-box-multiple-outline":"material/minus-box-multiple-outline.svg","material-minus-box-multiple":"material/minus-box-multiple.svg","material-minus-box-outline":"material/minus-box-outline.svg","material-minus-box":"material/minus-box.svg","material-minus-circle-multiple-outline":"material/minus-circle-multiple-outline.svg","material-minus-circle-multiple":"material/minus-circle-multiple.svg","material-minus-circle-off-outline":"material/minus-circle-off-outline.svg","material-minus-circle-off":"material/minus-circle-off.svg","material-minus-circle-outline":"material/minus-circle-outline.svg","material-minus-circle":"material/minus-circle.svg","material-minus-network-outline":"material/minus-network-outline.svg","material-minus-network":"material/minus-network.svg","material-minus-thick":"material/minus-thick.svg","material-minus":"material/minus.svg","material-mirror":"material/mirror.svg","material-mixed-martial-arts":"material/mixed-martial-arts.svg","material-mixed-reality":"material/mixed-reality.svg","material-molecule-co":"material/molecule-co.svg","material-molecule-co2":"material/molecule-co2.svg","material-molecule":"material/molecule.svg","material-monitor-cellphone-star":"material/monitor-cellphone-star.svg","material-monitor-cellphone":"material/monitor-cellphone.svg","material-monitor-clean":"material/monitor-clean.svg","material-monitor-dashboard":"material/monitor-dashboard.svg","material-monitor-edit":"material/monitor-edit.svg","material-monitor-eye":"material/monitor-eye.svg","material-monitor-lock":"material/monitor-lock.svg","material-monitor-multiple":"material/monitor-multiple.svg","material-monitor-off":"material/monitor-off.svg","material-monitor-screenshot":"material/monitor-screenshot.svg","material-monitor-share":"material/monitor-share.svg","material-monitor-speaker-off":"material/monitor-speaker-off.svg","material-monitor-speaker":"material/monitor-speaker.svg","material-monitor-star":"material/monitor-star.svg","material-monitor":"material/monitor.svg","material-moon-first-quarter":"material/moon-first-quarter.svg","material-moon-full":"material/moon-full.svg","material-moon-last-quarter":"material/moon-last-quarter.svg","material-moon-new":"material/moon-new.svg","material-moon-waning-crescent":"material/moon-waning-crescent.svg","material-moon-waning-gibbous":"material/moon-waning-gibbous.svg","material-moon-waxing-crescent":"material/moon-waxing-crescent.svg","material-moon-waxing-gibbous":"material/moon-waxing-gibbous.svg","material-moped-electric-outline":"material/moped-electric-outline.svg","material-moped-electric":"material/moped-electric.svg","material-moped-outline":"material/moped-outline.svg","material-moped":"material/moped.svg","material-more":"material/more.svg","material-mother-heart":"material/mother-heart.svg","material-mother-nurse":"material/mother-nurse.svg","material-motion-outline":"material/motion-outline.svg","material-motion-pause-outline":"material/motion-pause-outline.svg","material-motion-pause":"material/motion-pause.svg","material-motion-play-outline":"material/motion-play-outline.svg","material-motion-play":"material/motion-play.svg","material-motion-sensor-off":"material/motion-sensor-off.svg","material-motion-sensor":"material/motion-sensor.svg","material-motion":"material/motion.svg","material-motorbike-electric":"material/motorbike-electric.svg","material-motorbike":"material/motorbike.svg","material-mouse-bluetooth":"material/mouse-bluetooth.svg","material-mouse-move-down":"material/mouse-move-down.svg","material-mouse-move-up":"material/mouse-move-up.svg","material-mouse-move-vertical":"material/mouse-move-vertical.svg","material-mouse-off":"material/mouse-off.svg","material-mouse-variant-off":"material/mouse-variant-off.svg","material-mouse-variant":"material/mouse-variant.svg","material-mouse":"material/mouse.svg","material-move-resize-variant":"material/move-resize-variant.svg","material-move-resize":"material/move-resize.svg","material-movie-check-outline":"material/movie-check-outline.svg","material-movie-check":"material/movie-check.svg","material-movie-cog-outline":"material/movie-cog-outline.svg","material-movie-cog":"material/movie-cog.svg","material-movie-edit-outline":"material/movie-edit-outline.svg","material-movie-edit":"material/movie-edit.svg","material-movie-filter-outline":"material/movie-filter-outline.svg","material-movie-filter":"material/movie-filter.svg","material-movie-minus-outline":"material/movie-minus-outline.svg","material-movie-minus":"material/movie-minus.svg","material-movie-off-outline":"material/movie-off-outline.svg","material-movie-off":"material/movie-off.svg","material-movie-open-check-outline":"material/movie-open-check-outline.svg","material-movie-open-check":"material/movie-open-check.svg","material-movie-open-cog-outline":"material/movie-open-cog-outline.svg","material-movie-open-cog":"material/movie-open-cog.svg","material-movie-open-edit-outline":"material/movie-open-edit-outline.svg","material-movie-open-edit":"material/movie-open-edit.svg","material-movie-open-minus-outline":"material/movie-open-minus-outline.svg","material-movie-open-minus":"material/movie-open-minus.svg","material-movie-open-off-outline":"material/movie-open-off-outline.svg","material-movie-open-off":"material/movie-open-off.svg","material-movie-open-outline":"material/movie-open-outline.svg","material-movie-open-play-outline":"material/movie-open-play-outline.svg","material-movie-open-play":"material/movie-open-play.svg","material-movie-open-plus-outline":"material/movie-open-plus-outline.svg","material-movie-open-plus":"material/movie-open-plus.svg","material-movie-open-remove-outline":"material/movie-open-remove-outline.svg","material-movie-open-remove":"material/movie-open-remove.svg","material-movie-open-settings-outline":"material/movie-open-settings-outline.svg","material-movie-open-settings":"material/movie-open-settings.svg","material-movie-open-star-outline":"material/movie-open-star-outline.svg","material-movie-open-star":"material/movie-open-star.svg","material-movie-open":"material/movie-open.svg","material-movie-outline":"material/movie-outline.svg","material-movie-play-outline":"material/movie-play-outline.svg","material-movie-play":"material/movie-play.svg","material-movie-plus-outline":"material/movie-plus-outline.svg","material-movie-plus":"material/movie-plus.svg","material-movie-remove-outline":"material/movie-remove-outline.svg","material-movie-remove":"material/movie-remove.svg","material-movie-roll":"material/movie-roll.svg","material-movie-search-outline":"material/movie-search-outline.svg","material-movie-search":"material/movie-search.svg","material-movie-settings-outline":"material/movie-settings-outline.svg","material-movie-settings":"material/movie-settings.svg","material-movie-star-outline":"material/movie-star-outline.svg","material-movie-star":"material/movie-star.svg","material-movie":"material/movie.svg","material-mower-bag":"material/mower-bag.svg","material-mower":"material/mower.svg","material-muffin":"material/muffin.svg","material-multiplication-box":"material/multiplication-box.svg","material-multiplication":"material/multiplication.svg","material-mushroom-off-outline":"material/mushroom-off-outline.svg","material-mushroom-off":"material/mushroom-off.svg","material-mushroom-outline":"material/mushroom-outline.svg","material-mushroom":"material/mushroom.svg","material-music-accidental-double-flat":"material/music-accidental-double-flat.svg","material-music-accidental-double-sharp":"material/music-accidental-double-sharp.svg","material-music-accidental-flat":"material/music-accidental-flat.svg","material-music-accidental-natural":"material/music-accidental-natural.svg","material-music-accidental-sharp":"material/music-accidental-sharp.svg","material-music-box-multiple-outline":"material/music-box-multiple-outline.svg","material-music-box-multiple":"material/music-box-multiple.svg","material-music-box-outline":"material/music-box-outline.svg","material-music-box":"material/music-box.svg","material-music-circle-outline":"material/music-circle-outline.svg","material-music-circle":"material/music-circle.svg","material-music-clef-alto":"material/music-clef-alto.svg","material-music-clef-bass":"material/music-clef-bass.svg","material-music-clef-treble":"material/music-clef-treble.svg","material-music-note-bluetooth-off":"material/music-note-bluetooth-off.svg","material-music-note-bluetooth":"material/music-note-bluetooth.svg","material-music-note-eighth-dotted":"material/music-note-eighth-dotted.svg","material-music-note-eighth":"material/music-note-eighth.svg","material-music-note-half-dotted":"material/music-note-half-dotted.svg","material-music-note-half":"material/music-note-half.svg","material-music-note-off-outline":"material/music-note-off-outline.svg","material-music-note-off":"material/music-note-off.svg","material-music-note-outline":"material/music-note-outline.svg","material-music-note-plus":"material/music-note-plus.svg","material-music-note-quarter-dotted":"material/music-note-quarter-dotted.svg","material-music-note-quarter":"material/music-note-quarter.svg","material-music-note-sixteenth-dotted":"material/music-note-sixteenth-dotted.svg","material-music-note-sixteenth":"material/music-note-sixteenth.svg","material-music-note-whole-dotted":"material/music-note-whole-dotted.svg","material-music-note-whole":"material/music-note-whole.svg","material-music-note":"material/music-note.svg","material-music-off":"material/music-off.svg","material-music-rest-eighth":"material/music-rest-eighth.svg","material-music-rest-half":"material/music-rest-half.svg","material-music-rest-quarter":"material/music-rest-quarter.svg","material-music-rest-sixteenth":"material/music-rest-sixteenth.svg","material-music-rest-whole":"material/music-rest-whole.svg","material-music":"material/music.svg","material-mustache":"material/mustache.svg","material-nail":"material/nail.svg","material-nas":"material/nas.svg","material-nativescript":"material/nativescript.svg","material-nature-people":"material/nature-people.svg","material-nature":"material/nature.svg","material-navigation-outline":"material/navigation-outline.svg","material-navigation":"material/navigation.svg","material-near-me":"material/near-me.svg","material-necklace":"material/necklace.svg","material-needle":"material/needle.svg","material-netflix":"material/netflix.svg","material-network-off-outline":"material/network-off-outline.svg","material-network-off":"material/network-off.svg","material-network-outline":"material/network-outline.svg","material-network-strength-1-alert":"material/network-strength-1-alert.svg","material-network-strength-1":"material/network-strength-1.svg","material-network-strength-2-alert":"material/network-strength-2-alert.svg","material-network-strength-2":"material/network-strength-2.svg","material-network-strength-3-alert":"material/network-strength-3-alert.svg","material-network-strength-3":"material/network-strength-3.svg","material-network-strength-4-alert":"material/network-strength-4-alert.svg","material-network-strength-4":"material/network-strength-4.svg","material-network-strength-off-outline":"material/network-strength-off-outline.svg","material-network-strength-off":"material/network-strength-off.svg","material-network-strength-outline":"material/network-strength-outline.svg","material-network":"material/network.svg","material-new-box":"material/new-box.svg","material-newspaper-minus":"material/newspaper-minus.svg","material-newspaper-plus":"material/newspaper-plus.svg","material-newspaper-variant-multiple-outline":"material/newspaper-variant-multiple-outline.svg","material-newspaper-variant-multiple":"material/newspaper-variant-multiple.svg","material-newspaper-variant-outline":"material/newspaper-variant-outline.svg","material-newspaper-variant":"material/newspaper-variant.svg","material-newspaper":"material/newspaper.svg","material-nfc-search-variant":"material/nfc-search-variant.svg","material-nfc-tap":"material/nfc-tap.svg","material-nfc-variant-off":"material/nfc-variant-off.svg","material-nfc-variant":"material/nfc-variant.svg","material-nfc":"material/nfc.svg","material-ninja":"material/ninja.svg","material-nintendo-game-boy":"material/nintendo-game-boy.svg","material-nintendo-switch":"material/nintendo-switch.svg","material-nintendo-wii":"material/nintendo-wii.svg","material-nintendo-wiiu":"material/nintendo-wiiu.svg","material-nix":"material/nix.svg","material-nodejs":"material/nodejs.svg","material-noodles":"material/noodles.svg","material-not-equal-variant":"material/not-equal-variant.svg","material-not-equal":"material/not-equal.svg","material-note-minus-outline":"material/note-minus-outline.svg","material-note-minus":"material/note-minus.svg","material-note-multiple-outline":"material/note-multiple-outline.svg","material-note-multiple":"material/note-multiple.svg","material-note-outline":"material/note-outline.svg","material-note-plus-outline":"material/note-plus-outline.svg","material-note-plus":"material/note-plus.svg","material-note-remove-outline":"material/note-remove-outline.svg","material-note-remove":"material/note-remove.svg","material-note-search-outline":"material/note-search-outline.svg","material-note-search":"material/note-search.svg","material-note-text-outline":"material/note-text-outline.svg","material-note-text":"material/note-text.svg","material-note":"material/note.svg","material-notebook-check-outline":"material/notebook-check-outline.svg","material-notebook-check":"material/notebook-check.svg","material-notebook-edit-outline":"material/notebook-edit-outline.svg","material-notebook-edit":"material/notebook-edit.svg","material-notebook-minus-outline":"material/notebook-minus-outline.svg","material-notebook-minus":"material/notebook-minus.svg","material-notebook-multiple":"material/notebook-multiple.svg","material-notebook-outline":"material/notebook-outline.svg","material-notebook-plus-outline":"material/notebook-plus-outline.svg","material-notebook-plus":"material/notebook-plus.svg","material-notebook-remove-outline":"material/notebook-remove-outline.svg","material-notebook-remove":"material/notebook-remove.svg","material-notebook":"material/notebook.svg","material-notification-clear-all":"material/notification-clear-all.svg","material-npm":"material/npm.svg","material-nuke":"material/nuke.svg","material-null":"material/null.svg","material-numeric-0-box-multiple-outline":"material/numeric-0-box-multiple-outline.svg","material-numeric-0-box-multiple":"material/numeric-0-box-multiple.svg","material-numeric-0-box-outline":"material/numeric-0-box-outline.svg","material-numeric-0-box":"material/numeric-0-box.svg","material-numeric-0-circle-outline":"material/numeric-0-circle-outline.svg","material-numeric-0-circle":"material/numeric-0-circle.svg","material-numeric-0":"material/numeric-0.svg","material-numeric-1-box-multiple-outline":"material/numeric-1-box-multiple-outline.svg","material-numeric-1-box-multiple":"material/numeric-1-box-multiple.svg","material-numeric-1-box-outline":"material/numeric-1-box-outline.svg","material-numeric-1-box":"material/numeric-1-box.svg","material-numeric-1-circle-outline":"material/numeric-1-circle-outline.svg","material-numeric-1-circle":"material/numeric-1-circle.svg","material-numeric-1":"material/numeric-1.svg","material-numeric-10-box-multiple-outline":"material/numeric-10-box-multiple-outline.svg","material-numeric-10-box-multiple":"material/numeric-10-box-multiple.svg","material-numeric-10-box-outline":"material/numeric-10-box-outline.svg","material-numeric-10-box":"material/numeric-10-box.svg","material-numeric-10-circle-outline":"material/numeric-10-circle-outline.svg","material-numeric-10-circle":"material/numeric-10-circle.svg","material-numeric-10":"material/numeric-10.svg","material-numeric-2-box-multiple-outline":"material/numeric-2-box-multiple-outline.svg","material-numeric-2-box-multiple":"material/numeric-2-box-multiple.svg","material-numeric-2-box-outline":"material/numeric-2-box-outline.svg","material-numeric-2-box":"material/numeric-2-box.svg","material-numeric-2-circle-outline":"material/numeric-2-circle-outline.svg","material-numeric-2-circle":"material/numeric-2-circle.svg","material-numeric-2":"material/numeric-2.svg","material-numeric-3-box-multiple-outline":"material/numeric-3-box-multiple-outline.svg","material-numeric-3-box-multiple":"material/numeric-3-box-multiple.svg","material-numeric-3-box-outline":"material/numeric-3-box-outline.svg","material-numeric-3-box":"material/numeric-3-box.svg","material-numeric-3-circle-outline":"material/numeric-3-circle-outline.svg","material-numeric-3-circle":"material/numeric-3-circle.svg","material-numeric-3":"material/numeric-3.svg","material-numeric-4-box-multiple-outline":"material/numeric-4-box-multiple-outline.svg","material-numeric-4-box-multiple":"material/numeric-4-box-multiple.svg","material-numeric-4-box-outline":"material/numeric-4-box-outline.svg","material-numeric-4-box":"material/numeric-4-box.svg","material-numeric-4-circle-outline":"material/numeric-4-circle-outline.svg","material-numeric-4-circle":"material/numeric-4-circle.svg","material-numeric-4":"material/numeric-4.svg","material-numeric-5-box-multiple-outline":"material/numeric-5-box-multiple-outline.svg","material-numeric-5-box-multiple":"material/numeric-5-box-multiple.svg","material-numeric-5-box-outline":"material/numeric-5-box-outline.svg","material-numeric-5-box":"material/numeric-5-box.svg","material-numeric-5-circle-outline":"material/numeric-5-circle-outline.svg","material-numeric-5-circle":"material/numeric-5-circle.svg","material-numeric-5":"material/numeric-5.svg","material-numeric-6-box-multiple-outline":"material/numeric-6-box-multiple-outline.svg","material-numeric-6-box-multiple":"material/numeric-6-box-multiple.svg","material-numeric-6-box-outline":"material/numeric-6-box-outline.svg","material-numeric-6-box":"material/numeric-6-box.svg","material-numeric-6-circle-outline":"material/numeric-6-circle-outline.svg","material-numeric-6-circle":"material/numeric-6-circle.svg","material-numeric-6":"material/numeric-6.svg","material-numeric-7-box-multiple-outline":"material/numeric-7-box-multiple-outline.svg","material-numeric-7-box-multiple":"material/numeric-7-box-multiple.svg","material-numeric-7-box-outline":"material/numeric-7-box-outline.svg","material-numeric-7-box":"material/numeric-7-box.svg","material-numeric-7-circle-outline":"material/numeric-7-circle-outline.svg","material-numeric-7-circle":"material/numeric-7-circle.svg","material-numeric-7":"material/numeric-7.svg","material-numeric-8-box-multiple-outline":"material/numeric-8-box-multiple-outline.svg","material-numeric-8-box-multiple":"material/numeric-8-box-multiple.svg","material-numeric-8-box-outline":"material/numeric-8-box-outline.svg","material-numeric-8-box":"material/numeric-8-box.svg","material-numeric-8-circle-outline":"material/numeric-8-circle-outline.svg","material-numeric-8-circle":"material/numeric-8-circle.svg","material-numeric-8":"material/numeric-8.svg","material-numeric-9-box-multiple-outline":"material/numeric-9-box-multiple-outline.svg","material-numeric-9-box-multiple":"material/numeric-9-box-multiple.svg","material-numeric-9-box-outline":"material/numeric-9-box-outline.svg","material-numeric-9-box":"material/numeric-9-box.svg","material-numeric-9-circle-outline":"material/numeric-9-circle-outline.svg","material-numeric-9-circle":"material/numeric-9-circle.svg","material-numeric-9-plus-box-multiple-outline":"material/numeric-9-plus-box-multiple-outline.svg","material-numeric-9-plus-box-multiple":"material/numeric-9-plus-box-multiple.svg","material-numeric-9-plus-box-outline":"material/numeric-9-plus-box-outline.svg","material-numeric-9-plus-box":"material/numeric-9-plus-box.svg","material-numeric-9-plus-circle-outline":"material/numeric-9-plus-circle-outline.svg","material-numeric-9-plus-circle":"material/numeric-9-plus-circle.svg","material-numeric-9-plus":"material/numeric-9-plus.svg","material-numeric-9":"material/numeric-9.svg","material-numeric-negative-1":"material/numeric-negative-1.svg","material-numeric-positive-1":"material/numeric-positive-1.svg","material-numeric":"material/numeric.svg","material-nut":"material/nut.svg","material-nutrition":"material/nutrition.svg","material-nuxt":"material/nuxt.svg","material-oar":"material/oar.svg","material-ocarina":"material/ocarina.svg","material-oci":"material/oci.svg","material-ocr":"material/ocr.svg","material-octagon-outline":"material/octagon-outline.svg","material-octagon":"material/octagon.svg","material-octagram-outline":"material/octagram-outline.svg","material-octagram":"material/octagram.svg","material-odnoklassniki":"material/odnoklassniki.svg","material-offer":"material/offer.svg","material-office-building-marker-outline":"material/office-building-marker-outline.svg","material-office-building-marker":"material/office-building-marker.svg","material-office-building-outline":"material/office-building-outline.svg","material-office-building":"material/office-building.svg","material-oil-lamp":"material/oil-lamp.svg","material-oil-level":"material/oil-level.svg","material-oil-temperature":"material/oil-temperature.svg","material-oil":"material/oil.svg","material-omega":"material/omega.svg","material-one-up":"material/one-up.svg","material-onepassword":"material/onepassword.svg","material-opacity":"material/opacity.svg","material-open-in-app":"material/open-in-app.svg","material-open-in-new":"material/open-in-new.svg","material-open-source-initiative":"material/open-source-initiative.svg","material-openid":"material/openid.svg","material-opera":"material/opera.svg","material-orbit-variant":"material/orbit-variant.svg","material-orbit":"material/orbit.svg","material-order-alphabetical-ascending":"material/order-alphabetical-ascending.svg","material-order-alphabetical-descending":"material/order-alphabetical-descending.svg","material-order-bool-ascending-variant":"material/order-bool-ascending-variant.svg","material-order-bool-ascending":"material/order-bool-ascending.svg","material-order-bool-descending-variant":"material/order-bool-descending-variant.svg","material-order-bool-descending":"material/order-bool-descending.svg","material-order-numeric-ascending":"material/order-numeric-ascending.svg","material-order-numeric-descending":"material/order-numeric-descending.svg","material-origin":"material/origin.svg","material-ornament-variant":"material/ornament-variant.svg","material-ornament":"material/ornament.svg","material-outdoor-lamp":"material/outdoor-lamp.svg","material-overscan":"material/overscan.svg","material-owl":"material/owl.svg","material-pac-man":"material/pac-man.svg","material-package-down":"material/package-down.svg","material-package-up":"material/package-up.svg","material-package-variant-closed":"material/package-variant-closed.svg","material-package-variant":"material/package-variant.svg","material-package":"material/package.svg","material-page-first":"material/page-first.svg","material-page-last":"material/page-last.svg","material-page-layout-body":"material/page-layout-body.svg","material-page-layout-footer":"material/page-layout-footer.svg","material-page-layout-header-footer":"material/page-layout-header-footer.svg","material-page-layout-header":"material/page-layout-header.svg","material-page-layout-sidebar-left":"material/page-layout-sidebar-left.svg","material-page-layout-sidebar-right":"material/page-layout-sidebar-right.svg","material-page-next-outline":"material/page-next-outline.svg","material-page-next":"material/page-next.svg","material-page-previous-outline":"material/page-previous-outline.svg","material-page-previous":"material/page-previous.svg","material-pail-minus-outline":"material/pail-minus-outline.svg","material-pail-minus":"material/pail-minus.svg","material-pail-off-outline":"material/pail-off-outline.svg","material-pail-off":"material/pail-off.svg","material-pail-outline":"material/pail-outline.svg","material-pail-plus-outline":"material/pail-plus-outline.svg","material-pail-plus":"material/pail-plus.svg","material-pail-remove-outline":"material/pail-remove-outline.svg","material-pail-remove":"material/pail-remove.svg","material-pail":"material/pail.svg","material-palette-advanced":"material/palette-advanced.svg","material-palette-outline":"material/palette-outline.svg","material-palette-swatch-outline":"material/palette-swatch-outline.svg","material-palette-swatch":"material/palette-swatch.svg","material-palette":"material/palette.svg","material-palm-tree":"material/palm-tree.svg","material-pan-bottom-left":"material/pan-bottom-left.svg","material-pan-bottom-right":"material/pan-bottom-right.svg","material-pan-down":"material/pan-down.svg","material-pan-horizontal":"material/pan-horizontal.svg","material-pan-left":"material/pan-left.svg","material-pan-right":"material/pan-right.svg","material-pan-top-left":"material/pan-top-left.svg","material-pan-top-right":"material/pan-top-right.svg","material-pan-up":"material/pan-up.svg","material-pan-vertical":"material/pan-vertical.svg","material-pan":"material/pan.svg","material-panda":"material/panda.svg","material-pandora":"material/pandora.svg","material-panorama-fisheye":"material/panorama-fisheye.svg","material-panorama-horizontal":"material/panorama-horizontal.svg","material-panorama-vertical":"material/panorama-vertical.svg","material-panorama-wide-angle":"material/panorama-wide-angle.svg","material-panorama":"material/panorama.svg","material-paper-cut-vertical":"material/paper-cut-vertical.svg","material-paper-roll-outline":"material/paper-roll-outline.svg","material-paper-roll":"material/paper-roll.svg","material-paperclip":"material/paperclip.svg","material-parachute-outline":"material/parachute-outline.svg","material-parachute":"material/parachute.svg","material-parking":"material/parking.svg","material-party-popper":"material/party-popper.svg","material-passport-biometric":"material/passport-biometric.svg","material-passport":"material/passport.svg","material-pasta":"material/pasta.svg","material-patio-heater":"material/patio-heater.svg","material-patreon":"material/patreon.svg","material-pause-circle-outline":"material/pause-circle-outline.svg","material-pause-circle":"material/pause-circle.svg","material-pause-octagon-outline":"material/pause-octagon-outline.svg","material-pause-octagon":"material/pause-octagon.svg","material-pause":"material/pause.svg","material-paw-off-outline":"material/paw-off-outline.svg","material-paw-off":"material/paw-off.svg","material-paw-outline":"material/paw-outline.svg","material-paw":"material/paw.svg","material-pdf-box":"material/pdf-box.svg","material-peace":"material/peace.svg","material-peanut-off-outline":"material/peanut-off-outline.svg","material-peanut-off":"material/peanut-off.svg","material-peanut-outline":"material/peanut-outline.svg","material-peanut":"material/peanut.svg","material-pen-lock":"material/pen-lock.svg","material-pen-minus":"material/pen-minus.svg","material-pen-off":"material/pen-off.svg","material-pen-plus":"material/pen-plus.svg","material-pen-remove":"material/pen-remove.svg","material-pen":"material/pen.svg","material-pencil-box-multiple-outline":"material/pencil-box-multiple-outline.svg","material-pencil-box-multiple":"material/pencil-box-multiple.svg","material-pencil-box-outline":"material/pencil-box-outline.svg","material-pencil-box":"material/pencil-box.svg","material-pencil-circle-outline":"material/pencil-circle-outline.svg","material-pencil-circle":"material/pencil-circle.svg","material-pencil-lock-outline":"material/pencil-lock-outline.svg","material-pencil-lock":"material/pencil-lock.svg","material-pencil-minus-outline":"material/pencil-minus-outline.svg","material-pencil-minus":"material/pencil-minus.svg","material-pencil-off-outline":"material/pencil-off-outline.svg","material-pencil-off":"material/pencil-off.svg","material-pencil-outline":"material/pencil-outline.svg","material-pencil-plus-outline":"material/pencil-plus-outline.svg","material-pencil-plus":"material/pencil-plus.svg","material-pencil-remove-outline":"material/pencil-remove-outline.svg","material-pencil-remove":"material/pencil-remove.svg","material-pencil-ruler":"material/pencil-ruler.svg","material-pencil":"material/pencil.svg","material-penguin":"material/penguin.svg","material-pentagon-outline":"material/pentagon-outline.svg","material-pentagon":"material/pentagon.svg","material-pentagram":"material/pentagram.svg","material-percent-outline":"material/percent-outline.svg","material-percent":"material/percent.svg","material-periodic-table":"material/periodic-table.svg","material-perspective-less":"material/perspective-less.svg","material-perspective-more":"material/perspective-more.svg","material-pharmacy":"material/pharmacy.svg","material-phone-alert-outline":"material/phone-alert-outline.svg","material-phone-alert":"material/phone-alert.svg","material-phone-bluetooth-outline":"material/phone-bluetooth-outline.svg","material-phone-bluetooth":"material/phone-bluetooth.svg","material-phone-cancel-outline":"material/phone-cancel-outline.svg","material-phone-cancel":"material/phone-cancel.svg","material-phone-check-outline":"material/phone-check-outline.svg","material-phone-check":"material/phone-check.svg","material-phone-classic-off":"material/phone-classic-off.svg","material-phone-classic":"material/phone-classic.svg","material-phone-dial-outline":"material/phone-dial-outline.svg","material-phone-dial":"material/phone-dial.svg","material-phone-forward-outline":"material/phone-forward-outline.svg","material-phone-forward":"material/phone-forward.svg","material-phone-hangup-outline":"material/phone-hangup-outline.svg","material-phone-hangup":"material/phone-hangup.svg","material-phone-in-talk-outline":"material/phone-in-talk-outline.svg","material-phone-in-talk":"material/phone-in-talk.svg","material-phone-incoming-outline":"material/phone-incoming-outline.svg","material-phone-incoming":"material/phone-incoming.svg","material-phone-lock-outline":"material/phone-lock-outline.svg","material-phone-lock":"material/phone-lock.svg","material-phone-log-outline":"material/phone-log-outline.svg","material-phone-log":"material/phone-log.svg","material-phone-message-outline":"material/phone-message-outline.svg","material-phone-message":"material/phone-message.svg","material-phone-minus-outline":"material/phone-minus-outline.svg","material-phone-minus":"material/phone-minus.svg","material-phone-missed-outline":"material/phone-missed-outline.svg","material-phone-missed":"material/phone-missed.svg","material-phone-off-outline":"material/phone-off-outline.svg","material-phone-off":"material/phone-off.svg","material-phone-outgoing-outline":"material/phone-outgoing-outline.svg","material-phone-outgoing":"material/phone-outgoing.svg","material-phone-outline":"material/phone-outline.svg","material-phone-paused-outline":"material/phone-paused-outline.svg","material-phone-paused":"material/phone-paused.svg","material-phone-plus-outline":"material/phone-plus-outline.svg","material-phone-plus":"material/phone-plus.svg","material-phone-remove-outline":"material/phone-remove-outline.svg","material-phone-remove":"material/phone-remove.svg","material-phone-return-outline":"material/phone-return-outline.svg","material-phone-return":"material/phone-return.svg","material-phone-ring-outline":"material/phone-ring-outline.svg","material-phone-ring":"material/phone-ring.svg","material-phone-rotate-landscape":"material/phone-rotate-landscape.svg","material-phone-rotate-portrait":"material/phone-rotate-portrait.svg","material-phone-settings-outline":"material/phone-settings-outline.svg","material-phone-settings":"material/phone-settings.svg","material-phone-voip":"material/phone-voip.svg","material-phone":"material/phone.svg","material-pi-box":"material/pi-box.svg","material-pi-hole":"material/pi-hole.svg","material-pi":"material/pi.svg","material-piano":"material/piano.svg","material-pickaxe":"material/pickaxe.svg","material-picture-in-picture-bottom-right-outline":"material/picture-in-picture-bottom-right-outline.svg","material-picture-in-picture-bottom-right":"material/picture-in-picture-bottom-right.svg","material-picture-in-picture-top-right-outline":"material/picture-in-picture-top-right-outline.svg","material-picture-in-picture-top-right":"material/picture-in-picture-top-right.svg","material-pier-crane":"material/pier-crane.svg","material-pier":"material/pier.svg","material-pig-variant-outline":"material/pig-variant-outline.svg","material-pig-variant":"material/pig-variant.svg","material-pig":"material/pig.svg","material-piggy-bank-outline":"material/piggy-bank-outline.svg","material-piggy-bank":"material/piggy-bank.svg","material-pill":"material/pill.svg","material-pillar":"material/pillar.svg","material-pin-off-outline":"material/pin-off-outline.svg","material-pin-off":"material/pin-off.svg","material-pin-outline":"material/pin-outline.svg","material-pin":"material/pin.svg","material-pine-tree-box":"material/pine-tree-box.svg","material-pine-tree-fire":"material/pine-tree-fire.svg","material-pine-tree":"material/pine-tree.svg","material-pinterest":"material/pinterest.svg","material-pinwheel-outline":"material/pinwheel-outline.svg","material-pinwheel":"material/pinwheel.svg","material-pipe-disconnected":"material/pipe-disconnected.svg","material-pipe-leak":"material/pipe-leak.svg","material-pipe-wrench":"material/pipe-wrench.svg","material-pipe":"material/pipe.svg","material-pirate":"material/pirate.svg","material-pistol":"material/pistol.svg","material-piston":"material/piston.svg","material-pitchfork":"material/pitchfork.svg","material-pizza":"material/pizza.svg","material-play-box-multiple-outline":"material/play-box-multiple-outline.svg","material-play-box-multiple":"material/play-box-multiple.svg","material-play-box-outline":"material/play-box-outline.svg","material-play-box":"material/play-box.svg","material-play-circle-outline":"material/play-circle-outline.svg","material-play-circle":"material/play-circle.svg","material-play-network-outline":"material/play-network-outline.svg","material-play-network":"material/play-network.svg","material-play-outline":"material/play-outline.svg","material-play-pause":"material/play-pause.svg","material-play-protected-content":"material/play-protected-content.svg","material-play-speed":"material/play-speed.svg","material-play":"material/play.svg","material-playlist-check":"material/playlist-check.svg","material-playlist-edit":"material/playlist-edit.svg","material-playlist-minus":"material/playlist-minus.svg","material-playlist-music-outline":"material/playlist-music-outline.svg","material-playlist-music":"material/playlist-music.svg","material-playlist-play":"material/playlist-play.svg","material-playlist-plus":"material/playlist-plus.svg","material-playlist-remove":"material/playlist-remove.svg","material-playlist-star":"material/playlist-star.svg","material-plex":"material/plex.svg","material-plus-box-multiple-outline":"material/plus-box-multiple-outline.svg","material-plus-box-multiple":"material/plus-box-multiple.svg","material-plus-box-outline":"material/plus-box-outline.svg","material-plus-box":"material/plus-box.svg","material-plus-circle-multiple-outline":"material/plus-circle-multiple-outline.svg","material-plus-circle-multiple":"material/plus-circle-multiple.svg","material-plus-circle-outline":"material/plus-circle-outline.svg","material-plus-circle":"material/plus-circle.svg","material-plus-minus-box":"material/plus-minus-box.svg","material-plus-minus-variant":"material/plus-minus-variant.svg","material-plus-minus":"material/plus-minus.svg","material-plus-network-outline":"material/plus-network-outline.svg","material-plus-network":"material/plus-network.svg","material-plus-one":"material/plus-one.svg","material-plus-outline":"material/plus-outline.svg","material-plus-thick":"material/plus-thick.svg","material-plus":"material/plus.svg","material-podcast":"material/podcast.svg","material-podium-bronze":"material/podium-bronze.svg","material-podium-gold":"material/podium-gold.svg","material-podium-silver":"material/podium-silver.svg","material-podium":"material/podium.svg","material-point-of-sale":"material/point-of-sale.svg","material-pokeball":"material/pokeball.svg","material-pokemon-go":"material/pokemon-go.svg","material-poker-chip":"material/poker-chip.svg","material-polaroid":"material/polaroid.svg","material-police-badge-outline":"material/police-badge-outline.svg","material-police-badge":"material/police-badge.svg","material-poll-box-outline":"material/poll-box-outline.svg","material-poll-box":"material/poll-box.svg","material-poll":"material/poll.svg","material-polo":"material/polo.svg","material-polymer":"material/polymer.svg","material-pool":"material/pool.svg","material-popcorn":"material/popcorn.svg","material-post-outline":"material/post-outline.svg","material-post":"material/post.svg","material-postage-stamp":"material/postage-stamp.svg","material-pot-mix-outline":"material/pot-mix-outline.svg","material-pot-mix":"material/pot-mix.svg","material-pot-outline":"material/pot-outline.svg","material-pot-steam-outline":"material/pot-steam-outline.svg","material-pot-steam":"material/pot-steam.svg","material-pot":"material/pot.svg","material-pound-box-outline":"material/pound-box-outline.svg","material-pound-box":"material/pound-box.svg","material-pound":"material/pound.svg","material-power-cycle":"material/power-cycle.svg","material-power-off":"material/power-off.svg","material-power-on":"material/power-on.svg","material-power-plug-off-outline":"material/power-plug-off-outline.svg","material-power-plug-off":"material/power-plug-off.svg","material-power-plug-outline":"material/power-plug-outline.svg","material-power-plug":"material/power-plug.svg","material-power-settings":"material/power-settings.svg","material-power-sleep":"material/power-sleep.svg","material-power-socket-au":"material/power-socket-au.svg","material-power-socket-de":"material/power-socket-de.svg","material-power-socket-eu":"material/power-socket-eu.svg","material-power-socket-fr":"material/power-socket-fr.svg","material-power-socket-it":"material/power-socket-it.svg","material-power-socket-jp":"material/power-socket-jp.svg","material-power-socket-uk":"material/power-socket-uk.svg","material-power-socket-us":"material/power-socket-us.svg","material-power-socket":"material/power-socket.svg","material-power-standby":"material/power-standby.svg","material-power":"material/power.svg","material-powershell":"material/powershell.svg","material-prescription":"material/prescription.svg","material-presentation-play":"material/presentation-play.svg","material-presentation":"material/presentation.svg","material-pretzel":"material/pretzel.svg","material-printer-3d-nozzle-alert-outline":"material/printer-3d-nozzle-alert-outline.svg","material-printer-3d-nozzle-alert":"material/printer-3d-nozzle-alert.svg","material-printer-3d-nozzle-outline":"material/printer-3d-nozzle-outline.svg","material-printer-3d-nozzle":"material/printer-3d-nozzle.svg","material-printer-3d":"material/printer-3d.svg","material-printer-alert":"material/printer-alert.svg","material-printer-check":"material/printer-check.svg","material-printer-eye":"material/printer-eye.svg","material-printer-off":"material/printer-off.svg","material-printer-pos":"material/printer-pos.svg","material-printer-search":"material/printer-search.svg","material-printer-settings":"material/printer-settings.svg","material-printer-wireless":"material/printer-wireless.svg","material-printer":"material/printer.svg","material-priority-high":"material/priority-high.svg","material-priority-low":"material/priority-low.svg","material-professional-hexagon":"material/professional-hexagon.svg","material-progress-alert":"material/progress-alert.svg","material-progress-check":"material/progress-check.svg","material-progress-clock":"material/progress-clock.svg","material-progress-close":"material/progress-close.svg","material-progress-download":"material/progress-download.svg","material-progress-question":"material/progress-question.svg","material-progress-upload":"material/progress-upload.svg","material-progress-wrench":"material/progress-wrench.svg","material-projector-screen-outline":"material/projector-screen-outline.svg","material-projector-screen":"material/projector-screen.svg","material-projector":"material/projector.svg","material-propane-tank-outline":"material/propane-tank-outline.svg","material-propane-tank":"material/propane-tank.svg","material-protocol":"material/protocol.svg","material-publish":"material/publish.svg","material-pulse":"material/pulse.svg","material-pump":"material/pump.svg","material-pumpkin":"material/pumpkin.svg","material-purse-outline":"material/purse-outline.svg","material-purse":"material/purse.svg","material-puzzle-check-outline":"material/puzzle-check-outline.svg","material-puzzle-check":"material/puzzle-check.svg","material-puzzle-edit-outline":"material/puzzle-edit-outline.svg","material-puzzle-edit":"material/puzzle-edit.svg","material-puzzle-heart-outline":"material/puzzle-heart-outline.svg","material-puzzle-heart":"material/puzzle-heart.svg","material-puzzle-minus-outline":"material/puzzle-minus-outline.svg","material-puzzle-minus":"material/puzzle-minus.svg","material-puzzle-outline":"material/puzzle-outline.svg","material-puzzle-plus-outline":"material/puzzle-plus-outline.svg","material-puzzle-plus":"material/puzzle-plus.svg","material-puzzle-remove-outline":"material/puzzle-remove-outline.svg","material-puzzle-remove":"material/puzzle-remove.svg","material-puzzle-star-outline":"material/puzzle-star-outline.svg","material-puzzle-star":"material/puzzle-star.svg","material-puzzle":"material/puzzle.svg","material-qi":"material/qi.svg","material-qqchat":"material/qqchat.svg","material-qrcode-edit":"material/qrcode-edit.svg","material-qrcode-minus":"material/qrcode-minus.svg","material-qrcode-plus":"material/qrcode-plus.svg","material-qrcode-remove":"material/qrcode-remove.svg","material-qrcode-scan":"material/qrcode-scan.svg","material-qrcode":"material/qrcode.svg","material-quadcopter":"material/quadcopter.svg","material-quality-high":"material/quality-high.svg","material-quality-low":"material/quality-low.svg","material-quality-medium":"material/quality-medium.svg","material-quora":"material/quora.svg","material-rabbit":"material/rabbit.svg","material-racing-helmet":"material/racing-helmet.svg","material-racquetball":"material/racquetball.svg","material-radar":"material/radar.svg","material-radiator-disabled":"material/radiator-disabled.svg","material-radiator-off":"material/radiator-off.svg","material-radiator":"material/radiator.svg","material-radio-am":"material/radio-am.svg","material-radio-fm":"material/radio-fm.svg","material-radio-handheld":"material/radio-handheld.svg","material-radio-off":"material/radio-off.svg","material-radio-tower":"material/radio-tower.svg","material-radio":"material/radio.svg","material-radioactive-off":"material/radioactive-off.svg","material-radioactive":"material/radioactive.svg","material-radiobox-blank":"material/radiobox-blank.svg","material-radiobox-marked":"material/radiobox-marked.svg","material-radiology-box-outline":"material/radiology-box-outline.svg","material-radiology-box":"material/radiology-box.svg","material-radius-outline":"material/radius-outline.svg","material-radius":"material/radius.svg","material-railroad-light":"material/railroad-light.svg","material-rake":"material/rake.svg","material-raspberry-pi":"material/raspberry-pi.svg","material-ray-end-arrow":"material/ray-end-arrow.svg","material-ray-end":"material/ray-end.svg","material-ray-start-arrow":"material/ray-start-arrow.svg","material-ray-start-end":"material/ray-start-end.svg","material-ray-start-vertex-end":"material/ray-start-vertex-end.svg","material-ray-start":"material/ray-start.svg","material-ray-vertex":"material/ray-vertex.svg","material-react":"material/react.svg","material-read":"material/read.svg","material-receipt":"material/receipt.svg","material-record-circle-outline":"material/record-circle-outline.svg","material-record-circle":"material/record-circle.svg","material-record-player":"material/record-player.svg","material-record-rec":"material/record-rec.svg","material-record":"material/record.svg","material-rectangle-outline":"material/rectangle-outline.svg","material-rectangle":"material/rectangle.svg","material-recycle-variant":"material/recycle-variant.svg","material-recycle":"material/recycle.svg","material-reddit":"material/reddit.svg","material-redhat":"material/redhat.svg","material-redo-variant":"material/redo-variant.svg","material-redo":"material/redo.svg","material-reflect-horizontal":"material/reflect-horizontal.svg","material-reflect-vertical":"material/reflect-vertical.svg","material-refresh-circle":"material/refresh-circle.svg","material-refresh":"material/refresh.svg","material-regex":"material/regex.svg","material-registered-trademark":"material/registered-trademark.svg","material-reiterate":"material/reiterate.svg","material-relation-many-to-many":"material/relation-many-to-many.svg","material-relation-many-to-one-or-many":"material/relation-many-to-one-or-many.svg","material-relation-many-to-one":"material/relation-many-to-one.svg","material-relation-many-to-only-one":"material/relation-many-to-only-one.svg","material-relation-many-to-zero-or-many":"material/relation-many-to-zero-or-many.svg","material-relation-many-to-zero-or-one":"material/relation-many-to-zero-or-one.svg","material-relation-one-or-many-to-many":"material/relation-one-or-many-to-many.svg","material-relation-one-or-many-to-one-or-many":"material/relation-one-or-many-to-one-or-many.svg","material-relation-one-or-many-to-one":"material/relation-one-or-many-to-one.svg","material-relation-one-or-many-to-only-one":"material/relation-one-or-many-to-only-one.svg","material-relation-one-or-many-to-zero-or-many":"material/relation-one-or-many-to-zero-or-many.svg","material-relation-one-or-many-to-zero-or-one":"material/relation-one-or-many-to-zero-or-one.svg","material-relation-one-to-many":"material/relation-one-to-many.svg","material-relation-one-to-one-or-many":"material/relation-one-to-one-or-many.svg","material-relation-one-to-one":"material/relation-one-to-one.svg","material-relation-one-to-only-one":"material/relation-one-to-only-one.svg","material-relation-one-to-zero-or-many":"material/relation-one-to-zero-or-many.svg","material-relation-one-to-zero-or-one":"material/relation-one-to-zero-or-one.svg","material-relation-only-one-to-many":"material/relation-only-one-to-many.svg","material-relation-only-one-to-one-or-many":"material/relation-only-one-to-one-or-many.svg","material-relation-only-one-to-one":"material/relation-only-one-to-one.svg","material-relation-only-one-to-only-one":"material/relation-only-one-to-only-one.svg","material-relation-only-one-to-zero-or-many":"material/relation-only-one-to-zero-or-many.svg","material-relation-only-one-to-zero-or-one":"material/relation-only-one-to-zero-or-one.svg","material-relation-zero-or-many-to-many":"material/relation-zero-or-many-to-many.svg","material-relation-zero-or-many-to-one-or-many":"material/relation-zero-or-many-to-one-or-many.svg","material-relation-zero-or-many-to-one":"material/relation-zero-or-many-to-one.svg","material-relation-zero-or-many-to-only-one":"material/relation-zero-or-many-to-only-one.svg","material-relation-zero-or-many-to-zero-or-many":"material/relation-zero-or-many-to-zero-or-many.svg","material-relation-zero-or-many-to-zero-or-one":"material/relation-zero-or-many-to-zero-or-one.svg","material-relation-zero-or-one-to-many":"material/relation-zero-or-one-to-many.svg","material-relation-zero-or-one-to-one-or-many":"material/relation-zero-or-one-to-one-or-many.svg","material-relation-zero-or-one-to-one":"material/relation-zero-or-one-to-one.svg","material-relation-zero-or-one-to-only-one":"material/relation-zero-or-one-to-only-one.svg","material-relation-zero-or-one-to-zero-or-many":"material/relation-zero-or-one-to-zero-or-many.svg","material-relation-zero-or-one-to-zero-or-one":"material/relation-zero-or-one-to-zero-or-one.svg","material-relative-scale":"material/relative-scale.svg","material-reload-alert":"material/reload-alert.svg","material-reload":"material/reload.svg","material-reminder":"material/reminder.svg","material-remote-desktop":"material/remote-desktop.svg","material-remote-off":"material/remote-off.svg","material-remote-tv-off":"material/remote-tv-off.svg","material-remote-tv":"material/remote-tv.svg","material-remote":"material/remote.svg","material-rename-box":"material/rename-box.svg","material-reorder-horizontal":"material/reorder-horizontal.svg","material-reorder-vertical":"material/reorder-vertical.svg","material-repeat-off":"material/repeat-off.svg","material-repeat-once":"material/repeat-once.svg","material-repeat":"material/repeat.svg","material-replay":"material/replay.svg","material-reply-all-outline":"material/reply-all-outline.svg","material-reply-all":"material/reply-all.svg","material-reply-circle":"material/reply-circle.svg","material-reply-outline":"material/reply-outline.svg","material-reply":"material/reply.svg","material-reproduction":"material/reproduction.svg","material-resistor-nodes":"material/resistor-nodes.svg","material-resistor":"material/resistor.svg","material-resize-bottom-right":"material/resize-bottom-right.svg","material-resize":"material/resize.svg","material-responsive":"material/responsive.svg","material-restart-alert":"material/restart-alert.svg","material-restart-off":"material/restart-off.svg","material-restart":"material/restart.svg","material-restore-alert":"material/restore-alert.svg","material-restore":"material/restore.svg","material-rewind-10":"material/rewind-10.svg","material-rewind-30":"material/rewind-30.svg","material-rewind-5":"material/rewind-5.svg","material-rewind-60":"material/rewind-60.svg","material-rewind-outline":"material/rewind-outline.svg","material-rewind":"material/rewind.svg","material-rhombus-medium-outline":"material/rhombus-medium-outline.svg","material-rhombus-medium":"material/rhombus-medium.svg","material-rhombus-outline":"material/rhombus-outline.svg","material-rhombus-split-outline":"material/rhombus-split-outline.svg","material-rhombus-split":"material/rhombus-split.svg","material-rhombus":"material/rhombus.svg","material-ribbon":"material/ribbon.svg","material-rice":"material/rice.svg","material-rickshaw-electric":"material/rickshaw-electric.svg","material-rickshaw":"material/rickshaw.svg","material-ring":"material/ring.svg","material-rivet":"material/rivet.svg","material-road-variant":"material/road-variant.svg","material-road":"material/road.svg","material-robber":"material/robber.svg","material-robot-angry-outline":"material/robot-angry-outline.svg","material-robot-angry":"material/robot-angry.svg","material-robot-confused-outline":"material/robot-confused-outline.svg","material-robot-confused":"material/robot-confused.svg","material-robot-dead-outline":"material/robot-dead-outline.svg","material-robot-dead":"material/robot-dead.svg","material-robot-excited-outline":"material/robot-excited-outline.svg","material-robot-excited":"material/robot-excited.svg","material-robot-happy-outline":"material/robot-happy-outline.svg","material-robot-happy":"material/robot-happy.svg","material-robot-industrial":"material/robot-industrial.svg","material-robot-love-outline":"material/robot-love-outline.svg","material-robot-love":"material/robot-love.svg","material-robot-mower-outline":"material/robot-mower-outline.svg","material-robot-mower":"material/robot-mower.svg","material-robot-off-outline":"material/robot-off-outline.svg","material-robot-off":"material/robot-off.svg","material-robot-outline":"material/robot-outline.svg","material-robot-vacuum-variant":"material/robot-vacuum-variant.svg","material-robot-vacuum":"material/robot-vacuum.svg","material-robot":"material/robot.svg","material-rocket-launch-outline":"material/rocket-launch-outline.svg","material-rocket-launch":"material/rocket-launch.svg","material-rocket-outline":"material/rocket-outline.svg","material-rocket":"material/rocket.svg","material-rodent":"material/rodent.svg","material-roller-skate-off":"material/roller-skate-off.svg","material-roller-skate":"material/roller-skate.svg","material-rollerblade-off":"material/rollerblade-off.svg","material-rollerblade":"material/rollerblade.svg","material-rollupjs":"material/rollupjs.svg","material-roman-numeral-1":"material/roman-numeral-1.svg","material-roman-numeral-10":"material/roman-numeral-10.svg","material-roman-numeral-2":"material/roman-numeral-2.svg","material-roman-numeral-3":"material/roman-numeral-3.svg","material-roman-numeral-4":"material/roman-numeral-4.svg","material-roman-numeral-5":"material/roman-numeral-5.svg","material-roman-numeral-6":"material/roman-numeral-6.svg","material-roman-numeral-7":"material/roman-numeral-7.svg","material-roman-numeral-8":"material/roman-numeral-8.svg","material-roman-numeral-9":"material/roman-numeral-9.svg","material-room-service-outline":"material/room-service-outline.svg","material-room-service":"material/room-service.svg","material-rotate-3d-variant":"material/rotate-3d-variant.svg","material-rotate-3d":"material/rotate-3d.svg","material-rotate-left-variant":"material/rotate-left-variant.svg","material-rotate-left":"material/rotate-left.svg","material-rotate-orbit":"material/rotate-orbit.svg","material-rotate-right-variant":"material/rotate-right-variant.svg","material-rotate-right":"material/rotate-right.svg","material-rounded-corner":"material/rounded-corner.svg","material-router-network":"material/router-network.svg","material-router-wireless-off":"material/router-wireless-off.svg","material-router-wireless-settings":"material/router-wireless-settings.svg","material-router-wireless":"material/router-wireless.svg","material-router":"material/router.svg","material-routes-clock":"material/routes-clock.svg","material-routes":"material/routes.svg","material-rowing":"material/rowing.svg","material-rss-box":"material/rss-box.svg","material-rss-off":"material/rss-off.svg","material-rss":"material/rss.svg","material-rug":"material/rug.svg","material-rugby":"material/rugby.svg","material-ruler-square-compass":"material/ruler-square-compass.svg","material-ruler-square":"material/ruler-square.svg","material-ruler":"material/ruler.svg","material-run-fast":"material/run-fast.svg","material-run":"material/run.svg","material-rv-truck":"material/rv-truck.svg","material-sack-percent":"material/sack-percent.svg","material-sack":"material/sack.svg","material-safe-square-outline":"material/safe-square-outline.svg","material-safe-square":"material/safe-square.svg","material-safe":"material/safe.svg","material-safety-goggles":"material/safety-goggles.svg","material-sail-boat":"material/sail-boat.svg","material-sale":"material/sale.svg","material-salesforce":"material/salesforce.svg","material-sass":"material/sass.svg","material-satellite-uplink":"material/satellite-uplink.svg","material-satellite-variant":"material/satellite-variant.svg","material-satellite":"material/satellite.svg","material-sausage":"material/sausage.svg","material-saw-blade":"material/saw-blade.svg","material-sawtooth-wave":"material/sawtooth-wave.svg","material-saxophone":"material/saxophone.svg","material-scale-balance":"material/scale-balance.svg","material-scale-bathroom":"material/scale-bathroom.svg","material-scale-off":"material/scale-off.svg","material-scale":"material/scale.svg","material-scan-helper":"material/scan-helper.svg","material-scanner-off":"material/scanner-off.svg","material-scanner":"material/scanner.svg","material-scatter-plot-outline":"material/scatter-plot-outline.svg","material-scatter-plot":"material/scatter-plot.svg","material-school-outline":"material/school-outline.svg","material-school":"material/school.svg","material-scissors-cutting":"material/scissors-cutting.svg","material-scooter-electric":"material/scooter-electric.svg","material-scooter":"material/scooter.svg","material-scoreboard-outline":"material/scoreboard-outline.svg","material-scoreboard":"material/scoreboard.svg","material-screen-rotation-lock":"material/screen-rotation-lock.svg","material-screen-rotation":"material/screen-rotation.svg","material-screw-flat-top":"material/screw-flat-top.svg","material-screw-lag":"material/screw-lag.svg","material-screw-machine-flat-top":"material/screw-machine-flat-top.svg","material-screw-machine-round-top":"material/screw-machine-round-top.svg","material-screw-round-top":"material/screw-round-top.svg","material-screwdriver":"material/screwdriver.svg","material-script-outline":"material/script-outline.svg","material-script-text-key-outline":"material/script-text-key-outline.svg","material-script-text-key":"material/script-text-key.svg","material-script-text-outline":"material/script-text-outline.svg","material-script-text-play-outline":"material/script-text-play-outline.svg","material-script-text-play":"material/script-text-play.svg","material-script-text":"material/script-text.svg","material-script":"material/script.svg","material-sd":"material/sd.svg","material-seal-variant":"material/seal-variant.svg","material-seal":"material/seal.svg","material-search-web":"material/search-web.svg","material-seat-flat-angled":"material/seat-flat-angled.svg","material-seat-flat":"material/seat-flat.svg","material-seat-individual-suite":"material/seat-individual-suite.svg","material-seat-legroom-extra":"material/seat-legroom-extra.svg","material-seat-legroom-normal":"material/seat-legroom-normal.svg","material-seat-legroom-reduced":"material/seat-legroom-reduced.svg","material-seat-outline":"material/seat-outline.svg","material-seat-passenger":"material/seat-passenger.svg","material-seat-recline-extra":"material/seat-recline-extra.svg","material-seat-recline-normal":"material/seat-recline-normal.svg","material-seat":"material/seat.svg","material-seatbelt":"material/seatbelt.svg","material-security-network":"material/security-network.svg","material-security":"material/security.svg","material-seed-off-outline":"material/seed-off-outline.svg","material-seed-off":"material/seed-off.svg","material-seed-outline":"material/seed-outline.svg","material-seed":"material/seed.svg","material-seesaw":"material/seesaw.svg","material-segment":"material/segment.svg","material-select-all":"material/select-all.svg","material-select-color":"material/select-color.svg","material-select-compare":"material/select-compare.svg","material-select-drag":"material/select-drag.svg","material-select-group":"material/select-group.svg","material-select-inverse":"material/select-inverse.svg","material-select-marker":"material/select-marker.svg","material-select-multiple-marker":"material/select-multiple-marker.svg","material-select-multiple":"material/select-multiple.svg","material-select-off":"material/select-off.svg","material-select-place":"material/select-place.svg","material-select-search":"material/select-search.svg","material-select":"material/select.svg","material-selection-drag":"material/selection-drag.svg","material-selection-ellipse-arrow-inside":"material/selection-ellipse-arrow-inside.svg","material-selection-ellipse":"material/selection-ellipse.svg","material-selection-marker":"material/selection-marker.svg","material-selection-multiple-marker":"material/selection-multiple-marker.svg","material-selection-multiple":"material/selection-multiple.svg","material-selection-off":"material/selection-off.svg","material-selection-search":"material/selection-search.svg","material-selection":"material/selection.svg","material-semantic-web":"material/semantic-web.svg","material-send-check-outline":"material/send-check-outline.svg","material-send-check":"material/send-check.svg","material-send-circle-outline":"material/send-circle-outline.svg","material-send-circle":"material/send-circle.svg","material-send-clock-outline":"material/send-clock-outline.svg","material-send-clock":"material/send-clock.svg","material-send-lock-outline":"material/send-lock-outline.svg","material-send-lock":"material/send-lock.svg","material-send-outline":"material/send-outline.svg","material-send":"material/send.svg","material-serial-port":"material/serial-port.svg","material-server-minus":"material/server-minus.svg","material-server-network-off":"material/server-network-off.svg","material-server-network":"material/server-network.svg","material-server-off":"material/server-off.svg","material-server-plus":"material/server-plus.svg","material-server-remove":"material/server-remove.svg","material-server-security":"material/server-security.svg","material-server":"material/server.svg","material-set-all":"material/set-all.svg","material-set-center-right":"material/set-center-right.svg","material-set-center":"material/set-center.svg","material-set-left-center":"material/set-left-center.svg","material-set-left-right":"material/set-left-right.svg","material-set-left":"material/set-left.svg","material-set-merge":"material/set-merge.svg","material-set-none":"material/set-none.svg","material-set-right":"material/set-right.svg","material-set-split":"material/set-split.svg","material-set-square":"material/set-square.svg","material-set-top-box":"material/set-top-box.svg","material-settings-helper":"material/settings-helper.svg","material-shaker-outline":"material/shaker-outline.svg","material-shaker":"material/shaker.svg","material-shape-circle-plus":"material/shape-circle-plus.svg","material-shape-outline":"material/shape-outline.svg","material-shape-oval-plus":"material/shape-oval-plus.svg","material-shape-plus":"material/shape-plus.svg","material-shape-polygon-plus":"material/shape-polygon-plus.svg","material-shape-rectangle-plus":"material/shape-rectangle-plus.svg","material-shape-square-plus":"material/shape-square-plus.svg","material-shape-square-rounded-plus":"material/shape-square-rounded-plus.svg","material-shape":"material/shape.svg","material-share-all-outline":"material/share-all-outline.svg","material-share-all":"material/share-all.svg","material-share-circle":"material/share-circle.svg","material-share-off-outline":"material/share-off-outline.svg","material-share-off":"material/share-off.svg","material-share-outline":"material/share-outline.svg","material-share-variant-outline":"material/share-variant-outline.svg","material-share-variant":"material/share-variant.svg","material-share":"material/share.svg","material-shark-fin-outline":"material/shark-fin-outline.svg","material-shark-fin":"material/shark-fin.svg","material-sheep":"material/sheep.svg","material-shield-account-outline":"material/shield-account-outline.svg","material-shield-account-variant-outline":"material/shield-account-variant-outline.svg","material-shield-account-variant":"material/shield-account-variant.svg","material-shield-account":"material/shield-account.svg","material-shield-airplane-outline":"material/shield-airplane-outline.svg","material-shield-airplane":"material/shield-airplane.svg","material-shield-alert-outline":"material/shield-alert-outline.svg","material-shield-alert":"material/shield-alert.svg","material-shield-bug-outline":"material/shield-bug-outline.svg","material-shield-bug":"material/shield-bug.svg","material-shield-car":"material/shield-car.svg","material-shield-check-outline":"material/shield-check-outline.svg","material-shield-check":"material/shield-check.svg","material-shield-cross-outline":"material/shield-cross-outline.svg","material-shield-cross":"material/shield-cross.svg","material-shield-edit-outline":"material/shield-edit-outline.svg","material-shield-edit":"material/shield-edit.svg","material-shield-half-full":"material/shield-half-full.svg","material-shield-half":"material/shield-half.svg","material-shield-home-outline":"material/shield-home-outline.svg","material-shield-home":"material/shield-home.svg","material-shield-key-outline":"material/shield-key-outline.svg","material-shield-key":"material/shield-key.svg","material-shield-link-variant-outline":"material/shield-link-variant-outline.svg","material-shield-link-variant":"material/shield-link-variant.svg","material-shield-lock-outline":"material/shield-lock-outline.svg","material-shield-lock":"material/shield-lock.svg","material-shield-off-outline":"material/shield-off-outline.svg","material-shield-off":"material/shield-off.svg","material-shield-outline":"material/shield-outline.svg","material-shield-plus-outline":"material/shield-plus-outline.svg","material-shield-plus":"material/shield-plus.svg","material-shield-refresh-outline":"material/shield-refresh-outline.svg","material-shield-refresh":"material/shield-refresh.svg","material-shield-remove-outline":"material/shield-remove-outline.svg","material-shield-remove":"material/shield-remove.svg","material-shield-search":"material/shield-search.svg","material-shield-star-outline":"material/shield-star-outline.svg","material-shield-star":"material/shield-star.svg","material-shield-sun-outline":"material/shield-sun-outline.svg","material-shield-sun":"material/shield-sun.svg","material-shield-sync-outline":"material/shield-sync-outline.svg","material-shield-sync":"material/shield-sync.svg","material-shield":"material/shield.svg","material-ship-wheel":"material/ship-wheel.svg","material-shoe-ballet":"material/shoe-ballet.svg","material-shoe-cleat":"material/shoe-cleat.svg","material-shoe-formal":"material/shoe-formal.svg","material-shoe-heel":"material/shoe-heel.svg","material-shoe-print":"material/shoe-print.svg","material-shoe-sneaker":"material/shoe-sneaker.svg","material-shopping-music":"material/shopping-music.svg","material-shopping-outline":"material/shopping-outline.svg","material-shopping-search":"material/shopping-search.svg","material-shopping":"material/shopping.svg","material-shore":"material/shore.svg","material-shovel-off":"material/shovel-off.svg","material-shovel":"material/shovel.svg","material-shower-head":"material/shower-head.svg","material-shower":"material/shower.svg","material-shredder":"material/shredder.svg","material-shuffle-disabled":"material/shuffle-disabled.svg","material-shuffle-variant":"material/shuffle-variant.svg","material-shuffle":"material/shuffle.svg","material-shuriken":"material/shuriken.svg","material-sigma-lower":"material/sigma-lower.svg","material-sigma":"material/sigma.svg","material-sign-caution":"material/sign-caution.svg","material-sign-direction-minus":"material/sign-direction-minus.svg","material-sign-direction-plus":"material/sign-direction-plus.svg","material-sign-direction-remove":"material/sign-direction-remove.svg","material-sign-direction":"material/sign-direction.svg","material-sign-pole":"material/sign-pole.svg","material-sign-real-estate":"material/sign-real-estate.svg","material-sign-text":"material/sign-text.svg","material-signal-2g":"material/signal-2g.svg","material-signal-3g":"material/signal-3g.svg","material-signal-4g":"material/signal-4g.svg","material-signal-5g":"material/signal-5g.svg","material-signal-cellular-1":"material/signal-cellular-1.svg","material-signal-cellular-2":"material/signal-cellular-2.svg","material-signal-cellular-3":"material/signal-cellular-3.svg","material-signal-cellular-outline":"material/signal-cellular-outline.svg","material-signal-distance-variant":"material/signal-distance-variant.svg","material-signal-hspa-plus":"material/signal-hspa-plus.svg","material-signal-hspa":"material/signal-hspa.svg","material-signal-off":"material/signal-off.svg","material-signal-variant":"material/signal-variant.svg","material-signal":"material/signal.svg","material-signature-freehand":"material/signature-freehand.svg","material-signature-image":"material/signature-image.svg","material-signature-text":"material/signature-text.svg","material-signature":"material/signature.svg","material-silo":"material/silo.svg","material-silverware-clean":"material/silverware-clean.svg","material-silverware-fork-knife":"material/silverware-fork-knife.svg","material-silverware-fork":"material/silverware-fork.svg","material-silverware-spoon":"material/silverware-spoon.svg","material-silverware-variant":"material/silverware-variant.svg","material-silverware":"material/silverware.svg","material-sim-alert-outline":"material/sim-alert-outline.svg","material-sim-alert":"material/sim-alert.svg","material-sim-off-outline":"material/sim-off-outline.svg","material-sim-off":"material/sim-off.svg","material-sim-outline":"material/sim-outline.svg","material-sim":"material/sim.svg","material-simple-icons":"material/simple-icons.svg","material-sina-weibo":"material/sina-weibo.svg","material-sine-wave":"material/sine-wave.svg","material-sitemap":"material/sitemap.svg","material-size-l":"material/size-l.svg","material-size-m":"material/size-m.svg","material-size-s":"material/size-s.svg","material-size-xl":"material/size-xl.svg","material-size-xs":"material/size-xs.svg","material-size-xxl":"material/size-xxl.svg","material-size-xxs":"material/size-xxs.svg","material-size-xxxl":"material/size-xxxl.svg","material-skate":"material/skate.svg","material-skateboard":"material/skateboard.svg","material-skew-less":"material/skew-less.svg","material-skew-more":"material/skew-more.svg","material-ski-cross-country":"material/ski-cross-country.svg","material-ski-water":"material/ski-water.svg","material-ski":"material/ski.svg","material-skip-backward-outline":"material/skip-backward-outline.svg","material-skip-backward":"material/skip-backward.svg","material-skip-forward-outline":"material/skip-forward-outline.svg","material-skip-forward":"material/skip-forward.svg","material-skip-next-circle-outline":"material/skip-next-circle-outline.svg","material-skip-next-circle":"material/skip-next-circle.svg","material-skip-next-outline":"material/skip-next-outline.svg","material-skip-next":"material/skip-next.svg","material-skip-previous-circle-outline":"material/skip-previous-circle-outline.svg","material-skip-previous-circle":"material/skip-previous-circle.svg","material-skip-previous-outline":"material/skip-previous-outline.svg","material-skip-previous":"material/skip-previous.svg","material-skull-crossbones-outline":"material/skull-crossbones-outline.svg","material-skull-crossbones":"material/skull-crossbones.svg","material-skull-outline":"material/skull-outline.svg","material-skull-scan-outline":"material/skull-scan-outline.svg","material-skull-scan":"material/skull-scan.svg","material-skull":"material/skull.svg","material-skype-business":"material/skype-business.svg","material-skype":"material/skype.svg","material-slack":"material/slack.svg","material-slash-forward-box":"material/slash-forward-box.svg","material-slash-forward":"material/slash-forward.svg","material-sleep-off":"material/sleep-off.svg","material-sleep":"material/sleep.svg","material-slide":"material/slide.svg","material-slope-downhill":"material/slope-downhill.svg","material-slope-uphill":"material/slope-uphill.svg","material-slot-machine-outline":"material/slot-machine-outline.svg","material-slot-machine":"material/slot-machine.svg","material-smart-card-outline":"material/smart-card-outline.svg","material-smart-card-reader-outline":"material/smart-card-reader-outline.svg","material-smart-card-reader":"material/smart-card-reader.svg","material-smart-card":"material/smart-card.svg","material-smog":"material/smog.svg","material-smoke-detector":"material/smoke-detector.svg","material-smoking-off":"material/smoking-off.svg","material-smoking-pipe-off":"material/smoking-pipe-off.svg","material-smoking-pipe":"material/smoking-pipe.svg","material-smoking":"material/smoking.svg","material-snail":"material/snail.svg","material-snake":"material/snake.svg","material-snapchat":"material/snapchat.svg","material-snowboard":"material/snowboard.svg","material-snowflake-alert":"material/snowflake-alert.svg","material-snowflake-melt":"material/snowflake-melt.svg","material-snowflake-off":"material/snowflake-off.svg","material-snowflake-variant":"material/snowflake-variant.svg","material-snowflake":"material/snowflake.svg","material-snowman":"material/snowman.svg","material-soccer-field":"material/soccer-field.svg","material-soccer":"material/soccer.svg","material-social-distance-2-meters":"material/social-distance-2-meters.svg","material-social-distance-6-feet":"material/social-distance-6-feet.svg","material-sofa-outline":"material/sofa-outline.svg","material-sofa-single-outline":"material/sofa-single-outline.svg","material-sofa-single":"material/sofa-single.svg","material-sofa":"material/sofa.svg","material-solar-panel-large":"material/solar-panel-large.svg","material-solar-panel":"material/solar-panel.svg","material-solar-power":"material/solar-power.svg","material-soldering-iron":"material/soldering-iron.svg","material-solid":"material/solid.svg","material-sony-playstation":"material/sony-playstation.svg","material-sort-alphabetical-ascending-variant":"material/sort-alphabetical-ascending-variant.svg","material-sort-alphabetical-ascending":"material/sort-alphabetical-ascending.svg","material-sort-alphabetical-descending-variant":"material/sort-alphabetical-descending-variant.svg","material-sort-alphabetical-descending":"material/sort-alphabetical-descending.svg","material-sort-alphabetical-variant":"material/sort-alphabetical-variant.svg","material-sort-ascending":"material/sort-ascending.svg","material-sort-bool-ascending-variant":"material/sort-bool-ascending-variant.svg","material-sort-bool-ascending":"material/sort-bool-ascending.svg","material-sort-bool-descending-variant":"material/sort-bool-descending-variant.svg","material-sort-bool-descending":"material/sort-bool-descending.svg","material-sort-calendar-ascending":"material/sort-calendar-ascending.svg","material-sort-calendar-descending":"material/sort-calendar-descending.svg","material-sort-clock-ascending-outline":"material/sort-clock-ascending-outline.svg","material-sort-clock-ascending":"material/sort-clock-ascending.svg","material-sort-clock-descending-outline":"material/sort-clock-descending-outline.svg","material-sort-clock-descending":"material/sort-clock-descending.svg","material-sort-descending":"material/sort-descending.svg","material-sort-numeric-ascending-variant":"material/sort-numeric-ascending-variant.svg","material-sort-numeric-ascending":"material/sort-numeric-ascending.svg","material-sort-numeric-descending-variant":"material/sort-numeric-descending-variant.svg","material-sort-numeric-descending":"material/sort-numeric-descending.svg","material-sort-numeric-variant":"material/sort-numeric-variant.svg","material-sort-reverse-variant":"material/sort-reverse-variant.svg","material-sort-variant-lock-open":"material/sort-variant-lock-open.svg","material-sort-variant-lock":"material/sort-variant-lock.svg","material-sort-variant-remove":"material/sort-variant-remove.svg","material-sort-variant":"material/sort-variant.svg","material-sort":"material/sort.svg","material-soundcloud":"material/soundcloud.svg","material-source-branch-check":"material/source-branch-check.svg","material-source-branch-minus":"material/source-branch-minus.svg","material-source-branch-plus":"material/source-branch-plus.svg","material-source-branch-refresh":"material/source-branch-refresh.svg","material-source-branch-remove":"material/source-branch-remove.svg","material-source-branch-sync":"material/source-branch-sync.svg","material-source-branch":"material/source-branch.svg","material-source-commit-end-local":"material/source-commit-end-local.svg","material-source-commit-end":"material/source-commit-end.svg","material-source-commit-local":"material/source-commit-local.svg","material-source-commit-next-local":"material/source-commit-next-local.svg","material-source-commit-start-next-local":"material/source-commit-start-next-local.svg","material-source-commit-start":"material/source-commit-start.svg","material-source-commit":"material/source-commit.svg","material-source-fork":"material/source-fork.svg","material-source-merge":"material/source-merge.svg","material-source-pull":"material/source-pull.svg","material-source-repository-multiple":"material/source-repository-multiple.svg","material-source-repository":"material/source-repository.svg","material-soy-sauce-off":"material/soy-sauce-off.svg","material-soy-sauce":"material/soy-sauce.svg","material-spa-outline":"material/spa-outline.svg","material-spa":"material/spa.svg","material-space-invaders":"material/space-invaders.svg","material-space-station":"material/space-station.svg","material-spade":"material/spade.svg","material-sparkles":"material/sparkles.svg","material-speaker-bluetooth":"material/speaker-bluetooth.svg","material-speaker-multiple":"material/speaker-multiple.svg","material-speaker-off":"material/speaker-off.svg","material-speaker-wireless":"material/speaker-wireless.svg","material-speaker":"material/speaker.svg","material-speedometer-medium":"material/speedometer-medium.svg","material-speedometer-slow":"material/speedometer-slow.svg","material-speedometer":"material/speedometer.svg","material-spellcheck":"material/spellcheck.svg","material-spider-thread":"material/spider-thread.svg","material-spider-web":"material/spider-web.svg","material-spider":"material/spider.svg","material-spirit-level":"material/spirit-level.svg","material-spoon-sugar":"material/spoon-sugar.svg","material-spotify":"material/spotify.svg","material-spotlight-beam":"material/spotlight-beam.svg","material-spotlight":"material/spotlight.svg","material-spray-bottle":"material/spray-bottle.svg","material-spray":"material/spray.svg","material-sprinkler-variant":"material/sprinkler-variant.svg","material-sprinkler":"material/sprinkler.svg","material-sprout-outline":"material/sprout-outline.svg","material-sprout":"material/sprout.svg","material-square-circle":"material/square-circle.svg","material-square-edit-outline":"material/square-edit-outline.svg","material-square-medium-outline":"material/square-medium-outline.svg","material-square-medium":"material/square-medium.svg","material-square-off-outline":"material/square-off-outline.svg","material-square-off":"material/square-off.svg","material-square-outline":"material/square-outline.svg","material-square-root-box":"material/square-root-box.svg","material-square-root":"material/square-root.svg","material-square-rounded-outline":"material/square-rounded-outline.svg","material-square-rounded":"material/square-rounded.svg","material-square-small":"material/square-small.svg","material-square-wave":"material/square-wave.svg","material-square":"material/square.svg","material-squeegee":"material/squeegee.svg","material-ssh":"material/ssh.svg","material-stack-exchange":"material/stack-exchange.svg","material-stack-overflow":"material/stack-overflow.svg","material-stackpath":"material/stackpath.svg","material-stadium-variant":"material/stadium-variant.svg","material-stadium":"material/stadium.svg","material-stairs-box":"material/stairs-box.svg","material-stairs-down":"material/stairs-down.svg","material-stairs-up":"material/stairs-up.svg","material-stairs":"material/stairs.svg","material-stamper":"material/stamper.svg","material-standard-definition":"material/standard-definition.svg","material-star-box-multiple-outline":"material/star-box-multiple-outline.svg","material-star-box-multiple":"material/star-box-multiple.svg","material-star-box-outline":"material/star-box-outline.svg","material-star-box":"material/star-box.svg","material-star-check-outline":"material/star-check-outline.svg","material-star-check":"material/star-check.svg","material-star-circle-outline":"material/star-circle-outline.svg","material-star-circle":"material/star-circle.svg","material-star-cog-outline":"material/star-cog-outline.svg","material-star-cog":"material/star-cog.svg","material-star-face":"material/star-face.svg","material-star-four-points-outline":"material/star-four-points-outline.svg","material-star-four-points":"material/star-four-points.svg","material-star-half-full":"material/star-half-full.svg","material-star-half":"material/star-half.svg","material-star-minus-outline":"material/star-minus-outline.svg","material-star-minus":"material/star-minus.svg","material-star-off-outline":"material/star-off-outline.svg","material-star-off":"material/star-off.svg","material-star-outline":"material/star-outline.svg","material-star-plus-outline":"material/star-plus-outline.svg","material-star-plus":"material/star-plus.svg","material-star-remove-outline":"material/star-remove-outline.svg","material-star-remove":"material/star-remove.svg","material-star-settings-outline":"material/star-settings-outline.svg","material-star-settings":"material/star-settings.svg","material-star-shooting-outline":"material/star-shooting-outline.svg","material-star-shooting":"material/star-shooting.svg","material-star-three-points-outline":"material/star-three-points-outline.svg","material-star-three-points":"material/star-three-points.svg","material-star":"material/star.svg","material-state-machine":"material/state-machine.svg","material-steam":"material/steam.svg","material-steering-off":"material/steering-off.svg","material-steering":"material/steering.svg","material-step-backward-2":"material/step-backward-2.svg","material-step-backward":"material/step-backward.svg","material-step-forward-2":"material/step-forward-2.svg","material-step-forward":"material/step-forward.svg","material-stethoscope":"material/stethoscope.svg","material-sticker-alert-outline":"material/sticker-alert-outline.svg","material-sticker-alert":"material/sticker-alert.svg","material-sticker-check-outline":"material/sticker-check-outline.svg","material-sticker-check":"material/sticker-check.svg","material-sticker-circle-outline":"material/sticker-circle-outline.svg","material-sticker-emoji":"material/sticker-emoji.svg","material-sticker-minus-outline":"material/sticker-minus-outline.svg","material-sticker-minus":"material/sticker-minus.svg","material-sticker-outline":"material/sticker-outline.svg","material-sticker-plus-outline":"material/sticker-plus-outline.svg","material-sticker-plus":"material/sticker-plus.svg","material-sticker-remove-outline":"material/sticker-remove-outline.svg","material-sticker-remove":"material/sticker-remove.svg","material-sticker":"material/sticker.svg","material-stocking":"material/stocking.svg","material-stomach":"material/stomach.svg","material-stop-circle-outline":"material/stop-circle-outline.svg","material-stop-circle":"material/stop-circle.svg","material-stop":"material/stop.svg","material-store-24-hour":"material/store-24-hour.svg","material-store-minus":"material/store-minus.svg","material-store-outline":"material/store-outline.svg","material-store-plus":"material/store-plus.svg","material-store-remove":"material/store-remove.svg","material-store":"material/store.svg","material-storefront-outline":"material/storefront-outline.svg","material-storefront":"material/storefront.svg","material-stove":"material/stove.svg","material-strategy":"material/strategy.svg","material-stretch-to-page-outline":"material/stretch-to-page-outline.svg","material-stretch-to-page":"material/stretch-to-page.svg","material-string-lights-off":"material/string-lights-off.svg","material-string-lights":"material/string-lights.svg","material-subdirectory-arrow-left":"material/subdirectory-arrow-left.svg","material-subdirectory-arrow-right":"material/subdirectory-arrow-right.svg","material-submarine":"material/submarine.svg","material-subtitles-outline":"material/subtitles-outline.svg","material-subtitles":"material/subtitles.svg","material-subway-alert-variant":"material/subway-alert-variant.svg","material-subway-variant":"material/subway-variant.svg","material-subway":"material/subway.svg","material-summit":"material/summit.svg","material-sunglasses":"material/sunglasses.svg","material-surround-sound-2-0":"material/surround-sound-2-0.svg","material-surround-sound-2-1":"material/surround-sound-2-1.svg","material-surround-sound-3-1":"material/surround-sound-3-1.svg","material-surround-sound-5-1-2":"material/surround-sound-5-1-2.svg","material-surround-sound-5-1":"material/surround-sound-5-1.svg","material-surround-sound-7-1":"material/surround-sound-7-1.svg","material-surround-sound":"material/surround-sound.svg","material-svg":"material/svg.svg","material-swap-horizontal-bold":"material/swap-horizontal-bold.svg","material-swap-horizontal-circle-outline":"material/swap-horizontal-circle-outline.svg","material-swap-horizontal-circle":"material/swap-horizontal-circle.svg","material-swap-horizontal-variant":"material/swap-horizontal-variant.svg","material-swap-horizontal":"material/swap-horizontal.svg","material-swap-vertical-bold":"material/swap-vertical-bold.svg","material-swap-vertical-circle-outline":"material/swap-vertical-circle-outline.svg","material-swap-vertical-circle":"material/swap-vertical-circle.svg","material-swap-vertical-variant":"material/swap-vertical-variant.svg","material-swap-vertical":"material/swap-vertical.svg","material-swim":"material/swim.svg","material-switch":"material/switch.svg","material-sword-cross":"material/sword-cross.svg","material-sword":"material/sword.svg","material-syllabary-hangul":"material/syllabary-hangul.svg","material-syllabary-hiragana":"material/syllabary-hiragana.svg","material-syllabary-katakana-halfwidth":"material/syllabary-katakana-halfwidth.svg","material-syllabary-katakana":"material/syllabary-katakana.svg","material-symbol":"material/symbol.svg","material-symfony":"material/symfony.svg","material-sync-alert":"material/sync-alert.svg","material-sync-circle":"material/sync-circle.svg","material-sync-off":"material/sync-off.svg","material-sync":"material/sync.svg","material-tab-minus":"material/tab-minus.svg","material-tab-plus":"material/tab-plus.svg","material-tab-remove":"material/tab-remove.svg","material-tab-unselected":"material/tab-unselected.svg","material-tab":"material/tab.svg","material-table-account":"material/table-account.svg","material-table-alert":"material/table-alert.svg","material-table-arrow-down":"material/table-arrow-down.svg","material-table-arrow-left":"material/table-arrow-left.svg","material-table-arrow-right":"material/table-arrow-right.svg","material-table-arrow-up":"material/table-arrow-up.svg","material-table-border":"material/table-border.svg","material-table-cancel":"material/table-cancel.svg","material-table-chair":"material/table-chair.svg","material-table-check":"material/table-check.svg","material-table-clock":"material/table-clock.svg","material-table-cog":"material/table-cog.svg","material-table-column-plus-after":"material/table-column-plus-after.svg","material-table-column-plus-before":"material/table-column-plus-before.svg","material-table-column-remove":"material/table-column-remove.svg","material-table-column-width":"material/table-column-width.svg","material-table-column":"material/table-column.svg","material-table-edit":"material/table-edit.svg","material-table-eye-off":"material/table-eye-off.svg","material-table-eye":"material/table-eye.svg","material-table-furniture":"material/table-furniture.svg","material-table-headers-eye-off":"material/table-headers-eye-off.svg","material-table-headers-eye":"material/table-headers-eye.svg","material-table-heart":"material/table-heart.svg","material-table-key":"material/table-key.svg","material-table-large-plus":"material/table-large-plus.svg","material-table-large-remove":"material/table-large-remove.svg","material-table-large":"material/table-large.svg","material-table-lock":"material/table-lock.svg","material-table-merge-cells":"material/table-merge-cells.svg","material-table-minus":"material/table-minus.svg","material-table-multiple":"material/table-multiple.svg","material-table-network":"material/table-network.svg","material-table-of-contents":"material/table-of-contents.svg","material-table-off":"material/table-off.svg","material-table-picnic":"material/table-picnic.svg","material-table-plus":"material/table-plus.svg","material-table-refresh":"material/table-refresh.svg","material-table-remove":"material/table-remove.svg","material-table-row-height":"material/table-row-height.svg","material-table-row-plus-after":"material/table-row-plus-after.svg","material-table-row-plus-before":"material/table-row-plus-before.svg","material-table-row-remove":"material/table-row-remove.svg","material-table-row":"material/table-row.svg","material-table-search":"material/table-search.svg","material-table-settings":"material/table-settings.svg","material-table-split-cell":"material/table-split-cell.svg","material-table-star":"material/table-star.svg","material-table-sync":"material/table-sync.svg","material-table-tennis":"material/table-tennis.svg","material-table":"material/table.svg","material-tablet-android":"material/tablet-android.svg","material-tablet-cellphone":"material/tablet-cellphone.svg","material-tablet-dashboard":"material/tablet-dashboard.svg","material-tablet-ipad":"material/tablet-ipad.svg","material-tablet":"material/tablet.svg","material-taco":"material/taco.svg","material-tag-arrow-down-outline":"material/tag-arrow-down-outline.svg","material-tag-arrow-down":"material/tag-arrow-down.svg","material-tag-arrow-left-outline":"material/tag-arrow-left-outline.svg","material-tag-arrow-left":"material/tag-arrow-left.svg","material-tag-arrow-right-outline":"material/tag-arrow-right-outline.svg","material-tag-arrow-right":"material/tag-arrow-right.svg","material-tag-arrow-up-outline":"material/tag-arrow-up-outline.svg","material-tag-arrow-up":"material/tag-arrow-up.svg","material-tag-faces":"material/tag-faces.svg","material-tag-heart-outline":"material/tag-heart-outline.svg","material-tag-heart":"material/tag-heart.svg","material-tag-minus-outline":"material/tag-minus-outline.svg","material-tag-minus":"material/tag-minus.svg","material-tag-multiple-outline":"material/tag-multiple-outline.svg","material-tag-multiple":"material/tag-multiple.svg","material-tag-off-outline":"material/tag-off-outline.svg","material-tag-off":"material/tag-off.svg","material-tag-outline":"material/tag-outline.svg","material-tag-plus-outline":"material/tag-plus-outline.svg","material-tag-plus":"material/tag-plus.svg","material-tag-remove-outline":"material/tag-remove-outline.svg","material-tag-remove":"material/tag-remove.svg","material-tag-text-outline":"material/tag-text-outline.svg","material-tag-text":"material/tag-text.svg","material-tag":"material/tag.svg","material-tailwind":"material/tailwind.svg","material-tank":"material/tank.svg","material-tanker-truck":"material/tanker-truck.svg","material-tape-drive":"material/tape-drive.svg","material-tape-measure":"material/tape-measure.svg","material-target-account":"material/target-account.svg","material-target-variant":"material/target-variant.svg","material-target":"material/target.svg","material-taxi":"material/taxi.svg","material-tea-outline":"material/tea-outline.svg","material-tea":"material/tea.svg","material-teach":"material/teach.svg","material-teamviewer":"material/teamviewer.svg","material-telegram":"material/telegram.svg","material-telescope":"material/telescope.svg","material-television-ambient-light":"material/television-ambient-light.svg","material-television-box":"material/television-box.svg","material-television-classic-off":"material/television-classic-off.svg","material-television-classic":"material/television-classic.svg","material-television-clean":"material/television-clean.svg","material-television-guide":"material/television-guide.svg","material-television-off":"material/television-off.svg","material-television-pause":"material/television-pause.svg","material-television-play":"material/television-play.svg","material-television-stop":"material/television-stop.svg","material-television":"material/television.svg","material-temperature-celsius":"material/temperature-celsius.svg","material-temperature-fahrenheit":"material/temperature-fahrenheit.svg","material-temperature-kelvin":"material/temperature-kelvin.svg","material-tennis-ball":"material/tennis-ball.svg","material-tennis":"material/tennis.svg","material-tent":"material/tent.svg","material-terraform":"material/terraform.svg","material-terrain":"material/terrain.svg","material-test-tube-empty":"material/test-tube-empty.svg","material-test-tube-off":"material/test-tube-off.svg","material-test-tube":"material/test-tube.svg","material-text-account":"material/text-account.svg","material-text-box-check-outline":"material/text-box-check-outline.svg","material-text-box-check":"material/text-box-check.svg","material-text-box-minus-outline":"material/text-box-minus-outline.svg","material-text-box-minus":"material/text-box-minus.svg","material-text-box-multiple-outline":"material/text-box-multiple-outline.svg","material-text-box-multiple":"material/text-box-multiple.svg","material-text-box-outline":"material/text-box-outline.svg","material-text-box-plus-outline":"material/text-box-plus-outline.svg","material-text-box-plus":"material/text-box-plus.svg","material-text-box-remove-outline":"material/text-box-remove-outline.svg","material-text-box-remove":"material/text-box-remove.svg","material-text-box-search-outline":"material/text-box-search-outline.svg","material-text-box-search":"material/text-box-search.svg","material-text-box":"material/text-box.svg","material-text-recognition":"material/text-recognition.svg","material-text-search":"material/text-search.svg","material-text-shadow":"material/text-shadow.svg","material-text-short":"material/text-short.svg","material-text-subject":"material/text-subject.svg","material-text-to-speech-off":"material/text-to-speech-off.svg","material-text-to-speech":"material/text-to-speech.svg","material-text":"material/text.svg","material-texture-box":"material/texture-box.svg","material-texture":"material/texture.svg","material-theater":"material/theater.svg","material-theme-light-dark":"material/theme-light-dark.svg","material-thermometer-alert":"material/thermometer-alert.svg","material-thermometer-chevron-down":"material/thermometer-chevron-down.svg","material-thermometer-chevron-up":"material/thermometer-chevron-up.svg","material-thermometer-high":"material/thermometer-high.svg","material-thermometer-lines":"material/thermometer-lines.svg","material-thermometer-low":"material/thermometer-low.svg","material-thermometer-minus":"material/thermometer-minus.svg","material-thermometer-off":"material/thermometer-off.svg","material-thermometer-plus":"material/thermometer-plus.svg","material-thermometer":"material/thermometer.svg","material-thermostat-box":"material/thermostat-box.svg","material-thermostat":"material/thermostat.svg","material-thought-bubble-outline":"material/thought-bubble-outline.svg","material-thought-bubble":"material/thought-bubble.svg","material-thumb-down-outline":"material/thumb-down-outline.svg","material-thumb-down":"material/thumb-down.svg","material-thumb-up-outline":"material/thumb-up-outline.svg","material-thumb-up":"material/thumb-up.svg","material-thumbs-up-down":"material/thumbs-up-down.svg","material-ticket-account":"material/ticket-account.svg","material-ticket-confirmation-outline":"material/ticket-confirmation-outline.svg","material-ticket-confirmation":"material/ticket-confirmation.svg","material-ticket-outline":"material/ticket-outline.svg","material-ticket-percent-outline":"material/ticket-percent-outline.svg","material-ticket-percent":"material/ticket-percent.svg","material-ticket":"material/ticket.svg","material-tie":"material/tie.svg","material-tilde":"material/tilde.svg","material-timelapse":"material/timelapse.svg","material-timeline-alert-outline":"material/timeline-alert-outline.svg","material-timeline-alert":"material/timeline-alert.svg","material-timeline-check-outline":"material/timeline-check-outline.svg","material-timeline-check":"material/timeline-check.svg","material-timeline-clock-outline":"material/timeline-clock-outline.svg","material-timeline-clock":"material/timeline-clock.svg","material-timeline-help-outline":"material/timeline-help-outline.svg","material-timeline-help":"material/timeline-help.svg","material-timeline-minus-outline":"material/timeline-minus-outline.svg","material-timeline-minus":"material/timeline-minus.svg","material-timeline-outline":"material/timeline-outline.svg","material-timeline-plus-outline":"material/timeline-plus-outline.svg","material-timeline-plus":"material/timeline-plus.svg","material-timeline-remove-outline":"material/timeline-remove-outline.svg","material-timeline-remove":"material/timeline-remove.svg","material-timeline-text-outline":"material/timeline-text-outline.svg","material-timeline-text":"material/timeline-text.svg","material-timeline":"material/timeline.svg","material-timer-10":"material/timer-10.svg","material-timer-3":"material/timer-3.svg","material-timer-off-outline":"material/timer-off-outline.svg","material-timer-off":"material/timer-off.svg","material-timer-outline":"material/timer-outline.svg","material-timer-sand-empty":"material/timer-sand-empty.svg","material-timer-sand-full":"material/timer-sand-full.svg","material-timer-sand":"material/timer-sand.svg","material-timer":"material/timer.svg","material-timetable":"material/timetable.svg","material-toaster-off":"material/toaster-off.svg","material-toaster-oven":"material/toaster-oven.svg","material-toaster":"material/toaster.svg","material-toggle-switch-off-outline":"material/toggle-switch-off-outline.svg","material-toggle-switch-off":"material/toggle-switch-off.svg","material-toggle-switch-outline":"material/toggle-switch-outline.svg","material-toggle-switch":"material/toggle-switch.svg","material-toilet":"material/toilet.svg","material-toolbox-outline":"material/toolbox-outline.svg","material-toolbox":"material/toolbox.svg","material-tools":"material/tools.svg","material-tooltip-account":"material/tooltip-account.svg","material-tooltip-check-outline":"material/tooltip-check-outline.svg","material-tooltip-check":"material/tooltip-check.svg","material-tooltip-edit-outline":"material/tooltip-edit-outline.svg","material-tooltip-edit":"material/tooltip-edit.svg","material-tooltip-image-outline":"material/tooltip-image-outline.svg","material-tooltip-image":"material/tooltip-image.svg","material-tooltip-minus-outline":"material/tooltip-minus-outline.svg","material-tooltip-minus":"material/tooltip-minus.svg","material-tooltip-outline":"material/tooltip-outline.svg","material-tooltip-plus-outline":"material/tooltip-plus-outline.svg","material-tooltip-plus":"material/tooltip-plus.svg","material-tooltip-remove-outline":"material/tooltip-remove-outline.svg","material-tooltip-remove":"material/tooltip-remove.svg","material-tooltip-text-outline":"material/tooltip-text-outline.svg","material-tooltip-text":"material/tooltip-text.svg","material-tooltip":"material/tooltip.svg","material-tooth-outline":"material/tooth-outline.svg","material-tooth":"material/tooth.svg","material-toothbrush-electric":"material/toothbrush-electric.svg","material-toothbrush-paste":"material/toothbrush-paste.svg","material-toothbrush":"material/toothbrush.svg","material-torch":"material/torch.svg","material-tortoise":"material/tortoise.svg","material-toslink":"material/toslink.svg","material-tournament":"material/tournament.svg","material-tow-truck":"material/tow-truck.svg","material-tower-beach":"material/tower-beach.svg","material-tower-fire":"material/tower-fire.svg","material-toy-brick-marker-outline":"material/toy-brick-marker-outline.svg","material-toy-brick-marker":"material/toy-brick-marker.svg","material-toy-brick-minus-outline":"material/toy-brick-minus-outline.svg","material-toy-brick-minus":"material/toy-brick-minus.svg","material-toy-brick-outline":"material/toy-brick-outline.svg","material-toy-brick-plus-outline":"material/toy-brick-plus-outline.svg","material-toy-brick-plus":"material/toy-brick-plus.svg","material-toy-brick-remove-outline":"material/toy-brick-remove-outline.svg","material-toy-brick-remove":"material/toy-brick-remove.svg","material-toy-brick-search-outline":"material/toy-brick-search-outline.svg","material-toy-brick-search":"material/toy-brick-search.svg","material-toy-brick":"material/toy-brick.svg","material-track-light":"material/track-light.svg","material-trackpad-lock":"material/trackpad-lock.svg","material-trackpad":"material/trackpad.svg","material-tractor-variant":"material/tractor-variant.svg","material-tractor":"material/tractor.svg","material-trademark":"material/trademark.svg","material-traffic-cone":"material/traffic-cone.svg","material-traffic-light":"material/traffic-light.svg","material-train-car-passenger-door-open":"material/train-car-passenger-door-open.svg","material-train-car-passenger-door":"material/train-car-passenger-door.svg","material-train-car-passenger-variant":"material/train-car-passenger-variant.svg","material-train-car-passenger":"material/train-car-passenger.svg","material-train-car":"material/train-car.svg","material-train-variant":"material/train-variant.svg","material-train":"material/train.svg","material-tram-side":"material/tram-side.svg","material-tram":"material/tram.svg","material-transcribe-close":"material/transcribe-close.svg","material-transcribe":"material/transcribe.svg","material-transfer-down":"material/transfer-down.svg","material-transfer-left":"material/transfer-left.svg","material-transfer-right":"material/transfer-right.svg","material-transfer-up":"material/transfer-up.svg","material-transfer":"material/transfer.svg","material-transit-connection-horizontal":"material/transit-connection-horizontal.svg","material-transit-connection-variant":"material/transit-connection-variant.svg","material-transit-connection":"material/transit-connection.svg","material-transit-detour":"material/transit-detour.svg","material-transit-skip":"material/transit-skip.svg","material-transit-transfer":"material/transit-transfer.svg","material-transition-masked":"material/transition-masked.svg","material-transition":"material/transition.svg","material-translate-off":"material/translate-off.svg","material-translate":"material/translate.svg","material-transmission-tower":"material/transmission-tower.svg","material-trash-can-outline":"material/trash-can-outline.svg","material-trash-can":"material/trash-can.svg","material-tray-alert":"material/tray-alert.svg","material-tray-full":"material/tray-full.svg","material-tray-minus":"material/tray-minus.svg","material-tray-plus":"material/tray-plus.svg","material-tray-remove":"material/tray-remove.svg","material-tray":"material/tray.svg","material-treasure-chest":"material/treasure-chest.svg","material-tree-outline":"material/tree-outline.svg","material-tree":"material/tree.svg","material-trello":"material/trello.svg","material-trending-down":"material/trending-down.svg","material-trending-neutral":"material/trending-neutral.svg","material-trending-up":"material/trending-up.svg","material-triangle-outline":"material/triangle-outline.svg","material-triangle-wave":"material/triangle-wave.svg","material-triangle":"material/triangle.svg","material-triforce":"material/triforce.svg","material-trophy-award":"material/trophy-award.svg","material-trophy-broken":"material/trophy-broken.svg","material-trophy-outline":"material/trophy-outline.svg","material-trophy-variant-outline":"material/trophy-variant-outline.svg","material-trophy-variant":"material/trophy-variant.svg","material-trophy":"material/trophy.svg","material-truck-check-outline":"material/truck-check-outline.svg","material-truck-check":"material/truck-check.svg","material-truck-delivery-outline":"material/truck-delivery-outline.svg","material-truck-delivery":"material/truck-delivery.svg","material-truck-fast-outline":"material/truck-fast-outline.svg","material-truck-fast":"material/truck-fast.svg","material-truck-outline":"material/truck-outline.svg","material-truck-trailer":"material/truck-trailer.svg","material-truck":"material/truck.svg","material-trumpet":"material/trumpet.svg","material-tshirt-crew-outline":"material/tshirt-crew-outline.svg","material-tshirt-crew":"material/tshirt-crew.svg","material-tshirt-v-outline":"material/tshirt-v-outline.svg","material-tshirt-v":"material/tshirt-v.svg","material-tumble-dryer-alert":"material/tumble-dryer-alert.svg","material-tumble-dryer-off":"material/tumble-dryer-off.svg","material-tumble-dryer":"material/tumble-dryer.svg","material-tune-variant":"material/tune-variant.svg","material-tune-vertical-variant":"material/tune-vertical-variant.svg","material-tune-vertical":"material/tune-vertical.svg","material-tune":"material/tune.svg","material-turkey":"material/turkey.svg","material-turnstile-outline":"material/turnstile-outline.svg","material-turnstile":"material/turnstile.svg","material-turtle":"material/turtle.svg","material-twitch":"material/twitch.svg","material-twitter-retweet":"material/twitter-retweet.svg","material-twitter":"material/twitter.svg","material-two-factor-authentication":"material/two-factor-authentication.svg","material-typewriter":"material/typewriter.svg","material-ubisoft":"material/ubisoft.svg","material-ubuntu":"material/ubuntu.svg","material-ufo-outline":"material/ufo-outline.svg","material-ufo":"material/ufo.svg","material-ultra-high-definition":"material/ultra-high-definition.svg","material-umbraco":"material/umbraco.svg","material-umbrella-closed-outline":"material/umbrella-closed-outline.svg","material-umbrella-closed-variant":"material/umbrella-closed-variant.svg","material-umbrella-closed":"material/umbrella-closed.svg","material-umbrella-outline":"material/umbrella-outline.svg","material-umbrella":"material/umbrella.svg","material-undo-variant":"material/undo-variant.svg","material-undo":"material/undo.svg","material-unfold-less-horizontal":"material/unfold-less-horizontal.svg","material-unfold-less-vertical":"material/unfold-less-vertical.svg","material-unfold-more-horizontal":"material/unfold-more-horizontal.svg","material-unfold-more-vertical":"material/unfold-more-vertical.svg","material-ungroup":"material/ungroup.svg","material-unicode":"material/unicode.svg","material-unicorn-variant":"material/unicorn-variant.svg","material-unicorn":"material/unicorn.svg","material-unicycle":"material/unicycle.svg","material-unity":"material/unity.svg","material-unreal":"material/unreal.svg","material-untappd":"material/untappd.svg","material-update":"material/update.svg","material-upload-lock-outline":"material/upload-lock-outline.svg","material-upload-lock":"material/upload-lock.svg","material-upload-multiple":"material/upload-multiple.svg","material-upload-network-outline":"material/upload-network-outline.svg","material-upload-network":"material/upload-network.svg","material-upload-off-outline":"material/upload-off-outline.svg","material-upload-off":"material/upload-off.svg","material-upload-outline":"material/upload-outline.svg","material-upload":"material/upload.svg","material-usb-flash-drive-outline":"material/usb-flash-drive-outline.svg","material-usb-flash-drive":"material/usb-flash-drive.svg","material-usb-port":"material/usb-port.svg","material-usb":"material/usb.svg","material-valve-closed":"material/valve-closed.svg","material-valve-open":"material/valve-open.svg","material-valve":"material/valve.svg","material-van-passenger":"material/van-passenger.svg","material-van-utility":"material/van-utility.svg","material-vanish-quarter":"material/vanish-quarter.svg","material-vanish":"material/vanish.svg","material-vanity-light":"material/vanity-light.svg","material-variable-box":"material/variable-box.svg","material-variable":"material/variable.svg","material-vector-arrange-above":"material/vector-arrange-above.svg","material-vector-arrange-below":"material/vector-arrange-below.svg","material-vector-bezier":"material/vector-bezier.svg","material-vector-circle-variant":"material/vector-circle-variant.svg","material-vector-circle":"material/vector-circle.svg","material-vector-combine":"material/vector-combine.svg","material-vector-curve":"material/vector-curve.svg","material-vector-difference-ab":"material/vector-difference-ab.svg","material-vector-difference-ba":"material/vector-difference-ba.svg","material-vector-difference":"material/vector-difference.svg","material-vector-ellipse":"material/vector-ellipse.svg","material-vector-intersection":"material/vector-intersection.svg","material-vector-line":"material/vector-line.svg","material-vector-link":"material/vector-link.svg","material-vector-point":"material/vector-point.svg","material-vector-polygon":"material/vector-polygon.svg","material-vector-polyline-edit":"material/vector-polyline-edit.svg","material-vector-polyline-minus":"material/vector-polyline-minus.svg","material-vector-polyline-plus":"material/vector-polyline-plus.svg","material-vector-polyline-remove":"material/vector-polyline-remove.svg","material-vector-polyline":"material/vector-polyline.svg","material-vector-radius":"material/vector-radius.svg","material-vector-rectangle":"material/vector-rectangle.svg","material-vector-selection":"material/vector-selection.svg","material-vector-square":"material/vector-square.svg","material-vector-triangle":"material/vector-triangle.svg","material-vector-union":"material/vector-union.svg","material-vhs":"material/vhs.svg","material-vibrate-off":"material/vibrate-off.svg","material-vibrate":"material/vibrate.svg","material-video-3d-off":"material/video-3d-off.svg","material-video-3d-variant":"material/video-3d-variant.svg","material-video-3d":"material/video-3d.svg","material-video-4k-box":"material/video-4k-box.svg","material-video-account":"material/video-account.svg","material-video-box-off":"material/video-box-off.svg","material-video-box":"material/video-box.svg","material-video-check-outline":"material/video-check-outline.svg","material-video-check":"material/video-check.svg","material-video-high-definition":"material/video-high-definition.svg","material-video-image":"material/video-image.svg","material-video-input-antenna":"material/video-input-antenna.svg","material-video-input-component":"material/video-input-component.svg","material-video-input-hdmi":"material/video-input-hdmi.svg","material-video-input-scart":"material/video-input-scart.svg","material-video-input-svideo":"material/video-input-svideo.svg","material-video-minus-outline":"material/video-minus-outline.svg","material-video-minus":"material/video-minus.svg","material-video-off-outline":"material/video-off-outline.svg","material-video-off":"material/video-off.svg","material-video-outline":"material/video-outline.svg","material-video-plus-outline":"material/video-plus-outline.svg","material-video-plus":"material/video-plus.svg","material-video-stabilization":"material/video-stabilization.svg","material-video-switch-outline":"material/video-switch-outline.svg","material-video-switch":"material/video-switch.svg","material-video-vintage":"material/video-vintage.svg","material-video-wireless-outline":"material/video-wireless-outline.svg","material-video-wireless":"material/video-wireless.svg","material-video":"material/video.svg","material-view-agenda-outline":"material/view-agenda-outline.svg","material-view-agenda":"material/view-agenda.svg","material-view-array-outline":"material/view-array-outline.svg","material-view-array":"material/view-array.svg","material-view-carousel-outline":"material/view-carousel-outline.svg","material-view-carousel":"material/view-carousel.svg","material-view-column-outline":"material/view-column-outline.svg","material-view-column":"material/view-column.svg","material-view-comfy-outline":"material/view-comfy-outline.svg","material-view-comfy":"material/view-comfy.svg","material-view-compact-outline":"material/view-compact-outline.svg","material-view-compact":"material/view-compact.svg","material-view-dashboard-outline":"material/view-dashboard-outline.svg","material-view-dashboard-variant-outline":"material/view-dashboard-variant-outline.svg","material-view-dashboard-variant":"material/view-dashboard-variant.svg","material-view-dashboard":"material/view-dashboard.svg","material-view-day-outline":"material/view-day-outline.svg","material-view-day":"material/view-day.svg","material-view-grid-outline":"material/view-grid-outline.svg","material-view-grid-plus-outline":"material/view-grid-plus-outline.svg","material-view-grid-plus":"material/view-grid-plus.svg","material-view-grid":"material/view-grid.svg","material-view-headline":"material/view-headline.svg","material-view-list-outline":"material/view-list-outline.svg","material-view-list":"material/view-list.svg","material-view-module-outline":"material/view-module-outline.svg","material-view-module":"material/view-module.svg","material-view-parallel-outline":"material/view-parallel-outline.svg","material-view-parallel":"material/view-parallel.svg","material-view-quilt-outline":"material/view-quilt-outline.svg","material-view-quilt":"material/view-quilt.svg","material-view-sequential-outline":"material/view-sequential-outline.svg","material-view-sequential":"material/view-sequential.svg","material-view-split-horizontal":"material/view-split-horizontal.svg","material-view-split-vertical":"material/view-split-vertical.svg","material-view-stream-outline":"material/view-stream-outline.svg","material-view-stream":"material/view-stream.svg","material-view-week-outline":"material/view-week-outline.svg","material-view-week":"material/view-week.svg","material-vimeo":"material/vimeo.svg","material-violin":"material/violin.svg","material-virtual-reality":"material/virtual-reality.svg","material-virus-outline":"material/virus-outline.svg","material-virus":"material/virus.svg","material-vk":"material/vk.svg","material-vlc":"material/vlc.svg","material-voice-off":"material/voice-off.svg","material-voicemail":"material/voicemail.svg","material-volleyball":"material/volleyball.svg","material-volume-high":"material/volume-high.svg","material-volume-low":"material/volume-low.svg","material-volume-medium":"material/volume-medium.svg","material-volume-minus":"material/volume-minus.svg","material-volume-mute":"material/volume-mute.svg","material-volume-off":"material/volume-off.svg","material-volume-plus":"material/volume-plus.svg","material-volume-source":"material/volume-source.svg","material-volume-variant-off":"material/volume-variant-off.svg","material-volume-vibrate":"material/volume-vibrate.svg","material-vote-outline":"material/vote-outline.svg","material-vote":"material/vote.svg","material-vpn":"material/vpn.svg","material-vuejs":"material/vuejs.svg","material-vuetify":"material/vuetify.svg","material-walk":"material/walk.svg","material-wall-sconce-flat-variant":"material/wall-sconce-flat-variant.svg","material-wall-sconce-flat":"material/wall-sconce-flat.svg","material-wall-sconce-round-variant":"material/wall-sconce-round-variant.svg","material-wall-sconce-round":"material/wall-sconce-round.svg","material-wall-sconce":"material/wall-sconce.svg","material-wall":"material/wall.svg","material-wallet-giftcard":"material/wallet-giftcard.svg","material-wallet-membership":"material/wallet-membership.svg","material-wallet-outline":"material/wallet-outline.svg","material-wallet-plus-outline":"material/wallet-plus-outline.svg","material-wallet-plus":"material/wallet-plus.svg","material-wallet-travel":"material/wallet-travel.svg","material-wallet":"material/wallet.svg","material-wallpaper":"material/wallpaper.svg","material-wan":"material/wan.svg","material-wardrobe-outline":"material/wardrobe-outline.svg","material-wardrobe":"material/wardrobe.svg","material-warehouse":"material/warehouse.svg","material-washing-machine-alert":"material/washing-machine-alert.svg","material-washing-machine-off":"material/washing-machine-off.svg","material-washing-machine":"material/washing-machine.svg","material-watch-export-variant":"material/watch-export-variant.svg","material-watch-export":"material/watch-export.svg","material-watch-import-variant":"material/watch-import-variant.svg","material-watch-import":"material/watch-import.svg","material-watch-variant":"material/watch-variant.svg","material-watch-vibrate-off":"material/watch-vibrate-off.svg","material-watch-vibrate":"material/watch-vibrate.svg","material-watch":"material/watch.svg","material-water-alert-outline":"material/water-alert-outline.svg","material-water-alert":"material/water-alert.svg","material-water-boiler-alert":"material/water-boiler-alert.svg","material-water-boiler-off":"material/water-boiler-off.svg","material-water-boiler":"material/water-boiler.svg","material-water-check-outline":"material/water-check-outline.svg","material-water-check":"material/water-check.svg","material-water-minus-outline":"material/water-minus-outline.svg","material-water-minus":"material/water-minus.svg","material-water-off-outline":"material/water-off-outline.svg","material-water-off":"material/water-off.svg","material-water-outline":"material/water-outline.svg","material-water-percent-alert":"material/water-percent-alert.svg","material-water-percent":"material/water-percent.svg","material-water-plus-outline":"material/water-plus-outline.svg","material-water-plus":"material/water-plus.svg","material-water-polo":"material/water-polo.svg","material-water-pump-off":"material/water-pump-off.svg","material-water-pump":"material/water-pump.svg","material-water-remove-outline":"material/water-remove-outline.svg","material-water-remove":"material/water-remove.svg","material-water-well-outline":"material/water-well-outline.svg","material-water-well":"material/water-well.svg","material-water":"material/water.svg","material-watering-can-outline":"material/watering-can-outline.svg","material-watering-can":"material/watering-can.svg","material-watermark":"material/watermark.svg","material-wave":"material/wave.svg","material-waveform":"material/waveform.svg","material-waves":"material/waves.svg","material-waze":"material/waze.svg","material-weather-cloudy-alert":"material/weather-cloudy-alert.svg","material-weather-cloudy-arrow-right":"material/weather-cloudy-arrow-right.svg","material-weather-cloudy":"material/weather-cloudy.svg","material-weather-fog":"material/weather-fog.svg","material-weather-hail":"material/weather-hail.svg","material-weather-hazy":"material/weather-hazy.svg","material-weather-hurricane":"material/weather-hurricane.svg","material-weather-lightning-rainy":"material/weather-lightning-rainy.svg","material-weather-lightning":"material/weather-lightning.svg","material-weather-night-partly-cloudy":"material/weather-night-partly-cloudy.svg","material-weather-night":"material/weather-night.svg","material-weather-partly-cloudy":"material/weather-partly-cloudy.svg","material-weather-partly-lightning":"material/weather-partly-lightning.svg","material-weather-partly-rainy":"material/weather-partly-rainy.svg","material-weather-partly-snowy-rainy":"material/weather-partly-snowy-rainy.svg","material-weather-partly-snowy":"material/weather-partly-snowy.svg","material-weather-pouring":"material/weather-pouring.svg","material-weather-rainy":"material/weather-rainy.svg","material-weather-snowy-heavy":"material/weather-snowy-heavy.svg","material-weather-snowy-rainy":"material/weather-snowy-rainy.svg","material-weather-snowy":"material/weather-snowy.svg","material-weather-sunny-alert":"material/weather-sunny-alert.svg","material-weather-sunny-off":"material/weather-sunny-off.svg","material-weather-sunny":"material/weather-sunny.svg","material-weather-sunset-down":"material/weather-sunset-down.svg","material-weather-sunset-up":"material/weather-sunset-up.svg","material-weather-sunset":"material/weather-sunset.svg","material-weather-tornado":"material/weather-tornado.svg","material-weather-windy-variant":"material/weather-windy-variant.svg","material-weather-windy":"material/weather-windy.svg","material-web-box":"material/web-box.svg","material-web-clock":"material/web-clock.svg","material-web":"material/web.svg","material-webcam-off":"material/webcam-off.svg","material-webcam":"material/webcam.svg","material-webhook":"material/webhook.svg","material-webpack":"material/webpack.svg","material-webrtc":"material/webrtc.svg","material-wechat":"material/wechat.svg","material-weight-gram":"material/weight-gram.svg","material-weight-kilogram":"material/weight-kilogram.svg","material-weight-lifter":"material/weight-lifter.svg","material-weight-pound":"material/weight-pound.svg","material-weight":"material/weight.svg","material-whatsapp":"material/whatsapp.svg","material-wheel-barrow":"material/wheel-barrow.svg","material-wheelchair-accessibility":"material/wheelchair-accessibility.svg","material-whistle-outline":"material/whistle-outline.svg","material-whistle":"material/whistle.svg","material-white-balance-auto":"material/white-balance-auto.svg","material-white-balance-incandescent":"material/white-balance-incandescent.svg","material-white-balance-iridescent":"material/white-balance-iridescent.svg","material-white-balance-sunny":"material/white-balance-sunny.svg","material-widgets-outline":"material/widgets-outline.svg","material-widgets":"material/widgets.svg","material-wifi-alert":"material/wifi-alert.svg","material-wifi-arrow-down":"material/wifi-arrow-down.svg","material-wifi-arrow-left-right":"material/wifi-arrow-left-right.svg","material-wifi-arrow-left":"material/wifi-arrow-left.svg","material-wifi-arrow-right":"material/wifi-arrow-right.svg","material-wifi-arrow-up-down":"material/wifi-arrow-up-down.svg","material-wifi-arrow-up":"material/wifi-arrow-up.svg","material-wifi-cancel":"material/wifi-cancel.svg","material-wifi-check":"material/wifi-check.svg","material-wifi-cog":"material/wifi-cog.svg","material-wifi-lock-open":"material/wifi-lock-open.svg","material-wifi-lock":"material/wifi-lock.svg","material-wifi-marker":"material/wifi-marker.svg","material-wifi-minus":"material/wifi-minus.svg","material-wifi-off":"material/wifi-off.svg","material-wifi-plus":"material/wifi-plus.svg","material-wifi-refresh":"material/wifi-refresh.svg","material-wifi-remove":"material/wifi-remove.svg","material-wifi-settings":"material/wifi-settings.svg","material-wifi-star":"material/wifi-star.svg","material-wifi-strength-1-alert":"material/wifi-strength-1-alert.svg","material-wifi-strength-1-lock-open":"material/wifi-strength-1-lock-open.svg","material-wifi-strength-1-lock":"material/wifi-strength-1-lock.svg","material-wifi-strength-1":"material/wifi-strength-1.svg","material-wifi-strength-2-alert":"material/wifi-strength-2-alert.svg","material-wifi-strength-2-lock-open":"material/wifi-strength-2-lock-open.svg","material-wifi-strength-2-lock":"material/wifi-strength-2-lock.svg","material-wifi-strength-2":"material/wifi-strength-2.svg","material-wifi-strength-3-alert":"material/wifi-strength-3-alert.svg","material-wifi-strength-3-lock-open":"material/wifi-strength-3-lock-open.svg","material-wifi-strength-3-lock":"material/wifi-strength-3-lock.svg","material-wifi-strength-3":"material/wifi-strength-3.svg","material-wifi-strength-4-alert":"material/wifi-strength-4-alert.svg","material-wifi-strength-4-lock-open":"material/wifi-strength-4-lock-open.svg","material-wifi-strength-4-lock":"material/wifi-strength-4-lock.svg","material-wifi-strength-4":"material/wifi-strength-4.svg","material-wifi-strength-alert-outline":"material/wifi-strength-alert-outline.svg","material-wifi-strength-lock-open-outline":"material/wifi-strength-lock-open-outline.svg","material-wifi-strength-lock-outline":"material/wifi-strength-lock-outline.svg","material-wifi-strength-off-outline":"material/wifi-strength-off-outline.svg","material-wifi-strength-off":"material/wifi-strength-off.svg","material-wifi-strength-outline":"material/wifi-strength-outline.svg","material-wifi-sync":"material/wifi-sync.svg","material-wifi":"material/wifi.svg","material-wikipedia":"material/wikipedia.svg","material-wind-turbine":"material/wind-turbine.svg","material-window-close":"material/window-close.svg","material-window-closed-variant":"material/window-closed-variant.svg","material-window-closed":"material/window-closed.svg","material-window-maximize":"material/window-maximize.svg","material-window-minimize":"material/window-minimize.svg","material-window-open-variant":"material/window-open-variant.svg","material-window-open":"material/window-open.svg","material-window-restore":"material/window-restore.svg","material-window-shutter-alert":"material/window-shutter-alert.svg","material-window-shutter-open":"material/window-shutter-open.svg","material-window-shutter":"material/window-shutter.svg","material-windsock":"material/windsock.svg","material-wiper-wash":"material/wiper-wash.svg","material-wiper":"material/wiper.svg","material-wizard-hat":"material/wizard-hat.svg","material-wordpress":"material/wordpress.svg","material-wrap-disabled":"material/wrap-disabled.svg","material-wrap":"material/wrap.svg","material-wrench-outline":"material/wrench-outline.svg","material-wrench":"material/wrench.svg","material-xamarin-outline":"material/xamarin-outline.svg","material-xamarin":"material/xamarin.svg","material-xing":"material/xing.svg","material-xml":"material/xml.svg","material-xmpp":"material/xmpp.svg","material-y-combinator":"material/y-combinator.svg","material-yahoo":"material/yahoo.svg","material-yeast":"material/yeast.svg","material-yin-yang":"material/yin-yang.svg","material-yoga":"material/yoga.svg","material-youtube-gaming":"material/youtube-gaming.svg","material-youtube-studio":"material/youtube-studio.svg","material-youtube-subscription":"material/youtube-subscription.svg","material-youtube-tv":"material/youtube-tv.svg","material-youtube":"material/youtube.svg","material-yurt":"material/yurt.svg","material-z-wave":"material/z-wave.svg","material-zend":"material/zend.svg","material-zigbee":"material/zigbee.svg","material-zip-box-outline":"material/zip-box-outline.svg","material-zip-box":"material/zip-box.svg","material-zip-disk":"material/zip-disk.svg","material-zodiac-aquarius":"material/zodiac-aquarius.svg","material-zodiac-aries":"material/zodiac-aries.svg","material-zodiac-cancer":"material/zodiac-cancer.svg","material-zodiac-capricorn":"material/zodiac-capricorn.svg","material-zodiac-gemini":"material/zodiac-gemini.svg","material-zodiac-leo":"material/zodiac-leo.svg","material-zodiac-libra":"material/zodiac-libra.svg","material-zodiac-pisces":"material/zodiac-pisces.svg","material-zodiac-sagittarius":"material/zodiac-sagittarius.svg","material-zodiac-scorpio":"material/zodiac-scorpio.svg","material-zodiac-taurus":"material/zodiac-taurus.svg","material-zodiac-virgo":"material/zodiac-virgo.svg","octicons-alert-16":"octicons/alert-16.svg","octicons-alert-24":"octicons/alert-24.svg","octicons-archive-16":"octicons/archive-16.svg","octicons-archive-24":"octicons/archive-24.svg","octicons-arrow-both-16":"octicons/arrow-both-16.svg","octicons-arrow-both-24":"octicons/arrow-both-24.svg","octicons-arrow-down-16":"octicons/arrow-down-16.svg","octicons-arrow-down-24":"octicons/arrow-down-24.svg","octicons-arrow-down-left-24":"octicons/arrow-down-left-24.svg","octicons-arrow-down-right-24":"octicons/arrow-down-right-24.svg","octicons-arrow-left-16":"octicons/arrow-left-16.svg","octicons-arrow-left-24":"octicons/arrow-left-24.svg","octicons-arrow-right-16":"octicons/arrow-right-16.svg","octicons-arrow-right-24":"octicons/arrow-right-24.svg","octicons-arrow-switch-16":"octicons/arrow-switch-16.svg","octicons-arrow-switch-24":"octicons/arrow-switch-24.svg","octicons-arrow-up-16":"octicons/arrow-up-16.svg","octicons-arrow-up-24":"octicons/arrow-up-24.svg","octicons-arrow-up-left-24":"octicons/arrow-up-left-24.svg","octicons-arrow-up-right-24":"octicons/arrow-up-right-24.svg","octicons-beaker-16":"octicons/beaker-16.svg","octicons-beaker-24":"octicons/beaker-24.svg","octicons-bell-16":"octicons/bell-16.svg","octicons-bell-24":"octicons/bell-24.svg","octicons-bell-fill-24":"octicons/bell-fill-24.svg","octicons-bell-slash-16":"octicons/bell-slash-16.svg","octicons-bell-slash-24":"octicons/bell-slash-24.svg","octicons-bold-16":"octicons/bold-16.svg","octicons-bold-24":"octicons/bold-24.svg","octicons-book-16":"octicons/book-16.svg","octicons-book-24":"octicons/book-24.svg","octicons-bookmark-16":"octicons/bookmark-16.svg","octicons-bookmark-24":"octicons/bookmark-24.svg","octicons-bookmark-fill-24":"octicons/bookmark-fill-24.svg","octicons-bookmark-slash-16":"octicons/bookmark-slash-16.svg","octicons-bookmark-slash-24":"octicons/bookmark-slash-24.svg","octicons-bookmark-slash-fill-24":"octicons/bookmark-slash-fill-24.svg","octicons-briefcase-16":"octicons/briefcase-16.svg","octicons-briefcase-24":"octicons/briefcase-24.svg","octicons-broadcast-16":"octicons/broadcast-16.svg","octicons-broadcast-24":"octicons/broadcast-24.svg","octicons-browser-16":"octicons/browser-16.svg","octicons-bug-16":"octicons/bug-16.svg","octicons-bug-24":"octicons/bug-24.svg","octicons-calendar-16":"octicons/calendar-16.svg","octicons-calendar-24":"octicons/calendar-24.svg","octicons-check-16":"octicons/check-16.svg","octicons-check-24":"octicons/check-24.svg","octicons-check-circle-16":"octicons/check-circle-16.svg","octicons-check-circle-24":"octicons/check-circle-24.svg","octicons-check-circle-fill-16":"octicons/check-circle-fill-16.svg","octicons-check-circle-fill-24":"octicons/check-circle-fill-24.svg","octicons-checklist-16":"octicons/checklist-16.svg","octicons-checklist-24":"octicons/checklist-24.svg","octicons-chevron-down-16":"octicons/chevron-down-16.svg","octicons-chevron-down-24":"octicons/chevron-down-24.svg","octicons-chevron-left-16":"octicons/chevron-left-16.svg","octicons-chevron-left-24":"octicons/chevron-left-24.svg","octicons-chevron-right-16":"octicons/chevron-right-16.svg","octicons-chevron-right-24":"octicons/chevron-right-24.svg","octicons-chevron-up-16":"octicons/chevron-up-16.svg","octicons-chevron-up-24":"octicons/chevron-up-24.svg","octicons-circle-16":"octicons/circle-16.svg","octicons-circle-24":"octicons/circle-24.svg","octicons-circle-slash-16":"octicons/circle-slash-16.svg","octicons-circle-slash-24":"octicons/circle-slash-24.svg","octicons-clippy-16":"octicons/clippy-16.svg","octicons-clippy-24":"octicons/clippy-24.svg","octicons-clock-16":"octicons/clock-16.svg","octicons-clock-24":"octicons/clock-24.svg","octicons-code-16":"octicons/code-16.svg","octicons-code-24":"octicons/code-24.svg","octicons-code-review-16":"octicons/code-review-16.svg","octicons-code-review-24":"octicons/code-review-24.svg","octicons-code-square-16":"octicons/code-square-16.svg","octicons-code-square-24":"octicons/code-square-24.svg","octicons-comment-16":"octicons/comment-16.svg","octicons-comment-24":"octicons/comment-24.svg","octicons-comment-discussion-16":"octicons/comment-discussion-16.svg","octicons-comment-discussion-24":"octicons/comment-discussion-24.svg","octicons-commit-24":"octicons/commit-24.svg","octicons-container-16":"octicons/container-16.svg","octicons-container-24":"octicons/container-24.svg","octicons-copy-24":"octicons/copy-24.svg","octicons-cpu-16":"octicons/cpu-16.svg","octicons-cpu-24":"octicons/cpu-24.svg","octicons-credit-card-16":"octicons/credit-card-16.svg","octicons-credit-card-24":"octicons/credit-card-24.svg","octicons-cross-reference-16":"octicons/cross-reference-16.svg","octicons-cross-reference-24":"octicons/cross-reference-24.svg","octicons-dash-16":"octicons/dash-16.svg","octicons-dash-24":"octicons/dash-24.svg","octicons-database-16":"octicons/database-16.svg","octicons-database-24":"octicons/database-24.svg","octicons-desktop-download-16":"octicons/desktop-download-16.svg","octicons-desktop-download-24":"octicons/desktop-download-24.svg","octicons-device-camera-16":"octicons/device-camera-16.svg","octicons-device-camera-video-16":"octicons/device-camera-video-16.svg","octicons-device-camera-video-24":"octicons/device-camera-video-24.svg","octicons-device-desktop-16":"octicons/device-desktop-16.svg","octicons-device-desktop-24":"octicons/device-desktop-24.svg","octicons-device-mobile-16":"octicons/device-mobile-16.svg","octicons-device-mobile-24":"octicons/device-mobile-24.svg","octicons-diff-16":"octicons/diff-16.svg","octicons-diff-24":"octicons/diff-24.svg","octicons-diff-added-16":"octicons/diff-added-16.svg","octicons-diff-ignored-16":"octicons/diff-ignored-16.svg","octicons-diff-modified-16":"octicons/diff-modified-16.svg","octicons-diff-removed-16":"octicons/diff-removed-16.svg","octicons-diff-renamed-16":"octicons/diff-renamed-16.svg","octicons-dot-16":"octicons/dot-16.svg","octicons-dot-24":"octicons/dot-24.svg","octicons-dot-fill-16":"octicons/dot-fill-16.svg","octicons-dot-fill-24":"octicons/dot-fill-24.svg","octicons-download-16":"octicons/download-16.svg","octicons-download-24":"octicons/download-24.svg","octicons-ellipsis-16":"octicons/ellipsis-16.svg","octicons-eye-16":"octicons/eye-16.svg","octicons-eye-24":"octicons/eye-24.svg","octicons-eye-closed-16":"octicons/eye-closed-16.svg","octicons-eye-closed-24":"octicons/eye-closed-24.svg","octicons-file-16":"octicons/file-16.svg","octicons-file-24":"octicons/file-24.svg","octicons-file-badge-16":"octicons/file-badge-16.svg","octicons-file-binary-16":"octicons/file-binary-16.svg","octicons-file-binary-24":"octicons/file-binary-24.svg","octicons-file-code-16":"octicons/file-code-16.svg","octicons-file-code-24":"octicons/file-code-24.svg","octicons-file-diff-16":"octicons/file-diff-16.svg","octicons-file-diff-24":"octicons/file-diff-24.svg","octicons-file-directory-16":"octicons/file-directory-16.svg","octicons-file-directory-24":"octicons/file-directory-24.svg","octicons-file-directory-fill-24":"octicons/file-directory-fill-24.svg","octicons-file-media-24":"octicons/file-media-24.svg","octicons-file-submodule-16":"octicons/file-submodule-16.svg","octicons-file-submodule-24":"octicons/file-submodule-24.svg","octicons-file-symlink-file-16":"octicons/file-symlink-file-16.svg","octicons-file-symlink-file-24":"octicons/file-symlink-file-24.svg","octicons-file-zip-16":"octicons/file-zip-16.svg","octicons-file-zip-24":"octicons/file-zip-24.svg","octicons-filter-16":"octicons/filter-16.svg","octicons-filter-24":"octicons/filter-24.svg","octicons-flame-16":"octicons/flame-16.svg","octicons-flame-24":"octicons/flame-24.svg","octicons-fold-16":"octicons/fold-16.svg","octicons-fold-24":"octicons/fold-24.svg","octicons-fold-down-16":"octicons/fold-down-16.svg","octicons-fold-down-24":"octicons/fold-down-24.svg","octicons-fold-up-16":"octicons/fold-up-16.svg","octicons-fold-up-24":"octicons/fold-up-24.svg","octicons-gear-16":"octicons/gear-16.svg","octicons-gear-24":"octicons/gear-24.svg","octicons-gift-16":"octicons/gift-16.svg","octicons-gift-24":"octicons/gift-24.svg","octicons-git-branch-16":"octicons/git-branch-16.svg","octicons-git-branch-24":"octicons/git-branch-24.svg","octicons-git-commit-16":"octicons/git-commit-16.svg","octicons-git-commit-24":"octicons/git-commit-24.svg","octicons-git-compare-16":"octicons/git-compare-16.svg","octicons-git-compare-24":"octicons/git-compare-24.svg","octicons-git-fork-24":"octicons/git-fork-24.svg","octicons-git-merge-16":"octicons/git-merge-16.svg","octicons-git-merge-24":"octicons/git-merge-24.svg","octicons-git-pull-request-16":"octicons/git-pull-request-16.svg","octicons-git-pull-request-24":"octicons/git-pull-request-24.svg","octicons-globe-16":"octicons/globe-16.svg","octicons-globe-24":"octicons/globe-24.svg","octicons-grabber-16":"octicons/grabber-16.svg","octicons-grabber-24":"octicons/grabber-24.svg","octicons-graph-16":"octicons/graph-16.svg","octicons-graph-24":"octicons/graph-24.svg","octicons-heading-16":"octicons/heading-16.svg","octicons-heading-24":"octicons/heading-24.svg","octicons-heart-16":"octicons/heart-16.svg","octicons-heart-24":"octicons/heart-24.svg","octicons-heart-fill-16":"octicons/heart-fill-16.svg","octicons-heart-fill-24":"octicons/heart-fill-24.svg","octicons-history-16":"octicons/history-16.svg","octicons-history-24":"octicons/history-24.svg","octicons-home-16":"octicons/home-16.svg","octicons-home-24":"octicons/home-24.svg","octicons-home-fill-24":"octicons/home-fill-24.svg","octicons-horizontal-rule-16":"octicons/horizontal-rule-16.svg","octicons-horizontal-rule-24":"octicons/horizontal-rule-24.svg","octicons-hourglass-16":"octicons/hourglass-16.svg","octicons-hourglass-24":"octicons/hourglass-24.svg","octicons-hubot-16":"octicons/hubot-16.svg","octicons-hubot-24":"octicons/hubot-24.svg","octicons-image-16":"octicons/image-16.svg","octicons-image-24":"octicons/image-24.svg","octicons-inbox-16":"octicons/inbox-16.svg","octicons-inbox-24":"octicons/inbox-24.svg","octicons-infinity-16":"octicons/infinity-16.svg","octicons-infinity-24":"octicons/infinity-24.svg","octicons-info-16":"octicons/info-16.svg","octicons-info-24":"octicons/info-24.svg","octicons-insights-24":"octicons/insights-24.svg","octicons-issue-closed-16":"octicons/issue-closed-16.svg","octicons-issue-closed-24":"octicons/issue-closed-24.svg","octicons-issue-opened-16":"octicons/issue-opened-16.svg","octicons-issue-opened-24":"octicons/issue-opened-24.svg","octicons-issue-reopened-16":"octicons/issue-reopened-16.svg","octicons-issue-reopened-24":"octicons/issue-reopened-24.svg","octicons-italic-16":"octicons/italic-16.svg","octicons-italic-24":"octicons/italic-24.svg","octicons-kebab-horizontal-16":"octicons/kebab-horizontal-16.svg","octicons-kebab-horizontal-24":"octicons/kebab-horizontal-24.svg","octicons-key-16":"octicons/key-16.svg","octicons-key-24":"octicons/key-24.svg","octicons-law-16":"octicons/law-16.svg","octicons-law-24":"octicons/law-24.svg","octicons-light-bulb-16":"octicons/light-bulb-16.svg","octicons-light-bulb-24":"octicons/light-bulb-24.svg","octicons-link-16":"octicons/link-16.svg","octicons-link-24":"octicons/link-24.svg","octicons-link-external-16":"octicons/link-external-16.svg","octicons-link-external-24":"octicons/link-external-24.svg","octicons-list-ordered-16":"octicons/list-ordered-16.svg","octicons-list-ordered-24":"octicons/list-ordered-24.svg","octicons-list-unordered-16":"octicons/list-unordered-16.svg","octicons-list-unordered-24":"octicons/list-unordered-24.svg","octicons-location-16":"octicons/location-16.svg","octicons-location-24":"octicons/location-24.svg","octicons-lock-16":"octicons/lock-16.svg","octicons-lock-24":"octicons/lock-24.svg","octicons-logo-gist-16":"octicons/logo-gist-16.svg","octicons-logo-github-16":"octicons/logo-github-16.svg","octicons-mail-16":"octicons/mail-16.svg","octicons-mail-24":"octicons/mail-24.svg","octicons-mark-github-16":"octicons/mark-github-16.svg","octicons-markdown-16":"octicons/markdown-16.svg","octicons-megaphone-16":"octicons/megaphone-16.svg","octicons-megaphone-24":"octicons/megaphone-24.svg","octicons-mention-16":"octicons/mention-16.svg","octicons-mention-24":"octicons/mention-24.svg","octicons-meter-16":"octicons/meter-16.svg","octicons-milestone-16":"octicons/milestone-16.svg","octicons-milestone-24":"octicons/milestone-24.svg","octicons-mirror-16":"octicons/mirror-16.svg","octicons-mirror-24":"octicons/mirror-24.svg","octicons-moon-16":"octicons/moon-16.svg","octicons-moon-24":"octicons/moon-24.svg","octicons-mortar-board-16":"octicons/mortar-board-16.svg","octicons-mortar-board-24":"octicons/mortar-board-24.svg","octicons-multi-select-16":"octicons/multi-select-16.svg","octicons-multi-select-24":"octicons/multi-select-24.svg","octicons-mute-16":"octicons/mute-16.svg","octicons-mute-24":"octicons/mute-24.svg","octicons-no-entry-16":"octicons/no-entry-16.svg","octicons-no-entry-24":"octicons/no-entry-24.svg","octicons-north-star-16":"octicons/north-star-16.svg","octicons-north-star-24":"octicons/north-star-24.svg","octicons-note-16":"octicons/note-16.svg","octicons-note-24":"octicons/note-24.svg","octicons-number-16":"octicons/number-16.svg","octicons-number-24":"octicons/number-24.svg","octicons-octoface-16":"octicons/octoface-16.svg","octicons-octoface-24":"octicons/octoface-24.svg","octicons-organization-16":"octicons/organization-16.svg","octicons-organization-24":"octicons/organization-24.svg","octicons-package-16":"octicons/package-16.svg","octicons-package-24":"octicons/package-24.svg","octicons-package-dependencies-16":"octicons/package-dependencies-16.svg","octicons-package-dependencies-24":"octicons/package-dependencies-24.svg","octicons-package-dependents-16":"octicons/package-dependents-16.svg","octicons-package-dependents-24":"octicons/package-dependents-24.svg","octicons-paintbrush-16":"octicons/paintbrush-16.svg","octicons-paper-airplane-16":"octicons/paper-airplane-16.svg","octicons-paper-airplane-24":"octicons/paper-airplane-24.svg","octicons-pencil-16":"octicons/pencil-16.svg","octicons-pencil-24":"octicons/pencil-24.svg","octicons-people-16":"octicons/people-16.svg","octicons-people-24":"octicons/people-24.svg","octicons-person-16":"octicons/person-16.svg","octicons-person-24":"octicons/person-24.svg","octicons-pin-16":"octicons/pin-16.svg","octicons-pin-24":"octicons/pin-24.svg","octicons-play-16":"octicons/play-16.svg","octicons-play-24":"octicons/play-24.svg","octicons-plug-16":"octicons/plug-16.svg","octicons-plug-24":"octicons/plug-24.svg","octicons-plus-16":"octicons/plus-16.svg","octicons-plus-24":"octicons/plus-24.svg","octicons-plus-circle-16":"octicons/plus-circle-16.svg","octicons-plus-circle-24":"octicons/plus-circle-24.svg","octicons-project-16":"octicons/project-16.svg","octicons-project-24":"octicons/project-24.svg","octicons-pulse-16":"octicons/pulse-16.svg","octicons-pulse-24":"octicons/pulse-24.svg","octicons-question-16":"octicons/question-16.svg","octicons-question-24":"octicons/question-24.svg","octicons-quote-16":"octicons/quote-16.svg","octicons-quote-24":"octicons/quote-24.svg","octicons-reply-16":"octicons/reply-16.svg","octicons-reply-24":"octicons/reply-24.svg","octicons-repo-16":"octicons/repo-16.svg","octicons-repo-24":"octicons/repo-24.svg","octicons-repo-clone-16":"octicons/repo-clone-16.svg","octicons-repo-forked-16":"octicons/repo-forked-16.svg","octicons-repo-pull-16":"octicons/repo-pull-16.svg","octicons-repo-push-16":"octicons/repo-push-16.svg","octicons-repo-push-24":"octicons/repo-push-24.svg","octicons-repo-template-16":"octicons/repo-template-16.svg","octicons-repo-template-24":"octicons/repo-template-24.svg","octicons-report-16":"octicons/report-16.svg","octicons-report-24":"octicons/report-24.svg","octicons-rocket-16":"octicons/rocket-16.svg","octicons-rocket-24":"octicons/rocket-24.svg","octicons-rss-16":"octicons/rss-16.svg","octicons-rss-24":"octicons/rss-24.svg","octicons-ruby-16":"octicons/ruby-16.svg","octicons-ruby-24":"octicons/ruby-24.svg","octicons-screen-full-16":"octicons/screen-full-16.svg","octicons-screen-full-24":"octicons/screen-full-24.svg","octicons-screen-normal-16":"octicons/screen-normal-16.svg","octicons-screen-normal-24":"octicons/screen-normal-24.svg","octicons-search-16":"octicons/search-16.svg","octicons-search-24":"octicons/search-24.svg","octicons-server-16":"octicons/server-16.svg","octicons-server-24":"octicons/server-24.svg","octicons-share-16":"octicons/share-16.svg","octicons-share-24":"octicons/share-24.svg","octicons-share-android-16":"octicons/share-android-16.svg","octicons-share-android-24":"octicons/share-android-24.svg","octicons-shield-16":"octicons/shield-16.svg","octicons-shield-24":"octicons/shield-24.svg","octicons-shield-check-16":"octicons/shield-check-16.svg","octicons-shield-check-24":"octicons/shield-check-24.svg","octicons-shield-lock-16":"octicons/shield-lock-16.svg","octicons-shield-lock-24":"octicons/shield-lock-24.svg","octicons-shield-x-16":"octicons/shield-x-16.svg","octicons-shield-x-24":"octicons/shield-x-24.svg","octicons-sign-in-16":"octicons/sign-in-16.svg","octicons-sign-in-24":"octicons/sign-in-24.svg","octicons-sign-out-16":"octicons/sign-out-16.svg","octicons-sign-out-24":"octicons/sign-out-24.svg","octicons-skip-16":"octicons/skip-16.svg","octicons-skip-24":"octicons/skip-24.svg","octicons-smiley-16":"octicons/smiley-16.svg","octicons-smiley-24":"octicons/smiley-24.svg","octicons-square-16":"octicons/square-16.svg","octicons-square-24":"octicons/square-24.svg","octicons-square-fill-16":"octicons/square-fill-16.svg","octicons-square-fill-24":"octicons/square-fill-24.svg","octicons-squirrel-16":"octicons/squirrel-16.svg","octicons-squirrel-24":"octicons/squirrel-24.svg","octicons-star-16":"octicons/star-16.svg","octicons-star-24":"octicons/star-24.svg","octicons-star-fill-16":"octicons/star-fill-16.svg","octicons-star-fill-24":"octicons/star-fill-24.svg","octicons-stop-16":"octicons/stop-16.svg","octicons-stop-24":"octicons/stop-24.svg","octicons-stopwatch-16":"octicons/stopwatch-16.svg","octicons-stopwatch-24":"octicons/stopwatch-24.svg","octicons-strikethrough-16":"octicons/strikethrough-16.svg","octicons-strikethrough-24":"octicons/strikethrough-24.svg","octicons-sun-16":"octicons/sun-16.svg","octicons-sun-24":"octicons/sun-24.svg","octicons-sync-16":"octicons/sync-16.svg","octicons-sync-24":"octicons/sync-24.svg","octicons-tab-24":"octicons/tab-24.svg","octicons-tag-16":"octicons/tag-16.svg","octicons-tag-24":"octicons/tag-24.svg","octicons-tasklist-16":"octicons/tasklist-16.svg","octicons-tasklist-24":"octicons/tasklist-24.svg","octicons-telescope-16":"octicons/telescope-16.svg","octicons-telescope-24":"octicons/telescope-24.svg","octicons-terminal-16":"octicons/terminal-16.svg","octicons-terminal-24":"octicons/terminal-24.svg","octicons-three-bars-16":"octicons/three-bars-16.svg","octicons-thumbsdown-16":"octicons/thumbsdown-16.svg","octicons-thumbsdown-24":"octicons/thumbsdown-24.svg","octicons-thumbsup-16":"octicons/thumbsup-16.svg","octicons-thumbsup-24":"octicons/thumbsup-24.svg","octicons-tools-16":"octicons/tools-16.svg","octicons-tools-24":"octicons/tools-24.svg","octicons-trash-16":"octicons/trash-16.svg","octicons-trash-24":"octicons/trash-24.svg","octicons-triangle-down-16":"octicons/triangle-down-16.svg","octicons-triangle-down-24":"octicons/triangle-down-24.svg","octicons-triangle-left-16":"octicons/triangle-left-16.svg","octicons-triangle-left-24":"octicons/triangle-left-24.svg","octicons-triangle-right-16":"octicons/triangle-right-16.svg","octicons-triangle-right-24":"octicons/triangle-right-24.svg","octicons-triangle-up-16":"octicons/triangle-up-16.svg","octicons-triangle-up-24":"octicons/triangle-up-24.svg","octicons-typography-16":"octicons/typography-16.svg","octicons-typography-24":"octicons/typography-24.svg","octicons-unfold-16":"octicons/unfold-16.svg","octicons-unfold-24":"octicons/unfold-24.svg","octicons-unlock-16":"octicons/unlock-16.svg","octicons-unlock-24":"octicons/unlock-24.svg","octicons-unmute-16":"octicons/unmute-16.svg","octicons-unmute-24":"octicons/unmute-24.svg","octicons-unverified-16":"octicons/unverified-16.svg","octicons-unverified-24":"octicons/unverified-24.svg","octicons-upload-16":"octicons/upload-16.svg","octicons-upload-24":"octicons/upload-24.svg","octicons-verified-16":"octicons/verified-16.svg","octicons-verified-24":"octicons/verified-24.svg","octicons-versions-16":"octicons/versions-16.svg","octicons-versions-24":"octicons/versions-24.svg","octicons-video-16":"octicons/video-16.svg","octicons-video-24":"octicons/video-24.svg","octicons-workflow-16":"octicons/workflow-16.svg","octicons-workflow-24":"octicons/workflow-24.svg","octicons-x-16":"octicons/x-16.svg","octicons-x-24":"octicons/x-24.svg","octicons-x-circle-16":"octicons/x-circle-16.svg","octicons-x-circle-24":"octicons/x-circle-24.svg","octicons-x-circle-fill-16":"octicons/x-circle-fill-16.svg","octicons-x-circle-fill-24":"octicons/x-circle-fill-24.svg","octicons-zap-16":"octicons/zap-16.svg","octicons-zap-24":"octicons/zap-24.svg"}},"emojis":{"base":"https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/","data":{"100":"1f4af.svg","1234":"1f522.svg","8ball":"1f3b1.svg","a":"1f170.svg","ab":"1f18e.svg","abacus":"1f9ee.svg","abc":"1f524.svg","abcd":"1f521.svg","accept":"1f251.svg","adhesive_bandage":"1fa79.svg","adult":"1f9d1.svg","adult_tone1":"1f9d1-1f3fb.svg","adult_tone2":"1f9d1-1f3fc.svg","adult_tone3":"1f9d1-1f3fd.svg","adult_tone4":"1f9d1-1f3fe.svg","adult_tone5":"1f9d1-1f3ff.svg","aerial_tramway":"1f6a1.svg","airplane":"2708.svg","airplane_arriving":"1f6ec.svg","airplane_departure":"1f6eb.svg","airplane_small":"1f6e9.svg","alarm_clock":"23f0.svg","alembic":"2697.svg","alien":"1f47d.svg","ambulance":"1f691.svg","amphora":"1f3fa.svg","anchor":"2693.svg","angel":"1f47c.svg","angel_tone1":"1f47c-1f3fb.svg","angel_tone2":"1f47c-1f3fc.svg","angel_tone3":"1f47c-1f3fd.svg","angel_tone4":"1f47c-1f3fe.svg","angel_tone5":"1f47c-1f3ff.svg","anger":"1f4a2.svg","anger_right":"1f5ef.svg","angry":"1f620.svg","anguished":"1f627.svg","ant":"1f41c.svg","apple":"1f34e.svg","aquarius":"2652.svg","aries":"2648.svg","arrow_backward":"25c0.svg","arrow_double_down":"23ec.svg","arrow_double_up":"23eb.svg","arrow_down":"2b07.svg","arrow_down_small":"1f53d.svg","arrow_forward":"25b6.svg","arrow_heading_down":"2935.svg","arrow_heading_up":"2934.svg","arrow_left":"2b05.svg","arrow_lower_left":"2199.svg","arrow_lower_right":"2198.svg","arrow_right":"27a1.svg","arrow_right_hook":"21aa.svg","arrow_up":"2b06.svg","arrow_up_down":"2195.svg","arrow_up_small":"1f53c.svg","arrow_upper_left":"2196.svg","arrow_upper_right":"2197.svg","arrows_clockwise":"1f503.svg","arrows_counterclockwise":"1f504.svg","art":"1f3a8.svg","articulated_lorry":"1f69b.svg","artist":"1f9d1-200d-1f3a8.svg","artist_tone1":"1f9d1-1f3fb-200d-1f3a8.svg","artist_tone2":"1f9d1-1f3fc-200d-1f3a8.svg","artist_tone3":"1f9d1-1f3fd-200d-1f3a8.svg","artist_tone4":"1f9d1-1f3fe-200d-1f3a8.svg","artist_tone5":"1f9d1-1f3ff-200d-1f3a8.svg","asterisk":"2a-20e3.svg","astonished":"1f632.svg","astronaut":"1f9d1-200d-1f680.svg","astronaut_tone1":"1f9d1-1f3fb-200d-1f680.svg","astronaut_tone2":"1f9d1-1f3fc-200d-1f680.svg","astronaut_tone3":"1f9d1-1f3fd-200d-1f680.svg","astronaut_tone4":"1f9d1-1f3fe-200d-1f680.svg","astronaut_tone5":"1f9d1-1f3ff-200d-1f680.svg","athletic_shoe":"1f45f.svg","atm":"1f3e7.svg","atom":"269b.svg","auto_rickshaw":"1f6fa.svg","avocado":"1f951.svg","axe":"1fa93.svg","b":"1f171.svg","baby":"1f476.svg","baby_bottle":"1f37c.svg","baby_chick":"1f424.svg","baby_symbol":"1f6bc.svg","baby_tone1":"1f476-1f3fb.svg","baby_tone2":"1f476-1f3fc.svg","baby_tone3":"1f476-1f3fd.svg","baby_tone4":"1f476-1f3fe.svg","baby_tone5":"1f476-1f3ff.svg","back":"1f519.svg","bacon":"1f953.svg","badger":"1f9a1.svg","badminton":"1f3f8.svg","bagel":"1f96f.svg","baggage_claim":"1f6c4.svg","bald":"1f9b2.svg","ballet_shoes":"1fa70.svg","balloon":"1f388.svg","ballot_box":"1f5f3.svg","ballot_box_with_check":"2611.svg","bamboo":"1f38d.svg","banana":"1f34c.svg","bangbang":"203c.svg","banjo":"1fa95.svg","bank":"1f3e6.svg","bar_chart":"1f4ca.svg","barber":"1f488.svg","baseball":"26be.svg","basket":"1f9fa.svg","basketball":"1f3c0.svg","bat":"1f987.svg","bath":"1f6c0.svg","bath_tone1":"1f6c0-1f3fb.svg","bath_tone2":"1f6c0-1f3fc.svg","bath_tone3":"1f6c0-1f3fd.svg","bath_tone4":"1f6c0-1f3fe.svg","bath_tone5":"1f6c0-1f3ff.svg","bathtub":"1f6c1.svg","battery":"1f50b.svg","beach":"1f3d6.svg","beach_umbrella":"26f1.svg","bear":"1f43b.svg","bearded_person":"1f9d4.svg","bearded_person_tone1":"1f9d4-1f3fb.svg","bearded_person_tone2":"1f9d4-1f3fc.svg","bearded_person_tone3":"1f9d4-1f3fd.svg","bearded_person_tone4":"1f9d4-1f3fe.svg","bearded_person_tone5":"1f9d4-1f3ff.svg","bed":"1f6cf.svg","bee":"1f41d.svg","beer":"1f37a.svg","beers":"1f37b.svg","beetle":"1f41e.svg","beginner":"1f530.svg","bell":"1f514.svg","bellhop":"1f6ce.svg","bento":"1f371.svg","beverage_box":"1f9c3.svg","bike":"1f6b2.svg","bikini":"1f459.svg","billed_cap":"1f9e2.svg","biohazard":"2623.svg","bird":"1f426.svg","birthday":"1f382.svg","black_circle":"26ab.svg","black_heart":"1f5a4.svg","black_joker":"1f0cf.svg","black_large_square":"2b1b.svg","black_medium_small_square":"25fe.svg","black_medium_square":"25fc.svg","black_nib":"2712.svg","black_small_square":"25aa.svg","black_square_button":"1f532.svg","blond-haired_man":"1f471-200d-2642-fe0f.svg","blond-haired_man_tone1":"1f471-1f3fb-200d-2642-fe0f.svg","blond-haired_man_tone2":"1f471-1f3fc-200d-2642-fe0f.svg","blond-haired_man_tone3":"1f471-1f3fd-200d-2642-fe0f.svg","blond-haired_man_tone4":"1f471-1f3fe-200d-2642-fe0f.svg","blond-haired_man_tone5":"1f471-1f3ff-200d-2642-fe0f.svg","blond-haired_woman":"1f471-200d-2640-fe0f.svg","blond-haired_woman_tone1":"1f471-1f3fb-200d-2640-fe0f.svg","blond-haired_woman_tone2":"1f471-1f3fc-200d-2640-fe0f.svg","blond-haired_woman_tone3":"1f471-1f3fd-200d-2640-fe0f.svg","blond-haired_woman_tone4":"1f471-1f3fe-200d-2640-fe0f.svg","blond-haired_woman_tone5":"1f471-1f3ff-200d-2640-fe0f.svg","blond_haired_person":"1f471.svg","blond_haired_person_tone1":"1f471-1f3fb.svg","blond_haired_person_tone2":"1f471-1f3fc.svg","blond_haired_person_tone3":"1f471-1f3fd.svg","blond_haired_person_tone4":"1f471-1f3fe.svg","blond_haired_person_tone5":"1f471-1f3ff.svg","blossom":"1f33c.svg","blowfish":"1f421.svg","blue_book":"1f4d8.svg","blue_car":"1f699.svg","blue_circle":"1f535.svg","blue_heart":"1f499.svg","blue_square":"1f7e6.svg","blush":"1f60a.svg","boar":"1f417.svg","bomb":"1f4a3.svg","bone":"1f9b4.svg","book":"1f4d6.svg","bookmark":"1f516.svg","bookmark_tabs":"1f4d1.svg","books":"1f4da.svg","boom":"1f4a5.svg","boot":"1f462.svg","bouquet":"1f490.svg","bow_and_arrow":"1f3f9.svg","bowl_with_spoon":"1f963.svg","bowling":"1f3b3.svg","boxing_glove":"1f94a.svg","boy":"1f466.svg","boy_tone1":"1f466-1f3fb.svg","boy_tone2":"1f466-1f3fc.svg","boy_tone3":"1f466-1f3fd.svg","boy_tone4":"1f466-1f3fe.svg","boy_tone5":"1f466-1f3ff.svg","brain":"1f9e0.svg","bread":"1f35e.svg","breast_feeding":"1f931.svg","breast_feeding_tone1":"1f931-1f3fb.svg","breast_feeding_tone2":"1f931-1f3fc.svg","breast_feeding_tone3":"1f931-1f3fd.svg","breast_feeding_tone4":"1f931-1f3fe.svg","breast_feeding_tone5":"1f931-1f3ff.svg","bricks":"1f9f1.svg","bride_with_veil":"1f470.svg","bride_with_veil_tone1":"1f470-1f3fb.svg","bride_with_veil_tone2":"1f470-1f3fc.svg","bride_with_veil_tone3":"1f470-1f3fd.svg","bride_with_veil_tone4":"1f470-1f3fe.svg","bride_with_veil_tone5":"1f470-1f3ff.svg","bridge_at_night":"1f309.svg","briefcase":"1f4bc.svg","briefs":"1fa72.svg","broccoli":"1f966.svg","broken_heart":"1f494.svg","broom":"1f9f9.svg","brown_circle":"1f7e4.svg","brown_heart":"1f90e.svg","brown_square":"1f7eb.svg","bug":"1f41b.svg","bulb":"1f4a1.svg","bullettrain_front":"1f685.svg","bullettrain_side":"1f684.svg","burrito":"1f32f.svg","bus":"1f68c.svg","busstop":"1f68f.svg","bust_in_silhouette":"1f464.svg","busts_in_silhouette":"1f465.svg","butter":"1f9c8.svg","butterfly":"1f98b.svg","cactus":"1f335.svg","cake":"1f370.svg","calendar":"1f4c6.svg","calendar_spiral":"1f5d3.svg","call_me":"1f919.svg","call_me_tone1":"1f919-1f3fb.svg","call_me_tone2":"1f919-1f3fc.svg","call_me_tone3":"1f919-1f3fd.svg","call_me_tone4":"1f919-1f3fe.svg","call_me_tone5":"1f919-1f3ff.svg","calling":"1f4f2.svg","camel":"1f42b.svg","camera":"1f4f7.svg","camera_with_flash":"1f4f8.svg","camping":"1f3d5.svg","cancer":"264b.svg","candle":"1f56f.svg","candy":"1f36c.svg","canned_food":"1f96b.svg","canoe":"1f6f6.svg","capital_abcd":"1f520.svg","capricorn":"2651.svg","card_box":"1f5c3.svg","card_index":"1f4c7.svg","carousel_horse":"1f3a0.svg","carrot":"1f955.svg","cat2":"1f408.svg","cat":"1f431.svg","cd":"1f4bf.svg","chains":"26d3.svg","chair":"1fa91.svg","champagne":"1f37e.svg","champagne_glass":"1f942.svg","chart":"1f4b9.svg","chart_with_downwards_trend":"1f4c9.svg","chart_with_upwards_trend":"1f4c8.svg","checkered_flag":"1f3c1.svg","cheese":"1f9c0.svg","cherries":"1f352.svg","cherry_blossom":"1f338.svg","chess_pawn":"265f.svg","chestnut":"1f330.svg","chicken":"1f414.svg","child":"1f9d2.svg","child_tone1":"1f9d2-1f3fb.svg","child_tone2":"1f9d2-1f3fc.svg","child_tone3":"1f9d2-1f3fd.svg","child_tone4":"1f9d2-1f3fe.svg","child_tone5":"1f9d2-1f3ff.svg","children_crossing":"1f6b8.svg","chipmunk":"1f43f.svg","chocolate_bar":"1f36b.svg","chopsticks":"1f962.svg","christmas_tree":"1f384.svg","church":"26ea.svg","cinema":"1f3a6.svg","circus_tent":"1f3aa.svg","city_dusk":"1f306.svg","city_sunset":"1f307.svg","cityscape":"1f3d9.svg","cl":"1f191.svg","clap":"1f44f.svg","clap_tone1":"1f44f-1f3fb.svg","clap_tone2":"1f44f-1f3fc.svg","clap_tone3":"1f44f-1f3fd.svg","clap_tone4":"1f44f-1f3fe.svg","clap_tone5":"1f44f-1f3ff.svg","clapper":"1f3ac.svg","classical_building":"1f3db.svg","clipboard":"1f4cb.svg","clock1030":"1f565.svg","clock10":"1f559.svg","clock1130":"1f566.svg","clock11":"1f55a.svg","clock1230":"1f567.svg","clock12":"1f55b.svg","clock130":"1f55c.svg","clock1":"1f550.svg","clock230":"1f55d.svg","clock2":"1f551.svg","clock330":"1f55e.svg","clock3":"1f552.svg","clock430":"1f55f.svg","clock4":"1f553.svg","clock530":"1f560.svg","clock5":"1f554.svg","clock630":"1f561.svg","clock6":"1f555.svg","clock730":"1f562.svg","clock7":"1f556.svg","clock830":"1f563.svg","clock8":"1f557.svg","clock930":"1f564.svg","clock9":"1f558.svg","clock":"1f570.svg","closed_book":"1f4d5.svg","closed_lock_with_key":"1f510.svg","closed_umbrella":"1f302.svg","cloud":"2601.svg","cloud_lightning":"1f329.svg","cloud_rain":"1f327.svg","cloud_snow":"1f328.svg","cloud_tornado":"1f32a.svg","clown":"1f921.svg","clubs":"2663.svg","coat":"1f9e5.svg","cocktail":"1f378.svg","coconut":"1f965.svg","coffee":"2615.svg","coffin":"26b0.svg","cold_face":"1f976.svg","cold_sweat":"1f630.svg","comet":"2604.svg","compass":"1f9ed.svg","compression":"1f5dc.svg","computer":"1f4bb.svg","confetti_ball":"1f38a.svg","confounded":"1f616.svg","confused":"1f615.svg","congratulations":"3297.svg","construction":"1f6a7.svg","construction_site":"1f3d7.svg","construction_worker":"1f477.svg","construction_worker_tone1":"1f477-1f3fb.svg","construction_worker_tone2":"1f477-1f3fc.svg","construction_worker_tone3":"1f477-1f3fd.svg","construction_worker_tone4":"1f477-1f3fe.svg","construction_worker_tone5":"1f477-1f3ff.svg","control_knobs":"1f39b.svg","convenience_store":"1f3ea.svg","cook":"1f9d1-200d-1f373.svg","cook_tone1":"1f9d1-1f3fb-200d-1f373.svg","cook_tone2":"1f9d1-1f3fc-200d-1f373.svg","cook_tone3":"1f9d1-1f3fd-200d-1f373.svg","cook_tone4":"1f9d1-1f3fe-200d-1f373.svg","cook_tone5":"1f9d1-1f3ff-200d-1f373.svg","cookie":"1f36a.svg","cooking":"1f373.svg","cool":"1f192.svg","copyright":"a9.svg","corn":"1f33d.svg","couch":"1f6cb.svg","couple":"1f46b.svg","couple_mm":"1f468-200d-2764-fe0f-200d-1f468.svg","couple_with_heart":"1f491.svg","couple_with_heart_woman_man":"1f469-200d-2764-fe0f-200d-1f468.svg","couple_ww":"1f469-200d-2764-fe0f-200d-1f469.svg","couplekiss":"1f48f.svg","cow2":"1f404.svg","cow":"1f42e.svg","cowboy":"1f920.svg","crab":"1f980.svg","crayon":"1f58d.svg","credit_card":"1f4b3.svg","crescent_moon":"1f319.svg","cricket":"1f997.svg","cricket_game":"1f3cf.svg","crocodile":"1f40a.svg","croissant":"1f950.svg","cross":"271d.svg","crossed_flags":"1f38c.svg","crossed_swords":"2694.svg","crown":"1f451.svg","cruise_ship":"1f6f3.svg","cry":"1f622.svg","crying_cat_face":"1f63f.svg","crystal_ball":"1f52e.svg","cucumber":"1f952.svg","cup_with_straw":"1f964.svg","cupcake":"1f9c1.svg","cupid":"1f498.svg","curling_stone":"1f94c.svg","curly_haired":"1f9b1.svg","curly_loop":"27b0.svg","currency_exchange":"1f4b1.svg","curry":"1f35b.svg","custard":"1f36e.svg","customs":"1f6c3.svg","cut_of_meat":"1f969.svg","cyclone":"1f300.svg","dagger":"1f5e1.svg","dancer":"1f483.svg","dancer_tone1":"1f483-1f3fb.svg","dancer_tone2":"1f483-1f3fc.svg","dancer_tone3":"1f483-1f3fd.svg","dancer_tone4":"1f483-1f3fe.svg","dancer_tone5":"1f483-1f3ff.svg","dango":"1f361.svg","dark_sunglasses":"1f576.svg","dart":"1f3af.svg","dash":"1f4a8.svg","date":"1f4c5.svg","deaf_man":"1f9cf-200d-2642-fe0f.svg","deaf_man_tone1":"1f9cf-1f3fb-200d-2642-fe0f.svg","deaf_man_tone2":"1f9cf-1f3fc-200d-2642-fe0f.svg","deaf_man_tone3":"1f9cf-1f3fd-200d-2642-fe0f.svg","deaf_man_tone4":"1f9cf-1f3fe-200d-2642-fe0f.svg","deaf_man_tone5":"1f9cf-1f3ff-200d-2642-fe0f.svg","deaf_person":"1f9cf.svg","deaf_person_tone1":"1f9cf-1f3fb.svg","deaf_person_tone2":"1f9cf-1f3fc.svg","deaf_person_tone3":"1f9cf-1f3fd.svg","deaf_person_tone4":"1f9cf-1f3fe.svg","deaf_person_tone5":"1f9cf-1f3ff.svg","deaf_woman":"1f9cf-200d-2640-fe0f.svg","deaf_woman_tone1":"1f9cf-1f3fb-200d-2640-fe0f.svg","deaf_woman_tone2":"1f9cf-1f3fc-200d-2640-fe0f.svg","deaf_woman_tone3":"1f9cf-1f3fd-200d-2640-fe0f.svg","deaf_woman_tone4":"1f9cf-1f3fe-200d-2640-fe0f.svg","deaf_woman_tone5":"1f9cf-1f3ff-200d-2640-fe0f.svg","deciduous_tree":"1f333.svg","deer":"1f98c.svg","department_store":"1f3ec.svg","desert":"1f3dc.svg","desktop":"1f5a5.svg","detective":"1f575.svg","detective_tone1":"1f575-1f3fb.svg","detective_tone2":"1f575-1f3fc.svg","detective_tone3":"1f575-1f3fd.svg","detective_tone4":"1f575-1f3fe.svg","detective_tone5":"1f575-1f3ff.svg","diamond_shape_with_a_dot_inside":"1f4a0.svg","diamonds":"2666.svg","disappointed":"1f61e.svg","disappointed_relieved":"1f625.svg","dividers":"1f5c2.svg","diving_mask":"1f93f.svg","diya_lamp":"1fa94.svg","dizzy":"1f4ab.svg","dizzy_face":"1f635.svg","dna":"1f9ec.svg","do_not_litter":"1f6af.svg","dog2":"1f415.svg","dog":"1f436.svg","dollar":"1f4b5.svg","dolls":"1f38e.svg","dolphin":"1f42c.svg","door":"1f6aa.svg","doughnut":"1f369.svg","dove":"1f54a.svg","dragon":"1f409.svg","dragon_face":"1f432.svg","dress":"1f457.svg","dromedary_camel":"1f42a.svg","drooling_face":"1f924.svg","drop_of_blood":"1fa78.svg","droplet":"1f4a7.svg","drum":"1f941.svg","duck":"1f986.svg","dumpling":"1f95f.svg","dvd":"1f4c0.svg","e-mail":"1f4e7.svg","eagle":"1f985.svg","ear":"1f442.svg","ear_of_rice":"1f33e.svg","ear_tone1":"1f442-1f3fb.svg","ear_tone2":"1f442-1f3fc.svg","ear_tone3":"1f442-1f3fd.svg","ear_tone4":"1f442-1f3fe.svg","ear_tone5":"1f442-1f3ff.svg","ear_with_hearing_aid":"1f9bb.svg","ear_with_hearing_aid_tone1":"1f9bb-1f3fb.svg","ear_with_hearing_aid_tone2":"1f9bb-1f3fc.svg","ear_with_hearing_aid_tone3":"1f9bb-1f3fd.svg","ear_with_hearing_aid_tone4":"1f9bb-1f3fe.svg","ear_with_hearing_aid_tone5":"1f9bb-1f3ff.svg","earth_africa":"1f30d.svg","earth_americas":"1f30e.svg","earth_asia":"1f30f.svg","egg":"1f95a.svg","eggplant":"1f346.svg","eight":"38-20e3.svg","eight_pointed_black_star":"2734.svg","eight_spoked_asterisk":"2733.svg","eject":"23cf.svg","electric_plug":"1f50c.svg","elephant":"1f418.svg","elf":"1f9dd.svg","elf_tone1":"1f9dd-1f3fb.svg","elf_tone2":"1f9dd-1f3fc.svg","elf_tone3":"1f9dd-1f3fd.svg","elf_tone4":"1f9dd-1f3fe.svg","elf_tone5":"1f9dd-1f3ff.svg","end":"1f51a.svg","england":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.svg","envelope":"2709.svg","envelope_with_arrow":"1f4e9.svg","euro":"1f4b6.svg","european_castle":"1f3f0.svg","european_post_office":"1f3e4.svg","evergreen_tree":"1f332.svg","exclamation":"2757.svg","exploding_head":"1f92f.svg","expressionless":"1f611.svg","eye":"1f441.svg","eye_in_speech_bubble":"1f441-200d-1f5e8.svg","eyeglasses":"1f453.svg","eyes":"1f440.svg","face_vomiting":"1f92e.svg","face_with_hand_over_mouth":"1f92d.svg","face_with_monocle":"1f9d0.svg","face_with_raised_eyebrow":"1f928.svg","face_with_symbols_over_mouth":"1f92c.svg","factory":"1f3ed.svg","factory_worker":"1f9d1-200d-1f3ed.svg","factory_worker_tone1":"1f9d1-1f3fb-200d-1f3ed.svg","factory_worker_tone2":"1f9d1-1f3fc-200d-1f3ed.svg","factory_worker_tone3":"1f9d1-1f3fd-200d-1f3ed.svg","factory_worker_tone4":"1f9d1-1f3fe-200d-1f3ed.svg","factory_worker_tone5":"1f9d1-1f3ff-200d-1f3ed.svg","fairy":"1f9da.svg","fairy_tone1":"1f9da-1f3fb.svg","fairy_tone2":"1f9da-1f3fc.svg","fairy_tone3":"1f9da-1f3fd.svg","fairy_tone4":"1f9da-1f3fe.svg","fairy_tone5":"1f9da-1f3ff.svg","falafel":"1f9c6.svg","fallen_leaf":"1f342.svg","family":"1f46a.svg","family_man_boy":"1f468-200d-1f466.svg","family_man_boy_boy":"1f468-200d-1f466-200d-1f466.svg","family_man_girl":"1f468-200d-1f467.svg","family_man_girl_boy":"1f468-200d-1f467-200d-1f466.svg","family_man_girl_girl":"1f468-200d-1f467-200d-1f467.svg","family_man_woman_boy":"1f468-200d-1f469-200d-1f466.svg","family_mmb":"1f468-200d-1f468-200d-1f466.svg","family_mmbb":"1f468-200d-1f468-200d-1f466-200d-1f466.svg","family_mmg":"1f468-200d-1f468-200d-1f467.svg","family_mmgb":"1f468-200d-1f468-200d-1f467-200d-1f466.svg","family_mmgg":"1f468-200d-1f468-200d-1f467-200d-1f467.svg","family_mwbb":"1f468-200d-1f469-200d-1f466-200d-1f466.svg","family_mwg":"1f468-200d-1f469-200d-1f467.svg","family_mwgb":"1f468-200d-1f469-200d-1f467-200d-1f466.svg","family_mwgg":"1f468-200d-1f469-200d-1f467-200d-1f467.svg","family_woman_boy":"1f469-200d-1f466.svg","family_woman_boy_boy":"1f469-200d-1f466-200d-1f466.svg","family_woman_girl":"1f469-200d-1f467.svg","family_woman_girl_boy":"1f469-200d-1f467-200d-1f466.svg","family_woman_girl_girl":"1f469-200d-1f467-200d-1f467.svg","family_wwb":"1f469-200d-1f469-200d-1f466.svg","family_wwbb":"1f469-200d-1f469-200d-1f466-200d-1f466.svg","family_wwg":"1f469-200d-1f469-200d-1f467.svg","family_wwgb":"1f469-200d-1f469-200d-1f467-200d-1f466.svg","family_wwgg":"1f469-200d-1f469-200d-1f467-200d-1f467.svg","farmer":"1f9d1-200d-1f33e.svg","farmer_tone1":"1f9d1-1f3fb-200d-1f33e.svg","farmer_tone2":"1f9d1-1f3fc-200d-1f33e.svg","farmer_tone3":"1f9d1-1f3fd-200d-1f33e.svg","farmer_tone4":"1f9d1-1f3fe-200d-1f33e.svg","farmer_tone5":"1f9d1-1f3ff-200d-1f33e.svg","fast_forward":"23e9.svg","fax":"1f4e0.svg","fearful":"1f628.svg","feet":"1f43e.svg","female_sign":"2640.svg","ferris_wheel":"1f3a1.svg","ferry":"26f4.svg","field_hockey":"1f3d1.svg","file_cabinet":"1f5c4.svg","file_folder":"1f4c1.svg","film_frames":"1f39e.svg","fingers_crossed":"1f91e.svg","fingers_crossed_tone1":"1f91e-1f3fb.svg","fingers_crossed_tone2":"1f91e-1f3fc.svg","fingers_crossed_tone3":"1f91e-1f3fd.svg","fingers_crossed_tone4":"1f91e-1f3fe.svg","fingers_crossed_tone5":"1f91e-1f3ff.svg","fire":"1f525.svg","fire_engine":"1f692.svg","fire_extinguisher":"1f9ef.svg","firecracker":"1f9e8.svg","firefighter":"1f9d1-200d-1f692.svg","firefighter_tone1":"1f9d1-1f3fb-200d-1f692.svg","firefighter_tone2":"1f9d1-1f3fc-200d-1f692.svg","firefighter_tone3":"1f9d1-1f3fd-200d-1f692.svg","firefighter_tone4":"1f9d1-1f3fe-200d-1f692.svg","firefighter_tone5":"1f9d1-1f3ff-200d-1f692.svg","fireworks":"1f386.svg","first_place":"1f947.svg","first_quarter_moon":"1f313.svg","first_quarter_moon_with_face":"1f31b.svg","fish":"1f41f.svg","fish_cake":"1f365.svg","fishing_pole_and_fish":"1f3a3.svg","fist":"270a.svg","fist_tone1":"270a-1f3fb.svg","fist_tone2":"270a-1f3fc.svg","fist_tone3":"270a-1f3fd.svg","fist_tone4":"270a-1f3fe.svg","fist_tone5":"270a-1f3ff.svg","five":"35-20e3.svg","flag_ac":"1f1e6-1f1e8.svg","flag_ad":"1f1e6-1f1e9.svg","flag_ae":"1f1e6-1f1ea.svg","flag_af":"1f1e6-1f1eb.svg","flag_ag":"1f1e6-1f1ec.svg","flag_ai":"1f1e6-1f1ee.svg","flag_al":"1f1e6-1f1f1.svg","flag_am":"1f1e6-1f1f2.svg","flag_ao":"1f1e6-1f1f4.svg","flag_aq":"1f1e6-1f1f6.svg","flag_ar":"1f1e6-1f1f7.svg","flag_as":"1f1e6-1f1f8.svg","flag_at":"1f1e6-1f1f9.svg","flag_au":"1f1e6-1f1fa.svg","flag_aw":"1f1e6-1f1fc.svg","flag_ax":"1f1e6-1f1fd.svg","flag_az":"1f1e6-1f1ff.svg","flag_ba":"1f1e7-1f1e6.svg","flag_bb":"1f1e7-1f1e7.svg","flag_bd":"1f1e7-1f1e9.svg","flag_be":"1f1e7-1f1ea.svg","flag_bf":"1f1e7-1f1eb.svg","flag_bg":"1f1e7-1f1ec.svg","flag_bh":"1f1e7-1f1ed.svg","flag_bi":"1f1e7-1f1ee.svg","flag_bj":"1f1e7-1f1ef.svg","flag_bl":"1f1e7-1f1f1.svg","flag_black":"1f3f4.svg","flag_bm":"1f1e7-1f1f2.svg","flag_bn":"1f1e7-1f1f3.svg","flag_bo":"1f1e7-1f1f4.svg","flag_bq":"1f1e7-1f1f6.svg","flag_br":"1f1e7-1f1f7.svg","flag_bs":"1f1e7-1f1f8.svg","flag_bt":"1f1e7-1f1f9.svg","flag_bv":"1f1e7-1f1fb.svg","flag_bw":"1f1e7-1f1fc.svg","flag_by":"1f1e7-1f1fe.svg","flag_bz":"1f1e7-1f1ff.svg","flag_ca":"1f1e8-1f1e6.svg","flag_cc":"1f1e8-1f1e8.svg","flag_cd":"1f1e8-1f1e9.svg","flag_cf":"1f1e8-1f1eb.svg","flag_cg":"1f1e8-1f1ec.svg","flag_ch":"1f1e8-1f1ed.svg","flag_ci":"1f1e8-1f1ee.svg","flag_ck":"1f1e8-1f1f0.svg","flag_cl":"1f1e8-1f1f1.svg","flag_cm":"1f1e8-1f1f2.svg","flag_cn":"1f1e8-1f1f3.svg","flag_co":"1f1e8-1f1f4.svg","flag_cp":"1f1e8-1f1f5.svg","flag_cr":"1f1e8-1f1f7.svg","flag_cu":"1f1e8-1f1fa.svg","flag_cv":"1f1e8-1f1fb.svg","flag_cw":"1f1e8-1f1fc.svg","flag_cx":"1f1e8-1f1fd.svg","flag_cy":"1f1e8-1f1fe.svg","flag_cz":"1f1e8-1f1ff.svg","flag_de":"1f1e9-1f1ea.svg","flag_dg":"1f1e9-1f1ec.svg","flag_dj":"1f1e9-1f1ef.svg","flag_dk":"1f1e9-1f1f0.svg","flag_dm":"1f1e9-1f1f2.svg","flag_do":"1f1e9-1f1f4.svg","flag_dz":"1f1e9-1f1ff.svg","flag_ea":"1f1ea-1f1e6.svg","flag_ec":"1f1ea-1f1e8.svg","flag_ee":"1f1ea-1f1ea.svg","flag_eg":"1f1ea-1f1ec.svg","flag_eh":"1f1ea-1f1ed.svg","flag_er":"1f1ea-1f1f7.svg","flag_es":"1f1ea-1f1f8.svg","flag_et":"1f1ea-1f1f9.svg","flag_eu":"1f1ea-1f1fa.svg","flag_fi":"1f1eb-1f1ee.svg","flag_fj":"1f1eb-1f1ef.svg","flag_fk":"1f1eb-1f1f0.svg","flag_fm":"1f1eb-1f1f2.svg","flag_fo":"1f1eb-1f1f4.svg","flag_fr":"1f1eb-1f1f7.svg","flag_ga":"1f1ec-1f1e6.svg","flag_gb":"1f1ec-1f1e7.svg","flag_gd":"1f1ec-1f1e9.svg","flag_ge":"1f1ec-1f1ea.svg","flag_gf":"1f1ec-1f1eb.svg","flag_gg":"1f1ec-1f1ec.svg","flag_gh":"1f1ec-1f1ed.svg","flag_gi":"1f1ec-1f1ee.svg","flag_gl":"1f1ec-1f1f1.svg","flag_gm":"1f1ec-1f1f2.svg","flag_gn":"1f1ec-1f1f3.svg","flag_gp":"1f1ec-1f1f5.svg","flag_gq":"1f1ec-1f1f6.svg","flag_gr":"1f1ec-1f1f7.svg","flag_gs":"1f1ec-1f1f8.svg","flag_gt":"1f1ec-1f1f9.svg","flag_gu":"1f1ec-1f1fa.svg","flag_gw":"1f1ec-1f1fc.svg","flag_gy":"1f1ec-1f1fe.svg","flag_hk":"1f1ed-1f1f0.svg","flag_hm":"1f1ed-1f1f2.svg","flag_hn":"1f1ed-1f1f3.svg","flag_hr":"1f1ed-1f1f7.svg","flag_ht":"1f1ed-1f1f9.svg","flag_hu":"1f1ed-1f1fa.svg","flag_ic":"1f1ee-1f1e8.svg","flag_id":"1f1ee-1f1e9.svg","flag_ie":"1f1ee-1f1ea.svg","flag_il":"1f1ee-1f1f1.svg","flag_im":"1f1ee-1f1f2.svg","flag_in":"1f1ee-1f1f3.svg","flag_io":"1f1ee-1f1f4.svg","flag_iq":"1f1ee-1f1f6.svg","flag_ir":"1f1ee-1f1f7.svg","flag_is":"1f1ee-1f1f8.svg","flag_it":"1f1ee-1f1f9.svg","flag_je":"1f1ef-1f1ea.svg","flag_jm":"1f1ef-1f1f2.svg","flag_jo":"1f1ef-1f1f4.svg","flag_jp":"1f1ef-1f1f5.svg","flag_ke":"1f1f0-1f1ea.svg","flag_kg":"1f1f0-1f1ec.svg","flag_kh":"1f1f0-1f1ed.svg","flag_ki":"1f1f0-1f1ee.svg","flag_km":"1f1f0-1f1f2.svg","flag_kn":"1f1f0-1f1f3.svg","flag_kp":"1f1f0-1f1f5.svg","flag_kr":"1f1f0-1f1f7.svg","flag_kw":"1f1f0-1f1fc.svg","flag_ky":"1f1f0-1f1fe.svg","flag_kz":"1f1f0-1f1ff.svg","flag_la":"1f1f1-1f1e6.svg","flag_lb":"1f1f1-1f1e7.svg","flag_lc":"1f1f1-1f1e8.svg","flag_li":"1f1f1-1f1ee.svg","flag_lk":"1f1f1-1f1f0.svg","flag_lr":"1f1f1-1f1f7.svg","flag_ls":"1f1f1-1f1f8.svg","flag_lt":"1f1f1-1f1f9.svg","flag_lu":"1f1f1-1f1fa.svg","flag_lv":"1f1f1-1f1fb.svg","flag_ly":"1f1f1-1f1fe.svg","flag_ma":"1f1f2-1f1e6.svg","flag_mc":"1f1f2-1f1e8.svg","flag_md":"1f1f2-1f1e9.svg","flag_me":"1f1f2-1f1ea.svg","flag_mf":"1f1f2-1f1eb.svg","flag_mg":"1f1f2-1f1ec.svg","flag_mh":"1f1f2-1f1ed.svg","flag_mk":"1f1f2-1f1f0.svg","flag_ml":"1f1f2-1f1f1.svg","flag_mm":"1f1f2-1f1f2.svg","flag_mn":"1f1f2-1f1f3.svg","flag_mo":"1f1f2-1f1f4.svg","flag_mp":"1f1f2-1f1f5.svg","flag_mq":"1f1f2-1f1f6.svg","flag_mr":"1f1f2-1f1f7.svg","flag_ms":"1f1f2-1f1f8.svg","flag_mt":"1f1f2-1f1f9.svg","flag_mu":"1f1f2-1f1fa.svg","flag_mv":"1f1f2-1f1fb.svg","flag_mw":"1f1f2-1f1fc.svg","flag_mx":"1f1f2-1f1fd.svg","flag_my":"1f1f2-1f1fe.svg","flag_mz":"1f1f2-1f1ff.svg","flag_na":"1f1f3-1f1e6.svg","flag_nc":"1f1f3-1f1e8.svg","flag_ne":"1f1f3-1f1ea.svg","flag_nf":"1f1f3-1f1eb.svg","flag_ng":"1f1f3-1f1ec.svg","flag_ni":"1f1f3-1f1ee.svg","flag_nl":"1f1f3-1f1f1.svg","flag_no":"1f1f3-1f1f4.svg","flag_np":"1f1f3-1f1f5.svg","flag_nr":"1f1f3-1f1f7.svg","flag_nu":"1f1f3-1f1fa.svg","flag_nz":"1f1f3-1f1ff.svg","flag_om":"1f1f4-1f1f2.svg","flag_pa":"1f1f5-1f1e6.svg","flag_pe":"1f1f5-1f1ea.svg","flag_pf":"1f1f5-1f1eb.svg","flag_pg":"1f1f5-1f1ec.svg","flag_ph":"1f1f5-1f1ed.svg","flag_pk":"1f1f5-1f1f0.svg","flag_pl":"1f1f5-1f1f1.svg","flag_pm":"1f1f5-1f1f2.svg","flag_pn":"1f1f5-1f1f3.svg","flag_pr":"1f1f5-1f1f7.svg","flag_ps":"1f1f5-1f1f8.svg","flag_pt":"1f1f5-1f1f9.svg","flag_pw":"1f1f5-1f1fc.svg","flag_py":"1f1f5-1f1fe.svg","flag_qa":"1f1f6-1f1e6.svg","flag_re":"1f1f7-1f1ea.svg","flag_ro":"1f1f7-1f1f4.svg","flag_rs":"1f1f7-1f1f8.svg","flag_ru":"1f1f7-1f1fa.svg","flag_rw":"1f1f7-1f1fc.svg","flag_sa":"1f1f8-1f1e6.svg","flag_sb":"1f1f8-1f1e7.svg","flag_sc":"1f1f8-1f1e8.svg","flag_sd":"1f1f8-1f1e9.svg","flag_se":"1f1f8-1f1ea.svg","flag_sg":"1f1f8-1f1ec.svg","flag_sh":"1f1f8-1f1ed.svg","flag_si":"1f1f8-1f1ee.svg","flag_sj":"1f1f8-1f1ef.svg","flag_sk":"1f1f8-1f1f0.svg","flag_sl":"1f1f8-1f1f1.svg","flag_sm":"1f1f8-1f1f2.svg","flag_sn":"1f1f8-1f1f3.svg","flag_so":"1f1f8-1f1f4.svg","flag_sr":"1f1f8-1f1f7.svg","flag_ss":"1f1f8-1f1f8.svg","flag_st":"1f1f8-1f1f9.svg","flag_sv":"1f1f8-1f1fb.svg","flag_sx":"1f1f8-1f1fd.svg","flag_sy":"1f1f8-1f1fe.svg","flag_sz":"1f1f8-1f1ff.svg","flag_ta":"1f1f9-1f1e6.svg","flag_tc":"1f1f9-1f1e8.svg","flag_td":"1f1f9-1f1e9.svg","flag_tf":"1f1f9-1f1eb.svg","flag_tg":"1f1f9-1f1ec.svg","flag_th":"1f1f9-1f1ed.svg","flag_tj":"1f1f9-1f1ef.svg","flag_tk":"1f1f9-1f1f0.svg","flag_tl":"1f1f9-1f1f1.svg","flag_tm":"1f1f9-1f1f2.svg","flag_tn":"1f1f9-1f1f3.svg","flag_to":"1f1f9-1f1f4.svg","flag_tr":"1f1f9-1f1f7.svg","flag_tt":"1f1f9-1f1f9.svg","flag_tv":"1f1f9-1f1fb.svg","flag_tw":"1f1f9-1f1fc.svg","flag_tz":"1f1f9-1f1ff.svg","flag_ua":"1f1fa-1f1e6.svg","flag_ug":"1f1fa-1f1ec.svg","flag_um":"1f1fa-1f1f2.svg","flag_us":"1f1fa-1f1f8.svg","flag_uy":"1f1fa-1f1fe.svg","flag_uz":"1f1fa-1f1ff.svg","flag_va":"1f1fb-1f1e6.svg","flag_vc":"1f1fb-1f1e8.svg","flag_ve":"1f1fb-1f1ea.svg","flag_vg":"1f1fb-1f1ec.svg","flag_vi":"1f1fb-1f1ee.svg","flag_vn":"1f1fb-1f1f3.svg","flag_vu":"1f1fb-1f1fa.svg","flag_wf":"1f1fc-1f1eb.svg","flag_white":"1f3f3.svg","flag_ws":"1f1fc-1f1f8.svg","flag_xk":"1f1fd-1f1f0.svg","flag_ye":"1f1fe-1f1ea.svg","flag_yt":"1f1fe-1f1f9.svg","flag_za":"1f1ff-1f1e6.svg","flag_zm":"1f1ff-1f1f2.svg","flag_zw":"1f1ff-1f1fc.svg","flags":"1f38f.svg","flamingo":"1f9a9.svg","flashlight":"1f526.svg","fleur-de-lis":"269c.svg","floppy_disk":"1f4be.svg","flower_playing_cards":"1f3b4.svg","flushed":"1f633.svg","flying_disc":"1f94f.svg","flying_saucer":"1f6f8.svg","fog":"1f32b.svg","foggy":"1f301.svg","foot":"1f9b6.svg","foot_tone1":"1f9b6-1f3fb.svg","foot_tone2":"1f9b6-1f3fc.svg","foot_tone3":"1f9b6-1f3fd.svg","foot_tone4":"1f9b6-1f3fe.svg","foot_tone5":"1f9b6-1f3ff.svg","football":"1f3c8.svg","footprints":"1f463.svg","fork_and_knife":"1f374.svg","fork_knife_plate":"1f37d.svg","fortune_cookie":"1f960.svg","fountain":"26f2.svg","four":"34-20e3.svg","four_leaf_clover":"1f340.svg","fox":"1f98a.svg","frame_photo":"1f5bc.svg","free":"1f193.svg","french_bread":"1f956.svg","fried_shrimp":"1f364.svg","fries":"1f35f.svg","frog":"1f438.svg","frowning2":"2639.svg","frowning":"1f626.svg","fuelpump":"26fd.svg","full_moon":"1f315.svg","full_moon_with_face":"1f31d.svg","game_die":"1f3b2.svg","garlic":"1f9c4.svg","gear":"2699.svg","gem":"1f48e.svg","gemini":"264a.svg","genie":"1f9de.svg","ghost":"1f47b.svg","gift":"1f381.svg","gift_heart":"1f49d.svg","giraffe":"1f992.svg","girl":"1f467.svg","girl_tone1":"1f467-1f3fb.svg","girl_tone2":"1f467-1f3fc.svg","girl_tone3":"1f467-1f3fd.svg","girl_tone4":"1f467-1f3fe.svg","girl_tone5":"1f467-1f3ff.svg","globe_with_meridians":"1f310.svg","gloves":"1f9e4.svg","goal":"1f945.svg","goat":"1f410.svg","goggles":"1f97d.svg","golf":"26f3.svg","gorilla":"1f98d.svg","grapes":"1f347.svg","green_apple":"1f34f.svg","green_book":"1f4d7.svg","green_circle":"1f7e2.svg","green_heart":"1f49a.svg","green_square":"1f7e9.svg","grey_exclamation":"2755.svg","grey_question":"2754.svg","grimacing":"1f62c.svg","grin":"1f601.svg","grinning":"1f600.svg","guard":"1f482.svg","guard_tone1":"1f482-1f3fb.svg","guard_tone2":"1f482-1f3fc.svg","guard_tone3":"1f482-1f3fd.svg","guard_tone4":"1f482-1f3fe.svg","guard_tone5":"1f482-1f3ff.svg","guide_dog":"1f9ae.svg","guitar":"1f3b8.svg","gun":"1f52b.svg","hamburger":"1f354.svg","hammer":"1f528.svg","hammer_pick":"2692.svg","hamster":"1f439.svg","hand_splayed":"1f590.svg","hand_splayed_tone1":"1f590-1f3fb.svg","hand_splayed_tone2":"1f590-1f3fc.svg","hand_splayed_tone3":"1f590-1f3fd.svg","hand_splayed_tone4":"1f590-1f3fe.svg","hand_splayed_tone5":"1f590-1f3ff.svg","handbag":"1f45c.svg","handshake":"1f91d.svg","hash":"23-20e3.svg","hatched_chick":"1f425.svg","hatching_chick":"1f423.svg","head_bandage":"1f915.svg","headphones":"1f3a7.svg","health_worker":"1f9d1-200d-2695-fe0f.svg","health_worker_tone1":"1f9d1-1f3fb-200d-2695-fe0f.svg","health_worker_tone2":"1f9d1-1f3fc-200d-2695-fe0f.svg","health_worker_tone3":"1f9d1-1f3fd-200d-2695-fe0f.svg","health_worker_tone4":"1f9d1-1f3fe-200d-2695-fe0f.svg","health_worker_tone5":"1f9d1-1f3ff-200d-2695-fe0f.svg","hear_no_evil":"1f649.svg","heart":"2764.svg","heart_decoration":"1f49f.svg","heart_exclamation":"2763.svg","heart_eyes":"1f60d.svg","heart_eyes_cat":"1f63b.svg","heartbeat":"1f493.svg","heartpulse":"1f497.svg","hearts":"2665.svg","heavy_check_mark":"2714.svg","heavy_division_sign":"2797.svg","heavy_dollar_sign":"1f4b2.svg","heavy_minus_sign":"2796.svg","heavy_multiplication_x":"2716.svg","heavy_plus_sign":"2795.svg","hedgehog":"1f994.svg","helicopter":"1f681.svg","helmet_with_cross":"26d1.svg","herb":"1f33f.svg","hibiscus":"1f33a.svg","high_brightness":"1f506.svg","high_heel":"1f460.svg","hiking_boot":"1f97e.svg","hindu_temple":"1f6d5.svg","hippopotamus":"1f99b.svg","hockey":"1f3d2.svg","hole":"1f573.svg","homes":"1f3d8.svg","honey_pot":"1f36f.svg","horse":"1f434.svg","horse_racing":"1f3c7.svg","horse_racing_tone1":"1f3c7-1f3fb.svg","horse_racing_tone2":"1f3c7-1f3fc.svg","horse_racing_tone3":"1f3c7-1f3fd.svg","horse_racing_tone4":"1f3c7-1f3fe.svg","horse_racing_tone5":"1f3c7-1f3ff.svg","hospital":"1f3e5.svg","hot_face":"1f975.svg","hot_pepper":"1f336.svg","hotdog":"1f32d.svg","hotel":"1f3e8.svg","hotsprings":"2668.svg","hourglass":"231b.svg","hourglass_flowing_sand":"23f3.svg","house":"1f3e0.svg","house_abandoned":"1f3da.svg","house_with_garden":"1f3e1.svg","hugging":"1f917.svg","hushed":"1f62f.svg","ice_cream":"1f368.svg","ice_cube":"1f9ca.svg","ice_skate":"26f8.svg","icecream":"1f366.svg","id":"1f194.svg","ideograph_advantage":"1f250.svg","imp":"1f47f.svg","inbox_tray":"1f4e5.svg","incoming_envelope":"1f4e8.svg","infinity":"267e.svg","information_source":"2139.svg","innocent":"1f607.svg","interrobang":"2049.svg","island":"1f3dd.svg","izakaya_lantern":"1f3ee.svg","jack_o_lantern":"1f383.svg","japan":"1f5fe.svg","japanese_castle":"1f3ef.svg","japanese_goblin":"1f47a.svg","japanese_ogre":"1f479.svg","jeans":"1f456.svg","jigsaw":"1f9e9.svg","joy":"1f602.svg","joy_cat":"1f639.svg","joystick":"1f579.svg","judge":"1f9d1-200d-2696-fe0f.svg","judge_tone1":"1f9d1-1f3fb-200d-2696-fe0f.svg","judge_tone2":"1f9d1-1f3fc-200d-2696-fe0f.svg","judge_tone3":"1f9d1-1f3fd-200d-2696-fe0f.svg","judge_tone4":"1f9d1-1f3fe-200d-2696-fe0f.svg","judge_tone5":"1f9d1-1f3ff-200d-2696-fe0f.svg","kaaba":"1f54b.svg","kangaroo":"1f998.svg","key2":"1f5dd.svg","key":"1f511.svg","keyboard":"2328.svg","keycap_ten":"1f51f.svg","kimono":"1f458.svg","kiss":"1f48b.svg","kiss_mm":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_woman_man":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_ww":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469.svg","kissing":"1f617.svg","kissing_cat":"1f63d.svg","kissing_closed_eyes":"1f61a.svg","kissing_heart":"1f618.svg","kissing_smiling_eyes":"1f619.svg","kite":"1fa81.svg","kiwi":"1f95d.svg","knife":"1f52a.svg","koala":"1f428.svg","koko":"1f201.svg","lab_coat":"1f97c.svg","label":"1f3f7.svg","lacrosse":"1f94d.svg","large_blue_diamond":"1f537.svg","large_orange_diamond":"1f536.svg","last_quarter_moon":"1f317.svg","last_quarter_moon_with_face":"1f31c.svg","laughing":"1f606.svg","leafy_green":"1f96c.svg","leaves":"1f343.svg","ledger":"1f4d2.svg","left_facing_fist":"1f91b.svg","left_facing_fist_tone1":"1f91b-1f3fb.svg","left_facing_fist_tone2":"1f91b-1f3fc.svg","left_facing_fist_tone3":"1f91b-1f3fd.svg","left_facing_fist_tone4":"1f91b-1f3fe.svg","left_facing_fist_tone5":"1f91b-1f3ff.svg","left_luggage":"1f6c5.svg","left_right_arrow":"2194.svg","leftwards_arrow_with_hook":"21a9.svg","leg":"1f9b5.svg","leg_tone1":"1f9b5-1f3fb.svg","leg_tone2":"1f9b5-1f3fc.svg","leg_tone3":"1f9b5-1f3fd.svg","leg_tone4":"1f9b5-1f3fe.svg","leg_tone5":"1f9b5-1f3ff.svg","lemon":"1f34b.svg","leo":"264c.svg","leopard":"1f406.svg","level_slider":"1f39a.svg","levitate":"1f574.svg","levitate_tone1":"1f574-1f3fb.svg","levitate_tone2":"1f574-1f3fc.svg","levitate_tone3":"1f574-1f3fd.svg","levitate_tone4":"1f574-1f3fe.svg","levitate_tone5":"1f574-1f3ff.svg","libra":"264e.svg","light_rail":"1f688.svg","link":"1f517.svg","lion_face":"1f981.svg","lips":"1f444.svg","lipstick":"1f484.svg","lizard":"1f98e.svg","llama":"1f999.svg","lobster":"1f99e.svg","lock":"1f512.svg","lock_with_ink_pen":"1f50f.svg","lollipop":"1f36d.svg","loop":"27bf.svg","loud_sound":"1f50a.svg","loudspeaker":"1f4e2.svg","love_hotel":"1f3e9.svg","love_letter":"1f48c.svg","love_you_gesture":"1f91f.svg","love_you_gesture_tone1":"1f91f-1f3fb.svg","love_you_gesture_tone2":"1f91f-1f3fc.svg","love_you_gesture_tone3":"1f91f-1f3fd.svg","love_you_gesture_tone4":"1f91f-1f3fe.svg","love_you_gesture_tone5":"1f91f-1f3ff.svg","low_brightness":"1f505.svg","luggage":"1f9f3.svg","lying_face":"1f925.svg","m":"24c2.svg","mag":"1f50d.svg","mag_right":"1f50e.svg","mage":"1f9d9.svg","mage_tone1":"1f9d9-1f3fb.svg","mage_tone2":"1f9d9-1f3fc.svg","mage_tone3":"1f9d9-1f3fd.svg","mage_tone4":"1f9d9-1f3fe.svg","mage_tone5":"1f9d9-1f3ff.svg","magnet":"1f9f2.svg","mahjong":"1f004.svg","mailbox":"1f4eb.svg","mailbox_closed":"1f4ea.svg","mailbox_with_mail":"1f4ec.svg","mailbox_with_no_mail":"1f4ed.svg","male_sign":"2642.svg","man":"1f468.svg","man_artist":"1f468-200d-1f3a8.svg","man_artist_tone1":"1f468-1f3fb-200d-1f3a8.svg","man_artist_tone2":"1f468-1f3fc-200d-1f3a8.svg","man_artist_tone3":"1f468-1f3fd-200d-1f3a8.svg","man_artist_tone4":"1f468-1f3fe-200d-1f3a8.svg","man_artist_tone5":"1f468-1f3ff-200d-1f3a8.svg","man_astronaut":"1f468-200d-1f680.svg","man_astronaut_tone1":"1f468-1f3fb-200d-1f680.svg","man_astronaut_tone2":"1f468-1f3fc-200d-1f680.svg","man_astronaut_tone3":"1f468-1f3fd-200d-1f680.svg","man_astronaut_tone4":"1f468-1f3fe-200d-1f680.svg","man_astronaut_tone5":"1f468-1f3ff-200d-1f680.svg","man_bald":"1f468-200d-1f9b2.svg","man_bald_tone1":"1f468-1f3fb-200d-1f9b2.svg","man_bald_tone2":"1f468-1f3fc-200d-1f9b2.svg","man_bald_tone3":"1f468-1f3fd-200d-1f9b2.svg","man_bald_tone4":"1f468-1f3fe-200d-1f9b2.svg","man_bald_tone5":"1f468-1f3ff-200d-1f9b2.svg","man_biking":"1f6b4-200d-2642-fe0f.svg","man_biking_tone1":"1f6b4-1f3fb-200d-2642-fe0f.svg","man_biking_tone2":"1f6b4-1f3fc-200d-2642-fe0f.svg","man_biking_tone3":"1f6b4-1f3fd-200d-2642-fe0f.svg","man_biking_tone4":"1f6b4-1f3fe-200d-2642-fe0f.svg","man_biking_tone5":"1f6b4-1f3ff-200d-2642-fe0f.svg","man_bouncing_ball":"26f9-fe0f-200d-2642-fe0f.svg","man_bouncing_ball_tone1":"26f9-1f3fb-200d-2642-fe0f.svg","man_bouncing_ball_tone2":"26f9-1f3fc-200d-2642-fe0f.svg","man_bouncing_ball_tone3":"26f9-1f3fd-200d-2642-fe0f.svg","man_bouncing_ball_tone4":"26f9-1f3fe-200d-2642-fe0f.svg","man_bouncing_ball_tone5":"26f9-1f3ff-200d-2642-fe0f.svg","man_bowing":"1f647-200d-2642-fe0f.svg","man_bowing_tone1":"1f647-1f3fb-200d-2642-fe0f.svg","man_bowing_tone2":"1f647-1f3fc-200d-2642-fe0f.svg","man_bowing_tone3":"1f647-1f3fd-200d-2642-fe0f.svg","man_bowing_tone4":"1f647-1f3fe-200d-2642-fe0f.svg","man_bowing_tone5":"1f647-1f3ff-200d-2642-fe0f.svg","man_cartwheeling":"1f938-200d-2642-fe0f.svg","man_cartwheeling_tone1":"1f938-1f3fb-200d-2642-fe0f.svg","man_cartwheeling_tone2":"1f938-1f3fc-200d-2642-fe0f.svg","man_cartwheeling_tone3":"1f938-1f3fd-200d-2642-fe0f.svg","man_cartwheeling_tone4":"1f938-1f3fe-200d-2642-fe0f.svg","man_cartwheeling_tone5":"1f938-1f3ff-200d-2642-fe0f.svg","man_climbing":"1f9d7-200d-2642-fe0f.svg","man_climbing_tone1":"1f9d7-1f3fb-200d-2642-fe0f.svg","man_climbing_tone2":"1f9d7-1f3fc-200d-2642-fe0f.svg","man_climbing_tone3":"1f9d7-1f3fd-200d-2642-fe0f.svg","man_climbing_tone4":"1f9d7-1f3fe-200d-2642-fe0f.svg","man_climbing_tone5":"1f9d7-1f3ff-200d-2642-fe0f.svg","man_construction_worker":"1f477-200d-2642-fe0f.svg","man_construction_worker_tone1":"1f477-1f3fb-200d-2642-fe0f.svg","man_construction_worker_tone2":"1f477-1f3fc-200d-2642-fe0f.svg","man_construction_worker_tone3":"1f477-1f3fd-200d-2642-fe0f.svg","man_construction_worker_tone4":"1f477-1f3fe-200d-2642-fe0f.svg","man_construction_worker_tone5":"1f477-1f3ff-200d-2642-fe0f.svg","man_cook":"1f468-200d-1f373.svg","man_cook_tone1":"1f468-1f3fb-200d-1f373.svg","man_cook_tone2":"1f468-1f3fc-200d-1f373.svg","man_cook_tone3":"1f468-1f3fd-200d-1f373.svg","man_cook_tone4":"1f468-1f3fe-200d-1f373.svg","man_cook_tone5":"1f468-1f3ff-200d-1f373.svg","man_curly_haired":"1f468-200d-1f9b1.svg","man_curly_haired_tone1":"1f468-1f3fb-200d-1f9b1.svg","man_curly_haired_tone2":"1f468-1f3fc-200d-1f9b1.svg","man_curly_haired_tone3":"1f468-1f3fd-200d-1f9b1.svg","man_curly_haired_tone4":"1f468-1f3fe-200d-1f9b1.svg","man_curly_haired_tone5":"1f468-1f3ff-200d-1f9b1.svg","man_dancing":"1f57a.svg","man_dancing_tone1":"1f57a-1f3fb.svg","man_dancing_tone2":"1f57a-1f3fc.svg","man_dancing_tone3":"1f57a-1f3fd.svg","man_dancing_tone4":"1f57a-1f3fe.svg","man_dancing_tone5":"1f57a-1f3ff.svg","man_detective":"1f575-fe0f-200d-2642-fe0f.svg","man_detective_tone1":"1f575-1f3fb-200d-2642-fe0f.svg","man_detective_tone2":"1f575-1f3fc-200d-2642-fe0f.svg","man_detective_tone3":"1f575-1f3fd-200d-2642-fe0f.svg","man_detective_tone4":"1f575-1f3fe-200d-2642-fe0f.svg","man_detective_tone5":"1f575-1f3ff-200d-2642-fe0f.svg","man_elf":"1f9dd-200d-2642-fe0f.svg","man_elf_tone1":"1f9dd-1f3fb-200d-2642-fe0f.svg","man_elf_tone2":"1f9dd-1f3fc-200d-2642-fe0f.svg","man_elf_tone3":"1f9dd-1f3fd-200d-2642-fe0f.svg","man_elf_tone4":"1f9dd-1f3fe-200d-2642-fe0f.svg","man_elf_tone5":"1f9dd-1f3ff-200d-2642-fe0f.svg","man_facepalming":"1f926-200d-2642-fe0f.svg","man_facepalming_tone1":"1f926-1f3fb-200d-2642-fe0f.svg","man_facepalming_tone2":"1f926-1f3fc-200d-2642-fe0f.svg","man_facepalming_tone3":"1f926-1f3fd-200d-2642-fe0f.svg","man_facepalming_tone4":"1f926-1f3fe-200d-2642-fe0f.svg","man_facepalming_tone5":"1f926-1f3ff-200d-2642-fe0f.svg","man_factory_worker":"1f468-200d-1f3ed.svg","man_factory_worker_tone1":"1f468-1f3fb-200d-1f3ed.svg","man_factory_worker_tone2":"1f468-1f3fc-200d-1f3ed.svg","man_factory_worker_tone3":"1f468-1f3fd-200d-1f3ed.svg","man_factory_worker_tone4":"1f468-1f3fe-200d-1f3ed.svg","man_factory_worker_tone5":"1f468-1f3ff-200d-1f3ed.svg","man_fairy":"1f9da-200d-2642-fe0f.svg","man_fairy_tone1":"1f9da-1f3fb-200d-2642-fe0f.svg","man_fairy_tone2":"1f9da-1f3fc-200d-2642-fe0f.svg","man_fairy_tone3":"1f9da-1f3fd-200d-2642-fe0f.svg","man_fairy_tone4":"1f9da-1f3fe-200d-2642-fe0f.svg","man_fairy_tone5":"1f9da-1f3ff-200d-2642-fe0f.svg","man_farmer":"1f468-200d-1f33e.svg","man_farmer_tone1":"1f468-1f3fb-200d-1f33e.svg","man_farmer_tone2":"1f468-1f3fc-200d-1f33e.svg","man_farmer_tone3":"1f468-1f3fd-200d-1f33e.svg","man_farmer_tone4":"1f468-1f3fe-200d-1f33e.svg","man_farmer_tone5":"1f468-1f3ff-200d-1f33e.svg","man_firefighter":"1f468-200d-1f692.svg","man_firefighter_tone1":"1f468-1f3fb-200d-1f692.svg","man_firefighter_tone2":"1f468-1f3fc-200d-1f692.svg","man_firefighter_tone3":"1f468-1f3fd-200d-1f692.svg","man_firefighter_tone4":"1f468-1f3fe-200d-1f692.svg","man_firefighter_tone5":"1f468-1f3ff-200d-1f692.svg","man_frowning":"1f64d-200d-2642-fe0f.svg","man_frowning_tone1":"1f64d-1f3fb-200d-2642-fe0f.svg","man_frowning_tone2":"1f64d-1f3fc-200d-2642-fe0f.svg","man_frowning_tone3":"1f64d-1f3fd-200d-2642-fe0f.svg","man_frowning_tone4":"1f64d-1f3fe-200d-2642-fe0f.svg","man_frowning_tone5":"1f64d-1f3ff-200d-2642-fe0f.svg","man_genie":"1f9de-200d-2642-fe0f.svg","man_gesturing_no":"1f645-200d-2642-fe0f.svg","man_gesturing_no_tone1":"1f645-1f3fb-200d-2642-fe0f.svg","man_gesturing_no_tone2":"1f645-1f3fc-200d-2642-fe0f.svg","man_gesturing_no_tone3":"1f645-1f3fd-200d-2642-fe0f.svg","man_gesturing_no_tone4":"1f645-1f3fe-200d-2642-fe0f.svg","man_gesturing_no_tone5":"1f645-1f3ff-200d-2642-fe0f.svg","man_gesturing_ok":"1f646-200d-2642-fe0f.svg","man_gesturing_ok_tone1":"1f646-1f3fb-200d-2642-fe0f.svg","man_gesturing_ok_tone2":"1f646-1f3fc-200d-2642-fe0f.svg","man_gesturing_ok_tone3":"1f646-1f3fd-200d-2642-fe0f.svg","man_gesturing_ok_tone4":"1f646-1f3fe-200d-2642-fe0f.svg","man_gesturing_ok_tone5":"1f646-1f3ff-200d-2642-fe0f.svg","man_getting_face_massage":"1f486-200d-2642-fe0f.svg","man_getting_face_massage_tone1":"1f486-1f3fb-200d-2642-fe0f.svg","man_getting_face_massage_tone2":"1f486-1f3fc-200d-2642-fe0f.svg","man_getting_face_massage_tone3":"1f486-1f3fd-200d-2642-fe0f.svg","man_getting_face_massage_tone4":"1f486-1f3fe-200d-2642-fe0f.svg","man_getting_face_massage_tone5":"1f486-1f3ff-200d-2642-fe0f.svg","man_getting_haircut":"1f487-200d-2642-fe0f.svg","man_getting_haircut_tone1":"1f487-1f3fb-200d-2642-fe0f.svg","man_getting_haircut_tone2":"1f487-1f3fc-200d-2642-fe0f.svg","man_getting_haircut_tone3":"1f487-1f3fd-200d-2642-fe0f.svg","man_getting_haircut_tone4":"1f487-1f3fe-200d-2642-fe0f.svg","man_getting_haircut_tone5":"1f487-1f3ff-200d-2642-fe0f.svg","man_golfing":"1f3cc-fe0f-200d-2642-fe0f.svg","man_golfing_tone1":"1f3cc-1f3fb-200d-2642-fe0f.svg","man_golfing_tone2":"1f3cc-1f3fc-200d-2642-fe0f.svg","man_golfing_tone3":"1f3cc-1f3fd-200d-2642-fe0f.svg","man_golfing_tone4":"1f3cc-1f3fe-200d-2642-fe0f.svg","man_golfing_tone5":"1f3cc-1f3ff-200d-2642-fe0f.svg","man_guard":"1f482-200d-2642-fe0f.svg","man_guard_tone1":"1f482-1f3fb-200d-2642-fe0f.svg","man_guard_tone2":"1f482-1f3fc-200d-2642-fe0f.svg","man_guard_tone3":"1f482-1f3fd-200d-2642-fe0f.svg","man_guard_tone4":"1f482-1f3fe-200d-2642-fe0f.svg","man_guard_tone5":"1f482-1f3ff-200d-2642-fe0f.svg","man_health_worker":"1f468-200d-2695-fe0f.svg","man_health_worker_tone1":"1f468-1f3fb-200d-2695-fe0f.svg","man_health_worker_tone2":"1f468-1f3fc-200d-2695-fe0f.svg","man_health_worker_tone3":"1f468-1f3fd-200d-2695-fe0f.svg","man_health_worker_tone4":"1f468-1f3fe-200d-2695-fe0f.svg","man_health_worker_tone5":"1f468-1f3ff-200d-2695-fe0f.svg","man_in_lotus_position":"1f9d8-200d-2642-fe0f.svg","man_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2642-fe0f.svg","man_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2642-fe0f.svg","man_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2642-fe0f.svg","man_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2642-fe0f.svg","man_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2642-fe0f.svg","man_in_manual_wheelchair":"1f468-200d-1f9bd.svg","man_in_manual_wheelchair_tone1":"1f468-1f3fb-200d-1f9bd.svg","man_in_manual_wheelchair_tone2":"1f468-1f3fc-200d-1f9bd.svg","man_in_manual_wheelchair_tone3":"1f468-1f3fd-200d-1f9bd.svg","man_in_manual_wheelchair_tone4":"1f468-1f3fe-200d-1f9bd.svg","man_in_manual_wheelchair_tone5":"1f468-1f3ff-200d-1f9bd.svg","man_in_motorized_wheelchair":"1f468-200d-1f9bc.svg","man_in_motorized_wheelchair_tone1":"1f468-1f3fb-200d-1f9bc.svg","man_in_motorized_wheelchair_tone2":"1f468-1f3fc-200d-1f9bc.svg","man_in_motorized_wheelchair_tone3":"1f468-1f3fd-200d-1f9bc.svg","man_in_motorized_wheelchair_tone4":"1f468-1f3fe-200d-1f9bc.svg","man_in_motorized_wheelchair_tone5":"1f468-1f3ff-200d-1f9bc.svg","man_in_steamy_room":"1f9d6-200d-2642-fe0f.svg","man_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2642-fe0f.svg","man_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2642-fe0f.svg","man_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2642-fe0f.svg","man_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2642-fe0f.svg","man_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2642-fe0f.svg","man_in_tuxedo":"1f935.svg","man_in_tuxedo_tone1":"1f935-1f3fb.svg","man_in_tuxedo_tone2":"1f935-1f3fc.svg","man_in_tuxedo_tone3":"1f935-1f3fd.svg","man_in_tuxedo_tone4":"1f935-1f3fe.svg","man_in_tuxedo_tone5":"1f935-1f3ff.svg","man_judge":"1f468-200d-2696-fe0f.svg","man_judge_tone1":"1f468-1f3fb-200d-2696-fe0f.svg","man_judge_tone2":"1f468-1f3fc-200d-2696-fe0f.svg","man_judge_tone3":"1f468-1f3fd-200d-2696-fe0f.svg","man_judge_tone4":"1f468-1f3fe-200d-2696-fe0f.svg","man_judge_tone5":"1f468-1f3ff-200d-2696-fe0f.svg","man_juggling":"1f939-200d-2642-fe0f.svg","man_juggling_tone1":"1f939-1f3fb-200d-2642-fe0f.svg","man_juggling_tone2":"1f939-1f3fc-200d-2642-fe0f.svg","man_juggling_tone3":"1f939-1f3fd-200d-2642-fe0f.svg","man_juggling_tone4":"1f939-1f3fe-200d-2642-fe0f.svg","man_juggling_tone5":"1f939-1f3ff-200d-2642-fe0f.svg","man_kneeling":"1f9ce-200d-2642-fe0f.svg","man_kneeling_tone1":"1f9ce-1f3fb-200d-2642-fe0f.svg","man_kneeling_tone2":"1f9ce-1f3fc-200d-2642-fe0f.svg","man_kneeling_tone3":"1f9ce-1f3fd-200d-2642-fe0f.svg","man_kneeling_tone4":"1f9ce-1f3fe-200d-2642-fe0f.svg","man_kneeling_tone5":"1f9ce-1f3ff-200d-2642-fe0f.svg","man_lifting_weights":"1f3cb-fe0f-200d-2642-fe0f.svg","man_lifting_weights_tone1":"1f3cb-1f3fb-200d-2642-fe0f.svg","man_lifting_weights_tone2":"1f3cb-1f3fc-200d-2642-fe0f.svg","man_lifting_weights_tone3":"1f3cb-1f3fd-200d-2642-fe0f.svg","man_lifting_weights_tone4":"1f3cb-1f3fe-200d-2642-fe0f.svg","man_lifting_weights_tone5":"1f3cb-1f3ff-200d-2642-fe0f.svg","man_mage":"1f9d9-200d-2642-fe0f.svg","man_mage_tone1":"1f9d9-1f3fb-200d-2642-fe0f.svg","man_mage_tone2":"1f9d9-1f3fc-200d-2642-fe0f.svg","man_mage_tone3":"1f9d9-1f3fd-200d-2642-fe0f.svg","man_mage_tone4":"1f9d9-1f3fe-200d-2642-fe0f.svg","man_mage_tone5":"1f9d9-1f3ff-200d-2642-fe0f.svg","man_mechanic":"1f468-200d-1f527.svg","man_mechanic_tone1":"1f468-1f3fb-200d-1f527.svg","man_mechanic_tone2":"1f468-1f3fc-200d-1f527.svg","man_mechanic_tone3":"1f468-1f3fd-200d-1f527.svg","man_mechanic_tone4":"1f468-1f3fe-200d-1f527.svg","man_mechanic_tone5":"1f468-1f3ff-200d-1f527.svg","man_mountain_biking":"1f6b5-200d-2642-fe0f.svg","man_mountain_biking_tone1":"1f6b5-1f3fb-200d-2642-fe0f.svg","man_mountain_biking_tone2":"1f6b5-1f3fc-200d-2642-fe0f.svg","man_mountain_biking_tone3":"1f6b5-1f3fd-200d-2642-fe0f.svg","man_mountain_biking_tone4":"1f6b5-1f3fe-200d-2642-fe0f.svg","man_mountain_biking_tone5":"1f6b5-1f3ff-200d-2642-fe0f.svg","man_office_worker":"1f468-200d-1f4bc.svg","man_office_worker_tone1":"1f468-1f3fb-200d-1f4bc.svg","man_office_worker_tone2":"1f468-1f3fc-200d-1f4bc.svg","man_office_worker_tone3":"1f468-1f3fd-200d-1f4bc.svg","man_office_worker_tone4":"1f468-1f3fe-200d-1f4bc.svg","man_office_worker_tone5":"1f468-1f3ff-200d-1f4bc.svg","man_pilot":"1f468-200d-2708-fe0f.svg","man_pilot_tone1":"1f468-1f3fb-200d-2708-fe0f.svg","man_pilot_tone2":"1f468-1f3fc-200d-2708-fe0f.svg","man_pilot_tone3":"1f468-1f3fd-200d-2708-fe0f.svg","man_pilot_tone4":"1f468-1f3fe-200d-2708-fe0f.svg","man_pilot_tone5":"1f468-1f3ff-200d-2708-fe0f.svg","man_playing_handball":"1f93e-200d-2642-fe0f.svg","man_playing_handball_tone1":"1f93e-1f3fb-200d-2642-fe0f.svg","man_playing_handball_tone2":"1f93e-1f3fc-200d-2642-fe0f.svg","man_playing_handball_tone3":"1f93e-1f3fd-200d-2642-fe0f.svg","man_playing_handball_tone4":"1f93e-1f3fe-200d-2642-fe0f.svg","man_playing_handball_tone5":"1f93e-1f3ff-200d-2642-fe0f.svg","man_playing_water_polo":"1f93d-200d-2642-fe0f.svg","man_playing_water_polo_tone1":"1f93d-1f3fb-200d-2642-fe0f.svg","man_playing_water_polo_tone2":"1f93d-1f3fc-200d-2642-fe0f.svg","man_playing_water_polo_tone3":"1f93d-1f3fd-200d-2642-fe0f.svg","man_playing_water_polo_tone4":"1f93d-1f3fe-200d-2642-fe0f.svg","man_playing_water_polo_tone5":"1f93d-1f3ff-200d-2642-fe0f.svg","man_police_officer":"1f46e-200d-2642-fe0f.svg","man_police_officer_tone1":"1f46e-1f3fb-200d-2642-fe0f.svg","man_police_officer_tone2":"1f46e-1f3fc-200d-2642-fe0f.svg","man_police_officer_tone3":"1f46e-1f3fd-200d-2642-fe0f.svg","man_police_officer_tone4":"1f46e-1f3fe-200d-2642-fe0f.svg","man_police_officer_tone5":"1f46e-1f3ff-200d-2642-fe0f.svg","man_pouting":"1f64e-200d-2642-fe0f.svg","man_pouting_tone1":"1f64e-1f3fb-200d-2642-fe0f.svg","man_pouting_tone2":"1f64e-1f3fc-200d-2642-fe0f.svg","man_pouting_tone3":"1f64e-1f3fd-200d-2642-fe0f.svg","man_pouting_tone4":"1f64e-1f3fe-200d-2642-fe0f.svg","man_pouting_tone5":"1f64e-1f3ff-200d-2642-fe0f.svg","man_raising_hand":"1f64b-200d-2642-fe0f.svg","man_raising_hand_tone1":"1f64b-1f3fb-200d-2642-fe0f.svg","man_raising_hand_tone2":"1f64b-1f3fc-200d-2642-fe0f.svg","man_raising_hand_tone3":"1f64b-1f3fd-200d-2642-fe0f.svg","man_raising_hand_tone4":"1f64b-1f3fe-200d-2642-fe0f.svg","man_raising_hand_tone5":"1f64b-1f3ff-200d-2642-fe0f.svg","man_red_haired":"1f468-200d-1f9b0.svg","man_red_haired_tone1":"1f468-1f3fb-200d-1f9b0.svg","man_red_haired_tone2":"1f468-1f3fc-200d-1f9b0.svg","man_red_haired_tone3":"1f468-1f3fd-200d-1f9b0.svg","man_red_haired_tone4":"1f468-1f3fe-200d-1f9b0.svg","man_red_haired_tone5":"1f468-1f3ff-200d-1f9b0.svg","man_rowing_boat":"1f6a3-200d-2642-fe0f.svg","man_rowing_boat_tone1":"1f6a3-1f3fb-200d-2642-fe0f.svg","man_rowing_boat_tone2":"1f6a3-1f3fc-200d-2642-fe0f.svg","man_rowing_boat_tone3":"1f6a3-1f3fd-200d-2642-fe0f.svg","man_rowing_boat_tone4":"1f6a3-1f3fe-200d-2642-fe0f.svg","man_rowing_boat_tone5":"1f6a3-1f3ff-200d-2642-fe0f.svg","man_running":"1f3c3-200d-2642-fe0f.svg","man_running_tone1":"1f3c3-1f3fb-200d-2642-fe0f.svg","man_running_tone2":"1f3c3-1f3fc-200d-2642-fe0f.svg","man_running_tone3":"1f3c3-1f3fd-200d-2642-fe0f.svg","man_running_tone4":"1f3c3-1f3fe-200d-2642-fe0f.svg","man_running_tone5":"1f3c3-1f3ff-200d-2642-fe0f.svg","man_scientist":"1f468-200d-1f52c.svg","man_scientist_tone1":"1f468-1f3fb-200d-1f52c.svg","man_scientist_tone2":"1f468-1f3fc-200d-1f52c.svg","man_scientist_tone3":"1f468-1f3fd-200d-1f52c.svg","man_scientist_tone4":"1f468-1f3fe-200d-1f52c.svg","man_scientist_tone5":"1f468-1f3ff-200d-1f52c.svg","man_shrugging":"1f937-200d-2642-fe0f.svg","man_shrugging_tone1":"1f937-1f3fb-200d-2642-fe0f.svg","man_shrugging_tone2":"1f937-1f3fc-200d-2642-fe0f.svg","man_shrugging_tone3":"1f937-1f3fd-200d-2642-fe0f.svg","man_shrugging_tone4":"1f937-1f3fe-200d-2642-fe0f.svg","man_shrugging_tone5":"1f937-1f3ff-200d-2642-fe0f.svg","man_singer":"1f468-200d-1f3a4.svg","man_singer_tone1":"1f468-1f3fb-200d-1f3a4.svg","man_singer_tone2":"1f468-1f3fc-200d-1f3a4.svg","man_singer_tone3":"1f468-1f3fd-200d-1f3a4.svg","man_singer_tone4":"1f468-1f3fe-200d-1f3a4.svg","man_singer_tone5":"1f468-1f3ff-200d-1f3a4.svg","man_standing":"1f9cd-200d-2642-fe0f.svg","man_standing_tone1":"1f9cd-1f3fb-200d-2642-fe0f.svg","man_standing_tone2":"1f9cd-1f3fc-200d-2642-fe0f.svg","man_standing_tone3":"1f9cd-1f3fd-200d-2642-fe0f.svg","man_standing_tone4":"1f9cd-1f3fe-200d-2642-fe0f.svg","man_standing_tone5":"1f9cd-1f3ff-200d-2642-fe0f.svg","man_student":"1f468-200d-1f393.svg","man_student_tone1":"1f468-1f3fb-200d-1f393.svg","man_student_tone2":"1f468-1f3fc-200d-1f393.svg","man_student_tone3":"1f468-1f3fd-200d-1f393.svg","man_student_tone4":"1f468-1f3fe-200d-1f393.svg","man_student_tone5":"1f468-1f3ff-200d-1f393.svg","man_superhero":"1f9b8-200d-2642-fe0f.svg","man_superhero_tone1":"1f9b8-1f3fb-200d-2642-fe0f.svg","man_superhero_tone2":"1f9b8-1f3fc-200d-2642-fe0f.svg","man_superhero_tone3":"1f9b8-1f3fd-200d-2642-fe0f.svg","man_superhero_tone4":"1f9b8-1f3fe-200d-2642-fe0f.svg","man_superhero_tone5":"1f9b8-1f3ff-200d-2642-fe0f.svg","man_supervillain":"1f9b9-200d-2642-fe0f.svg","man_supervillain_tone1":"1f9b9-1f3fb-200d-2642-fe0f.svg","man_supervillain_tone2":"1f9b9-1f3fc-200d-2642-fe0f.svg","man_supervillain_tone3":"1f9b9-1f3fd-200d-2642-fe0f.svg","man_supervillain_tone4":"1f9b9-1f3fe-200d-2642-fe0f.svg","man_supervillain_tone5":"1f9b9-1f3ff-200d-2642-fe0f.svg","man_surfing":"1f3c4-200d-2642-fe0f.svg","man_surfing_tone1":"1f3c4-1f3fb-200d-2642-fe0f.svg","man_surfing_tone2":"1f3c4-1f3fc-200d-2642-fe0f.svg","man_surfing_tone3":"1f3c4-1f3fd-200d-2642-fe0f.svg","man_surfing_tone4":"1f3c4-1f3fe-200d-2642-fe0f.svg","man_surfing_tone5":"1f3c4-1f3ff-200d-2642-fe0f.svg","man_swimming":"1f3ca-200d-2642-fe0f.svg","man_swimming_tone1":"1f3ca-1f3fb-200d-2642-fe0f.svg","man_swimming_tone2":"1f3ca-1f3fc-200d-2642-fe0f.svg","man_swimming_tone3":"1f3ca-1f3fd-200d-2642-fe0f.svg","man_swimming_tone4":"1f3ca-1f3fe-200d-2642-fe0f.svg","man_swimming_tone5":"1f3ca-1f3ff-200d-2642-fe0f.svg","man_teacher":"1f468-200d-1f3eb.svg","man_teacher_tone1":"1f468-1f3fb-200d-1f3eb.svg","man_teacher_tone2":"1f468-1f3fc-200d-1f3eb.svg","man_teacher_tone3":"1f468-1f3fd-200d-1f3eb.svg","man_teacher_tone4":"1f468-1f3fe-200d-1f3eb.svg","man_teacher_tone5":"1f468-1f3ff-200d-1f3eb.svg","man_technologist":"1f468-200d-1f4bb.svg","man_technologist_tone1":"1f468-1f3fb-200d-1f4bb.svg","man_technologist_tone2":"1f468-1f3fc-200d-1f4bb.svg","man_technologist_tone3":"1f468-1f3fd-200d-1f4bb.svg","man_technologist_tone4":"1f468-1f3fe-200d-1f4bb.svg","man_technologist_tone5":"1f468-1f3ff-200d-1f4bb.svg","man_tipping_hand":"1f481-200d-2642-fe0f.svg","man_tipping_hand_tone1":"1f481-1f3fb-200d-2642-fe0f.svg","man_tipping_hand_tone2":"1f481-1f3fc-200d-2642-fe0f.svg","man_tipping_hand_tone3":"1f481-1f3fd-200d-2642-fe0f.svg","man_tipping_hand_tone4":"1f481-1f3fe-200d-2642-fe0f.svg","man_tipping_hand_tone5":"1f481-1f3ff-200d-2642-fe0f.svg","man_tone1":"1f468-1f3fb.svg","man_tone2":"1f468-1f3fc.svg","man_tone3":"1f468-1f3fd.svg","man_tone4":"1f468-1f3fe.svg","man_tone5":"1f468-1f3ff.svg","man_vampire":"1f9db-200d-2642-fe0f.svg","man_vampire_tone1":"1f9db-1f3fb-200d-2642-fe0f.svg","man_vampire_tone2":"1f9db-1f3fc-200d-2642-fe0f.svg","man_vampire_tone3":"1f9db-1f3fd-200d-2642-fe0f.svg","man_vampire_tone4":"1f9db-1f3fe-200d-2642-fe0f.svg","man_vampire_tone5":"1f9db-1f3ff-200d-2642-fe0f.svg","man_walking":"1f6b6-200d-2642-fe0f.svg","man_walking_tone1":"1f6b6-1f3fb-200d-2642-fe0f.svg","man_walking_tone2":"1f6b6-1f3fc-200d-2642-fe0f.svg","man_walking_tone3":"1f6b6-1f3fd-200d-2642-fe0f.svg","man_walking_tone4":"1f6b6-1f3fe-200d-2642-fe0f.svg","man_walking_tone5":"1f6b6-1f3ff-200d-2642-fe0f.svg","man_wearing_turban":"1f473-200d-2642-fe0f.svg","man_wearing_turban_tone1":"1f473-1f3fb-200d-2642-fe0f.svg","man_wearing_turban_tone2":"1f473-1f3fc-200d-2642-fe0f.svg","man_wearing_turban_tone3":"1f473-1f3fd-200d-2642-fe0f.svg","man_wearing_turban_tone4":"1f473-1f3fe-200d-2642-fe0f.svg","man_wearing_turban_tone5":"1f473-1f3ff-200d-2642-fe0f.svg","man_white_haired":"1f468-200d-1f9b3.svg","man_white_haired_tone1":"1f468-1f3fb-200d-1f9b3.svg","man_white_haired_tone2":"1f468-1f3fc-200d-1f9b3.svg","man_white_haired_tone3":"1f468-1f3fd-200d-1f9b3.svg","man_white_haired_tone4":"1f468-1f3fe-200d-1f9b3.svg","man_white_haired_tone5":"1f468-1f3ff-200d-1f9b3.svg","man_with_chinese_cap":"1f472.svg","man_with_chinese_cap_tone1":"1f472-1f3fb.svg","man_with_chinese_cap_tone2":"1f472-1f3fc.svg","man_with_chinese_cap_tone3":"1f472-1f3fd.svg","man_with_chinese_cap_tone4":"1f472-1f3fe.svg","man_with_chinese_cap_tone5":"1f472-1f3ff.svg","man_with_probing_cane":"1f468-200d-1f9af.svg","man_with_probing_cane_tone1":"1f468-1f3fb-200d-1f9af.svg","man_with_probing_cane_tone2":"1f468-1f3fc-200d-1f9af.svg","man_with_probing_cane_tone3":"1f468-1f3fd-200d-1f9af.svg","man_with_probing_cane_tone4":"1f468-1f3fe-200d-1f9af.svg","man_with_probing_cane_tone5":"1f468-1f3ff-200d-1f9af.svg","man_zombie":"1f9df-200d-2642-fe0f.svg","mango":"1f96d.svg","mans_shoe":"1f45e.svg","manual_wheelchair":"1f9bd.svg","map":"1f5fa.svg","maple_leaf":"1f341.svg","martial_arts_uniform":"1f94b.svg","mask":"1f637.svg","mate":"1f9c9.svg","meat_on_bone":"1f356.svg","mechanic":"1f9d1-200d-1f527.svg","mechanic_tone1":"1f9d1-1f3fb-200d-1f527.svg","mechanic_tone2":"1f9d1-1f3fc-200d-1f527.svg","mechanic_tone3":"1f9d1-1f3fd-200d-1f527.svg","mechanic_tone4":"1f9d1-1f3fe-200d-1f527.svg","mechanic_tone5":"1f9d1-1f3ff-200d-1f527.svg","mechanical_arm":"1f9be.svg","mechanical_leg":"1f9bf.svg","medal":"1f3c5.svg","medical_symbol":"2695.svg","mega":"1f4e3.svg","melon":"1f348.svg","men_holding_hands_tone1":"1f46c-1f3fb.svg","men_holding_hands_tone1_tone2":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone1_tone3":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone1_tone4":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone1_tone5":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone2":"1f46c-1f3fc.svg","men_holding_hands_tone2_tone1":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone2_tone3":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone2_tone4":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone2_tone5":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone3":"1f46c-1f3fd.svg","men_holding_hands_tone3_tone1":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone3_tone2":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone3_tone4":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone3_tone5":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone4":"1f46c-1f3fe.svg","men_holding_hands_tone4_tone1":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone4_tone2":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone4_tone3":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone4_tone5":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone5":"1f46c-1f3ff.svg","men_holding_hands_tone5_tone1":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone5_tone2":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone5_tone3":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone5_tone4":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","men_with_bunny_ears_partying":"1f46f-200d-2642-fe0f.svg","men_wrestling":"1f93c-200d-2642-fe0f.svg","menorah":"1f54e.svg","mens":"1f6b9.svg","mermaid":"1f9dc-200d-2640-fe0f.svg","mermaid_tone1":"1f9dc-1f3fb-200d-2640-fe0f.svg","mermaid_tone2":"1f9dc-1f3fc-200d-2640-fe0f.svg","mermaid_tone3":"1f9dc-1f3fd-200d-2640-fe0f.svg","mermaid_tone4":"1f9dc-1f3fe-200d-2640-fe0f.svg","mermaid_tone5":"1f9dc-1f3ff-200d-2640-fe0f.svg","merman":"1f9dc-200d-2642-fe0f.svg","merman_tone1":"1f9dc-1f3fb-200d-2642-fe0f.svg","merman_tone2":"1f9dc-1f3fc-200d-2642-fe0f.svg","merman_tone3":"1f9dc-1f3fd-200d-2642-fe0f.svg","merman_tone4":"1f9dc-1f3fe-200d-2642-fe0f.svg","merman_tone5":"1f9dc-1f3ff-200d-2642-fe0f.svg","merperson":"1f9dc.svg","merperson_tone1":"1f9dc-1f3fb.svg","merperson_tone2":"1f9dc-1f3fc.svg","merperson_tone3":"1f9dc-1f3fd.svg","merperson_tone4":"1f9dc-1f3fe.svg","merperson_tone5":"1f9dc-1f3ff.svg","metal":"1f918.svg","metal_tone1":"1f918-1f3fb.svg","metal_tone2":"1f918-1f3fc.svg","metal_tone3":"1f918-1f3fd.svg","metal_tone4":"1f918-1f3fe.svg","metal_tone5":"1f918-1f3ff.svg","metro":"1f687.svg","microbe":"1f9a0.svg","microphone2":"1f399.svg","microphone":"1f3a4.svg","microscope":"1f52c.svg","middle_finger":"1f595.svg","middle_finger_tone1":"1f595-1f3fb.svg","middle_finger_tone2":"1f595-1f3fc.svg","middle_finger_tone3":"1f595-1f3fd.svg","middle_finger_tone4":"1f595-1f3fe.svg","middle_finger_tone5":"1f595-1f3ff.svg","military_medal":"1f396.svg","milk":"1f95b.svg","milky_way":"1f30c.svg","minibus":"1f690.svg","minidisc":"1f4bd.svg","mobile_phone":"1f4f1.svg","mobile_phone_off":"1f4f4.svg","money_mouth":"1f911.svg","money_with_wings":"1f4b8.svg","moneybag":"1f4b0.svg","monkey":"1f412.svg","monkey_face":"1f435.svg","monorail":"1f69d.svg","moon_cake":"1f96e.svg","mortar_board":"1f393.svg","mosque":"1f54c.svg","mosquito":"1f99f.svg","motor_scooter":"1f6f5.svg","motorboat":"1f6e5.svg","motorcycle":"1f3cd.svg","motorized_wheelchair":"1f9bc.svg","motorway":"1f6e3.svg","mount_fuji":"1f5fb.svg","mountain":"26f0.svg","mountain_cableway":"1f6a0.svg","mountain_railway":"1f69e.svg","mountain_snow":"1f3d4.svg","mouse2":"1f401.svg","mouse":"1f42d.svg","mouse_three_button":"1f5b1.svg","movie_camera":"1f3a5.svg","moyai":"1f5ff.svg","mrs_claus":"1f936.svg","mrs_claus_tone1":"1f936-1f3fb.svg","mrs_claus_tone2":"1f936-1f3fc.svg","mrs_claus_tone3":"1f936-1f3fd.svg","mrs_claus_tone4":"1f936-1f3fe.svg","mrs_claus_tone5":"1f936-1f3ff.svg","muscle":"1f4aa.svg","muscle_tone1":"1f4aa-1f3fb.svg","muscle_tone2":"1f4aa-1f3fc.svg","muscle_tone3":"1f4aa-1f3fd.svg","muscle_tone4":"1f4aa-1f3fe.svg","muscle_tone5":"1f4aa-1f3ff.svg","mushroom":"1f344.svg","musical_keyboard":"1f3b9.svg","musical_note":"1f3b5.svg","musical_score":"1f3bc.svg","mute":"1f507.svg","nail_care":"1f485.svg","nail_care_tone1":"1f485-1f3fb.svg","nail_care_tone2":"1f485-1f3fc.svg","nail_care_tone3":"1f485-1f3fd.svg","nail_care_tone4":"1f485-1f3fe.svg","nail_care_tone5":"1f485-1f3ff.svg","name_badge":"1f4db.svg","nauseated_face":"1f922.svg","nazar_amulet":"1f9ff.svg","necktie":"1f454.svg","negative_squared_cross_mark":"274e.svg","nerd":"1f913.svg","neutral_face":"1f610.svg","new":"1f195.svg","new_moon":"1f311.svg","new_moon_with_face":"1f31a.svg","newspaper2":"1f5de.svg","newspaper":"1f4f0.svg","ng":"1f196.svg","night_with_stars":"1f303.svg","nine":"39-20e3.svg","no_bell":"1f515.svg","no_bicycles":"1f6b3.svg","no_entry":"26d4.svg","no_entry_sign":"1f6ab.svg","no_mobile_phones":"1f4f5.svg","no_mouth":"1f636.svg","no_pedestrians":"1f6b7.svg","no_smoking":"1f6ad.svg","non-potable_water":"1f6b1.svg","nose":"1f443.svg","nose_tone1":"1f443-1f3fb.svg","nose_tone2":"1f443-1f3fc.svg","nose_tone3":"1f443-1f3fd.svg","nose_tone4":"1f443-1f3fe.svg","nose_tone5":"1f443-1f3ff.svg","notebook":"1f4d3.svg","notebook_with_decorative_cover":"1f4d4.svg","notepad_spiral":"1f5d2.svg","notes":"1f3b6.svg","nut_and_bolt":"1f529.svg","o2":"1f17e.svg","o":"2b55.svg","ocean":"1f30a.svg","octagonal_sign":"1f6d1.svg","octopus":"1f419.svg","oden":"1f362.svg","office":"1f3e2.svg","office_worker":"1f9d1-200d-1f4bc.svg","office_worker_tone1":"1f9d1-1f3fb-200d-1f4bc.svg","office_worker_tone2":"1f9d1-1f3fc-200d-1f4bc.svg","office_worker_tone3":"1f9d1-1f3fd-200d-1f4bc.svg","office_worker_tone4":"1f9d1-1f3fe-200d-1f4bc.svg","office_worker_tone5":"1f9d1-1f3ff-200d-1f4bc.svg","oil":"1f6e2.svg","ok":"1f197.svg","ok_hand":"1f44c.svg","ok_hand_tone1":"1f44c-1f3fb.svg","ok_hand_tone2":"1f44c-1f3fc.svg","ok_hand_tone3":"1f44c-1f3fd.svg","ok_hand_tone4":"1f44c-1f3fe.svg","ok_hand_tone5":"1f44c-1f3ff.svg","older_adult":"1f9d3.svg","older_adult_tone1":"1f9d3-1f3fb.svg","older_adult_tone2":"1f9d3-1f3fc.svg","older_adult_tone3":"1f9d3-1f3fd.svg","older_adult_tone4":"1f9d3-1f3fe.svg","older_adult_tone5":"1f9d3-1f3ff.svg","older_man":"1f474.svg","older_man_tone1":"1f474-1f3fb.svg","older_man_tone2":"1f474-1f3fc.svg","older_man_tone3":"1f474-1f3fd.svg","older_man_tone4":"1f474-1f3fe.svg","older_man_tone5":"1f474-1f3ff.svg","older_woman":"1f475.svg","older_woman_tone1":"1f475-1f3fb.svg","older_woman_tone2":"1f475-1f3fc.svg","older_woman_tone3":"1f475-1f3fd.svg","older_woman_tone4":"1f475-1f3fe.svg","older_woman_tone5":"1f475-1f3ff.svg","om_symbol":"1f549.svg","on":"1f51b.svg","oncoming_automobile":"1f698.svg","oncoming_bus":"1f68d.svg","oncoming_police_car":"1f694.svg","oncoming_taxi":"1f696.svg","one":"31-20e3.svg","one_piece_swimsuit":"1fa71.svg","onion":"1f9c5.svg","open_file_folder":"1f4c2.svg","open_hands":"1f450.svg","open_hands_tone1":"1f450-1f3fb.svg","open_hands_tone2":"1f450-1f3fc.svg","open_hands_tone3":"1f450-1f3fd.svg","open_hands_tone4":"1f450-1f3fe.svg","open_hands_tone5":"1f450-1f3ff.svg","open_mouth":"1f62e.svg","ophiuchus":"26ce.svg","orange_book":"1f4d9.svg","orange_circle":"1f7e0.svg","orange_heart":"1f9e1.svg","orange_square":"1f7e7.svg","orangutan":"1f9a7.svg","orthodox_cross":"2626.svg","otter":"1f9a6.svg","outbox_tray":"1f4e4.svg","owl":"1f989.svg","ox":"1f402.svg","oyster":"1f9aa.svg","package":"1f4e6.svg","page_facing_up":"1f4c4.svg","page_with_curl":"1f4c3.svg","pager":"1f4df.svg","paintbrush":"1f58c.svg","palm_tree":"1f334.svg","palms_up_together":"1f932.svg","palms_up_together_tone1":"1f932-1f3fb.svg","palms_up_together_tone2":"1f932-1f3fc.svg","palms_up_together_tone3":"1f932-1f3fd.svg","palms_up_together_tone4":"1f932-1f3fe.svg","palms_up_together_tone5":"1f932-1f3ff.svg","pancakes":"1f95e.svg","panda_face":"1f43c.svg","paperclip":"1f4ce.svg","paperclips":"1f587.svg","parachute":"1fa82.svg","park":"1f3de.svg","parking":"1f17f.svg","parrot":"1f99c.svg","part_alternation_mark":"303d.svg","partly_sunny":"26c5.svg","partying_face":"1f973.svg","passport_control":"1f6c2.svg","pause_button":"23f8.svg","peace":"262e.svg","peach":"1f351.svg","peacock":"1f99a.svg","peanuts":"1f95c.svg","pear":"1f350.svg","pen_ballpoint":"1f58a.svg","pen_fountain":"1f58b.svg","pencil2":"270f.svg","pencil":"1f4dd.svg","penguin":"1f427.svg","pensive":"1f614.svg","people_holding_hands":"1f9d1-200d-1f91d-200d-1f9d1.svg","people_holding_hands_tone1":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone1_tone2":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone1_tone3":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone1_tone4":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone1_tone5":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone2":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone2_tone1":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone2_tone3":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone2_tone4":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone2_tone5":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone3":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone3_tone1":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone3_tone2":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone3_tone4":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone3_tone5":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone4":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone4_tone1":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone4_tone2":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone4_tone3":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone4_tone5":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5_tone1":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone5_tone2":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone5_tone3":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone5_tone4":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe.svg","people_with_bunny_ears_partying":"1f46f.svg","people_wrestling":"1f93c.svg","performing_arts":"1f3ad.svg","persevere":"1f623.svg","person_bald":"1f9d1-200d-1f9b2.svg","person_biking":"1f6b4.svg","person_biking_tone1":"1f6b4-1f3fb.svg","person_biking_tone2":"1f6b4-1f3fc.svg","person_biking_tone3":"1f6b4-1f3fd.svg","person_biking_tone4":"1f6b4-1f3fe.svg","person_biking_tone5":"1f6b4-1f3ff.svg","person_bouncing_ball":"26f9.svg","person_bouncing_ball_tone1":"26f9-1f3fb.svg","person_bouncing_ball_tone2":"26f9-1f3fc.svg","person_bouncing_ball_tone3":"26f9-1f3fd.svg","person_bouncing_ball_tone4":"26f9-1f3fe.svg","person_bouncing_ball_tone5":"26f9-1f3ff.svg","person_bowing":"1f647.svg","person_bowing_tone1":"1f647-1f3fb.svg","person_bowing_tone2":"1f647-1f3fc.svg","person_bowing_tone3":"1f647-1f3fd.svg","person_bowing_tone4":"1f647-1f3fe.svg","person_bowing_tone5":"1f647-1f3ff.svg","person_climbing":"1f9d7.svg","person_climbing_tone1":"1f9d7-1f3fb.svg","person_climbing_tone2":"1f9d7-1f3fc.svg","person_climbing_tone3":"1f9d7-1f3fd.svg","person_climbing_tone4":"1f9d7-1f3fe.svg","person_climbing_tone5":"1f9d7-1f3ff.svg","person_curly_hair":"1f9d1-200d-1f9b1.svg","person_doing_cartwheel":"1f938.svg","person_doing_cartwheel_tone1":"1f938-1f3fb.svg","person_doing_cartwheel_tone2":"1f938-1f3fc.svg","person_doing_cartwheel_tone3":"1f938-1f3fd.svg","person_doing_cartwheel_tone4":"1f938-1f3fe.svg","person_doing_cartwheel_tone5":"1f938-1f3ff.svg","person_facepalming":"1f926.svg","person_facepalming_tone1":"1f926-1f3fb.svg","person_facepalming_tone2":"1f926-1f3fc.svg","person_facepalming_tone3":"1f926-1f3fd.svg","person_facepalming_tone4":"1f926-1f3fe.svg","person_facepalming_tone5":"1f926-1f3ff.svg","person_fencing":"1f93a.svg","person_frowning":"1f64d.svg","person_frowning_tone1":"1f64d-1f3fb.svg","person_frowning_tone2":"1f64d-1f3fc.svg","person_frowning_tone3":"1f64d-1f3fd.svg","person_frowning_tone4":"1f64d-1f3fe.svg","person_frowning_tone5":"1f64d-1f3ff.svg","person_gesturing_no":"1f645.svg","person_gesturing_no_tone1":"1f645-1f3fb.svg","person_gesturing_no_tone2":"1f645-1f3fc.svg","person_gesturing_no_tone3":"1f645-1f3fd.svg","person_gesturing_no_tone4":"1f645-1f3fe.svg","person_gesturing_no_tone5":"1f645-1f3ff.svg","person_gesturing_ok":"1f646.svg","person_gesturing_ok_tone1":"1f646-1f3fb.svg","person_gesturing_ok_tone2":"1f646-1f3fc.svg","person_gesturing_ok_tone3":"1f646-1f3fd.svg","person_gesturing_ok_tone4":"1f646-1f3fe.svg","person_gesturing_ok_tone5":"1f646-1f3ff.svg","person_getting_haircut":"1f487.svg","person_getting_haircut_tone1":"1f487-1f3fb.svg","person_getting_haircut_tone2":"1f487-1f3fc.svg","person_getting_haircut_tone3":"1f487-1f3fd.svg","person_getting_haircut_tone4":"1f487-1f3fe.svg","person_getting_haircut_tone5":"1f487-1f3ff.svg","person_getting_massage":"1f486.svg","person_getting_massage_tone1":"1f486-1f3fb.svg","person_getting_massage_tone2":"1f486-1f3fc.svg","person_getting_massage_tone3":"1f486-1f3fd.svg","person_getting_massage_tone4":"1f486-1f3fe.svg","person_getting_massage_tone5":"1f486-1f3ff.svg","person_golfing":"1f3cc.svg","person_golfing_tone1":"1f3cc-1f3fb.svg","person_golfing_tone2":"1f3cc-1f3fc.svg","person_golfing_tone3":"1f3cc-1f3fd.svg","person_golfing_tone4":"1f3cc-1f3fe.svg","person_golfing_tone5":"1f3cc-1f3ff.svg","person_in_bed_tone1":"1f6cc-1f3fb.svg","person_in_bed_tone2":"1f6cc-1f3fc.svg","person_in_bed_tone3":"1f6cc-1f3fd.svg","person_in_bed_tone4":"1f6cc-1f3fe.svg","person_in_bed_tone5":"1f6cc-1f3ff.svg","person_in_lotus_position":"1f9d8.svg","person_in_lotus_position_tone1":"1f9d8-1f3fb.svg","person_in_lotus_position_tone2":"1f9d8-1f3fc.svg","person_in_lotus_position_tone3":"1f9d8-1f3fd.svg","person_in_lotus_position_tone4":"1f9d8-1f3fe.svg","person_in_lotus_position_tone5":"1f9d8-1f3ff.svg","person_in_manual_wheelchair":"1f9d1-200d-1f9bd.svg","person_in_manual_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bd.svg","person_in_manual_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bd.svg","person_in_manual_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bd.svg","person_in_manual_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bd.svg","person_in_manual_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bd.svg","person_in_motorized_wheelchair":"1f9d1-200d-1f9bc.svg","person_in_motorized_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bc.svg","person_in_motorized_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bc.svg","person_in_motorized_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bc.svg","person_in_motorized_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bc.svg","person_in_motorized_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bc.svg","person_in_steamy_room":"1f9d6.svg","person_in_steamy_room_tone1":"1f9d6-1f3fb.svg","person_in_steamy_room_tone2":"1f9d6-1f3fc.svg","person_in_steamy_room_tone3":"1f9d6-1f3fd.svg","person_in_steamy_room_tone4":"1f9d6-1f3fe.svg","person_in_steamy_room_tone5":"1f9d6-1f3ff.svg","person_juggling":"1f939.svg","person_juggling_tone1":"1f939-1f3fb.svg","person_juggling_tone2":"1f939-1f3fc.svg","person_juggling_tone3":"1f939-1f3fd.svg","person_juggling_tone4":"1f939-1f3fe.svg","person_juggling_tone5":"1f939-1f3ff.svg","person_kneeling":"1f9ce.svg","person_kneeling_tone1":"1f9ce-1f3fb.svg","person_kneeling_tone2":"1f9ce-1f3fc.svg","person_kneeling_tone3":"1f9ce-1f3fd.svg","person_kneeling_tone4":"1f9ce-1f3fe.svg","person_kneeling_tone5":"1f9ce-1f3ff.svg","person_lifting_weights":"1f3cb.svg","person_lifting_weights_tone1":"1f3cb-1f3fb.svg","person_lifting_weights_tone2":"1f3cb-1f3fc.svg","person_lifting_weights_tone3":"1f3cb-1f3fd.svg","person_lifting_weights_tone4":"1f3cb-1f3fe.svg","person_lifting_weights_tone5":"1f3cb-1f3ff.svg","person_mountain_biking":"1f6b5.svg","person_mountain_biking_tone1":"1f6b5-1f3fb.svg","person_mountain_biking_tone2":"1f6b5-1f3fc.svg","person_mountain_biking_tone3":"1f6b5-1f3fd.svg","person_mountain_biking_tone4":"1f6b5-1f3fe.svg","person_mountain_biking_tone5":"1f6b5-1f3ff.svg","person_playing_handball":"1f93e.svg","person_playing_handball_tone1":"1f93e-1f3fb.svg","person_playing_handball_tone2":"1f93e-1f3fc.svg","person_playing_handball_tone3":"1f93e-1f3fd.svg","person_playing_handball_tone4":"1f93e-1f3fe.svg","person_playing_handball_tone5":"1f93e-1f3ff.svg","person_playing_water_polo":"1f93d.svg","person_playing_water_polo_tone1":"1f93d-1f3fb.svg","person_playing_water_polo_tone2":"1f93d-1f3fc.svg","person_playing_water_polo_tone3":"1f93d-1f3fd.svg","person_playing_water_polo_tone4":"1f93d-1f3fe.svg","person_playing_water_polo_tone5":"1f93d-1f3ff.svg","person_pouting":"1f64e.svg","person_pouting_tone1":"1f64e-1f3fb.svg","person_pouting_tone2":"1f64e-1f3fc.svg","person_pouting_tone3":"1f64e-1f3fd.svg","person_pouting_tone4":"1f64e-1f3fe.svg","person_pouting_tone5":"1f64e-1f3ff.svg","person_raising_hand":"1f64b.svg","person_raising_hand_tone1":"1f64b-1f3fb.svg","person_raising_hand_tone2":"1f64b-1f3fc.svg","person_raising_hand_tone3":"1f64b-1f3fd.svg","person_raising_hand_tone4":"1f64b-1f3fe.svg","person_raising_hand_tone5":"1f64b-1f3ff.svg","person_red_hair":"1f9d1-200d-1f9b0.svg","person_rowing_boat":"1f6a3.svg","person_rowing_boat_tone1":"1f6a3-1f3fb.svg","person_rowing_boat_tone2":"1f6a3-1f3fc.svg","person_rowing_boat_tone3":"1f6a3-1f3fd.svg","person_rowing_boat_tone4":"1f6a3-1f3fe.svg","person_rowing_boat_tone5":"1f6a3-1f3ff.svg","person_running":"1f3c3.svg","person_running_tone1":"1f3c3-1f3fb.svg","person_running_tone2":"1f3c3-1f3fc.svg","person_running_tone3":"1f3c3-1f3fd.svg","person_running_tone4":"1f3c3-1f3fe.svg","person_running_tone5":"1f3c3-1f3ff.svg","person_shrugging":"1f937.svg","person_shrugging_tone1":"1f937-1f3fb.svg","person_shrugging_tone2":"1f937-1f3fc.svg","person_shrugging_tone3":"1f937-1f3fd.svg","person_shrugging_tone4":"1f937-1f3fe.svg","person_shrugging_tone5":"1f937-1f3ff.svg","person_standing":"1f9cd.svg","person_standing_tone1":"1f9cd-1f3fb.svg","person_standing_tone2":"1f9cd-1f3fc.svg","person_standing_tone3":"1f9cd-1f3fd.svg","person_standing_tone4":"1f9cd-1f3fe.svg","person_standing_tone5":"1f9cd-1f3ff.svg","person_surfing":"1f3c4.svg","person_surfing_tone1":"1f3c4-1f3fb.svg","person_surfing_tone2":"1f3c4-1f3fc.svg","person_surfing_tone3":"1f3c4-1f3fd.svg","person_surfing_tone4":"1f3c4-1f3fe.svg","person_surfing_tone5":"1f3c4-1f3ff.svg","person_swimming":"1f3ca.svg","person_swimming_tone1":"1f3ca-1f3fb.svg","person_swimming_tone2":"1f3ca-1f3fc.svg","person_swimming_tone3":"1f3ca-1f3fd.svg","person_swimming_tone4":"1f3ca-1f3fe.svg","person_swimming_tone5":"1f3ca-1f3ff.svg","person_tipping_hand":"1f481.svg","person_tipping_hand_tone1":"1f481-1f3fb.svg","person_tipping_hand_tone2":"1f481-1f3fc.svg","person_tipping_hand_tone3":"1f481-1f3fd.svg","person_tipping_hand_tone4":"1f481-1f3fe.svg","person_tipping_hand_tone5":"1f481-1f3ff.svg","person_tone1_bald":"1f9d1-1f3fb-200d-1f9b2.svg","person_tone1_curly_hair":"1f9d1-1f3fb-200d-1f9b1.svg","person_tone1_red_hair":"1f9d1-1f3fb-200d-1f9b0.svg","person_tone1_white_hair":"1f9d1-1f3fb-200d-1f9b3.svg","person_tone2_bald":"1f9d1-1f3fc-200d-1f9b2.svg","person_tone2_curly_hair":"1f9d1-1f3fc-200d-1f9b1.svg","person_tone2_red_hair":"1f9d1-1f3fc-200d-1f9b0.svg","person_tone2_white_hair":"1f9d1-1f3fc-200d-1f9b3.svg","person_tone3_bald":"1f9d1-1f3fd-200d-1f9b2.svg","person_tone3_curly_hair":"1f9d1-1f3fd-200d-1f9b1.svg","person_tone3_red_hair":"1f9d1-1f3fd-200d-1f9b0.svg","person_tone3_white_hair":"1f9d1-1f3fd-200d-1f9b3.svg","person_tone4_bald":"1f9d1-1f3fe-200d-1f9b2.svg","person_tone4_curly_hair":"1f9d1-1f3fe-200d-1f9b1.svg","person_tone4_red_hair":"1f9d1-1f3fe-200d-1f9b0.svg","person_tone4_white_hair":"1f9d1-1f3fe-200d-1f9b3.svg","person_tone5_bald":"1f9d1-1f3ff-200d-1f9b2.svg","person_tone5_curly_hair":"1f9d1-1f3ff-200d-1f9b1.svg","person_tone5_red_hair":"1f9d1-1f3ff-200d-1f9b0.svg","person_tone5_white_hair":"1f9d1-1f3ff-200d-1f9b3.svg","person_walking":"1f6b6.svg","person_walking_tone1":"1f6b6-1f3fb.svg","person_walking_tone2":"1f6b6-1f3fc.svg","person_walking_tone3":"1f6b6-1f3fd.svg","person_walking_tone4":"1f6b6-1f3fe.svg","person_walking_tone5":"1f6b6-1f3ff.svg","person_wearing_turban":"1f473.svg","person_wearing_turban_tone1":"1f473-1f3fb.svg","person_wearing_turban_tone2":"1f473-1f3fc.svg","person_wearing_turban_tone3":"1f473-1f3fd.svg","person_wearing_turban_tone4":"1f473-1f3fe.svg","person_wearing_turban_tone5":"1f473-1f3ff.svg","person_white_hair":"1f9d1-200d-1f9b3.svg","person_with_probing_cane":"1f9d1-200d-1f9af.svg","person_with_probing_cane_tone1":"1f9d1-1f3fb-200d-1f9af.svg","person_with_probing_cane_tone2":"1f9d1-1f3fc-200d-1f9af.svg","person_with_probing_cane_tone3":"1f9d1-1f3fd-200d-1f9af.svg","person_with_probing_cane_tone4":"1f9d1-1f3fe-200d-1f9af.svg","person_with_probing_cane_tone5":"1f9d1-1f3ff-200d-1f9af.svg","petri_dish":"1f9eb.svg","pick":"26cf.svg","pie":"1f967.svg","pig2":"1f416.svg","pig":"1f437.svg","pig_nose":"1f43d.svg","pill":"1f48a.svg","pilot":"1f9d1-200d-2708-fe0f.svg","pilot_tone1":"1f9d1-1f3fb-200d-2708-fe0f.svg","pilot_tone2":"1f9d1-1f3fc-200d-2708-fe0f.svg","pilot_tone3":"1f9d1-1f3fd-200d-2708-fe0f.svg","pilot_tone4":"1f9d1-1f3fe-200d-2708-fe0f.svg","pilot_tone5":"1f9d1-1f3ff-200d-2708-fe0f.svg","pinching_hand":"1f90f.svg","pinching_hand_tone1":"1f90f-1f3fb.svg","pinching_hand_tone2":"1f90f-1f3fc.svg","pinching_hand_tone3":"1f90f-1f3fd.svg","pinching_hand_tone4":"1f90f-1f3fe.svg","pinching_hand_tone5":"1f90f-1f3ff.svg","pineapple":"1f34d.svg","ping_pong":"1f3d3.svg","pirate_flag":"1f3f4-200d-2620-fe0f.svg","pisces":"2653.svg","pizza":"1f355.svg","place_of_worship":"1f6d0.svg","play_pause":"23ef.svg","pleading_face":"1f97a.svg","point_down":"1f447.svg","point_down_tone1":"1f447-1f3fb.svg","point_down_tone2":"1f447-1f3fc.svg","point_down_tone3":"1f447-1f3fd.svg","point_down_tone4":"1f447-1f3fe.svg","point_down_tone5":"1f447-1f3ff.svg","point_left":"1f448.svg","point_left_tone1":"1f448-1f3fb.svg","point_left_tone2":"1f448-1f3fc.svg","point_left_tone3":"1f448-1f3fd.svg","point_left_tone4":"1f448-1f3fe.svg","point_left_tone5":"1f448-1f3ff.svg","point_right":"1f449.svg","point_right_tone1":"1f449-1f3fb.svg","point_right_tone2":"1f449-1f3fc.svg","point_right_tone3":"1f449-1f3fd.svg","point_right_tone4":"1f449-1f3fe.svg","point_right_tone5":"1f449-1f3ff.svg","point_up":"261d.svg","point_up_2":"1f446.svg","point_up_2_tone1":"1f446-1f3fb.svg","point_up_2_tone2":"1f446-1f3fc.svg","point_up_2_tone3":"1f446-1f3fd.svg","point_up_2_tone4":"1f446-1f3fe.svg","point_up_2_tone5":"1f446-1f3ff.svg","point_up_tone1":"261d-1f3fb.svg","point_up_tone2":"261d-1f3fc.svg","point_up_tone3":"261d-1f3fd.svg","point_up_tone4":"261d-1f3fe.svg","point_up_tone5":"261d-1f3ff.svg","police_car":"1f693.svg","police_officer":"1f46e.svg","police_officer_tone1":"1f46e-1f3fb.svg","police_officer_tone2":"1f46e-1f3fc.svg","police_officer_tone3":"1f46e-1f3fd.svg","police_officer_tone4":"1f46e-1f3fe.svg","police_officer_tone5":"1f46e-1f3ff.svg","poodle":"1f429.svg","poop":"1f4a9.svg","popcorn":"1f37f.svg","post_office":"1f3e3.svg","postal_horn":"1f4ef.svg","postbox":"1f4ee.svg","potable_water":"1f6b0.svg","potato":"1f954.svg","pouch":"1f45d.svg","poultry_leg":"1f357.svg","pound":"1f4b7.svg","pouting_cat":"1f63e.svg","pray":"1f64f.svg","pray_tone1":"1f64f-1f3fb.svg","pray_tone2":"1f64f-1f3fc.svg","pray_tone3":"1f64f-1f3fd.svg","pray_tone4":"1f64f-1f3fe.svg","pray_tone5":"1f64f-1f3ff.svg","prayer_beads":"1f4ff.svg","pregnant_woman":"1f930.svg","pregnant_woman_tone1":"1f930-1f3fb.svg","pregnant_woman_tone2":"1f930-1f3fc.svg","pregnant_woman_tone3":"1f930-1f3fd.svg","pregnant_woman_tone4":"1f930-1f3fe.svg","pregnant_woman_tone5":"1f930-1f3ff.svg","pretzel":"1f968.svg","prince":"1f934.svg","prince_tone1":"1f934-1f3fb.svg","prince_tone2":"1f934-1f3fc.svg","prince_tone3":"1f934-1f3fd.svg","prince_tone4":"1f934-1f3fe.svg","prince_tone5":"1f934-1f3ff.svg","princess":"1f478.svg","princess_tone1":"1f478-1f3fb.svg","princess_tone2":"1f478-1f3fc.svg","princess_tone3":"1f478-1f3fd.svg","princess_tone4":"1f478-1f3fe.svg","princess_tone5":"1f478-1f3ff.svg","printer":"1f5a8.svg","probing_cane":"1f9af.svg","projector":"1f4fd.svg","punch":"1f44a.svg","punch_tone1":"1f44a-1f3fb.svg","punch_tone2":"1f44a-1f3fc.svg","punch_tone3":"1f44a-1f3fd.svg","punch_tone4":"1f44a-1f3fe.svg","punch_tone5":"1f44a-1f3ff.svg","purple_circle":"1f7e3.svg","purple_heart":"1f49c.svg","purple_square":"1f7ea.svg","purse":"1f45b.svg","pushpin":"1f4cc.svg","put_litter_in_its_place":"1f6ae.svg","question":"2753.svg","rabbit2":"1f407.svg","rabbit":"1f430.svg","raccoon":"1f99d.svg","race_car":"1f3ce.svg","racehorse":"1f40e.svg","radio":"1f4fb.svg","radio_button":"1f518.svg","radioactive":"2622.svg","rage":"1f621.svg","railway_car":"1f683.svg","railway_track":"1f6e4.svg","rainbow":"1f308.svg","rainbow_flag":"1f3f3-fe0f-200d-1f308.svg","raised_back_of_hand":"1f91a.svg","raised_back_of_hand_tone1":"1f91a-1f3fb.svg","raised_back_of_hand_tone2":"1f91a-1f3fc.svg","raised_back_of_hand_tone3":"1f91a-1f3fd.svg","raised_back_of_hand_tone4":"1f91a-1f3fe.svg","raised_back_of_hand_tone5":"1f91a-1f3ff.svg","raised_hand":"270b.svg","raised_hand_tone1":"270b-1f3fb.svg","raised_hand_tone2":"270b-1f3fc.svg","raised_hand_tone3":"270b-1f3fd.svg","raised_hand_tone4":"270b-1f3fe.svg","raised_hand_tone5":"270b-1f3ff.svg","raised_hands":"1f64c.svg","raised_hands_tone1":"1f64c-1f3fb.svg","raised_hands_tone2":"1f64c-1f3fc.svg","raised_hands_tone3":"1f64c-1f3fd.svg","raised_hands_tone4":"1f64c-1f3fe.svg","raised_hands_tone5":"1f64c-1f3ff.svg","ram":"1f40f.svg","ramen":"1f35c.svg","rat":"1f400.svg","razor":"1fa92.svg","receipt":"1f9fe.svg","record_button":"23fa.svg","recycle":"267b.svg","red_car":"1f697.svg","red_circle":"1f534.svg","red_envelope":"1f9e7.svg","red_haired":"1f9b0.svg","red_square":"1f7e5.svg","regional_indicator_a":"1f1e6.svg","regional_indicator_b":"1f1e7.svg","regional_indicator_c":"1f1e8.svg","regional_indicator_d":"1f1e9.svg","regional_indicator_e":"1f1ea.svg","regional_indicator_f":"1f1eb.svg","regional_indicator_g":"1f1ec.svg","regional_indicator_h":"1f1ed.svg","regional_indicator_i":"1f1ee.svg","regional_indicator_j":"1f1ef.svg","regional_indicator_k":"1f1f0.svg","regional_indicator_l":"1f1f1.svg","regional_indicator_m":"1f1f2.svg","regional_indicator_n":"1f1f3.svg","regional_indicator_o":"1f1f4.svg","regional_indicator_p":"1f1f5.svg","regional_indicator_q":"1f1f6.svg","regional_indicator_r":"1f1f7.svg","regional_indicator_s":"1f1f8.svg","regional_indicator_t":"1f1f9.svg","regional_indicator_u":"1f1fa.svg","regional_indicator_v":"1f1fb.svg","regional_indicator_w":"1f1fc.svg","regional_indicator_x":"1f1fd.svg","regional_indicator_y":"1f1fe.svg","regional_indicator_z":"1f1ff.svg","registered":"ae.svg","relaxed":"263a.svg","relieved":"1f60c.svg","reminder_ribbon":"1f397.svg","repeat":"1f501.svg","repeat_one":"1f502.svg","restroom":"1f6bb.svg","revolving_hearts":"1f49e.svg","rewind":"23ea.svg","rhino":"1f98f.svg","ribbon":"1f380.svg","rice":"1f35a.svg","rice_ball":"1f359.svg","rice_cracker":"1f358.svg","rice_scene":"1f391.svg","right_facing_fist":"1f91c.svg","right_facing_fist_tone1":"1f91c-1f3fb.svg","right_facing_fist_tone2":"1f91c-1f3fc.svg","right_facing_fist_tone3":"1f91c-1f3fd.svg","right_facing_fist_tone4":"1f91c-1f3fe.svg","right_facing_fist_tone5":"1f91c-1f3ff.svg","ring":"1f48d.svg","ringed_planet":"1fa90.svg","robot":"1f916.svg","rocket":"1f680.svg","rofl":"1f923.svg","roll_of_paper":"1f9fb.svg","roller_coaster":"1f3a2.svg","rolling_eyes":"1f644.svg","rooster":"1f413.svg","rose":"1f339.svg","rosette":"1f3f5.svg","rotating_light":"1f6a8.svg","round_pushpin":"1f4cd.svg","rugby_football":"1f3c9.svg","running_shirt_with_sash":"1f3bd.svg","sa":"1f202.svg","safety_pin":"1f9f7.svg","safety_vest":"1f9ba.svg","sagittarius":"2650.svg","sailboat":"26f5.svg","sake":"1f376.svg","salad":"1f957.svg","salt":"1f9c2.svg","sandal":"1f461.svg","sandwich":"1f96a.svg","santa":"1f385.svg","santa_tone1":"1f385-1f3fb.svg","santa_tone2":"1f385-1f3fc.svg","santa_tone3":"1f385-1f3fd.svg","santa_tone4":"1f385-1f3fe.svg","santa_tone5":"1f385-1f3ff.svg","sari":"1f97b.svg","satellite":"1f4e1.svg","satellite_orbital":"1f6f0.svg","sauropod":"1f995.svg","saxophone":"1f3b7.svg","scales":"2696.svg","scarf":"1f9e3.svg","school":"1f3eb.svg","school_satchel":"1f392.svg","scientist":"1f9d1-200d-1f52c.svg","scientist_tone1":"1f9d1-1f3fb-200d-1f52c.svg","scientist_tone2":"1f9d1-1f3fc-200d-1f52c.svg","scientist_tone3":"1f9d1-1f3fd-200d-1f52c.svg","scientist_tone4":"1f9d1-1f3fe-200d-1f52c.svg","scientist_tone5":"1f9d1-1f3ff-200d-1f52c.svg","scissors":"2702.svg","scooter":"1f6f4.svg","scorpion":"1f982.svg","scorpius":"264f.svg","scotland":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.svg","scream":"1f631.svg","scream_cat":"1f640.svg","scroll":"1f4dc.svg","seat":"1f4ba.svg","second_place":"1f948.svg","secret":"3299.svg","see_no_evil":"1f648.svg","seedling":"1f331.svg","selfie":"1f933.svg","selfie_tone1":"1f933-1f3fb.svg","selfie_tone2":"1f933-1f3fc.svg","selfie_tone3":"1f933-1f3fd.svg","selfie_tone4":"1f933-1f3fe.svg","selfie_tone5":"1f933-1f3ff.svg","service_dog":"1f415-200d-1f9ba.svg","seven":"37-20e3.svg","shallow_pan_of_food":"1f958.svg","shamrock":"2618.svg","shark":"1f988.svg","shaved_ice":"1f367.svg","sheep":"1f411.svg","shell":"1f41a.svg","shibuya":"e50a.svg","shield":"1f6e1.svg","shinto_shrine":"26e9.svg","ship":"1f6a2.svg","shirt":"1f455.svg","shopping_bags":"1f6cd.svg","shopping_cart":"1f6d2.svg","shorts":"1fa73.svg","shower":"1f6bf.svg","shrimp":"1f990.svg","shushing_face":"1f92b.svg","signal_strength":"1f4f6.svg","singer":"1f9d1-200d-1f3a4.svg","singer_tone1":"1f9d1-1f3fb-200d-1f3a4.svg","singer_tone2":"1f9d1-1f3fc-200d-1f3a4.svg","singer_tone3":"1f9d1-1f3fd-200d-1f3a4.svg","singer_tone4":"1f9d1-1f3fe-200d-1f3a4.svg","singer_tone5":"1f9d1-1f3ff-200d-1f3a4.svg","six":"36-20e3.svg","six_pointed_star":"1f52f.svg","skateboard":"1f6f9.svg","ski":"1f3bf.svg","skier":"26f7.svg","skier_tone1":"26f7-1f3fb.svg","skier_tone2":"26f7-1f3fc.svg","skier_tone3":"26f7-1f3fd.svg","skier_tone4":"26f7-1f3fe.svg","skier_tone5":"26f7-1f3ff.svg","skull":"1f480.svg","skull_crossbones":"2620.svg","skunk":"1f9a8.svg","sled":"1f6f7.svg","sleeping":"1f634.svg","sleeping_accommodation":"1f6cc.svg","sleepy":"1f62a.svg","slight_frown":"1f641.svg","slight_smile":"1f642.svg","slot_machine":"1f3b0.svg","sloth":"1f9a5.svg","small_blue_diamond":"1f539.svg","small_orange_diamond":"1f538.svg","small_red_triangle":"1f53a.svg","small_red_triangle_down":"1f53b.svg","smile":"1f604.svg","smile_cat":"1f638.svg","smiley":"1f603.svg","smiley_cat":"1f63a.svg","smiling_face_with_3_hearts":"1f970.svg","smiling_imp":"1f608.svg","smirk":"1f60f.svg","smirk_cat":"1f63c.svg","smoking":"1f6ac.svg","snail":"1f40c.svg","snake":"1f40d.svg","sneezing_face":"1f927.svg","snowboarder":"1f3c2.svg","snowboarder_tone1":"1f3c2-1f3fb.svg","snowboarder_tone2":"1f3c2-1f3fc.svg","snowboarder_tone3":"1f3c2-1f3fd.svg","snowboarder_tone4":"1f3c2-1f3fe.svg","snowboarder_tone5":"1f3c2-1f3ff.svg","snowflake":"2744.svg","snowman2":"2603.svg","snowman":"26c4.svg","soap":"1f9fc.svg","sob":"1f62d.svg","soccer":"26bd.svg","socks":"1f9e6.svg","softball":"1f94e.svg","soon":"1f51c.svg","sos":"1f198.svg","sound":"1f509.svg","space_invader":"1f47e.svg","spades":"2660.svg","spaghetti":"1f35d.svg","sparkle":"2747.svg","sparkler":"1f387.svg","sparkles":"2728.svg","sparkling_heart":"1f496.svg","speak_no_evil":"1f64a.svg","speaker":"1f508.svg","speaking_head":"1f5e3.svg","speech_balloon":"1f4ac.svg","speech_left":"1f5e8.svg","speedboat":"1f6a4.svg","spider":"1f577.svg","spider_web":"1f578.svg","sponge":"1f9fd.svg","spoon":"1f944.svg","squeeze_bottle":"1f9f4.svg","squid":"1f991.svg","stadium":"1f3df.svg","star2":"1f31f.svg","star":"2b50.svg","star_and_crescent":"262a.svg","star_of_david":"2721.svg","star_struck":"1f929.svg","stars":"1f320.svg","station":"1f689.svg","statue_of_liberty":"1f5fd.svg","steam_locomotive":"1f682.svg","stethoscope":"1fa7a.svg","stew":"1f372.svg","stop_button":"23f9.svg","stopwatch":"23f1.svg","straight_ruler":"1f4cf.svg","strawberry":"1f353.svg","stuck_out_tongue":"1f61b.svg","stuck_out_tongue_closed_eyes":"1f61d.svg","stuck_out_tongue_winking_eye":"1f61c.svg","student":"1f9d1-200d-1f393.svg","student_tone1":"1f9d1-1f3fb-200d-1f393.svg","student_tone2":"1f9d1-1f3fc-200d-1f393.svg","student_tone3":"1f9d1-1f3fd-200d-1f393.svg","student_tone4":"1f9d1-1f3fe-200d-1f393.svg","student_tone5":"1f9d1-1f3ff-200d-1f393.svg","stuffed_flatbread":"1f959.svg","sun_with_face":"1f31e.svg","sunflower":"1f33b.svg","sunglasses":"1f60e.svg","sunny":"2600.svg","sunrise":"1f305.svg","sunrise_over_mountains":"1f304.svg","superhero":"1f9b8.svg","superhero_tone1":"1f9b8-1f3fb.svg","superhero_tone2":"1f9b8-1f3fc.svg","superhero_tone3":"1f9b8-1f3fd.svg","superhero_tone4":"1f9b8-1f3fe.svg","superhero_tone5":"1f9b8-1f3ff.svg","supervillain":"1f9b9.svg","supervillain_tone1":"1f9b9-1f3fb.svg","supervillain_tone2":"1f9b9-1f3fc.svg","supervillain_tone3":"1f9b9-1f3fd.svg","supervillain_tone4":"1f9b9-1f3fe.svg","supervillain_tone5":"1f9b9-1f3ff.svg","sushi":"1f363.svg","suspension_railway":"1f69f.svg","swan":"1f9a2.svg","sweat":"1f613.svg","sweat_drops":"1f4a6.svg","sweat_smile":"1f605.svg","sweet_potato":"1f360.svg","symbols":"1f523.svg","synagogue":"1f54d.svg","syringe":"1f489.svg","t_rex":"1f996.svg","taco":"1f32e.svg","tada":"1f389.svg","takeout_box":"1f961.svg","tanabata_tree":"1f38b.svg","tangerine":"1f34a.svg","taurus":"2649.svg","taxi":"1f695.svg","tea":"1f375.svg","teacher":"1f9d1-200d-1f3eb.svg","teacher_tone1":"1f9d1-1f3fb-200d-1f3eb.svg","teacher_tone2":"1f9d1-1f3fc-200d-1f3eb.svg","teacher_tone3":"1f9d1-1f3fd-200d-1f3eb.svg","teacher_tone4":"1f9d1-1f3fe-200d-1f3eb.svg","teacher_tone5":"1f9d1-1f3ff-200d-1f3eb.svg","technologist":"1f9d1-200d-1f4bb.svg","technologist_tone1":"1f9d1-1f3fb-200d-1f4bb.svg","technologist_tone2":"1f9d1-1f3fc-200d-1f4bb.svg","technologist_tone3":"1f9d1-1f3fd-200d-1f4bb.svg","technologist_tone4":"1f9d1-1f3fe-200d-1f4bb.svg","technologist_tone5":"1f9d1-1f3ff-200d-1f4bb.svg","teddy_bear":"1f9f8.svg","telephone":"260e.svg","telephone_receiver":"1f4de.svg","telescope":"1f52d.svg","tennis":"1f3be.svg","tent":"26fa.svg","test_tube":"1f9ea.svg","thermometer":"1f321.svg","thermometer_face":"1f912.svg","thinking":"1f914.svg","third_place":"1f949.svg","thought_balloon":"1f4ad.svg","thread":"1f9f5.svg","three":"33-20e3.svg","thumbsdown":"1f44e.svg","thumbsdown_tone1":"1f44e-1f3fb.svg","thumbsdown_tone2":"1f44e-1f3fc.svg","thumbsdown_tone3":"1f44e-1f3fd.svg","thumbsdown_tone4":"1f44e-1f3fe.svg","thumbsdown_tone5":"1f44e-1f3ff.svg","thumbsup":"1f44d.svg","thumbsup_tone1":"1f44d-1f3fb.svg","thumbsup_tone2":"1f44d-1f3fc.svg","thumbsup_tone3":"1f44d-1f3fd.svg","thumbsup_tone4":"1f44d-1f3fe.svg","thumbsup_tone5":"1f44d-1f3ff.svg","thunder_cloud_rain":"26c8.svg","ticket":"1f3ab.svg","tickets":"1f39f.svg","tiger2":"1f405.svg","tiger":"1f42f.svg","timer":"23f2.svg","tired_face":"1f62b.svg","tm":"2122.svg","toilet":"1f6bd.svg","tokyo_tower":"1f5fc.svg","tomato":"1f345.svg","tone1":"1f3fb.svg","tone2":"1f3fc.svg","tone3":"1f3fd.svg","tone4":"1f3fe.svg","tone5":"1f3ff.svg","tongue":"1f445.svg","toolbox":"1f9f0.svg","tools":"1f6e0.svg","tooth":"1f9b7.svg","top":"1f51d.svg","tophat":"1f3a9.svg","track_next":"23ed.svg","track_previous":"23ee.svg","trackball":"1f5b2.svg","tractor":"1f69c.svg","traffic_light":"1f6a5.svg","train2":"1f686.svg","train":"1f68b.svg","tram":"1f68a.svg","transgender_flag":"1f3f3-fe0f-200d-26a7-fe0f.svg","transgender_sign":"26a7.svg","triangular_flag_on_post":"1f6a9.svg","triangular_ruler":"1f4d0.svg","trident":"1f531.svg","triumph":"1f624.svg","trolleybus":"1f68e.svg","trophy":"1f3c6.svg","tropical_drink":"1f379.svg","tropical_fish":"1f420.svg","truck":"1f69a.svg","trumpet":"1f3ba.svg","tulip":"1f337.svg","tumbler_glass":"1f943.svg","turkey":"1f983.svg","turtle":"1f422.svg","tv":"1f4fa.svg","twisted_rightwards_arrows":"1f500.svg","two":"32-20e3.svg","two_hearts":"1f495.svg","two_men_holding_hands":"1f46c.svg","two_women_holding_hands":"1f46d.svg","u5272":"1f239.svg","u5408":"1f234.svg","u55b6":"1f23a.svg","u6307":"1f22f.svg","u6708":"1f237.svg","u6709":"1f236.svg","u6e80":"1f235.svg","u7121":"1f21a.svg","u7533":"1f238.svg","u7981":"1f232.svg","u7a7a":"1f233.svg","umbrella2":"2602.svg","umbrella":"2614.svg","unamused":"1f612.svg","underage":"1f51e.svg","unicorn":"1f984.svg","united_nations":"1f1fa-1f1f3.svg","unlock":"1f513.svg","up":"1f199.svg","upside_down":"1f643.svg","urn":"26b1.svg","v":"270c.svg","v_tone1":"270c-1f3fb.svg","v_tone2":"270c-1f3fc.svg","v_tone3":"270c-1f3fd.svg","v_tone4":"270c-1f3fe.svg","v_tone5":"270c-1f3ff.svg","vampire":"1f9db.svg","vampire_tone1":"1f9db-1f3fb.svg","vampire_tone2":"1f9db-1f3fc.svg","vampire_tone3":"1f9db-1f3fd.svg","vampire_tone4":"1f9db-1f3fe.svg","vampire_tone5":"1f9db-1f3ff.svg","vertical_traffic_light":"1f6a6.svg","vhs":"1f4fc.svg","vibration_mode":"1f4f3.svg","video_camera":"1f4f9.svg","video_game":"1f3ae.svg","violin":"1f3bb.svg","virgo":"264d.svg","volcano":"1f30b.svg","volleyball":"1f3d0.svg","vs":"1f19a.svg","vulcan":"1f596.svg","vulcan_tone1":"1f596-1f3fb.svg","vulcan_tone2":"1f596-1f3fc.svg","vulcan_tone3":"1f596-1f3fd.svg","vulcan_tone4":"1f596-1f3fe.svg","vulcan_tone5":"1f596-1f3ff.svg","waffle":"1f9c7.svg","wales":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.svg","waning_crescent_moon":"1f318.svg","waning_gibbous_moon":"1f316.svg","warning":"26a0.svg","wastebasket":"1f5d1.svg","watch":"231a.svg","water_buffalo":"1f403.svg","watermelon":"1f349.svg","wave":"1f44b.svg","wave_tone1":"1f44b-1f3fb.svg","wave_tone2":"1f44b-1f3fc.svg","wave_tone3":"1f44b-1f3fd.svg","wave_tone4":"1f44b-1f3fe.svg","wave_tone5":"1f44b-1f3ff.svg","wavy_dash":"3030.svg","waxing_crescent_moon":"1f312.svg","waxing_gibbous_moon":"1f314.svg","wc":"1f6be.svg","weary":"1f629.svg","wedding":"1f492.svg","whale2":"1f40b.svg","whale":"1f433.svg","wheel_of_dharma":"2638.svg","wheelchair":"267f.svg","white_check_mark":"2705.svg","white_circle":"26aa.svg","white_flower":"1f4ae.svg","white_haired":"1f9b3.svg","white_heart":"1f90d.svg","white_large_square":"2b1c.svg","white_medium_small_square":"25fd.svg","white_medium_square":"25fb.svg","white_small_square":"25ab.svg","white_square_button":"1f533.svg","white_sun_cloud":"1f325.svg","white_sun_rain_cloud":"1f326.svg","white_sun_small_cloud":"1f324.svg","wilted_rose":"1f940.svg","wind_blowing_face":"1f32c.svg","wind_chime":"1f390.svg","wine_glass":"1f377.svg","wink":"1f609.svg","wolf":"1f43a.svg","woman":"1f469.svg","woman_and_man_holding_hands_tone1":"1f46b-1f3fb.svg","woman_and_man_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone2":"1f46b-1f3fc.svg","woman_and_man_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone3":"1f46b-1f3fd.svg","woman_and_man_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone4":"1f46b-1f3fe.svg","woman_and_man_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone5":"1f46b-1f3ff.svg","woman_and_man_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","woman_artist":"1f469-200d-1f3a8.svg","woman_artist_tone1":"1f469-1f3fb-200d-1f3a8.svg","woman_artist_tone2":"1f469-1f3fc-200d-1f3a8.svg","woman_artist_tone3":"1f469-1f3fd-200d-1f3a8.svg","woman_artist_tone4":"1f469-1f3fe-200d-1f3a8.svg","woman_artist_tone5":"1f469-1f3ff-200d-1f3a8.svg","woman_astronaut":"1f469-200d-1f680.svg","woman_astronaut_tone1":"1f469-1f3fb-200d-1f680.svg","woman_astronaut_tone2":"1f469-1f3fc-200d-1f680.svg","woman_astronaut_tone3":"1f469-1f3fd-200d-1f680.svg","woman_astronaut_tone4":"1f469-1f3fe-200d-1f680.svg","woman_astronaut_tone5":"1f469-1f3ff-200d-1f680.svg","woman_bald":"1f469-200d-1f9b2.svg","woman_bald_tone1":"1f469-1f3fb-200d-1f9b2.svg","woman_bald_tone2":"1f469-1f3fc-200d-1f9b2.svg","woman_bald_tone3":"1f469-1f3fd-200d-1f9b2.svg","woman_bald_tone4":"1f469-1f3fe-200d-1f9b2.svg","woman_bald_tone5":"1f469-1f3ff-200d-1f9b2.svg","woman_biking":"1f6b4-200d-2640-fe0f.svg","woman_biking_tone1":"1f6b4-1f3fb-200d-2640-fe0f.svg","woman_biking_tone2":"1f6b4-1f3fc-200d-2640-fe0f.svg","woman_biking_tone3":"1f6b4-1f3fd-200d-2640-fe0f.svg","woman_biking_tone4":"1f6b4-1f3fe-200d-2640-fe0f.svg","woman_biking_tone5":"1f6b4-1f3ff-200d-2640-fe0f.svg","woman_bouncing_ball":"26f9-fe0f-200d-2640-fe0f.svg","woman_bouncing_ball_tone1":"26f9-1f3fb-200d-2640-fe0f.svg","woman_bouncing_ball_tone2":"26f9-1f3fc-200d-2640-fe0f.svg","woman_bouncing_ball_tone3":"26f9-1f3fd-200d-2640-fe0f.svg","woman_bouncing_ball_tone4":"26f9-1f3fe-200d-2640-fe0f.svg","woman_bouncing_ball_tone5":"26f9-1f3ff-200d-2640-fe0f.svg","woman_bowing":"1f647-200d-2640-fe0f.svg","woman_bowing_tone1":"1f647-1f3fb-200d-2640-fe0f.svg","woman_bowing_tone2":"1f647-1f3fc-200d-2640-fe0f.svg","woman_bowing_tone3":"1f647-1f3fd-200d-2640-fe0f.svg","woman_bowing_tone4":"1f647-1f3fe-200d-2640-fe0f.svg","woman_bowing_tone5":"1f647-1f3ff-200d-2640-fe0f.svg","woman_cartwheeling":"1f938-200d-2640-fe0f.svg","woman_cartwheeling_tone1":"1f938-1f3fb-200d-2640-fe0f.svg","woman_cartwheeling_tone2":"1f938-1f3fc-200d-2640-fe0f.svg","woman_cartwheeling_tone3":"1f938-1f3fd-200d-2640-fe0f.svg","woman_cartwheeling_tone4":"1f938-1f3fe-200d-2640-fe0f.svg","woman_cartwheeling_tone5":"1f938-1f3ff-200d-2640-fe0f.svg","woman_climbing":"1f9d7-200d-2640-fe0f.svg","woman_climbing_tone1":"1f9d7-1f3fb-200d-2640-fe0f.svg","woman_climbing_tone2":"1f9d7-1f3fc-200d-2640-fe0f.svg","woman_climbing_tone3":"1f9d7-1f3fd-200d-2640-fe0f.svg","woman_climbing_tone4":"1f9d7-1f3fe-200d-2640-fe0f.svg","woman_climbing_tone5":"1f9d7-1f3ff-200d-2640-fe0f.svg","woman_construction_worker":"1f477-200d-2640-fe0f.svg","woman_construction_worker_tone1":"1f477-1f3fb-200d-2640-fe0f.svg","woman_construction_worker_tone2":"1f477-1f3fc-200d-2640-fe0f.svg","woman_construction_worker_tone3":"1f477-1f3fd-200d-2640-fe0f.svg","woman_construction_worker_tone4":"1f477-1f3fe-200d-2640-fe0f.svg","woman_construction_worker_tone5":"1f477-1f3ff-200d-2640-fe0f.svg","woman_cook":"1f469-200d-1f373.svg","woman_cook_tone1":"1f469-1f3fb-200d-1f373.svg","woman_cook_tone2":"1f469-1f3fc-200d-1f373.svg","woman_cook_tone3":"1f469-1f3fd-200d-1f373.svg","woman_cook_tone4":"1f469-1f3fe-200d-1f373.svg","woman_cook_tone5":"1f469-1f3ff-200d-1f373.svg","woman_curly_haired":"1f469-200d-1f9b1.svg","woman_curly_haired_tone1":"1f469-1f3fb-200d-1f9b1.svg","woman_curly_haired_tone2":"1f469-1f3fc-200d-1f9b1.svg","woman_curly_haired_tone3":"1f469-1f3fd-200d-1f9b1.svg","woman_curly_haired_tone4":"1f469-1f3fe-200d-1f9b1.svg","woman_curly_haired_tone5":"1f469-1f3ff-200d-1f9b1.svg","woman_detective":"1f575-fe0f-200d-2640-fe0f.svg","woman_detective_tone1":"1f575-1f3fb-200d-2640-fe0f.svg","woman_detective_tone2":"1f575-1f3fc-200d-2640-fe0f.svg","woman_detective_tone3":"1f575-1f3fd-200d-2640-fe0f.svg","woman_detective_tone4":"1f575-1f3fe-200d-2640-fe0f.svg","woman_detective_tone5":"1f575-1f3ff-200d-2640-fe0f.svg","woman_elf":"1f9dd-200d-2640-fe0f.svg","woman_elf_tone1":"1f9dd-1f3fb-200d-2640-fe0f.svg","woman_elf_tone2":"1f9dd-1f3fc-200d-2640-fe0f.svg","woman_elf_tone3":"1f9dd-1f3fd-200d-2640-fe0f.svg","woman_elf_tone4":"1f9dd-1f3fe-200d-2640-fe0f.svg","woman_elf_tone5":"1f9dd-1f3ff-200d-2640-fe0f.svg","woman_facepalming":"1f926-200d-2640-fe0f.svg","woman_facepalming_tone1":"1f926-1f3fb-200d-2640-fe0f.svg","woman_facepalming_tone2":"1f926-1f3fc-200d-2640-fe0f.svg","woman_facepalming_tone3":"1f926-1f3fd-200d-2640-fe0f.svg","woman_facepalming_tone4":"1f926-1f3fe-200d-2640-fe0f.svg","woman_facepalming_tone5":"1f926-1f3ff-200d-2640-fe0f.svg","woman_factory_worker":"1f469-200d-1f3ed.svg","woman_factory_worker_tone1":"1f469-1f3fb-200d-1f3ed.svg","woman_factory_worker_tone2":"1f469-1f3fc-200d-1f3ed.svg","woman_factory_worker_tone3":"1f469-1f3fd-200d-1f3ed.svg","woman_factory_worker_tone4":"1f469-1f3fe-200d-1f3ed.svg","woman_factory_worker_tone5":"1f469-1f3ff-200d-1f3ed.svg","woman_fairy":"1f9da-200d-2640-fe0f.svg","woman_fairy_tone1":"1f9da-1f3fb-200d-2640-fe0f.svg","woman_fairy_tone2":"1f9da-1f3fc-200d-2640-fe0f.svg","woman_fairy_tone3":"1f9da-1f3fd-200d-2640-fe0f.svg","woman_fairy_tone4":"1f9da-1f3fe-200d-2640-fe0f.svg","woman_fairy_tone5":"1f9da-1f3ff-200d-2640-fe0f.svg","woman_farmer":"1f469-200d-1f33e.svg","woman_farmer_tone1":"1f469-1f3fb-200d-1f33e.svg","woman_farmer_tone2":"1f469-1f3fc-200d-1f33e.svg","woman_farmer_tone3":"1f469-1f3fd-200d-1f33e.svg","woman_farmer_tone4":"1f469-1f3fe-200d-1f33e.svg","woman_farmer_tone5":"1f469-1f3ff-200d-1f33e.svg","woman_firefighter":"1f469-200d-1f692.svg","woman_firefighter_tone1":"1f469-1f3fb-200d-1f692.svg","woman_firefighter_tone2":"1f469-1f3fc-200d-1f692.svg","woman_firefighter_tone3":"1f469-1f3fd-200d-1f692.svg","woman_firefighter_tone4":"1f469-1f3fe-200d-1f692.svg","woman_firefighter_tone5":"1f469-1f3ff-200d-1f692.svg","woman_frowning":"1f64d-200d-2640-fe0f.svg","woman_frowning_tone1":"1f64d-1f3fb-200d-2640-fe0f.svg","woman_frowning_tone2":"1f64d-1f3fc-200d-2640-fe0f.svg","woman_frowning_tone3":"1f64d-1f3fd-200d-2640-fe0f.svg","woman_frowning_tone4":"1f64d-1f3fe-200d-2640-fe0f.svg","woman_frowning_tone5":"1f64d-1f3ff-200d-2640-fe0f.svg","woman_genie":"1f9de-200d-2640-fe0f.svg","woman_gesturing_no":"1f645-200d-2640-fe0f.svg","woman_gesturing_no_tone1":"1f645-1f3fb-200d-2640-fe0f.svg","woman_gesturing_no_tone2":"1f645-1f3fc-200d-2640-fe0f.svg","woman_gesturing_no_tone3":"1f645-1f3fd-200d-2640-fe0f.svg","woman_gesturing_no_tone4":"1f645-1f3fe-200d-2640-fe0f.svg","woman_gesturing_no_tone5":"1f645-1f3ff-200d-2640-fe0f.svg","woman_gesturing_ok":"1f646-200d-2640-fe0f.svg","woman_gesturing_ok_tone1":"1f646-1f3fb-200d-2640-fe0f.svg","woman_gesturing_ok_tone2":"1f646-1f3fc-200d-2640-fe0f.svg","woman_gesturing_ok_tone3":"1f646-1f3fd-200d-2640-fe0f.svg","woman_gesturing_ok_tone4":"1f646-1f3fe-200d-2640-fe0f.svg","woman_gesturing_ok_tone5":"1f646-1f3ff-200d-2640-fe0f.svg","woman_getting_face_massage":"1f486-200d-2640-fe0f.svg","woman_getting_face_massage_tone1":"1f486-1f3fb-200d-2640-fe0f.svg","woman_getting_face_massage_tone2":"1f486-1f3fc-200d-2640-fe0f.svg","woman_getting_face_massage_tone3":"1f486-1f3fd-200d-2640-fe0f.svg","woman_getting_face_massage_tone4":"1f486-1f3fe-200d-2640-fe0f.svg","woman_getting_face_massage_tone5":"1f486-1f3ff-200d-2640-fe0f.svg","woman_getting_haircut":"1f487-200d-2640-fe0f.svg","woman_getting_haircut_tone1":"1f487-1f3fb-200d-2640-fe0f.svg","woman_getting_haircut_tone2":"1f487-1f3fc-200d-2640-fe0f.svg","woman_getting_haircut_tone3":"1f487-1f3fd-200d-2640-fe0f.svg","woman_getting_haircut_tone4":"1f487-1f3fe-200d-2640-fe0f.svg","woman_getting_haircut_tone5":"1f487-1f3ff-200d-2640-fe0f.svg","woman_golfing":"1f3cc-fe0f-200d-2640-fe0f.svg","woman_golfing_tone1":"1f3cc-1f3fb-200d-2640-fe0f.svg","woman_golfing_tone2":"1f3cc-1f3fc-200d-2640-fe0f.svg","woman_golfing_tone3":"1f3cc-1f3fd-200d-2640-fe0f.svg","woman_golfing_tone4":"1f3cc-1f3fe-200d-2640-fe0f.svg","woman_golfing_tone5":"1f3cc-1f3ff-200d-2640-fe0f.svg","woman_guard":"1f482-200d-2640-fe0f.svg","woman_guard_tone1":"1f482-1f3fb-200d-2640-fe0f.svg","woman_guard_tone2":"1f482-1f3fc-200d-2640-fe0f.svg","woman_guard_tone3":"1f482-1f3fd-200d-2640-fe0f.svg","woman_guard_tone4":"1f482-1f3fe-200d-2640-fe0f.svg","woman_guard_tone5":"1f482-1f3ff-200d-2640-fe0f.svg","woman_health_worker":"1f469-200d-2695-fe0f.svg","woman_health_worker_tone1":"1f469-1f3fb-200d-2695-fe0f.svg","woman_health_worker_tone2":"1f469-1f3fc-200d-2695-fe0f.svg","woman_health_worker_tone3":"1f469-1f3fd-200d-2695-fe0f.svg","woman_health_worker_tone4":"1f469-1f3fe-200d-2695-fe0f.svg","woman_health_worker_tone5":"1f469-1f3ff-200d-2695-fe0f.svg","woman_in_lotus_position":"1f9d8-200d-2640-fe0f.svg","woman_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2640-fe0f.svg","woman_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2640-fe0f.svg","woman_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2640-fe0f.svg","woman_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2640-fe0f.svg","woman_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2640-fe0f.svg","woman_in_manual_wheelchair":"1f469-200d-1f9bd.svg","woman_in_manual_wheelchair_tone1":"1f469-1f3fb-200d-1f9bd.svg","woman_in_manual_wheelchair_tone2":"1f469-1f3fc-200d-1f9bd.svg","woman_in_manual_wheelchair_tone3":"1f469-1f3fd-200d-1f9bd.svg","woman_in_manual_wheelchair_tone4":"1f469-1f3fe-200d-1f9bd.svg","woman_in_manual_wheelchair_tone5":"1f469-1f3ff-200d-1f9bd.svg","woman_in_motorized_wheelchair":"1f469-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone1":"1f469-1f3fb-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone2":"1f469-1f3fc-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone3":"1f469-1f3fd-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone4":"1f469-1f3fe-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone5":"1f469-1f3ff-200d-1f9bc.svg","woman_in_steamy_room":"1f9d6-200d-2640-fe0f.svg","woman_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2640-fe0f.svg","woman_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2640-fe0f.svg","woman_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2640-fe0f.svg","woman_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2640-fe0f.svg","woman_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2640-fe0f.svg","woman_in_tuxedo":"1f935-200d-2640-fe0f.svg","woman_in_tuxedo_tone1":"1f935-1f3fb-200d-2640-fe0f.svg","woman_in_tuxedo_tone2":"1f935-1f3fc-200d-2640-fe0f.svg","woman_in_tuxedo_tone3":"1f935-1f3fd-200d-2640-fe0f.svg","woman_in_tuxedo_tone4":"1f935-1f3fe-200d-2640-fe0f.svg","woman_in_tuxedo_tone5":"1f935-1f3ff-200d-2640-fe0f.svg","woman_judge":"1f469-200d-2696-fe0f.svg","woman_judge_tone1":"1f469-1f3fb-200d-2696-fe0f.svg","woman_judge_tone2":"1f469-1f3fc-200d-2696-fe0f.svg","woman_judge_tone3":"1f469-1f3fd-200d-2696-fe0f.svg","woman_judge_tone4":"1f469-1f3fe-200d-2696-fe0f.svg","woman_judge_tone5":"1f469-1f3ff-200d-2696-fe0f.svg","woman_juggling":"1f939-200d-2640-fe0f.svg","woman_juggling_tone1":"1f939-1f3fb-200d-2640-fe0f.svg","woman_juggling_tone2":"1f939-1f3fc-200d-2640-fe0f.svg","woman_juggling_tone3":"1f939-1f3fd-200d-2640-fe0f.svg","woman_juggling_tone4":"1f939-1f3fe-200d-2640-fe0f.svg","woman_juggling_tone5":"1f939-1f3ff-200d-2640-fe0f.svg","woman_kneeling":"1f9ce-200d-2640-fe0f.svg","woman_kneeling_tone1":"1f9ce-1f3fb-200d-2640-fe0f.svg","woman_kneeling_tone2":"1f9ce-1f3fc-200d-2640-fe0f.svg","woman_kneeling_tone3":"1f9ce-1f3fd-200d-2640-fe0f.svg","woman_kneeling_tone4":"1f9ce-1f3fe-200d-2640-fe0f.svg","woman_kneeling_tone5":"1f9ce-1f3ff-200d-2640-fe0f.svg","woman_leviate_tone2":"1f574-1f3fc-200d-2640-fe0f.svg","woman_leviate_tone3":"1f574-1f3fd-200d-2640-fe0f.svg","woman_leviate_tone4":"1f574-1f3fe-200d-2640-fe0f.svg","woman_leviate_tone5":"1f574-1f3ff-200d-2640-fe0f.svg","woman_levitate":"1f574-fe0f-200d-2640-fe0f.svg","woman_levitate_tone1":"1f574-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights":"1f3cb-fe0f-200d-2640-fe0f.svg","woman_lifting_weights_tone1":"1f3cb-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights_tone2":"1f3cb-1f3fc-200d-2640-fe0f.svg","woman_lifting_weights_tone3":"1f3cb-1f3fd-200d-2640-fe0f.svg","woman_lifting_weights_tone4":"1f3cb-1f3fe-200d-2640-fe0f.svg","woman_lifting_weights_tone5":"1f3cb-1f3ff-200d-2640-fe0f.svg","woman_mage":"1f9d9-200d-2640-fe0f.svg","woman_mage_tone1":"1f9d9-1f3fb-200d-2640-fe0f.svg","woman_mage_tone2":"1f9d9-1f3fc-200d-2640-fe0f.svg","woman_mage_tone3":"1f9d9-1f3fd-200d-2640-fe0f.svg","woman_mage_tone4":"1f9d9-1f3fe-200d-2640-fe0f.svg","woman_mage_tone5":"1f9d9-1f3ff-200d-2640-fe0f.svg","woman_mechanic":"1f469-200d-1f527.svg","woman_mechanic_tone1":"1f469-1f3fb-200d-1f527.svg","woman_mechanic_tone2":"1f469-1f3fc-200d-1f527.svg","woman_mechanic_tone3":"1f469-1f3fd-200d-1f527.svg","woman_mechanic_tone4":"1f469-1f3fe-200d-1f527.svg","woman_mechanic_tone5":"1f469-1f3ff-200d-1f527.svg","woman_mountain_biking":"1f6b5-200d-2640-fe0f.svg","woman_mountain_biking_tone1":"1f6b5-1f3fb-200d-2640-fe0f.svg","woman_mountain_biking_tone2":"1f6b5-1f3fc-200d-2640-fe0f.svg","woman_mountain_biking_tone3":"1f6b5-1f3fd-200d-2640-fe0f.svg","woman_mountain_biking_tone4":"1f6b5-1f3fe-200d-2640-fe0f.svg","woman_mountain_biking_tone5":"1f6b5-1f3ff-200d-2640-fe0f.svg","woman_office_worker":"1f469-200d-1f4bc.svg","woman_office_worker_tone1":"1f469-1f3fb-200d-1f4bc.svg","woman_office_worker_tone2":"1f469-1f3fc-200d-1f4bc.svg","woman_office_worker_tone3":"1f469-1f3fd-200d-1f4bc.svg","woman_office_worker_tone4":"1f469-1f3fe-200d-1f4bc.svg","woman_office_worker_tone5":"1f469-1f3ff-200d-1f4bc.svg","woman_pilot":"1f469-200d-2708-fe0f.svg","woman_pilot_tone1":"1f469-1f3fb-200d-2708-fe0f.svg","woman_pilot_tone2":"1f469-1f3fc-200d-2708-fe0f.svg","woman_pilot_tone3":"1f469-1f3fd-200d-2708-fe0f.svg","woman_pilot_tone4":"1f469-1f3fe-200d-2708-fe0f.svg","woman_pilot_tone5":"1f469-1f3ff-200d-2708-fe0f.svg","woman_playing_handball":"1f93e-200d-2640-fe0f.svg","woman_playing_handball_tone1":"1f93e-1f3fb-200d-2640-fe0f.svg","woman_playing_handball_tone2":"1f93e-1f3fc-200d-2640-fe0f.svg","woman_playing_handball_tone3":"1f93e-1f3fd-200d-2640-fe0f.svg","woman_playing_handball_tone4":"1f93e-1f3fe-200d-2640-fe0f.svg","woman_playing_handball_tone5":"1f93e-1f3ff-200d-2640-fe0f.svg","woman_playing_water_polo":"1f93d-200d-2640-fe0f.svg","woman_playing_water_polo_tone1":"1f93d-1f3fb-200d-2640-fe0f.svg","woman_playing_water_polo_tone2":"1f93d-1f3fc-200d-2640-fe0f.svg","woman_playing_water_polo_tone3":"1f93d-1f3fd-200d-2640-fe0f.svg","woman_playing_water_polo_tone4":"1f93d-1f3fe-200d-2640-fe0f.svg","woman_playing_water_polo_tone5":"1f93d-1f3ff-200d-2640-fe0f.svg","woman_police_officer":"1f46e-200d-2640-fe0f.svg","woman_police_officer_tone1":"1f46e-1f3fb-200d-2640-fe0f.svg","woman_police_officer_tone2":"1f46e-1f3fc-200d-2640-fe0f.svg","woman_police_officer_tone3":"1f46e-1f3fd-200d-2640-fe0f.svg","woman_police_officer_tone4":"1f46e-1f3fe-200d-2640-fe0f.svg","woman_police_officer_tone5":"1f46e-1f3ff-200d-2640-fe0f.svg","woman_pouting":"1f64e-200d-2640-fe0f.svg","woman_pouting_tone1":"1f64e-1f3fb-200d-2640-fe0f.svg","woman_pouting_tone2":"1f64e-1f3fc-200d-2640-fe0f.svg","woman_pouting_tone3":"1f64e-1f3fd-200d-2640-fe0f.svg","woman_pouting_tone4":"1f64e-1f3fe-200d-2640-fe0f.svg","woman_pouting_tone5":"1f64e-1f3ff-200d-2640-fe0f.svg","woman_raising_hand":"1f64b-200d-2640-fe0f.svg","woman_raising_hand_tone1":"1f64b-1f3fb-200d-2640-fe0f.svg","woman_raising_hand_tone2":"1f64b-1f3fc-200d-2640-fe0f.svg","woman_raising_hand_tone3":"1f64b-1f3fd-200d-2640-fe0f.svg","woman_raising_hand_tone4":"1f64b-1f3fe-200d-2640-fe0f.svg","woman_raising_hand_tone5":"1f64b-1f3ff-200d-2640-fe0f.svg","woman_red_haired":"1f469-200d-1f9b0.svg","woman_red_haired_tone1":"1f469-1f3fb-200d-1f9b0.svg","woman_red_haired_tone2":"1f469-1f3fc-200d-1f9b0.svg","woman_red_haired_tone3":"1f469-1f3fd-200d-1f9b0.svg","woman_red_haired_tone4":"1f469-1f3fe-200d-1f9b0.svg","woman_red_haired_tone5":"1f469-1f3ff-200d-1f9b0.svg","woman_rowing_boat":"1f6a3-200d-2640-fe0f.svg","woman_rowing_boat_tone1":"1f6a3-1f3fb-200d-2640-fe0f.svg","woman_rowing_boat_tone2":"1f6a3-1f3fc-200d-2640-fe0f.svg","woman_rowing_boat_tone3":"1f6a3-1f3fd-200d-2640-fe0f.svg","woman_rowing_boat_tone4":"1f6a3-1f3fe-200d-2640-fe0f.svg","woman_rowing_boat_tone5":"1f6a3-1f3ff-200d-2640-fe0f.svg","woman_running":"1f3c3-200d-2640-fe0f.svg","woman_running_tone1":"1f3c3-1f3fb-200d-2640-fe0f.svg","woman_running_tone2":"1f3c3-1f3fc-200d-2640-fe0f.svg","woman_running_tone3":"1f3c3-1f3fd-200d-2640-fe0f.svg","woman_running_tone4":"1f3c3-1f3fe-200d-2640-fe0f.svg","woman_running_tone5":"1f3c3-1f3ff-200d-2640-fe0f.svg","woman_scientist":"1f469-200d-1f52c.svg","woman_scientist_tone1":"1f469-1f3fb-200d-1f52c.svg","woman_scientist_tone2":"1f469-1f3fc-200d-1f52c.svg","woman_scientist_tone3":"1f469-1f3fd-200d-1f52c.svg","woman_scientist_tone4":"1f469-1f3fe-200d-1f52c.svg","woman_scientist_tone5":"1f469-1f3ff-200d-1f52c.svg","woman_shrugging":"1f937-200d-2640-fe0f.svg","woman_shrugging_tone1":"1f937-1f3fb-200d-2640-fe0f.svg","woman_shrugging_tone2":"1f937-1f3fc-200d-2640-fe0f.svg","woman_shrugging_tone3":"1f937-1f3fd-200d-2640-fe0f.svg","woman_shrugging_tone4":"1f937-1f3fe-200d-2640-fe0f.svg","woman_shrugging_tone5":"1f937-1f3ff-200d-2640-fe0f.svg","woman_singer":"1f469-200d-1f3a4.svg","woman_singer_tone1":"1f469-1f3fb-200d-1f3a4.svg","woman_singer_tone2":"1f469-1f3fc-200d-1f3a4.svg","woman_singer_tone3":"1f469-1f3fd-200d-1f3a4.svg","woman_singer_tone4":"1f469-1f3fe-200d-1f3a4.svg","woman_singer_tone5":"1f469-1f3ff-200d-1f3a4.svg","woman_standing":"1f9cd-200d-2640-fe0f.svg","woman_standing_tone1":"1f9cd-1f3fb-200d-2640-fe0f.svg","woman_standing_tone2":"1f9cd-1f3fc-200d-2640-fe0f.svg","woman_standing_tone3":"1f9cd-1f3fd-200d-2640-fe0f.svg","woman_standing_tone4":"1f9cd-1f3fe-200d-2640-fe0f.svg","woman_standing_tone5":"1f9cd-1f3ff-200d-2640-fe0f.svg","woman_student":"1f469-200d-1f393.svg","woman_student_tone1":"1f469-1f3fb-200d-1f393.svg","woman_student_tone2":"1f469-1f3fc-200d-1f393.svg","woman_student_tone3":"1f469-1f3fd-200d-1f393.svg","woman_student_tone4":"1f469-1f3fe-200d-1f393.svg","woman_student_tone5":"1f469-1f3ff-200d-1f393.svg","woman_superhero":"1f9b8-200d-2640-fe0f.svg","woman_superhero_tone1":"1f9b8-1f3fb-200d-2640-fe0f.svg","woman_superhero_tone2":"1f9b8-1f3fc-200d-2640-fe0f.svg","woman_superhero_tone3":"1f9b8-1f3fd-200d-2640-fe0f.svg","woman_superhero_tone4":"1f9b8-1f3fe-200d-2640-fe0f.svg","woman_superhero_tone5":"1f9b8-1f3ff-200d-2640-fe0f.svg","woman_supervillain":"1f9b9-200d-2640-fe0f.svg","woman_supervillain_tone1":"1f9b9-1f3fb-200d-2640-fe0f.svg","woman_supervillain_tone2":"1f9b9-1f3fc-200d-2640-fe0f.svg","woman_supervillain_tone3":"1f9b9-1f3fd-200d-2640-fe0f.svg","woman_supervillain_tone4":"1f9b9-1f3fe-200d-2640-fe0f.svg","woman_supervillain_tone5":"1f9b9-1f3ff-200d-2640-fe0f.svg","woman_surfing":"1f3c4-200d-2640-fe0f.svg","woman_surfing_tone1":"1f3c4-1f3fb-200d-2640-fe0f.svg","woman_surfing_tone2":"1f3c4-1f3fc-200d-2640-fe0f.svg","woman_surfing_tone3":"1f3c4-1f3fd-200d-2640-fe0f.svg","woman_surfing_tone4":"1f3c4-1f3fe-200d-2640-fe0f.svg","woman_surfing_tone5":"1f3c4-1f3ff-200d-2640-fe0f.svg","woman_swimming":"1f3ca-200d-2640-fe0f.svg","woman_swimming_tone1":"1f3ca-1f3fb-200d-2640-fe0f.svg","woman_swimming_tone2":"1f3ca-1f3fc-200d-2640-fe0f.svg","woman_swimming_tone3":"1f3ca-1f3fd-200d-2640-fe0f.svg","woman_swimming_tone4":"1f3ca-1f3fe-200d-2640-fe0f.svg","woman_swimming_tone5":"1f3ca-1f3ff-200d-2640-fe0f.svg","woman_teacher":"1f469-200d-1f3eb.svg","woman_teacher_tone1":"1f469-1f3fb-200d-1f3eb.svg","woman_teacher_tone2":"1f469-1f3fc-200d-1f3eb.svg","woman_teacher_tone3":"1f469-1f3fd-200d-1f3eb.svg","woman_teacher_tone4":"1f469-1f3fe-200d-1f3eb.svg","woman_teacher_tone5":"1f469-1f3ff-200d-1f3eb.svg","woman_technologist":"1f469-200d-1f4bb.svg","woman_technologist_tone1":"1f469-1f3fb-200d-1f4bb.svg","woman_technologist_tone2":"1f469-1f3fc-200d-1f4bb.svg","woman_technologist_tone3":"1f469-1f3fd-200d-1f4bb.svg","woman_technologist_tone4":"1f469-1f3fe-200d-1f4bb.svg","woman_technologist_tone5":"1f469-1f3ff-200d-1f4bb.svg","woman_tipping_hand":"1f481-200d-2640-fe0f.svg","woman_tipping_hand_tone1":"1f481-1f3fb-200d-2640-fe0f.svg","woman_tipping_hand_tone2":"1f481-1f3fc-200d-2640-fe0f.svg","woman_tipping_hand_tone3":"1f481-1f3fd-200d-2640-fe0f.svg","woman_tipping_hand_tone4":"1f481-1f3fe-200d-2640-fe0f.svg","woman_tipping_hand_tone5":"1f481-1f3ff-200d-2640-fe0f.svg","woman_tone1":"1f469-1f3fb.svg","woman_tone2":"1f469-1f3fc.svg","woman_tone3":"1f469-1f3fd.svg","woman_tone4":"1f469-1f3fe.svg","woman_tone5":"1f469-1f3ff.svg","woman_vampire":"1f9db-200d-2640-fe0f.svg","woman_vampire_tone1":"1f9db-1f3fb-200d-2640-fe0f.svg","woman_vampire_tone2":"1f9db-1f3fc-200d-2640-fe0f.svg","woman_vampire_tone3":"1f9db-1f3fd-200d-2640-fe0f.svg","woman_vampire_tone4":"1f9db-1f3fe-200d-2640-fe0f.svg","woman_vampire_tone5":"1f9db-1f3ff-200d-2640-fe0f.svg","woman_walking":"1f6b6-200d-2640-fe0f.svg","woman_walking_tone1":"1f6b6-1f3fb-200d-2640-fe0f.svg","woman_walking_tone2":"1f6b6-1f3fc-200d-2640-fe0f.svg","woman_walking_tone3":"1f6b6-1f3fd-200d-2640-fe0f.svg","woman_walking_tone4":"1f6b6-1f3fe-200d-2640-fe0f.svg","woman_walking_tone5":"1f6b6-1f3ff-200d-2640-fe0f.svg","woman_wearing_turban":"1f473-200d-2640-fe0f.svg","woman_wearing_turban_tone1":"1f473-1f3fb-200d-2640-fe0f.svg","woman_wearing_turban_tone2":"1f473-1f3fc-200d-2640-fe0f.svg","woman_wearing_turban_tone3":"1f473-1f3fd-200d-2640-fe0f.svg","woman_wearing_turban_tone4":"1f473-1f3fe-200d-2640-fe0f.svg","woman_wearing_turban_tone5":"1f473-1f3ff-200d-2640-fe0f.svg","woman_white_haired":"1f469-200d-1f9b3.svg","woman_white_haired_tone1":"1f469-1f3fb-200d-1f9b3.svg","woman_white_haired_tone2":"1f469-1f3fc-200d-1f9b3.svg","woman_white_haired_tone3":"1f469-1f3fd-200d-1f9b3.svg","woman_white_haired_tone4":"1f469-1f3fe-200d-1f9b3.svg","woman_white_haired_tone5":"1f469-1f3ff-200d-1f9b3.svg","woman_with_headscarf":"1f9d5.svg","woman_with_headscarf_tone1":"1f9d5-1f3fb.svg","woman_with_headscarf_tone2":"1f9d5-1f3fc.svg","woman_with_headscarf_tone3":"1f9d5-1f3fd.svg","woman_with_headscarf_tone4":"1f9d5-1f3fe.svg","woman_with_headscarf_tone5":"1f9d5-1f3ff.svg","woman_with_probing_cane":"1f469-200d-1f9af.svg","woman_with_probing_cane_tone1":"1f469-1f3fb-200d-1f9af.svg","woman_with_probing_cane_tone2":"1f469-1f3fc-200d-1f9af.svg","woman_with_probing_cane_tone3":"1f469-1f3fd-200d-1f9af.svg","woman_with_probing_cane_tone4":"1f469-1f3fe-200d-1f9af.svg","woman_with_probing_cane_tone5":"1f469-1f3ff-200d-1f9af.svg","woman_zombie":"1f9df-200d-2640-fe0f.svg","womans_clothes":"1f45a.svg","womans_flat_shoe":"1f97f.svg","womans_hat":"1f452.svg","women_holding_hands_tone1":"1f46d-1f3fb.svg","women_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone2":"1f46d-1f3fc.svg","women_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone3":"1f46d-1f3fd.svg","women_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone4":"1f46d-1f3fe.svg","women_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone5":"1f46d-1f3ff.svg","women_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe.svg","women_with_bunny_ears_partying":"1f46f-200d-2640-fe0f.svg","women_wrestling":"1f93c-200d-2640-fe0f.svg","womens":"1f6ba.svg","woozy_face":"1f974.svg","worried":"1f61f.svg","wrench":"1f527.svg","writing_hand":"270d.svg","writing_hand_tone1":"270d-1f3fb.svg","writing_hand_tone2":"270d-1f3fc.svg","writing_hand_tone3":"270d-1f3fd.svg","writing_hand_tone4":"270d-1f3fe.svg","writing_hand_tone5":"270d-1f3ff.svg","x":"274c.svg","yarn":"1f9f6.svg","yawning_face":"1f971.svg","yellow_circle":"1f7e1.svg","yellow_heart":"1f49b.svg","yellow_square":"1f7e8.svg","yen":"1f4b4.svg","yin_yang":"262f.svg","yo_yo":"1fa80.svg","yum":"1f60b.svg","zany_face":"1f92a.svg","zap":"26a1.svg","zebra":"1f993.svg","zero":"30-20e3.svg","zipper_mouth":"1f910.svg","zombie":"1f9df.svg","zzz":"1f4a4.svg"}}} \ No newline at end of file diff --git a/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css b/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css new file mode 100644 index 0000000..62349a2 --- /dev/null +++ b/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css @@ -0,0 +1,3 @@ +@-webkit-keyframes tx-heart{0%,40%,80%,100%{transform:scale(1)}20%,60%{transform:scale(1.15)}}@keyframes tx-heart{0%,40%,80%,100%{transform:scale(1)}20%,60%{transform:scale(1.15)}}.md-typeset figure>p+figcaption{margin-top:-1.2rem}.md-typeset .twitter{color:#00acee}.md-typeset .tx-video{width:auto}.md-typeset .tx-video__inner{position:relative;width:100%;height:0;padding-bottom:56.138%}.md-typeset .tx-video iframe{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;border:none}.md-typeset .tx-heart{-webkit-animation:tx-heart 1000ms infinite;animation:tx-heart 1000ms infinite}.md-typeset .tx-insiders{color:#e91e63}.md-typeset .tx-insiders-button{font-weight:400}.md-typeset .tx-insiders-count{font-weight:700}.md-typeset .tx-insiders-list{margin:2em 0;overflow:auto}.md-typeset .tx-insiders-list__item{display:block;float:left;width:3rem;height:3rem;margin:.2rem;overflow:hidden;border-radius:100%;transform:scale(1);transition:color 125ms,transform 125ms}.md-typeset .tx-insiders-list__item img{display:block;width:100%;height:auto;-webkit-filter:grayscale(100%);filter:grayscale(100%);transition:-webkit-filter 125ms;transition:filter 125ms;transition:filter 125ms, -webkit-filter 125ms}.md-typeset .tx-insiders-list__item:focus,.md-typeset .tx-insiders-list__item:hover{transform:scale(1.1)}.md-typeset .tx-insiders-list__item:focus img,.md-typeset .tx-insiders-list__item:hover img{-webkit-filter:grayscale(0%);filter:grayscale(0%)}.md-typeset .tx-insiders-list__item--private{color:var(--md-default-fg-color--lighter);font-weight:700;font-size:1.2rem;line-height:3rem;text-align:center;background:var(--md-default-fg-color--lightest)}.md-typeset .tx-switch button{cursor:pointer;transition:opacity 250ms}.md-typeset .tx-switch button:focus,.md-typeset .tx-switch button:hover{opacity:.75}.md-typeset .tx-switch button>code{display:block;color:var(--md-primary-bg-color);background-color:var(--md-primary-fg-color)}.md-typeset .tx-columns ol,.md-typeset .tx-columns ul{-moz-columns:2;columns:2}@media screen and (max-width: 29.9375em){.md-typeset .tx-columns ol,.md-typeset .tx-columns ul{-moz-columns:initial;columns:initial}}.md-typeset .tx-columns li{-moz-column-break-inside:avoid;break-inside:avoid}.md-announce a,.md-announce a:focus,.md-announce a:hover{color:currentColor}.md-announce strong{white-space:nowrap}.md-announce .twitter{margin-left:.2em}.tx-content__footer{margin-top:1rem;text-align:center}.tx-content__footer a{display:inline-block;color:#e91e63;transition:transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),color 125ms}.tx-content__footer a:focus,.tx-content__footer a:hover{transform:scale(1.2)}.tx-content__footer hr{display:inline-block;width:2rem;margin:1em;vertical-align:middle;background-color:currentColor;border:none}.tx-container{padding-top:1rem;background:url("data:image/svg+xml;utf8,") no-repeat bottom,linear-gradient(to bottom, var(--md-primary-fg-color), #a63fd9 99%, var(--md-default-bg-color) 99%)}[data-md-color-scheme=slate] .tx-container{background:url("data:image/svg+xml;utf8,") no-repeat bottom,linear-gradient(to bottom, var(--md-primary-fg-color), #a63fd9 99%, var(--md-default-bg-color) 99%)}.tx-hero{margin:0 .8rem;color:var(--md-primary-bg-color)}.tx-hero h1{margin-bottom:1rem;color:currentColor;font-weight:700}@media screen and (max-width: 29.9375em){.tx-hero h1{font-size:1.4rem}}.tx-hero__content{padding-bottom:6rem}@media screen and (min-width: 60em){.tx-hero{display:flex;align-items:stretch}.tx-hero__content{max-width:19rem;margin-top:3.5rem;padding-bottom:14vw}.tx-hero__image{order:1;width:38rem;transform:translateX(4rem)}}@media screen and (min-width: 76.25em){.tx-hero__image{transform:translateX(8rem)}}.tx-hero .md-button{margin-top:.5rem;margin-right:.5rem;color:var(--md-primary-bg-color)}.tx-hero .md-button:focus,.tx-hero .md-button:hover{color:var(--md-default-bg-color);background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color)}.tx-hero .md-button--primary{color:#894da8;background-color:var(--md-primary-bg-color);border-color:var(--md-primary-bg-color)}.md-typeset .mdx-icon-search{position:relative;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.1),0 .025rem .05rem rgba(0,0,0,.1);transition:box-shadow 125ms}.md-typeset .mdx-icon-search:focus-within,.md-typeset .mdx-icon-search:hover{box-shadow:0 .4rem 1rem rgba(0,0,0,.15),0 .025rem .05rem rgba(0,0,0,.15)}.md-typeset .mdx-icon-search .md-input{background:var(--md-default-bg-color);box-shadow:0 0 .6rem rgba(0,0,0,.07)}[data-md-color-scheme=slate] .md-typeset .mdx-icon-search .md-input{background:var(--md-code-bg-color)}.md-typeset .mdx-icon-search-result{max-height:50vh;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden;touch-action:pan-y;scrollbar-width:thin;scrollbar-color:var(--md-default-fg-color--lighter) transparent}.md-typeset .mdx-icon-search-result::-webkit-scrollbar{width:.2rem;height:.2rem}.md-typeset .mdx-icon-search-result::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset .mdx-icon-search-result::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset .mdx-icon-search-result__meta{position:absolute;top:.4rem;right:.6rem;color:var(--md-default-fg-color--lighter);font-size:.64rem}.md-typeset .mdx-icon-search-result__list{margin:0;padding:0;list-style:none}.md-typeset .mdx-icon-search-result__item{margin:0;padding:.2rem .6rem;border-bottom:.05rem solid var(--md-default-fg-color--lightest)}.md-typeset .mdx-icon-search-result__item:last-child{border-bottom:none}.md-typeset .mdx-icon-search-result__item>*{margin-right:.6rem}.md-typeset .mdx-icon-search-result__item img{width:.9rem;height:.9rem}[data-md-color-scheme=slate] .md-typeset .mdx-icon-search-result__item img[src*=squidfunk]{-webkit-filter:invert(1);filter:invert(1)} + +/*# sourceMappingURL=main.01a7853e.min.css.map*/ \ No newline at end of file diff --git a/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css.map b/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css.map new file mode 100644 index 0000000..c3d9124 --- /dev/null +++ b/v2.0.2/overrides/assets/stylesheets/main.01a7853e.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./src/overrides/assets/stylesheets/main/_typeset.scss","webpack:///./node_modules/material-design-color/material-color.scss","webpack:///./src/assets/stylesheets/utilities/_break.scss","webpack:///./src/overrides/assets/stylesheets/main/layout/_announce.scss","webpack:///./src/overrides/assets/stylesheets/main/layout/_content.scss","webpack:///./src/overrides/assets/stylesheets/main/layout/_hero.scss","webpack:///./src/overrides/assets/stylesheets/main/_shame.scss"],"names":[],"mappings":"AA2BA,4BACE,gBAIE,mBAGF,QAEE,uBAVJ,oBACE,gBAIE,mBAGF,QAEE,uBAYF,gCACE,mBAIF,qBACE,cAIF,sBACE,WAGA,6BACE,kBACA,WACA,SACA,uBAIF,6BACE,kBACA,MACA,OACA,WACA,YACA,gBACA,YAKJ,sBACE,8EAIF,yBACE,aCqBY,CDjBd,gCACE,gBAIF,+BACE,gBAIF,8BACE,aACA,cAGA,oCACE,cACA,WACA,WACA,YACA,aACA,gBACA,mBACA,mBACA,sCACE,CAIF,wCACE,cACA,WACA,YACA,sDACA,sGAIF,oFAEE,qBAGA,4FACE,kDAKJ,6CACE,0CACA,gBACA,iBACA,iBACA,kBACA,gDAMN,8BACE,eACA,yBAGA,wEAEE,YAIF,mCACE,cACA,iCACA,4CAQF,sDAEE,yBE8BF,yCFhCA,sDAMI,sCAKJ,2BACE,kDG9JJ,yDAGE,mBAIF,oBACE,mBAIF,sBACE,iBChBJ,oBACE,gBACA,kBAGA,sBACE,qBACA,aH4EY,CG3EZ,qEACE,CAIF,wDAEE,qBAKJ,uBACE,qBACA,WACA,WACA,sBACA,8BACA,YC1BJ,cACE,iBACA,0YACE,CASF,2CACE,4YACE,CAWN,SACE,eACA,iCAGA,YACE,mBACA,mBACA,gBHoJA,yCGvJF,YAOI,kBAKJ,kBACE,oBHuHA,oCGzIJ,SAuBI,aACA,oBAGA,kBACE,gBACA,kBACA,oBAIF,gBACE,QACA,YACA,4BHoGF,uCG5FA,gBACE,4BAKJ,oBACE,iBACA,mBACA,iCAGA,oDAEE,iCACA,2CACA,uCAIF,6BACE,cACA,4CACA,wCC1FJ,6BACE,kBACA,4CACA,oBACA,uEACE,CAEF,4BAGA,6EAEE,wEACE,CAKJ,uCACE,sCACA,qCAGA,oEACE,mCAMN,oCACE,gBACA,gBAEA,8DACA,mBACA,qBACA,gEAGA,uDACE,YACA,aAIF,6DACE,qDAGA,mEACE,2CAKJ,0CACE,kBACA,UACA,YACA,0CACA,iBAIF,0CACE,SACA,UACA,gBAIF,0CACE,SACA,oBACA,gEAGA,qDACE,mBAIF,4CACE,mBAIF,8CACE,YACA,aAGA,2FACE,0C","file":"overrides/assets/stylesheets/main.01a7853e.min.css","sourcesContent":["////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Keyframes\n// ----------------------------------------------------------------------------\n\n// Pumping heart animation\n@keyframes tx-heart {\n 0%,\n 40%,\n 80%,\n 100% {\n transform: scale(1);\n }\n\n 20%,\n 60% {\n transform: scale(1.15);\n }\n}\n\n// ----------------------------------------------------------------------------\n// Rules\n// ----------------------------------------------------------------------------\n\n// Scoped in typesetted content to match specificity of regular content\n.md-typeset {\n\n // Screenshot caption\n figure > p + figcaption {\n margin-top: px2rem(-24px);\n }\n\n // Twitter icon\n .twitter {\n color: #00acee;\n }\n\n // Insiders video\n .tx-video {\n width: auto;\n\n // Insiders video container\n &__inner {\n position: relative;\n width: 100%;\n height: 0;\n padding-bottom: 56.138%;\n }\n\n // Insiders video iframe\n iframe {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n overflow: hidden;\n border: none;\n }\n }\n\n // Pumping heart\n .tx-heart {\n animation: tx-heart 1000ms infinite;\n }\n\n // Insiders color (for links, etc.)\n .tx-insiders {\n color: $clr-pink-500;\n }\n\n // Insiders button\n .tx-insiders-button {\n font-weight: 400;\n }\n\n // Insiders count\n .tx-insiders-count {\n font-weight: 700;\n }\n\n // Insiders list\n .tx-insiders-list {\n margin: 2em 0;\n overflow: auto;\n\n // Insiders list item\n &__item {\n display: block;\n float: left;\n width: px2rem(60px);\n height: px2rem(60px);\n margin: px2rem(4px);\n overflow: hidden;\n border-radius: 100%;\n transform: scale(1);\n transition:\n color 125ms,\n transform 125ms;\n\n // Sponsor avatar\n img {\n display: block;\n width: 100%;\n height: auto;\n filter: grayscale(100%);\n transition: filter 125ms;\n }\n\n // Sponsor item on focus/hover\n &:focus,\n &:hover {\n transform: scale(1.1);\n\n // Sponsor avatar\n img {\n filter: grayscale(0%);\n }\n }\n\n // Private sponsor\n &--private {\n color: var(--md-default-fg-color--lighter);\n font-weight: 700;\n font-size: px2rem(24px);\n line-height: px2rem(60px);\n text-align: center;\n background: var(--md-default-fg-color--lightest);\n }\n }\n }\n\n // Switch buttons\n .tx-switch button {\n cursor: pointer;\n transition: opacity 250ms;\n\n // Button on focus/hover\n &:focus,\n &:hover {\n opacity: 0.75;\n }\n\n // Code block\n > code {\n display: block;\n color: var(--md-primary-bg-color);\n background-color: var(--md-primary-fg-color);\n }\n }\n\n // Two-column layout\n .tx-columns {\n\n // Column\n ol,\n ul {\n columns: 2;\n\n // [mobile portrait -]: Reset columns on mobile\n @include break-to-device(mobile portrait) {\n columns: initial;\n }\n }\n\n // Column item\n li {\n break-inside: avoid;\n }\n }\n}\n","// ==========================================================================\n//\n// Name: UI Color Palette\n// Description: The color palette of material design.\n// Version: 2.3.1\n//\n// Author: Denis Malinochkin\n// Git: https://github.com/mrmlnc/material-color\n//\n// twitter: @mrmlnc\n//\n// ==========================================================================\n\n\n//\n// List of base colors\n//\n\n// $clr-red\n// $clr-pink\n// $clr-purple\n// $clr-deep-purple\n// $clr-indigo\n// $clr-blue\n// $clr-light-blue\n// $clr-cyan\n// $clr-teal\n// $clr-green\n// $clr-light-green\n// $clr-lime\n// $clr-yellow\n// $clr-amber\n// $clr-orange\n// $clr-deep-orange\n// $clr-brown\n// $clr-grey\n// $clr-blue-grey\n// $clr-black\n// $clr-white\n\n\n//\n// Red\n//\n\n$clr-red-list: (\n \"base\": #f44336,\n \"50\": #ffebee,\n \"100\": #ffcdd2,\n \"200\": #ef9a9a,\n \"300\": #e57373,\n \"400\": #ef5350,\n \"500\": #f44336,\n \"600\": #e53935,\n \"700\": #d32f2f,\n \"800\": #c62828,\n \"900\": #b71c1c,\n \"a100\": #ff8a80,\n \"a200\": #ff5252,\n \"a400\": #ff1744,\n \"a700\": #d50000\n);\n\n$clr-red: map-get($clr-red-list, \"base\");\n\n$clr-red-50: map-get($clr-red-list, \"50\");\n$clr-red-100: map-get($clr-red-list, \"100\");\n$clr-red-200: map-get($clr-red-list, \"200\");\n$clr-red-300: map-get($clr-red-list, \"300\");\n$clr-red-400: map-get($clr-red-list, \"400\");\n$clr-red-500: map-get($clr-red-list, \"500\");\n$clr-red-600: map-get($clr-red-list, \"600\");\n$clr-red-700: map-get($clr-red-list, \"700\");\n$clr-red-800: map-get($clr-red-list, \"800\");\n$clr-red-900: map-get($clr-red-list, \"900\");\n$clr-red-a100: map-get($clr-red-list, \"a100\");\n$clr-red-a200: map-get($clr-red-list, \"a200\");\n$clr-red-a400: map-get($clr-red-list, \"a400\");\n$clr-red-a700: map-get($clr-red-list, \"a700\");\n\n\n//\n// Pink\n//\n\n$clr-pink-list: (\n \"base\": #e91e63,\n \"50\": #fce4ec,\n \"100\": #f8bbd0,\n \"200\": #f48fb1,\n \"300\": #f06292,\n \"400\": #ec407a,\n \"500\": #e91e63,\n \"600\": #d81b60,\n \"700\": #c2185b,\n \"800\": #ad1457,\n \"900\": #880e4f,\n \"a100\": #ff80ab,\n \"a200\": #ff4081,\n \"a400\": #f50057,\n \"a700\": #c51162\n);\n\n$clr-pink: map-get($clr-pink-list, \"base\");\n\n$clr-pink-50: map-get($clr-pink-list, \"50\");\n$clr-pink-100: map-get($clr-pink-list, \"100\");\n$clr-pink-200: map-get($clr-pink-list, \"200\");\n$clr-pink-300: map-get($clr-pink-list, \"300\");\n$clr-pink-400: map-get($clr-pink-list, \"400\");\n$clr-pink-500: map-get($clr-pink-list, \"500\");\n$clr-pink-600: map-get($clr-pink-list, \"600\");\n$clr-pink-700: map-get($clr-pink-list, \"700\");\n$clr-pink-800: map-get($clr-pink-list, \"800\");\n$clr-pink-900: map-get($clr-pink-list, \"900\");\n$clr-pink-a100: map-get($clr-pink-list, \"a100\");\n$clr-pink-a200: map-get($clr-pink-list, \"a200\");\n$clr-pink-a400: map-get($clr-pink-list, \"a400\");\n$clr-pink-a700: map-get($clr-pink-list, \"a700\");\n\n\n//\n// Purple\n//\n\n$clr-purple-list: (\n \"base\": #9c27b0,\n \"50\": #f3e5f5,\n \"100\": #e1bee7,\n \"200\": #ce93d8,\n \"300\": #ba68c8,\n \"400\": #ab47bc,\n \"500\": #9c27b0,\n \"600\": #8e24aa,\n \"700\": #7b1fa2,\n \"800\": #6a1b9a,\n \"900\": #4a148c,\n \"a100\": #ea80fc,\n \"a200\": #e040fb,\n \"a400\": #d500f9,\n \"a700\": #aa00ff\n);\n\n$clr-purple: map-get($clr-purple-list, \"base\");\n\n$clr-purple-50: map-get($clr-purple-list, \"50\");\n$clr-purple-100: map-get($clr-purple-list, \"100\");\n$clr-purple-200: map-get($clr-purple-list, \"200\");\n$clr-purple-300: map-get($clr-purple-list, \"300\");\n$clr-purple-400: map-get($clr-purple-list, \"400\");\n$clr-purple-500: map-get($clr-purple-list, \"500\");\n$clr-purple-600: map-get($clr-purple-list, \"600\");\n$clr-purple-700: map-get($clr-purple-list, \"700\");\n$clr-purple-800: map-get($clr-purple-list, \"800\");\n$clr-purple-900: map-get($clr-purple-list, \"900\");\n$clr-purple-a100: map-get($clr-purple-list, \"a100\");\n$clr-purple-a200: map-get($clr-purple-list, \"a200\");\n$clr-purple-a400: map-get($clr-purple-list, \"a400\");\n$clr-purple-a700: map-get($clr-purple-list, \"a700\");\n\n\n//\n// Deep purple\n//\n\n$clr-deep-purple-list: (\n \"base\": #673ab7,\n \"50\": #ede7f6,\n \"100\": #d1c4e9,\n \"200\": #b39ddb,\n \"300\": #9575cd,\n \"400\": #7e57c2,\n \"500\": #673ab7,\n \"600\": #5e35b1,\n \"700\": #512da8,\n \"800\": #4527a0,\n \"900\": #311b92,\n \"a100\": #b388ff,\n \"a200\": #7c4dff,\n \"a400\": #651fff,\n \"a700\": #6200ea\n);\n\n$clr-deep-purple: map-get($clr-deep-purple-list, \"base\");\n\n$clr-deep-purple-50: map-get($clr-deep-purple-list, \"50\");\n$clr-deep-purple-100: map-get($clr-deep-purple-list, \"100\");\n$clr-deep-purple-200: map-get($clr-deep-purple-list, \"200\");\n$clr-deep-purple-300: map-get($clr-deep-purple-list, \"300\");\n$clr-deep-purple-400: map-get($clr-deep-purple-list, \"400\");\n$clr-deep-purple-500: map-get($clr-deep-purple-list, \"500\");\n$clr-deep-purple-600: map-get($clr-deep-purple-list, \"600\");\n$clr-deep-purple-700: map-get($clr-deep-purple-list, \"700\");\n$clr-deep-purple-800: map-get($clr-deep-purple-list, \"800\");\n$clr-deep-purple-900: map-get($clr-deep-purple-list, \"900\");\n$clr-deep-purple-a100: map-get($clr-deep-purple-list, \"a100\");\n$clr-deep-purple-a200: map-get($clr-deep-purple-list, \"a200\");\n$clr-deep-purple-a400: map-get($clr-deep-purple-list, \"a400\");\n$clr-deep-purple-a700: map-get($clr-deep-purple-list, \"a700\");\n\n\n//\n// Indigo\n//\n\n$clr-indigo-list: (\n \"base\": #3f51b5,\n \"50\": #e8eaf6,\n \"100\": #c5cae9,\n \"200\": #9fa8da,\n \"300\": #7986cb,\n \"400\": #5c6bc0,\n \"500\": #3f51b5,\n \"600\": #3949ab,\n \"700\": #303f9f,\n \"800\": #283593,\n \"900\": #1a237e,\n \"a100\": #8c9eff,\n \"a200\": #536dfe,\n \"a400\": #3d5afe,\n \"a700\": #304ffe\n);\n\n$clr-indigo: map-get($clr-indigo-list, \"base\");\n\n$clr-indigo-50: map-get($clr-indigo-list, \"50\");\n$clr-indigo-100: map-get($clr-indigo-list, \"100\");\n$clr-indigo-200: map-get($clr-indigo-list, \"200\");\n$clr-indigo-300: map-get($clr-indigo-list, \"300\");\n$clr-indigo-400: map-get($clr-indigo-list, \"400\");\n$clr-indigo-500: map-get($clr-indigo-list, \"500\");\n$clr-indigo-600: map-get($clr-indigo-list, \"600\");\n$clr-indigo-700: map-get($clr-indigo-list, \"700\");\n$clr-indigo-800: map-get($clr-indigo-list, \"800\");\n$clr-indigo-900: map-get($clr-indigo-list, \"900\");\n$clr-indigo-a100: map-get($clr-indigo-list, \"a100\");\n$clr-indigo-a200: map-get($clr-indigo-list, \"a200\");\n$clr-indigo-a400: map-get($clr-indigo-list, \"a400\");\n$clr-indigo-a700: map-get($clr-indigo-list, \"a700\");\n\n\n//\n// Blue\n//\n\n$clr-blue-list: (\n \"base\": #2196f3,\n \"50\": #e3f2fd,\n \"100\": #bbdefb,\n \"200\": #90caf9,\n \"300\": #64b5f6,\n \"400\": #42a5f5,\n \"500\": #2196f3,\n \"600\": #1e88e5,\n \"700\": #1976d2,\n \"800\": #1565c0,\n \"900\": #0d47a1,\n \"a100\": #82b1ff,\n \"a200\": #448aff,\n \"a400\": #2979ff,\n \"a700\": #2962ff\n);\n\n$clr-blue: map-get($clr-blue-list, \"base\");\n\n$clr-blue-50: map-get($clr-blue-list, \"50\");\n$clr-blue-100: map-get($clr-blue-list, \"100\");\n$clr-blue-200: map-get($clr-blue-list, \"200\");\n$clr-blue-300: map-get($clr-blue-list, \"300\");\n$clr-blue-400: map-get($clr-blue-list, \"400\");\n$clr-blue-500: map-get($clr-blue-list, \"500\");\n$clr-blue-600: map-get($clr-blue-list, \"600\");\n$clr-blue-700: map-get($clr-blue-list, \"700\");\n$clr-blue-800: map-get($clr-blue-list, \"800\");\n$clr-blue-900: map-get($clr-blue-list, \"900\");\n$clr-blue-a100: map-get($clr-blue-list, \"a100\");\n$clr-blue-a200: map-get($clr-blue-list, \"a200\");\n$clr-blue-a400: map-get($clr-blue-list, \"a400\");\n$clr-blue-a700: map-get($clr-blue-list, \"a700\");\n\n\n//\n// Light Blue\n//\n\n$clr-light-blue-list: (\n \"base\": #03a9f4,\n \"50\": #e1f5fe,\n \"100\": #b3e5fc,\n \"200\": #81d4fa,\n \"300\": #4fc3f7,\n \"400\": #29b6f6,\n \"500\": #03a9f4,\n \"600\": #039be5,\n \"700\": #0288d1,\n \"800\": #0277bd,\n \"900\": #01579b,\n \"a100\": #80d8ff,\n \"a200\": #40c4ff,\n \"a400\": #00b0ff,\n \"a700\": #0091ea\n);\n\n$clr-light-blue: map-get($clr-light-blue-list, \"base\");\n\n$clr-light-blue-50: map-get($clr-light-blue-list, \"50\");\n$clr-light-blue-100: map-get($clr-light-blue-list, \"100\");\n$clr-light-blue-200: map-get($clr-light-blue-list, \"200\");\n$clr-light-blue-300: map-get($clr-light-blue-list, \"300\");\n$clr-light-blue-400: map-get($clr-light-blue-list, \"400\");\n$clr-light-blue-500: map-get($clr-light-blue-list, \"500\");\n$clr-light-blue-600: map-get($clr-light-blue-list, \"600\");\n$clr-light-blue-700: map-get($clr-light-blue-list, \"700\");\n$clr-light-blue-800: map-get($clr-light-blue-list, \"800\");\n$clr-light-blue-900: map-get($clr-light-blue-list, \"900\");\n$clr-light-blue-a100: map-get($clr-light-blue-list, \"a100\");\n$clr-light-blue-a200: map-get($clr-light-blue-list, \"a200\");\n$clr-light-blue-a400: map-get($clr-light-blue-list, \"a400\");\n$clr-light-blue-a700: map-get($clr-light-blue-list, \"a700\");\n\n\n//\n// Cyan\n//\n\n$clr-cyan-list: (\n \"base\": #00bcd4,\n \"50\": #e0f7fa,\n \"100\": #b2ebf2,\n \"200\": #80deea,\n \"300\": #4dd0e1,\n \"400\": #26c6da,\n \"500\": #00bcd4,\n \"600\": #00acc1,\n \"700\": #0097a7,\n \"800\": #00838f,\n \"900\": #006064,\n \"a100\": #84ffff,\n \"a200\": #18ffff,\n \"a400\": #00e5ff,\n \"a700\": #00b8d4\n);\n\n$clr-cyan: map-get($clr-cyan-list, \"base\");\n\n$clr-cyan-50: map-get($clr-cyan-list, \"50\");\n$clr-cyan-100: map-get($clr-cyan-list, \"100\");\n$clr-cyan-200: map-get($clr-cyan-list, \"200\");\n$clr-cyan-300: map-get($clr-cyan-list, \"300\");\n$clr-cyan-400: map-get($clr-cyan-list, \"400\");\n$clr-cyan-500: map-get($clr-cyan-list, \"500\");\n$clr-cyan-600: map-get($clr-cyan-list, \"600\");\n$clr-cyan-700: map-get($clr-cyan-list, \"700\");\n$clr-cyan-800: map-get($clr-cyan-list, \"800\");\n$clr-cyan-900: map-get($clr-cyan-list, \"900\");\n$clr-cyan-a100: map-get($clr-cyan-list, \"a100\");\n$clr-cyan-a200: map-get($clr-cyan-list, \"a200\");\n$clr-cyan-a400: map-get($clr-cyan-list, \"a400\");\n$clr-cyan-a700: map-get($clr-cyan-list, \"a700\");\n\n\n//\n// Teal\n//\n\n$clr-teal-list: (\n \"base\": #009688,\n \"50\": #e0f2f1,\n \"100\": #b2dfdb,\n \"200\": #80cbc4,\n \"300\": #4db6ac,\n \"400\": #26a69a,\n \"500\": #009688,\n \"600\": #00897b,\n \"700\": #00796b,\n \"800\": #00695c,\n \"900\": #004d40,\n \"a100\": #a7ffeb,\n \"a200\": #64ffda,\n \"a400\": #1de9b6,\n \"a700\": #00bfa5\n);\n\n$clr-teal: map-get($clr-teal-list, \"base\");\n\n$clr-teal-50: map-get($clr-teal-list, \"50\");\n$clr-teal-100: map-get($clr-teal-list, \"100\");\n$clr-teal-200: map-get($clr-teal-list, \"200\");\n$clr-teal-300: map-get($clr-teal-list, \"300\");\n$clr-teal-400: map-get($clr-teal-list, \"400\");\n$clr-teal-500: map-get($clr-teal-list, \"500\");\n$clr-teal-600: map-get($clr-teal-list, \"600\");\n$clr-teal-700: map-get($clr-teal-list, \"700\");\n$clr-teal-800: map-get($clr-teal-list, \"800\");\n$clr-teal-900: map-get($clr-teal-list, \"900\");\n$clr-teal-a100: map-get($clr-teal-list, \"a100\");\n$clr-teal-a200: map-get($clr-teal-list, \"a200\");\n$clr-teal-a400: map-get($clr-teal-list, \"a400\");\n$clr-teal-a700: map-get($clr-teal-list, \"a700\");\n\n\n//\n// Green\n//\n\n$clr-green-list: (\n \"base\": #4caf50,\n \"50\": #e8f5e9,\n \"100\": #c8e6c9,\n \"200\": #a5d6a7,\n \"300\": #81c784,\n \"400\": #66bb6a,\n \"500\": #4caf50,\n \"600\": #43a047,\n \"700\": #388e3c,\n \"800\": #2e7d32,\n \"900\": #1b5e20,\n \"a100\": #b9f6ca,\n \"a200\": #69f0ae,\n \"a400\": #00e676,\n \"a700\": #00c853\n);\n\n$clr-green: map-get($clr-green-list, \"base\");\n\n$clr-green-50: map-get($clr-green-list, \"50\");\n$clr-green-100: map-get($clr-green-list, \"100\");\n$clr-green-200: map-get($clr-green-list, \"200\");\n$clr-green-300: map-get($clr-green-list, \"300\");\n$clr-green-400: map-get($clr-green-list, \"400\");\n$clr-green-500: map-get($clr-green-list, \"500\");\n$clr-green-600: map-get($clr-green-list, \"600\");\n$clr-green-700: map-get($clr-green-list, \"700\");\n$clr-green-800: map-get($clr-green-list, \"800\");\n$clr-green-900: map-get($clr-green-list, \"900\");\n$clr-green-a100: map-get($clr-green-list, \"a100\");\n$clr-green-a200: map-get($clr-green-list, \"a200\");\n$clr-green-a400: map-get($clr-green-list, \"a400\");\n$clr-green-a700: map-get($clr-green-list, \"a700\");\n\n\n//\n// Light green\n//\n\n$clr-light-green-list: (\n \"base\": #8bc34a,\n \"50\": #f1f8e9,\n \"100\": #dcedc8,\n \"200\": #c5e1a5,\n \"300\": #aed581,\n \"400\": #9ccc65,\n \"500\": #8bc34a,\n \"600\": #7cb342,\n \"700\": #689f38,\n \"800\": #558b2f,\n \"900\": #33691e,\n \"a100\": #ccff90,\n \"a200\": #b2ff59,\n \"a400\": #76ff03,\n \"a700\": #64dd17\n);\n\n$clr-light-green: map-get($clr-light-green-list, \"base\");\n\n$clr-light-green-50: map-get($clr-light-green-list, \"50\");\n$clr-light-green-100: map-get($clr-light-green-list, \"100\");\n$clr-light-green-200: map-get($clr-light-green-list, \"200\");\n$clr-light-green-300: map-get($clr-light-green-list, \"300\");\n$clr-light-green-400: map-get($clr-light-green-list, \"400\");\n$clr-light-green-500: map-get($clr-light-green-list, \"500\");\n$clr-light-green-600: map-get($clr-light-green-list, \"600\");\n$clr-light-green-700: map-get($clr-light-green-list, \"700\");\n$clr-light-green-800: map-get($clr-light-green-list, \"800\");\n$clr-light-green-900: map-get($clr-light-green-list, \"900\");\n$clr-light-green-a100: map-get($clr-light-green-list, \"a100\");\n$clr-light-green-a200: map-get($clr-light-green-list, \"a200\");\n$clr-light-green-a400: map-get($clr-light-green-list, \"a400\");\n$clr-light-green-a700: map-get($clr-light-green-list, \"a700\");\n\n\n//\n// Lime\n//\n\n$clr-lime-list: (\n \"base\": #cddc39,\n \"50\": #f9fbe7,\n \"100\": #f0f4c3,\n \"200\": #e6ee9c,\n \"300\": #dce775,\n \"400\": #d4e157,\n \"500\": #cddc39,\n \"600\": #c0ca33,\n \"700\": #afb42b,\n \"800\": #9e9d24,\n \"900\": #827717,\n \"a100\": #f4ff81,\n \"a200\": #eeff41,\n \"a400\": #c6ff00,\n \"a700\": #aeea00\n);\n\n$clr-lime: map-get($clr-lime-list, \"base\");\n\n$clr-lime-50: map-get($clr-lime-list, \"50\");\n$clr-lime-100: map-get($clr-lime-list, \"100\");\n$clr-lime-200: map-get($clr-lime-list, \"200\");\n$clr-lime-300: map-get($clr-lime-list, \"300\");\n$clr-lime-400: map-get($clr-lime-list, \"400\");\n$clr-lime-500: map-get($clr-lime-list, \"500\");\n$clr-lime-600: map-get($clr-lime-list, \"600\");\n$clr-lime-700: map-get($clr-lime-list, \"700\");\n$clr-lime-800: map-get($clr-lime-list, \"800\");\n$clr-lime-900: map-get($clr-lime-list, \"900\");\n$clr-lime-a100: map-get($clr-lime-list, \"a100\");\n$clr-lime-a200: map-get($clr-lime-list, \"a200\");\n$clr-lime-a400: map-get($clr-lime-list, \"a400\");\n$clr-lime-a700: map-get($clr-lime-list, \"a700\");\n\n\n//\n// Yellow\n//\n\n$clr-yellow-list: (\n \"base\": #ffeb3b,\n \"50\": #fffde7,\n \"100\": #fff9c4,\n \"200\": #fff59d,\n \"300\": #fff176,\n \"400\": #ffee58,\n \"500\": #ffeb3b,\n \"600\": #fdd835,\n \"700\": #fbc02d,\n \"800\": #f9a825,\n \"900\": #f57f17,\n \"a100\": #ffff8d,\n \"a200\": #ffff00,\n \"a400\": #ffea00,\n \"a700\": #ffd600\n);\n\n$clr-yellow: map-get($clr-yellow-list, \"base\");\n\n$clr-yellow-50: map-get($clr-yellow-list, \"50\");\n$clr-yellow-100: map-get($clr-yellow-list, \"100\");\n$clr-yellow-200: map-get($clr-yellow-list, \"200\");\n$clr-yellow-300: map-get($clr-yellow-list, \"300\");\n$clr-yellow-400: map-get($clr-yellow-list, \"400\");\n$clr-yellow-500: map-get($clr-yellow-list, \"500\");\n$clr-yellow-600: map-get($clr-yellow-list, \"600\");\n$clr-yellow-700: map-get($clr-yellow-list, \"700\");\n$clr-yellow-800: map-get($clr-yellow-list, \"800\");\n$clr-yellow-900: map-get($clr-yellow-list, \"900\");\n$clr-yellow-a100: map-get($clr-yellow-list, \"a100\");\n$clr-yellow-a200: map-get($clr-yellow-list, \"a200\");\n$clr-yellow-a400: map-get($clr-yellow-list, \"a400\");\n$clr-yellow-a700: map-get($clr-yellow-list, \"a700\");\n\n\n//\n// amber\n//\n\n$clr-amber-list: (\n \"base\": #ffc107,\n \"50\": #fff8e1,\n \"100\": #ffecb3,\n \"200\": #ffe082,\n \"300\": #ffd54f,\n \"400\": #ffca28,\n \"500\": #ffc107,\n \"600\": #ffb300,\n \"700\": #ffa000,\n \"800\": #ff8f00,\n \"900\": #ff6f00,\n \"a100\": #ffe57f,\n \"a200\": #ffd740,\n \"a400\": #ffc400,\n \"a700\": #ffab00\n);\n\n$clr-amber: map-get($clr-amber-list, \"base\");\n\n$clr-amber-50: map-get($clr-amber-list, \"50\");\n$clr-amber-100: map-get($clr-amber-list, \"100\");\n$clr-amber-200: map-get($clr-amber-list, \"200\");\n$clr-amber-300: map-get($clr-amber-list, \"300\");\n$clr-amber-400: map-get($clr-amber-list, \"400\");\n$clr-amber-500: map-get($clr-amber-list, \"500\");\n$clr-amber-600: map-get($clr-amber-list, \"600\");\n$clr-amber-700: map-get($clr-amber-list, \"700\");\n$clr-amber-800: map-get($clr-amber-list, \"800\");\n$clr-amber-900: map-get($clr-amber-list, \"900\");\n$clr-amber-a100: map-get($clr-amber-list, \"a100\");\n$clr-amber-a200: map-get($clr-amber-list, \"a200\");\n$clr-amber-a400: map-get($clr-amber-list, \"a400\");\n$clr-amber-a700: map-get($clr-amber-list, \"a700\");\n\n\n//\n// Orange\n//\n\n$clr-orange-list: (\n \"base\": #ff9800,\n \"50\": #fff3e0,\n \"100\": #ffe0b2,\n \"200\": #ffcc80,\n \"300\": #ffb74d,\n \"400\": #ffa726,\n \"500\": #ff9800,\n \"600\": #fb8c00,\n \"700\": #f57c00,\n \"800\": #ef6c00,\n \"900\": #e65100,\n \"a100\": #ffd180,\n \"a200\": #ffab40,\n \"a400\": #ff9100,\n \"a700\": #ff6d00\n);\n\n$clr-orange: map-get($clr-orange-list, \"base\");\n\n$clr-orange-50: map-get($clr-orange-list, \"50\");\n$clr-orange-100: map-get($clr-orange-list, \"100\");\n$clr-orange-200: map-get($clr-orange-list, \"200\");\n$clr-orange-300: map-get($clr-orange-list, \"300\");\n$clr-orange-400: map-get($clr-orange-list, \"400\");\n$clr-orange-500: map-get($clr-orange-list, \"500\");\n$clr-orange-600: map-get($clr-orange-list, \"600\");\n$clr-orange-700: map-get($clr-orange-list, \"700\");\n$clr-orange-800: map-get($clr-orange-list, \"800\");\n$clr-orange-900: map-get($clr-orange-list, \"900\");\n$clr-orange-a100: map-get($clr-orange-list, \"a100\");\n$clr-orange-a200: map-get($clr-orange-list, \"a200\");\n$clr-orange-a400: map-get($clr-orange-list, \"a400\");\n$clr-orange-a700: map-get($clr-orange-list, \"a700\");\n\n\n//\n// Deep orange\n//\n\n$clr-deep-orange-list: (\n \"base\": #ff5722,\n \"50\": #fbe9e7,\n \"100\": #ffccbc,\n \"200\": #ffab91,\n \"300\": #ff8a65,\n \"400\": #ff7043,\n \"500\": #ff5722,\n \"600\": #f4511e,\n \"700\": #e64a19,\n \"800\": #d84315,\n \"900\": #bf360c,\n \"a100\": #ff9e80,\n \"a200\": #ff6e40,\n \"a400\": #ff3d00,\n \"a700\": #dd2c00\n);\n\n$clr-deep-orange: map-get($clr-deep-orange-list, \"base\");\n\n$clr-deep-orange-50: map-get($clr-deep-orange-list, \"50\");\n$clr-deep-orange-100: map-get($clr-deep-orange-list, \"100\");\n$clr-deep-orange-200: map-get($clr-deep-orange-list, \"200\");\n$clr-deep-orange-300: map-get($clr-deep-orange-list, \"300\");\n$clr-deep-orange-400: map-get($clr-deep-orange-list, \"400\");\n$clr-deep-orange-500: map-get($clr-deep-orange-list, \"500\");\n$clr-deep-orange-600: map-get($clr-deep-orange-list, \"600\");\n$clr-deep-orange-700: map-get($clr-deep-orange-list, \"700\");\n$clr-deep-orange-800: map-get($clr-deep-orange-list, \"800\");\n$clr-deep-orange-900: map-get($clr-deep-orange-list, \"900\");\n$clr-deep-orange-a100: map-get($clr-deep-orange-list, \"a100\");\n$clr-deep-orange-a200: map-get($clr-deep-orange-list, \"a200\");\n$clr-deep-orange-a400: map-get($clr-deep-orange-list, \"a400\");\n$clr-deep-orange-a700: map-get($clr-deep-orange-list, \"a700\");\n\n\n//\n// Brown\n//\n\n$clr-brown-list: (\n \"base\": #795548,\n \"50\": #efebe9,\n \"100\": #d7ccc8,\n \"200\": #bcaaa4,\n \"300\": #a1887f,\n \"400\": #8d6e63,\n \"500\": #795548,\n \"600\": #6d4c41,\n \"700\": #5d4037,\n \"800\": #4e342e,\n \"900\": #3e2723,\n);\n\n$clr-brown: map-get($clr-brown-list, \"base\");\n\n$clr-brown-50: map-get($clr-brown-list, \"50\");\n$clr-brown-100: map-get($clr-brown-list, \"100\");\n$clr-brown-200: map-get($clr-brown-list, \"200\");\n$clr-brown-300: map-get($clr-brown-list, \"300\");\n$clr-brown-400: map-get($clr-brown-list, \"400\");\n$clr-brown-500: map-get($clr-brown-list, \"500\");\n$clr-brown-600: map-get($clr-brown-list, \"600\");\n$clr-brown-700: map-get($clr-brown-list, \"700\");\n$clr-brown-800: map-get($clr-brown-list, \"800\");\n$clr-brown-900: map-get($clr-brown-list, \"900\");\n\n\n//\n// Grey\n//\n\n$clr-grey-list: (\n \"base\": #9e9e9e,\n \"50\": #fafafa,\n \"100\": #f5f5f5,\n \"200\": #eeeeee,\n \"300\": #e0e0e0,\n \"400\": #bdbdbd,\n \"500\": #9e9e9e,\n \"600\": #757575,\n \"700\": #616161,\n \"800\": #424242,\n \"900\": #212121,\n);\n\n$clr-grey: map-get($clr-grey-list, \"base\");\n\n$clr-grey-50: map-get($clr-grey-list, \"50\");\n$clr-grey-100: map-get($clr-grey-list, \"100\");\n$clr-grey-200: map-get($clr-grey-list, \"200\");\n$clr-grey-300: map-get($clr-grey-list, \"300\");\n$clr-grey-400: map-get($clr-grey-list, \"400\");\n$clr-grey-500: map-get($clr-grey-list, \"500\");\n$clr-grey-600: map-get($clr-grey-list, \"600\");\n$clr-grey-700: map-get($clr-grey-list, \"700\");\n$clr-grey-800: map-get($clr-grey-list, \"800\");\n$clr-grey-900: map-get($clr-grey-list, \"900\");\n\n\n//\n// Blue grey\n//\n\n$clr-blue-grey-list: (\n \"base\": #607d8b,\n \"50\": #eceff1,\n \"100\": #cfd8dc,\n \"200\": #b0bec5,\n \"300\": #90a4ae,\n \"400\": #78909c,\n \"500\": #607d8b,\n \"600\": #546e7a,\n \"700\": #455a64,\n \"800\": #37474f,\n \"900\": #263238,\n);\n\n$clr-blue-grey: map-get($clr-blue-grey-list, \"base\");\n\n$clr-blue-grey-50: map-get($clr-blue-grey-list, \"50\");\n$clr-blue-grey-100: map-get($clr-blue-grey-list, \"100\");\n$clr-blue-grey-200: map-get($clr-blue-grey-list, \"200\");\n$clr-blue-grey-300: map-get($clr-blue-grey-list, \"300\");\n$clr-blue-grey-400: map-get($clr-blue-grey-list, \"400\");\n$clr-blue-grey-500: map-get($clr-blue-grey-list, \"500\");\n$clr-blue-grey-600: map-get($clr-blue-grey-list, \"600\");\n$clr-blue-grey-700: map-get($clr-blue-grey-list, \"700\");\n$clr-blue-grey-800: map-get($clr-blue-grey-list, \"800\");\n$clr-blue-grey-900: map-get($clr-blue-grey-list, \"900\");\n\n\n//\n// Black\n//\n\n$clr-black-list: (\n \"base\": #000\n);\n\n$clr-black: map-get($clr-black-list, \"base\");\n\n\n//\n// White\n//\n\n$clr-white-list: (\n \"base\": #fff\n);\n\n$clr-white: map-get($clr-white-list, \"base\");\n\n\n//\n// List for all Colors for looping\n//\n\n$clr-list-all: (\n \"red\": $clr-red-list,\n \"pink\": $clr-pink-list,\n \"purple\": $clr-purple-list,\n \"deep-purple\": $clr-deep-purple-list,\n \"indigo\": $clr-indigo-list,\n \"blue\": $clr-blue-list,\n \"light-blue\": $clr-light-blue-list,\n \"cyan\": $clr-cyan-list,\n \"teal\": $clr-teal-list,\n \"green\": $clr-green-list,\n \"light-green\": $clr-light-green-list,\n \"lime\": $clr-lime-list,\n \"yellow\": $clr-yellow-list,\n \"amber\": $clr-amber-list,\n \"orange\": $clr-orange-list,\n \"deep-orange\": $clr-deep-orange-list,\n \"brown\": $clr-brown-list,\n \"grey\": $clr-grey-list,\n \"blue-grey\": $clr-blue-grey-list,\n \"black\": $clr-black-list,\n \"white\": $clr-white-list\n);\n\n\n//\n// Typography\n//\n\n$clr-ui-display-4: $clr-grey-600;\n$clr-ui-display-3: $clr-grey-600;\n$clr-ui-display-2: $clr-grey-600;\n$clr-ui-display-1: $clr-grey-600;\n$clr-ui-headline: $clr-grey-900;\n$clr-ui-title: $clr-grey-900;\n$clr-ui-subhead-1: $clr-grey-900;\n$clr-ui-body-2: $clr-grey-900;\n$clr-ui-body-1: $clr-grey-900;\n$clr-ui-caption: $clr-grey-600;\n$clr-ui-menu: $clr-grey-900;\n$clr-ui-button: $clr-grey-900;\n","////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Variables\n// ----------------------------------------------------------------------------\n\n///\n/// Device-specific breakpoints\n///\n/// @example\n/// $break-devices: (\n/// mobile: (\n/// portrait: 220px 479px,\n/// landscape: 480px 719px\n/// ),\n/// tablet: (\n/// portrait: 720px 959px,\n/// landscape: 960px 1219px\n/// ),\n/// screen: (\n/// small: 1220px 1599px,\n/// medium: 1600px 1999px,\n/// large: 2000px\n/// )\n/// );\n///\n$break-devices: () !default;\n\n// ----------------------------------------------------------------------------\n// Helpers\n// ----------------------------------------------------------------------------\n\n///\n/// Choose minimum and maximum device widths\n///\n@function break-select-min-max($devices) {\n $min: 1000000;\n $max: 0;\n @each $key, $value in $devices {\n @while type-of($value) == map {\n $value: break-select-min-max($value);\n }\n @if type-of($value) == list {\n @each $number in $value {\n @if type-of($number) == number {\n $min: min($number, $min);\n @if $max {\n $max: max($number, $max);\n }\n } @else {\n @error \"Invalid number: #{$number}\";\n }\n }\n } @else if type-of($value) == number {\n $min: min($value, $min);\n $max: null;\n } @else {\n @error \"Invalid value: #{$value}\";\n }\n }\n @return $min, $max;\n}\n\n///\n/// Select minimum and maximum widths for a device breakpoint\n///\n@function break-select-device($device) {\n $current: $break-devices;\n @for $n from 1 through length($device) {\n @if type-of($current) == map {\n $current: map-get($current, nth($device, $n));\n } @else {\n @error \"Invalid device map: #{$devices}\";\n }\n }\n @if type-of($current) == list or type-of($current) == number {\n $current: (default: $current);\n }\n @return break-select-min-max($current);\n}\n\n// ----------------------------------------------------------------------------\n// Mixins\n// ----------------------------------------------------------------------------\n\n///\n/// A minimum-maximum media query breakpoint\n///\n@mixin break-at($breakpoint) {\n @if type-of($breakpoint) == number {\n @media screen and (min-width: $breakpoint) {\n @content;\n }\n } @else if type-of($breakpoint) == list {\n $min: nth($breakpoint, 1);\n $max: nth($breakpoint, 2);\n @if type-of($min) == number and type-of($max) == number {\n @media screen and (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else {\n @error \"Invalid breakpoint: #{$breakpoint}\";\n }\n } @else {\n @error \"Invalid breakpoint: #{$breakpoint}\";\n }\n}\n\n///\n/// An orientation media query breakpoint\n///\n@mixin break-at-orientation($breakpoint) {\n @if type-of($breakpoint) == string {\n @media screen and (orientation: $breakpoint) {\n @content;\n }\n } @else {\n @error \"Invalid breakpoint: #{$breakpoint}\";\n }\n}\n\n///\n/// A maximum-aspect-ratio media query breakpoint\n///\n@mixin break-at-ratio($breakpoint) {\n @if type-of($breakpoint) == number {\n @media screen and (max-aspect-ratio: $breakpoint) {\n @content;\n }\n } @else {\n @error \"Invalid breakpoint: #{$breakpoint}\";\n }\n}\n\n///\n/// A minimum-maximum media query device breakpoint\n///\n@mixin break-at-device($device) {\n @if type-of($device) == string {\n $device: $device,;\n }\n @if type-of($device) == list {\n $breakpoint: break-select-device($device);\n @if nth($breakpoint, 2) {\n $min: nth($breakpoint, 1);\n $max: nth($breakpoint, 2);\n\n @media screen and (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else {\n @error \"Invalid device: #{$device}\";\n }\n } @else {\n @error \"Invalid device: #{$device}\";\n }\n}\n\n///\n/// A minimum media query device breakpoint\n///\n@mixin break-from-device($device) {\n @if type-of($device) == string {\n $device: $device,;\n }\n @if type-of($device) == list {\n $breakpoint: break-select-device($device);\n $min: nth($breakpoint, 1);\n\n @media screen and (min-width: $min) {\n @content;\n }\n } @else {\n @error \"Invalid device: #{$device}\";\n }\n}\n\n///\n/// A maximum media query device breakpoint\n///\n@mixin break-to-device($device) {\n @if type-of($device) == string {\n $device: $device,;\n }\n @if type-of($device) == list {\n $breakpoint: break-select-device($device);\n $max: nth($breakpoint, 2);\n\n @media screen and (max-width: $max) {\n @content;\n }\n } @else {\n @error \"Invalid device: #{$device}\";\n }\n}\n","////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Rules\n// ----------------------------------------------------------------------------\n\n// Announcement bar\n.md-announce {\n\n // Text link, also on focus/hover\n a,\n a:focus,\n a:hover {\n color: currentColor;\n }\n\n // Don't wrap name of blog article\n strong {\n white-space: nowrap;\n }\n\n // Twitter icon\n .twitter {\n margin-left: 0.2em;\n }\n}\n","////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Rules\n// ----------------------------------------------------------------------------\n\n// Content footer\n.tx-content__footer {\n margin-top: px2rem(20px);\n text-align: center;\n\n // Link to Insiders\n a {\n display: inline-block;\n color: $clr-pink-500;\n transition:\n transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),\n color 125ms;\n\n // Link to Insiders on focus/hover\n &:focus,\n &:hover {\n transform: scale(1.2);\n }\n }\n\n // Horizontal separator\n hr {\n display: inline-block;\n width: px2rem(40px);\n margin: px2em(16px);\n vertical-align: middle;\n background-color: currentColor;\n border: none;\n }\n}\n","////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Rules\n// ----------------------------------------------------------------------------\n\n// Landing page container\n.tx-container {\n padding-top: px2rem(20px);\n background:\n url(\"data:image/svg+xml;utf8,\") no-repeat bottom,\n linear-gradient(\n to bottom,\n var(--md-primary-fg-color),\n hsla(280, 67%, 55%, 1) 99%,\n var(--md-default-bg-color) 99%\n );\n\n // Adjust background for slate theme\n [data-md-color-scheme=\"slate\"] & {\n background:\n url(\"data:image/svg+xml;utf8,\") no-repeat bottom,\n linear-gradient(\n to bottom,\n var(--md-primary-fg-color),\n hsla(280, 67%, 55%, 1) 99%,\n var(--md-default-bg-color) 99%\n );\n }\n}\n\n// Landing page hero\n.tx-hero {\n margin: 0 px2rem(16px);\n color: var(--md-primary-bg-color);\n\n // Hero headline\n h1 {\n margin-bottom: px2rem(20px);\n color: currentColor;\n font-weight: 700;\n\n // [mobile portrait -]: Larger hero headline\n @include break-to-device(mobile portrait) {\n font-size: px2rem(28px);\n }\n }\n\n // Hero content\n &__content {\n padding-bottom: px2rem(120px);\n }\n\n // [tablet landscape +]: Columnar display\n @include break-from-device(tablet landscape) {\n display: flex;\n align-items: stretch;\n\n // Adjust spacing and set dimensions\n &__content {\n max-width: px2rem(380px);\n margin-top: px2rem(70px);\n padding-bottom: 14vw;\n }\n\n // Hero image\n &__image {\n order: 1;\n width: px2rem(760px);\n transform: translateX(#{px2rem(80px)});\n }\n }\n\n // [screen +]: Columnar display and adjusted spacing\n @include break-from-device(screen) {\n\n // Hero image\n &__image {\n transform: translateX(#{px2rem(160px)});\n }\n }\n\n // Button\n .md-button {\n margin-top: px2rem(10px);\n margin-right: px2rem(10px);\n color: var(--md-primary-bg-color);\n\n // Button on focus/hover\n &:focus,\n &:hover {\n color: var(--md-default-bg-color);\n background-color: var(--md-accent-fg-color);\n border-color: var(--md-accent-fg-color);\n }\n\n // Primary button\n &--primary {\n color: hsla(280deg, 37%, 48%, 1);\n background-color: var(--md-primary-bg-color);\n border-color: var(--md-primary-bg-color);\n }\n }\n}\n","////\n/// Copyright (c) 2016-2021 Martin Donath \n///\n/// Permission is hereby granted, free of charge, to any person obtaining a\n/// copy of this software and associated documentation files (the \"Software\"),\n/// to deal in the Software without restriction, including without limitation\n/// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n/// and/or sell copies of the Software, and to permit persons to whom the\n/// Software is furnished to do so, subject to the following conditions:\n///\n/// The above copyright notice and this permission notice shall be included in\n/// all copies or substantial portions of the Software.\n///\n/// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n/// DEALINGS\n////\n\n// ----------------------------------------------------------------------------\n// Nothing to see here, move along\n// ----------------------------------------------------------------------------\n\n// Scoped in typesetted content to match specificity of regular content\n.md-typeset {\n\n // Icon search\n .mdx-icon-search {\n position: relative;\n background-color: var(--md-default-bg-color);\n border-radius: px2rem(2px);\n box-shadow:\n 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1),\n 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1);\n transition: box-shadow 125ms;\n\n // Icon search on focus/hover\n &:focus-within,\n &:hover {\n box-shadow:\n 0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15),\n 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15);\n }\n\n // Icon search input\n .md-input {\n background: var(--md-default-bg-color);\n box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07);\n\n // Slate theme, i.e. dark mode\n [data-md-color-scheme=\"slate\"] & {\n background: var(--md-code-bg-color);\n }\n }\n }\n\n // Icon search result\n .mdx-icon-search-result {\n max-height: 50vh;\n overflow-y: auto;\n // Hack: promote to own layer to reduce jitter\n backface-visibility: hidden;\n touch-action: pan-y;\n scrollbar-width: thin;\n scrollbar-color: var(--md-default-fg-color--lighter) transparent;\n\n // Webkit scrollbar\n &::-webkit-scrollbar {\n width: px2rem(4px);\n height: px2rem(4px);\n }\n\n // Webkit scrollbar thumb\n &::-webkit-scrollbar-thumb {\n background-color: var(--md-default-fg-color--lighter);\n\n // Webkit scrollbar thumb on hover\n &:hover {\n background-color: var(--md-accent-fg-color);\n }\n }\n\n // Icon search result metadata\n &__meta {\n position: absolute;\n top: px2rem(8px);\n right: px2rem(12px);\n color: var(--md-default-fg-color--lighter);\n font-size: px2rem(12.8px);\n }\n\n // Icon search result list\n &__list {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n // Icon search result item\n &__item {\n margin: 0;\n padding: px2rem(4px) px2rem(12px);\n border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest);\n\n // Omit border on last child\n &:last-child {\n border-bottom: none;\n }\n\n // Item content\n > * {\n margin-right: px2rem(12px);\n }\n\n // Set icon dimensions to fit\n img {\n width: px2rem(18px);\n height: px2rem(18px);\n\n // Slate theme, i.e. dark mode\n [data-md-color-scheme=\"slate\"] &[src*=squidfunk] {\n filter: invert(1);\n }\n }\n }\n }\n}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/v2.0.2/pdf/document.pdf b/v2.0.2/pdf/document.pdf new file mode 100644 index 0000000..dc1b69b Binary files /dev/null and b/v2.0.2/pdf/document.pdf differ diff --git a/v2.0.2/search/search_index.json b/v2.0.2/search/search_index.json new file mode 100644 index 0000000..2faecd0 --- /dev/null +++ b/v2.0.2/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"admin-guide/admin-configuration/","title":"Configuring zot","text":"

    The registry administrator configures zot primarily through settings in the configuration file.

    Using the information in this guide, you can compose a configuration file with the settings and features you require for your zot registry server.

    Before launching zot with a new configuration, we recommend that you verify the syntax of your configuration as described in Verifying the configuration file.

    "},{"location":"admin-guide/admin-configuration/#configuration-file","title":"Configuration file","text":"

    The configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:

    • network
    • storage
    • authentication
    • authorization
    • logging
    • metrics
    • synchronization with other registries
    • clustering

    The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:

    zot serve config.json

    The instructions and examples in this guide use zot as the name of the zot executable file. The examples do not include the path to the executable file.

    When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. This initial file is similar to the following example:

    {\n    \"distSpecVersion\": \"1.0.1\",\n    \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\"\n    },\n    \"http\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": \"8080\"\n    },\n    \"log\": {\n        \"level\": \"debug\"\n    }\n}\n

    The configuration file contains the Distribution Specification version (distSpecVersion). The structure and content of other attributes are described in the later sections of this guide.

    "},{"location":"admin-guide/admin-configuration/#extensions","title":"Extensions","text":"

    Additional registry features that are not a part of the Distribution Specification are allowed to be added as Extensions.

    With a full (not minimal) zot image, the following extension features can be enabled and configured under an extensions attribute in the configuration file as shown in the following example.

    {\n  ...\n  \"extensions\": {\n    \"metrics\": {},\n    \"sync\": {},\n    \"search\": {},\n    \"scrub\": {},\n    \"lint\": {},\n    \"trust\": {},\n    \"ui\": {}\n  }\n}\n

    The extension features are available only with a full zot image. With a minimal zot image, the extensions section is ignored if present.

    The following features are configured under the extensions attribute.

    • Metrics
    • Sync
    • Search
    • Scrub
    • Lint
    • ImageTrust
    • UI

    An extension feature is usually enabled by the presence of the feature\u2019s attribute under extensions. An extension feature can then be disabled by either omitting the feature attribute or by including an enable attribute with a value of false.

    Two API-only extensions, User Preferences and Mgmt, are not enabled or configured under the extensions section of the configuration file. These API-only extensions are enabled as follows:

    • Mgmt is enabled when the Search extension is enabled.

    • User Preferences is enabled when both the Search and UI extensions are enabled.

    "},{"location":"admin-guide/admin-configuration/#enabling-and-disabling-extensions","title":"Enabling and disabling extensions","text":"

    Following is an example of enabling or disabling a feature in the extensions section. The scrub feature is enabled in these two configurations:

    \"extensions\": {\n  \"scrub\": {}\n}\n
    \"extensions\": {\n  \"scrub\": {\n    \"enable\": true\n  }\n}\n

    The scrub feature is disabled in these two configurations:

    \"extensions\": {\n}\n
    \"extensions\": {\n  \"scrub\": {\n    \"enable\": false\n  }\n}\n
    "},{"location":"admin-guide/admin-configuration/#developing-custom-extensions","title":"Developing custom extensions","text":"

    New functionality can be added to the zot registry by developing custom extensions for integration into zot. For information about developing extensions, see Developing New Extensions.

    "},{"location":"admin-guide/admin-configuration/#network-configuration","title":"Network configuration","text":"

    Use the http attribute in the configuration file to configure the zot network settings, as shown in the following example.

    \"http\": {\n  \"address\":\"127.0.0.1\",\n  \"port\":\"8080\",\n  \"realm\":\"zot\",\n  \"tls\": {\n    \"cert\":\"test/data/server.cert\",\n    \"key\":\"test/data/server.key\"\n  }\n}\n

    The following table lists the configurable attributes.

    Attribute Description address The IP address of the zot server. port The port number of the zot server. realm The security policy domain defined for the server. tls The included attributes in this section specify the Transport Layer Security (TLS) settings for the server. cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key."},{"location":"admin-guide/admin-configuration/#storage","title":"Storage","text":"

    Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.

    Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following simple example.

    \"storage\":{\n  \"rootDirectory\":\"/tmp/zot\",\n  \"commit\": true,\n  \"dedupe\": true,\n  \"gc\": true,\n  \"gcDelay\": \"1h\",\n  \"gcInterval\": \"24h\"\n}\n

    With zot, you have the option to store your registry image files either in local filesystem storage or in cloud storage, such as an Amazon Simple Storage Service (S3) bucket.

    "},{"location":"admin-guide/admin-configuration/#local-storage","title":"Local storage","text":"

    zot can store and serve files from one or more local directories (folders). A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.

    Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.

    "},{"location":"admin-guide/admin-configuration/#remote-storage","title":"Remote storage","text":"

    zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS S3 storage service.

    For detailed information about configuring S3 storage, see the AWS S3 documentation and Storage Planning with zot.

    "},{"location":"admin-guide/admin-configuration/#storage-features","title":"Storage features","text":""},{"location":"admin-guide/admin-configuration/#commit","title":"Commit","text":"

    Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.

    "},{"location":"admin-guide/admin-configuration/#deduplication","title":"Deduplication","text":"

    Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.

    Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.

    "},{"location":"admin-guide/admin-configuration/#garbage-collection","title":"Garbage collection","text":"

    After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. The zot configuration model allows for enabling and disabling garbage collection (gc). The model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs.

    "},{"location":"admin-guide/admin-configuration/#scrub","title":"Scrub","text":"

    The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.

    "},{"location":"admin-guide/admin-configuration/#configuring-storage","title":"Configuring storage","text":"

    For detailed information about configuring local or remote storage and storage features for your zot registry, see Storage Planning with zot.

    "},{"location":"admin-guide/admin-configuration/#security-and-hardening","title":"Security and hardening","text":""},{"location":"admin-guide/admin-configuration/#authentication","title":"Authentication","text":"

    zot supports authentication by the following methods:

    • TLS mutual authentication

    • Basic local authentication using an htpasswd file

    • LDAP authentication

    • Bearer (OAuth2) authentication using an HTTP Bearer token

    For detailed information about configuring authentication for your zot registry, see User Authentication and Authorization with zot.

    "},{"location":"admin-guide/admin-configuration/#identity-based-authorization","title":"Identity-based authorization","text":"

    User identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific repository paths.

    For detailed information about configuring access control policies for your zot registry, see User Authentication and Authorization with zot.

    "},{"location":"admin-guide/admin-configuration/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"

    Use the auth and failDelay attributes under http in the configuration file to delay the response to an authentication failure. A delayed response helps to prevent automated attacks. The configuration is shown in the following example.

    \"http\": {\n  \"auth\": {\n    \"failDelay\": 5\n  }\n}\n

    The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.

    "},{"location":"admin-guide/admin-configuration/#rate-limiting","title":"Rate limiting","text":"

    You can limit the rate of API calls from users by configuring the Ratelimit attribute in the configuration file, as shown in the following example:

    \"http\": {\n    \"address\": \"127.0.0.1\",\n    \"port\": \"8080\",\n    \"Ratelimit\": {\n        \"Rate\": 10,\n        \"Methods\": [\n            {\n                \"Method\": \"GET\",\n                \"Rate\": 5\n            }\n        ]\n    }\n}\n

    In this example, the Rate attribute directly under Ratelimit sets a global rate limit of ten API calls per second. You can optionally override the global limit for specific API Methods. In this example, API GET calls are limited to five per second.

    "},{"location":"admin-guide/admin-configuration/#additional-security-features","title":"Additional security features","text":"

    For detailed information about configuring additional security features for your zot registry, see Security Posture.

    "},{"location":"admin-guide/admin-configuration/#monitoring","title":"Monitoring","text":"

    zot supports a range of monitoring tools including the following:

    • Logging

      Logging for zot operations is configured with the log attribute in the configuration file.

    • Metrics

      Metrics data is available in a Prometheus format. A full zot image with extensions includes a node exporter. A minimal zot image can use an external node exporter such as zxp.

    • Benchmarking

      The zot project includes the zb tool, which allows you to benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification.

    • Performance profiling

      Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

    When zot is deployed in a Kubernetes setup, a site reliability engineering (SRE) operator can monitor service level indicators (SLI) such as metrics and logs. Metrics will appear in Prometheus using the zot metrics extension, while logs will appear in the Elasticsearch stack (ELK stack) using Filebeat.

    For detailed information about the monitoring tools, see Monitoring the registry.

    For detailed information about benchmarking, see Benchmarking zot with zb.

    For detailed information about performance profiling, see Performance Profiling in zot.

    "},{"location":"admin-guide/admin-configuration/#clustering-zot","title":"Clustering zot","text":"

    To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.

    For detailed information about clustering with zot, see zot Clustering.

    "},{"location":"admin-guide/admin-configuration/#syncing-and-mirroring-registries","title":"Syncing and mirroring registries","text":"

    A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync extension feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Synchronization between registries can be implemented by periodic polling of the upstream registry or synchronization can occur on demand, when a user pulls an image from the downstream registry.

    As with git, wherein every clone is a full repository, you can configure a local zot instance to be a full OCI mirror registry. This allows for a fully distributed disconnected container image build pipeline.

    For detailed information about syncing and mirroring, see OCI Registry Mirroring With zot.

    "},{"location":"admin-guide/admin-configuration/#linting-uploaded-images","title":"Linting uploaded images","text":"

    The lint extension can check an uploaded image to enforce the presence of required annotations such as the author or the license.

    To configure linting, add the lint attribute under extensions in the configuration file, as shown in the following example:

    \"extensions\": {\n    \"lint\": {\n      \"enable\": true,\n      \"mandatoryAnnotations\": [\"annot1\", \"annot2\", \"annot3\"]\n      }\n  }\n

    The following table lists the configurable attributes of the lint extension.

    Attribute Description enable If this attribute is missing, incoming image linting is disabled by default. Linting can be enabled by including this attribute and setting it to true. mandatoryAnnotations A list of annotations that are required to be present in the image being pushed to the repository.

    If the mandatory annotations option is configured when you push an image, linter will verify that the mandatory annotations list present in the configuration is also found in the manifest's annotations list. If any annotations are missing, the push is denied.

    "},{"location":"admin-guide/admin-configuration/#verifying-the-signatures-of-uploaded-images","title":"Verifying the signatures of uploaded images","text":"

    The trust extension provides a mechanism to verify image signatures using certificates and public keys.

    To enable image signature verification, you must add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:

    \"extensions\": {\n  \"trust\": {\n    \"enable\": true,\n    \"cosign\": true,\n    \"notation\": true\n  }\n}\n

    You must also upload public keys (for cosign) or certificates (for notation) that can be used to verify the image signatures.

    For detailed information about configuring image signature verification, see Verifying image signatures.

    "},{"location":"admin-guide/admin-configuration/#enabling-the-registrys-graphical-user-interface","title":"Enabling the registry's graphical user interface","text":"

    Using the zot graphical user interface (GUI), a user can browse a zot registry for container images and artifacts.

    To configure zot's GUI, add the ui attribute under extensions in the configuration file, as shown in the following example:

    \"extensions\": {\n  \"ui\": {\n    \"enable\": true\n  }\n}\n

    The following table lists the configurable attributes of the ui extension.

    Attribute Description enable If this attribute is missing, the zot GUI is disabled by default. The GUI can be enabled by including this attribute and setting it to true."},{"location":"admin-guide/admin-configuration/#scrubbing-the-image-registry","title":"Scrubbing the image registry","text":"

    To check the integrity of the filesystem and the data in the registry, you can schedule a periodic scrub operation. The scrub process traverses the filesystem, verifying that all data blocks are readable. While running, the process may slightly reduce the registry performance.

    To enable scrubbing, add the scrub attribute under extensions in the configuration file, as shown in the following example:

    \"extensions\": {\n  \"scrub\": {\n    \"enable\": true,\n    \"interval\": \"24h\"\n  }\n}\n

    The following table lists the configurable attributes for scrubbing the registry.

    Attribute Description enable If this attribute is missing, registry scrubbing is enabled by default. Scrubbing can be disabled by setting this attribute to false. interval The time interval between periodic scrub operations. This value must be at least two hours (2h)."},{"location":"admin-guide/admin-configuration/#scheduling-background-tasks","title":"Scheduling background tasks","text":"

    Some zot functions, such as garbage collection and registry synchronization, run as background tasks. These tasks are queued and executed by the scheduler.

    The scheduler is by default allowed to simultaneously run a maximum number of tasks equal to four times the number of CPUs available to the zot process. For most users, there should be no need to modify this maximum number. If such a need arises, you can configure a new maximum number of simultaneous tasks in the numWorkers property of the scheduler attribute in the configuration file, as shown in the following example.

    {\n  \"distSpecVersion\": \"1.1.0-dev\",\n  \"scheduler\": {\n    \"numWorkers\": 3\n  },\n...\n}\n
    "},{"location":"admin-guide/admin-configuration/#enhanced-searching-and-querying-images","title":"Enhanced searching and querying images","text":"

    While basic searching is always enabled for images in the zot registry, you can enable enhanced registry searching and filtering using graphQL.

    Add the search attribute under extensions in the configuration file to enable and configure the enhanced search extension, as shown in the following example.

    \"extensions\": {\n  \"search\": {\n    \"enable\": true,\n    \"cve\": {\n      \"updateInterval\": \"2h\"\n    }\n  }\n}\n

    The following table lists the configurable attributes for enhanced search.

    Attribute Description enable If this attribute is missing, enhanced search is enabled by default. Enhanced search can be disabled by setting this attribute to false. cve Extends enhanced search to allow searching of Common Vulnerabilities and Exposures (CVE). updateInterval Sets the interval at which the searchable database of CVE items is refreshed."},{"location":"admin-guide/admin-configuration/#setting-user-preferences","title":"Setting user preferences","text":"

    The user preferences extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.

    The user preferences extension is enabled by default when the search and ui extensions are enabled. There are no other configuration file fields for this extension.

    A userprefs API endpoint accepts as a query parameter an action to perform along with any other required parameters for the specified action. The actions currently implemented do not require an HTTP payload, nor do they return any related data other than an HTTP response code.

    "},{"location":"admin-guide/admin-configuration/#current-functionality","title":"Current functionality","text":"

    The current functions implemented by this extension include:

    • Toggling the star (favorites) icon for a repository.
    • Toggling the bookmark icon for a repository.
    "},{"location":"admin-guide/admin-configuration/#toggle-repository-star","title":"Toggle repository star","text":"

    This action sets the repository star property to true if it is false, and to false if it is true.

    Action Parameter Parameter Description toggleStar repo The name of the repository whose star is to be changed

    This example toggles a star on a repository named repoName:

    PUT\nhttp://localhost:5000/v2/_zot/ext/userprefs?\naction=toggleStar&repo=repoName\n
    "},{"location":"admin-guide/admin-configuration/#toggle-repository-bookmark","title":"Toggle repository bookmark","text":"

    This action sets the repository bookmark property to true if it is false, and to false if it is true.

    Action Parameter Parameter Description toggleBookmark repo The name of the repository whose bookmark is to be changed

    This example toggles a bookmark on a repository named repoName:

    PUT\nhttp://localhost:5000/v2/_zot/ext/userprefs?\naction=toggleBookmark&repo=repoName\n
    "},{"location":"admin-guide/admin-configuration/#verifying-the-configuration-file","title":"Verifying the configuration file","text":"

    Before launching zot, verify the syntax of your configuration file using the following command:

    zot verify <configfile>

    Verifying the configuration file protects against operator errors and any conflicts arising from zot release version changes.

    After verifying your configuration file, you can launch zot with the following command:

    zot serve <configfile>

    "},{"location":"admin-guide/admin-getting-started/","title":"Getting Started with zot Administration","text":"

    This document helps you to deploy an appropriate zot image or to build zot if desired.

    After deploying zot, proceed to Configuring zot to choose and configure the features you need.

    "},{"location":"admin-guide/admin-getting-started/#installing-zot","title":"Installing zot","text":""},{"location":"admin-guide/admin-getting-started/#how-to-get-zot","title":"How to get zot","text":"

    The zot project is hosted on GitHub at project-zot. From GitHub, you can download zot executable binary images or full source code.

    "},{"location":"admin-guide/admin-getting-started/#supported-platforms","title":"Supported platforms","text":"

    zot is officially supported on Linux and Apple MacOS platforms, using Intel or ARM processors. However, development should be possible on any platform that supports the golang toolchain.

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*

    * NOTE: While binary images are available for FreeBSD, building container images is not supported at this time.

    "},{"location":"admin-guide/admin-getting-started/#about-binary-images","title":"About binary images","text":"

    Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.

    Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

    "},{"location":"admin-guide/admin-getting-started/#deployment-methods","title":"Deployment methods","text":"

    Several options exist for deploying zot:

    • You can launch a zot binary as a container service using a container management tool such as Podman, Docker, or Helm.

    • You can launch zot as a host-level service by downloading a binary image and running it as a systemd service.

    • You can copy or clone the full zot source code and build an image with custom build flags.

    "},{"location":"admin-guide/admin-getting-started/#deploying-a-zot-binary-image","title":"Deploying a zot binary image","text":"

    Executable binary images for supported server platforms and architectures are available from the zot package repository in GitHub.

    You can download the appropriate binary image and run it directly on your server, or you can use a container management tool such as Podman, runc, Helm, or Docker to fetch and deploy the image in a container on your server.

    For convenience, you can rename the binary image file to simply zot.

    "},{"location":"admin-guide/admin-getting-started/#example-deploying-with-a-container-manager","title":"Example: Deploying with a container manager","text":"

    Using a container manager such as Podman, runc, Helm, or Docker, you can install a zot binary image, as in the following examples.

    Using podman

    podman run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n\npodman run -p 5000:5000 ghcr.io/project-zot/zot-minimal-linux-amd64:latest\n
    Click here to view an example of deploying using podman.

    Using docker

    docker run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n

    Each of these example commands pulls a zot binary image from the GitHub Container Registry (ghcr.io) and launches a zot image registry at http://localhost:5000.

    Click here to view an example of deploying using docker.

    "},{"location":"admin-guide/admin-getting-started/#building-zot-from-source","title":"Building zot from source","text":""},{"location":"admin-guide/admin-getting-started/#prerequisites","title":"Prerequisites","text":""},{"location":"admin-guide/admin-getting-started/#install-golang","title":"Install golang","text":"

    Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.

    You must use a golang version of at least the minimum specified in go.mod or the build will fail.

    "},{"location":"admin-guide/admin-getting-started/#building-an-executable-binary-from-source","title":"Building an executable binary from source","text":"

    Download or clone the full zot project from GitHub at project-zot. To clone the zot project from GitHub, use this command:

    git clone https://github.com/project-zot/zot.git\n

    To build zot, execute the make command in the zot directory using the following general syntax:

    make OS=os ARCH=architecture {binary | binary-minimal}

    • The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.

    • The binary option builds the full zot binary image with all extensions.

    • The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.

    For example, to build a zot image with extensions for an Intel-based linux server, use the following command:

    make OS=linux ARCH=amd64 binary\n

    The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-linux-amd64-minimal.

    For convenience, you can rename the binary image file to simply zot.

    "},{"location":"admin-guide/admin-getting-started/#building-a-zot-container-image-from-source","title":"Building a zot container image from source","text":"

    with Stacker

    Using the settings in stacker.yaml, you can build a container image that runs the latest zot by running the following command:

    make binary-stacker\n

    with Docker

    A sample Dockerfile is provided on the zot project page in GitHub. You can edit the sample file with your specific values, such as the desired operating system, hardware architecture, and full or minimal build, as in this example:

    ARG OS=linux\nARG ARCH=amd64\n\nRUN make COMMIT=$COMMIT OS=$OS ARCH=$ARCH clean binary-minimal\n

    Using your edited Dockerfile, you can build a container image that runs the latest zot by running the following command:

    make image\n
    "},{"location":"admin-guide/admin-getting-started/#deploying-the-container-image","title":"Deploying the container image","text":"

    Deploy the image using your container manager, such as Podman, runc, Helm, or Docker, as in these examples:

    with Podman

    podman run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n

    with Docker

    docker run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n

    A container image built with the sample Dockerfile and deployed with the example command results in a running registry at http://localhost:5000. Registry content is stored at .registry, which is bind mounted to /var/lib/registry in the container. By default, auth is disabled. As part of the build, a YAML configuration file is created at /etc/zot/config.yml in the container.

    You can override the configuration file with custom configuration settings in the deployment command and in a local configuration file as shown in this example:

    podman run --rm -p 8080:8080 \\\n  -v $(pwd)/custom-config.yml:/etc/zot/config.yml \\\n  -v $(pwd)/registry:/tmp/zot \\\n  zot:latest\n

    This command causes the registry to listen on port 8080 and to use /tmp/zot for content storage.

    "},{"location":"admin-guide/admin-getting-started/#additional-recommended-steps","title":"Additional recommended steps","text":"

    We recommend that, when deploying zot, you also install the command line (zli) and benchmarking (zb) packages.

    "},{"location":"admin-guide/admin-getting-started/#launching-zot","title":"Launching zot","text":"

    The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:

    zot serve config.yml

    For convenience, you can rename the binary image file to simply zot.The instructions and examples in this guide use zot as the name of the zot executable file and do not include the path to the executable file.

    "},{"location":"admin-guide/admin-getting-started/#next-steps","title":"Next Steps","text":""},{"location":"admin-guide/admin-getting-started/#configuring-zot","title":"Configuring zot","text":"

    You configure zot primarily through adding and modifying settings in the zot configuration file. The configuration file is a JSON or YAML file that contains all configuration settings for zot functions.

    When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. You can modify the initial file or you can create a new file.

    Follow the instructions in Configuring zot, to compose a configuration file with the settings and features you require for your zot registry server.

    "},{"location":"articles/authn-authz/","title":"User Authentication and Authorization with zot","text":"

    A robust set of authentication/authorization options are supported:

    • Authentication

      • TLS, including mTLS
      • Username/password or token-based user authentication
      • LDAP
      • htpasswd
      • OAuth2 with bearer token
    • Authorization

      • Powerful identity-based access controls for repositories or specific repository paths
      • OpenID/OAuth2 social login with Google, GitHub, GitLab, and dex

    The zot configuration model supports both authentication and authorization. Authentication credentials allow access to zot HTTP APIs. Authorization policies provide fine-grained control of the actions each authenticated user can perform in the registry.

    "},{"location":"articles/authn-authz/#authentication","title":"Authentication","text":""},{"location":"articles/authn-authz/#tls-authentication","title":"TLS authentication","text":"

    Because authentication credentials are passed over HTTP, it is imperative that TLS be enabled. You can enable and configure TLS authentication in the zot configuration file, as shown in the following example.

    \"http\": {\n...\n  \"tls\": {\n    \"cert\": \"/etc/zot/certs/server.cert\",\n    \"key\": \"/etc/zot/certs/server.key\"\n  }\n

    See Mutual TLS authentication for additional information about TLS.

    "},{"location":"articles/authn-authz/#http-basic-authentication","title":"HTTP basic authentication","text":"

    When basic HTTP authentication is used, the username and password credentials are joined by a colon (:), base64 encoded, and passed in the HTTP Authorization header.

    "},{"location":"articles/authn-authz/#http-bearer-authentication","title":"HTTP bearer authentication","text":"

    To avoid passing the username and password credentials for every HTTP request, a zot client can use bearer token-based authentication. In this method, the client first authenticates with a token server and receives a short-lived token. The client then passes this token in the HTTP Authorization header, specifying Bearer as the authentication scheme.

    Configure bearer authentication in the zot configuration file as shown in this example.

    \"http\": {\n...\n  \"auth\": {\n    \"bearer\": {\n      \"realm\": \"https://auth.myreg.io/auth/token\",\n        \"service\": \"myauth\",\n        \"cert\": \"/etc/zot/auth.crt\"\n    }\n  }\n

    The following table lists the configurable attributes.

    Attribute Description realm A string typically related to the authentication scheme (BASIC and BEARER). service The name of the authentication service. cert The path and filename of the server\u2019s SSL/TLS certificate."},{"location":"articles/authn-authz/#mutual-tls-authentication","title":"Mutual TLS authentication","text":"

    zot supports basic TLS and password-less mutual TLS authentication (mTLS). Specifying a cacert file in the TLS section of the zot configuration file enables mTLS. The cacert parameter is used to validate the client-side TLS certificates.

    \"http\": {\n...\n  \"tls\": {\n    \"cert\": \"/etc/zot/certs/server.cert\",\n    \"key\": \"/etc/zot/certs/server.key\",\n    \"cacert\": \"/etc/zot/certs/ca.cert\"\n  }\n

    The following table lists the configurable attributes.

    Attribute Description cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key. cacert The path and filename of the server\u2019s cacerts file, which contains trusted certificate authority (CA) certificates."},{"location":"articles/authn-authz/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"

    To help prevent automated attacks, you can add a delayed response to an authentication failure. Configure the failDelay attribute in the configuration file as shown in the following example.

    \"http\": {\n  \"auth\": {\n    \"failDelay\": 5\n  }\n}\n

    The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.

    "},{"location":"articles/authn-authz/#server-side-authentication","title":"Server-side authentication","text":"

    You can implement server-side authentication for zot using htpasswd or LDAP or both.

    When both htpasswd and LDAP configuration are specified, LDAP authentication is given preference. Because htpasswd authentication is strictly local and requires no remote service, htpasswd serves as a fail-safe authentication mechanism should LDAP become unavailable.

    "},{"location":"articles/authn-authz/#ldap","title":"LDAP","text":"

    zot supports integration with an LDAP-based authentication service such as Microsoft Windows Active Directory (AD). Enable and configure LDAP authentication in the zot configuration file, as shown in the following example.

    \"http\": {\n...\n  \"auth\": {\n    \"ldap\": {\n      \"credentialsFile\": \"examples/config-ldap-credentials.json\",\n      \"address\": \"ldap.example.org\",\n      \"port\": 389,\n      \"startTLS\": false,\n      \"baseDN\": \"ou=Users,dc=example,dc=org\",\n      \"userAttribute\": \"uid\",\n      \"userGroupAttribute\": \"memberOf\",\n      \"bindDN\": \"cn=ldap-searcher,ou=Users,dc=example,dc=org\",\n      \"bindPassword\": \"ldap-searcher-password\",\n      \"skipVerify\": false,\n      \"subtreeSearch\": true\n    }\n  }\n}\n

    The following table lists the configurable attributes for LDAP authentication.

    Attribute Description credentialsFile The path to a file containing the bind credentials for LDAP. address The IP address or hostname of the LDAP server. port The port number used by the LDAP service. startTLS Set to true to enable TLS communication with the LDAP server. baseDN Starting location within the LDAP directory for performing user searches. userAttribute Attribute name used to obtain the username. userGroupAttribute Attribute name used to obtain groups to which a user belongs. skipVerify Skip TLS verification. subtreeSearch Set to true to expand the scope for search to include subtrees of the base DN.

    To allow for separation of configuration and credentials, the credentials for the LDAP server are specified in a separate file, as shown in the following example.

    {\n  \"bindDN\":\"cn=ldap-searcher,ou=Users,dc=example,dc=org\",\n  \"bindPassword\":\"ldap-searcher-password\"\n}\n

    The following table lists the configurable attributes of the LDAP credentials file.

    Attribute Description bindDN Base Distinguished Name for the LDAP search. bindPassword Password of the bind LDAP user."},{"location":"articles/authn-authz/#htpasswd","title":"htpasswd","text":"

    Enable and configure htpasswd authentication in the zot configuration file, as shown in the following example.

    1. Create and store an htpasswd file on the server.

      $ htpasswd -bBn <username> <password> >> /etc/zot/htpasswd\n

      For strong security, make sure to use the -B option, specifying the bcrypt hashing algorithm. This is the only algorithm supported by zot for htpasswd.

    2. Enable htpasswd authentication and configure the path to the htpasswd authentication in the zot configuration file.

      \"http\": {\n...\n  \"auth\": {\n      \"htpasswd\": {\n        \"path\": \"/etc/zot/htpasswd\"\n      },\n

      The path attribute specifies the path and filename of the htpasswd file, which contains user names and hashed passwords.

    "},{"location":"articles/authn-authz/#authorization","title":"Authorization","text":"

    With an access scheme that relies solely on authentication, any authenticated user would be given complete access to the registry. To better control access, zot supports identity-based repository-level access control (authorization) policies. The access control policy is a function of repository, user, and the action being performed on that repository.

    "},{"location":"articles/authn-authz/#access-control-policies","title":"Access control policies","text":"

    Five identity-based types of access control policies are supported:

    Policy type Attribute Access allowed Default defaultPolicy The default policy specifies what actions are allowed if a user is authenticated but does match any user-specific policy. User-specific users, actions A user-specific policy specifies access and actions for explicitly named users. Group-specific groups, actions A group-specific policy specifies access and actions for explicitly named groups. Anonymous anonymousPolicy An anonymous policy specifies what an unauthenticated user is allowed to do. This is an appropriate policy when you want to grant open read-only access to one or more repositories. Admin adminPolicy The admin policy is a global access control policy that grants privileges to perform actions on any repository.

    Access control is organized by repositories, users, and their actions. Most users of a particular repository will have similar access control requirements and can be served by a repository-specific defaultPolicy. Should a user require an exception to the default policy, a user-specific or group-specific override policy can be configured.

    With an anonymousPolicy, a repository can allow anonymous actions which do not require user authentication. Finally, one or more users can be designated as administrators, to whom the global adminPolicy applies.

    A user's access to a particular repository is evaluated first by whether a user-specific policy exists, then by group-specific policies, and then (in order) by default and admin policies.

    A group-specific policy can be applied within any type of access policy, including default or admin policies. The group policy name can also be used with LDAP.

    "},{"location":"articles/authn-authz/#configuring-access-control","title":"Configuring access control","text":"

    User identity or group identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific paths.

    When you define policies for specific repository paths, the paths can be specified explicitly or by using glob patterns with simple or recursive wildcards. When a repository path matches more than one path description, authorization is granted based on the policy of the longest (most specific) path matched. For example, if policies are defined for path descriptions ** and repos2/repo, the repos2/repo path will match both ** and repos2/repo descriptions. In this case, the repos2/repo policy will be applied because it is longer.

    Note that ** effectively defines the default policy, as it matches any path not matched by any other per-repository policy. To override all other policies, you can specify a global admin policy.

    Always include the read action in any policy that you define. The create, update, and delete actions cannot be used without the read action.

    "},{"location":"articles/authn-authz/#example-access-control-configuration","title":"Example: Access control configuration","text":"

    Use the accessControl attribute in the configuration file to define a set of identity-based authorization policies, as shown in the following example.

    \"http\": {\n...\n  \"accessControl\": {\n    \"groups\": {\n      \"group1\": {\n        \"users\": [\"bob\", \"mary\"]\n      },\n      \"group2\": {\n        \"users\": [\"alice\", \"mallory\", \"jim\"]\n      }\n    },\n    \"repositories\": {\n      \"**\": {\n        \"policies\": [{\n          \"users\": [\"charlie\"],\n          \"groups\": [\"group2\"],\n          \"actions\": [\"read\", \"create\", \"update\"]\n        }],\n        \"defaultPolicy\": [\"read\", \"create\"]\n      },\n      \"tmp/**\": {\n        \"anonymousPolicy\": [\"read\"],\n        \"defaultPolicy\": [\"read\", \"create\", \"update\"]\n      },\n      \"infra/*\": {\n        \"policies\": [{\n            \"users\": [\"alice\", \"bob\"],\n            \"actions\": [\"create\", \"read\", \"update\", \"delete\"]\n          },\n          {\n            \"users\": [\"mallory\"],\n            \"groups\": [\"group1\"],\n            \"actions\": [\"create\", \"read\"]\n          }\n        ],\n        \"defaultPolicy\": [\"read\"]\n      },\n      \"repos2/repo\": {\n        \"policies\": [{\n            \"users\": [\"bob\"],\n            \"actions\": [\"read\", \"create\"]\n          },\n          {\n            \"users\": [\"mallory\"],\n            \"actions\": [\"create\", \"read\"]\n          }\n        ],\n        \"defaultPolicy\": [\"read\"]\n      }\n    },\n    \"adminPolicy\": {\n      \"users\": [\"admin\"],\n      \"actions\": [\"read\", \"create\", \"update\", \"delete\"]\n    }\n  }\n

    In this example, five policies are defined:

    • The default policy (**) gives all authenticated users the ability to read or create content, while giving user \"charlie\" and those in \"group2\" the additional ability to update content.

    • The policy for tmp/** matches all repositories under tmp recursively and allows all authenticated users to read, create, or update content in those repositories. Unauthenticated users have read-only access to these repositories.

    • The policy for infra/* matches all repositories directly under infra. Separate policies are defined for specific users, along with a default read-only policy for all other users.

    • The policy for repos2/repo matches only that specific repository.

    • An admin policy (adminPolicy) gives the user \"admin\" global authorization to read, create, update, or delete content in any repository, overriding all other policies.

    In releases prior to zot v2.0.0, authorization policies were defined directly under the accessControl key in the zot configuration file. Beginning with v2.0.0, the set of authorization policies are now defined under a new repositories key.

    "},{"location":"articles/authn-authz/#social-login-using-openidoauth2","title":"Social login using OpenID/OAuth2","text":"

    Social login is an authentication/authorization method in which your existing credentials for another site or service can be used to log in to a service such as zot. For example, you can log in to zot using your GitHub account credentials, and zot will contact GitHub to verify your identity using OAuth 2.0 and OpenID Connect (OIDC) protocols.

    Several social login providers are supported by zot:

    • github
    • google
    • gitlab
    • oidc (for example, dex)

    The following example shows the zot configuration for these providers:

    {\n  \"http\": {\n    \"auth\": {\n      \"openid\": {\n        \"providers\": {\n          \"github\": {\n            \"clientid\": <client_id>,\n            \"clientsecret\": <client_secret>,\n            \"scopes\": [\"read:org\", \"user\", \"repo\"]\n          },\n          \"google\": {\n            \"issuer\": \"https://accounts.google.com\",\n            \"clientid\": <client_id>,\n            \"clientsecret\": <client_secret>,\n            \"scopes\": [\"openid\", \"email\"]\n          },\n          \"gitlab\": {\n            \"issuer\": \"https://gitlab.com\",\n            \"clientid\": <client_id>,\n            \"clientsecret\": <client_secret>,\n            \"scopes\": [\"openid\", \"read_api\", \"read_user\", \"profile\", \"email\"]\n          },\n          \"oidc\": {\n            \"issuer\": \"http://<zot-server>:5556/dex\",\n            \"clientid\": <client_id>,\n            \"clientsecret\": <client_secret>,\n            \"keypath\": \"\",\n            \"scopes\": [\"openid\", \"profile\", \"email\", \"groups\"]\n          }\n        }\n      }\n    }\n  }\n}\n
    "},{"location":"articles/authn-authz/#using-google-github-or-gitlab","title":"Using Google, GitHub, or GitLab","text":"

    A client logging into zot by social login must specify a supported OpenID/OAuth2 provider as a URL query parameter. A client logging in using Google, GitHub, or GitLab must additionally specify a callback URL for redirection to a zot page after a successful authentication.

    The login URL using Google, GitHub, or GitLab uses the following format:

    http://<zot-server>/auth/login?provider=<provider>&callback_ui=<zot-server>/<page>\n

    For example, a user logging in to the zot home page using GitHub as the authentication provider sends this URL:

    http://zot.example.com:8080/auth/login?provider=github&callback_ui=http://zot.example.com:8080/home\n

    Based on the specified provider, zot redirects the login to a provider service with the following URL:

    http://<zot-server>/zot/auth/callback/<provider>\n

    For the GitHub authentication example:

    http://zot.example.com:8080/zot/auth/callback/github\n

    If your network policy doesn't allow inbound connections, the callback will not work and this authentication method will fail.

    "},{"location":"articles/authn-authz/#using-dex","title":"Using dex","text":"

    dex is an identity service that uses OpenID Connect (OIDC) to drive authentication for client apps, such as zot. While this section shows how to use dex with zot, zot supports other OIDC services as well.

    Like zot, dex uses a configuration file for setup. To specify zot as a client in dex, configure a staticClients entry in the dex configuration file with a zot callback, such as the following example in the dex configuration file:

    staticClients:\n  - id: zot-client\n    redirectURIs:\n      - 'http://zot.example.com:8080/zot/auth/callback/oidc'\n    name: 'zot'\n    secret: ZXhhbXBsZS1hcHAtc2VjcmV0\n

    In the zot configuration file, configure dex as an OpenID auth provider as in the following example:

      \"http\": {\n    \"auth\": {\n      \"openid\": {\n        \"providers\": {\n          \"oidc\": {\n            \"name\": \"Corporate SSO\",\n            \"issuer\": \"http://<zot-server>:5556/dex\",\n            \"clientid\": \"zot-client\",\n            \"clientsecret\": \"ZXhhbXBsZS1hcHAtc2VjcmV0\",\n            \"keypath\": \"\",\n            \"scopes\": [\"openid\", \"profile\", \"email\", \"groups\"]\n          }\n        }\n      }\n    }\n  }\n

    A user logging in to zot using dex OpenID authentication sends a URL with dex as a URL query parameter, such as the following example:

    http://zot.example.com:8080/auth/login?provider=oidc

    For detailed information about configuring dex service, see the dex Getting Started documentation.

    "},{"location":"articles/authn-authz/#using-openidoauth2-when-zot-is-behind-a-proxy-or-load-balancer","title":"Using OpenID/OAuth2 when zot is behind a proxy or load balancer","text":"

    When the zot registry is running behind a proxy or load balancer, you must provide an external URL for OpenID/OAuth2 clients to redirect back to zot. This externalUrl attribute is the URL of the registry, as shown in this example:

      \"http\": {\n    \"address\": \"0.0.0.0\",\n    \"port\": \"8080\",\n    \"externalUrl\": \"https://zot.example.com\",\n    \"auth\": {\n      \"openid\": {\n        \"providers\": {\n          \"github\": {\n            \"clientid\": <client_id>,\n            \"clientsecret\": <client_secret>,\n            \"scopes\": [\"read:org\", \"user\", \"repo\"]\n          }\n        }\n      }\n    }\n  }\n
    "},{"location":"articles/benchmarking-with-zb/","title":"Benchmarking zot with zb","text":"

    The zb tool is useful for benchmarking OCI registry workloads in scenarios such as the following:

    • comparing configuration changes
    • comparing software versions
    • comparing hardware/deployment environments
    • comparing with other registries

    With the zb tool, you can benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification published by the Open Container Initiative (OCI).

    We recommend installing and benchmarking with zb when you install zot.

    "},{"location":"articles/benchmarking-with-zb/#how-to-get-zb","title":"How to get zb","text":"

    The zb project is hosted with zot on GitHub at project-zot. From GitHub, you can download the zb binary or you can build zb from the source. You can also directly run the released docker image.

    "},{"location":"articles/benchmarking-with-zb/#supported-platforms-and-architectures","title":"Supported platforms and architectures","text":"

    zb is supported for the following operating systems and platform architectures:

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"articles/benchmarking-with-zb/#downloading-zb-binaries","title":"Downloading zb binaries","text":"

    Download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.

    The binary image is named using the target platform and architecture from the Supported platforms and architectures table. For example, the binary for an Intel-based MacOS server is zb-darwin-amd64.

    "},{"location":"articles/benchmarking-with-zb/#building-zb-from-source","title":"Building zb from source","text":"

    To build the zb binary, copy or clone the zot project from GitHub and execute the make bench command in the zot directory. Use the same command options that you used to build zot, as shown:

    make OS=os ARCH=architecture bench

    For example, the following command builds zb for an Intel-based MacOS server:

    make OS=darwin ARCH=amd64 bench

    In this example, the resulting executable file is zb-darwin-amd64 in the zot/bin directory.

    A sample Dockerfile for zb is available at Dockerfile-zb.

    "},{"location":"articles/benchmarking-with-zb/#running-zb","title":"Running zb","text":"

    The original filename of the executable file will reflect the build options, such as zb-linux-amd64. For convenience, you can rename the executable to simply zb.

    The instructions and examples in this guide use zb as the name of the executable file.

    "},{"location":"articles/benchmarking-with-zb/#usage","title":"Usage","text":"

    To view the usage and options of zb, run the command with the --help option:

    bin/zb --help

    Command output:

        Usage:\n      zb <url> [flags]\n\n    Flags:\n      -A, --auth-creds string \u00a0 \u00a0 \u00a0Use colon-separated BASIC auth creds\n      -c, --concurrency int \u00a0 \u00a0 \u00a0 \u00a0Number of multiple requests to make at a time (default 1)\n \u00a0    -h, --help \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 help for zb\n \u00a0    -o, --output-format string \u00a0 Output format of test results: stdout (default), json, ci-cd\n \u00a0    -r, --repo string \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Use specified repo on remote registry for test data\n \u00a0    -n, --requests int \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Number of requests to perform (default 1)\n \u00a0    -s, --src-cidr string \u00a0 \u00a0 \u00a0 \u00a0Use specified cidr to obtain ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0    -i, --src-ips string \u00a0 \u00a0 \u00a0 \u00a0 Use colon-separated ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0    -v, --version \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Show the version and exit\n \u00a0    -d, --working-dir string \u00a0 \u00a0 Use specified directory to store test data\n
    "},{"location":"articles/benchmarking-with-zb/#example","title":"Example","text":"

    The following example executes a benchmark operation using zb.

    bin/zb -c 10 -s 127.0.10.0/24 -n 1000 http://localhost:8080

    You can also run the released docker image.

    docker run --net=host -it ghcr.io/project-zot/zb-linux-amd64:latest -c 10 -n 1000 -s 127.0.10.0/24 http://localhost:8080

    Command output:

        Registry URL: http://localhost:8080\n\n    Concurrency Level: 2\n    Total requests:    100\n    Working dir:\n\n    ========\n    Test name:            Get Catalog\n    Time taken for tests: 45.397205ms\n    Complete requests:    100\n    Failed requests:      0\n    Requests per second:  2202.7788\n\n    2xx responses: 100\n\n    min: 402.259\u00b5s\n    max: 3.295887ms\n    p50: 855.045\u00b5s\n    p75: 971.709\u00b5s\n    p90: 1.127389ms\n    p99: 3.295887ms\n\n    ========\n    Test name:            Push Monolith 1MB\n    Time taken for tests: 952.336383ms\n    Complete requests:    100\n    Failed requests:      0\n    Requests per second:  105.00491\n\n    2xx responses: 100\n\n    min: 11.125673ms\n    max: 26.375356ms\n    p50: 18.917253ms\n    p75: 21.753441ms\n    p90: 24.02137ms\n    p99: 26.375356ms\n\n    ...\n
    "},{"location":"articles/building-ci-cd-pipeline/","title":"Building an OCI-native Container Image CI/CD Pipeline","text":"

    An OCI-native secure container image build/delivery pipeline using the following tools:

    • stacker for building OCI images

    • zot as a vendor-neutral OCI image registry server

    • skopeo for performing repository interactions

    • cosign for container signing and verification

    • cri-o for deploying container images

    • cosigned for validating container images before deployment

    The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.

    This document describes a step-by-step procedure towards achieving an OCI-native secure software supply chain using zot in collaboration with other open source tools. The following diagram shows a portion of the CI/CD pipeline.

    "},{"location":"articles/building-ci-cd-pipeline/#build-images","title":"Build images","text":"

    stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout.

    example: stacker build command

    stacker build -f <stackerfile.yaml>\n
    "},{"location":"articles/building-ci-cd-pipeline/#image-registry","title":"Image registry","text":"

    zot is a production-ready vendor-neutral OCI image registry server purely based on the OCI Distribution Specification. If stacker is used to build the OCI image, it can also be used to publish the built image to an OCI registry.

    example: stacker publish command

    stacker publish --url <url> --username <user> --password <password>\n

    Alternatively, you can use skopeo, a command line utility that performs various operations on container images and image repositories.

    example: skopeo copies an image to a registry

    skopeo copy --format=oci oci:<oci-dir>/image:tag \\\n  docker://<zot-server>/image:tag\n
    Click here to view an example of pushing and pulling an image using skopeo.

    "},{"location":"articles/building-ci-cd-pipeline/#signing-images","title":"Signing images","text":"

    cosign is a tool that performs container signing, verification, and storage in an OCI registry.

    example: cosign generates keys and signs an image in the registry

    cosign generate-key-pair\n\ncosign sign --key cosign.key <zot-server>/image:tag\n
    Click here to view an example of cosign operations.

    "},{"location":"articles/building-ci-cd-pipeline/#deploying-container-images","title":"Deploying container images","text":"

    cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes.

    zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.

    example: kubelet configuration file

    apiVersion: v1\nkind: Pod\nmetadata:\n  name: example-pod\nspec:\n  containers:\n  - name: example-container\n    image: <zot-server>/image:tag\n
    "},{"location":"articles/building-ci-cd-pipeline/#container-image-verification","title":"Container image verification","text":"

    cosigned is an image admission controller that validates container images before deploying them.

    example: install cosigned using Helm

    kubectl create namespace cosign-system\n\nkubectl create secret generic mysecret -n \\\n  cosign-system --from-file=cosign.pub=./cosign.pub\n\nhelm repo add sigstore https://sigstore.github.io/helm-charts\n\nhelm repo update\n\nhelm install cosigned -n cosign-system sigstore/cosigned \\\n  --devel --set cosign.secretKeyRef.name=mysecret\n
    "},{"location":"articles/clustering/","title":"zot Clustering","text":"

    High availability of the zot registry is supported by the following features:

    • Stateless zot instances to simplify scale out
    • Bare-metal and Kubernetes deployments

    To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.

    Clustering is supported in both bare-metal and Kubernetes environments.

    The remote backend storage must be S3 API-compatible.

    "},{"location":"articles/clustering/#bare-metal-deployment","title":"Bare-metal deployment","text":""},{"location":"articles/clustering/#prerequisites","title":"Prerequisites","text":"
    • A highly-available loadbalancer such as HAProxy configured to direct traffic to zot replicas.

    • Multiple zot replicas as systemd services hosted on multiple hosts or VMs.

    • AWS S3 API-compatible remote backend storage.

    "},{"location":"articles/clustering/#kubernetes-deployment","title":"Kubernetes deployment","text":""},{"location":"articles/clustering/#prerequisites_1","title":"Prerequisites","text":"
    • A zot Kubernetes Deployment with required number of replicas.

    • AWS S3 API-compatible remote backend storage.

    • A zot Kubernetes Service.

    • A zot Kubernetes Ingress Gateway if the service needs to be exposed outside.

    "},{"location":"articles/clustering/#implementing-stateless-zot","title":"Implementing stateless zot","text":"

    zot maintains two types of durable state:

    • the actual image data itself

    • the image metadata in the registry\u2019s cache

    In a stateless clustering scheme, the image data is stored in the remote storage backend and the registry cache is disabled by turning off both deduplication and garbage collection.

    "},{"location":"articles/clustering/#ecosystem-tools","title":"Ecosystem tools","text":"

    The OCI Distribution Specification imposes certain rules about the HTTP URI paths to which various ecosystem tools must conform. Consider these rules when setting the HTTP prefixes during loadbalancing and ingress gateway configuration.

    "},{"location":"articles/clustering/#examples","title":"Examples","text":"

    zot supports clustering by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load-balancing traffic to the replicas.

    "},{"location":"articles/clustering/#yaml-configuration","title":"YAML configuration","text":"Click here to view a sample haproxy configuration.
    global\n        log /dev/log    local0\n        log /dev/log    local1 notice\n        chroot /var/lib/haproxy\n        maxconn 2000\n        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners\n        stats timeout 30s\n        user haproxy\n        group haproxy\n        daemon\n\n        # Default SSL material locations\n        ca-base /etc/ssl/certs\n        crt-base /etc/ssl/private\n\n        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate\n        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\n        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets\n\ndefaults\n        log     global\n        mode    http\n        option  httplog\n        option  dontlognull\n        timeout connect 5000\n        timeout client  50000\n        timeout server  50000\n        errorfile 400 /etc/haproxy/errors/400.http\n        errorfile 403 /etc/haproxy/errors/403.http\n        errorfile 408 /etc/haproxy/errors/408.http\n        errorfile 500 /etc/haproxy/errors/500.http\n        errorfile 502 /etc/haproxy/errors/502.http\n        errorfile 503 /etc/haproxy/errors/503.http\n        errorfile 504 /etc/haproxy/errors/504.http\n\nfrontend zot\n    bind *:8080\n    mode http\n    default_backend zot-cluster\n\nbackend zot-cluster\n    mode http\n    balance roundrobin\n    server zot1 127.0.0.1:8081 check\n    server zot2 127.0.0.1:8082 check\n    server zot3 127.0.0.1:8083 check\n
    "},{"location":"articles/clustering/#zot-s3-configuration","title":"zot S3 configuration","text":"Click here to view a sample zot configuration for S3.
    {\n    \"distSpecVersion\": \"1.0.1-dev\",\n    \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\",\n        \"dedupe\": true,\n        \"storageDriver\": {\n            \"name\": \"s3\",\n            \"rootdirectory\": \"/zot\",\n            \"region\": \"us-east-2\",\n            \"bucket\": \"zot-storage\",\n            \"secure\": true,\n            \"skipverify\": false\n        },\n        \"cacheDriver\": {\n            \"name\": \"dynamodb\",\n            \"endpoint\": \"http://localhost:4566\",\n            \"region\": \"us-east-2\",\n            \"tableName\": \"MainTable\"\n        }\n    },\n    \"http\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": \"8080\"\n    },\n    \"log\": {\n        \"level\": \"debug\"\n    }\n}\n
    "},{"location":"articles/graphql/","title":"Using GraphQL for Enhanced Searches","text":"

    A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. You can submit a GraphQL structured query as an API call or you can use a browser to access the GraphQL Playground, an interactive graphical environment for GraphQL queries.

    "},{"location":"articles/graphql/#how-to-use-graphql-for-search-queries","title":"How to use GraphQL for search queries","text":"

    GraphQL is a query language for APIs. A GraphQL server, as implemented in zot's registry search engine, executes GraphQL queries that match schema recognized by the server. In response, the server returns a structure containing the requested information. The schema currently recognized by zot are those that correspond to the queries listed in What GraphQL queries are supported.

    To learn more about GraphQL, see these resources:

    • Introduction to GraphQL

    • The Fullstack Tutorial for GraphQL

    To perform a search, compose a GraphQL structured query for a specific search and deliver it to zot using one of the methods described in the following sections.

    For examples of GraphQL queries supported in zot, see Examples of zot searches using GraphQL.

    "},{"location":"articles/graphql/#using-the-search-api-directly","title":"Using the search API directly","text":"

    You can submit a GraphQL structured query as the HTML data payload in a direct API call using a shell tool such as cURL or Postman. GraphQL queries are sent to the zot search extension API:

    /v2/_zot/ext/search\n

    The following example submits a zot GraphQL query using cURL:

    curl -X POST -H \"Content-Type: application/json\" --data '{ \"query\": \"{ ImageListForCVE (id:\\\"CVE-2002-1119\\\") { Results { Name Tags } } }\" }' http://localhost:8080/v2/_zot/ext/search\n

    The reply to your query is returned as a JSON payload in the HTML response.

    "},{"location":"articles/graphql/#using-the-graphql-playground","title":"Using the GraphQL Playground","text":"

    The GraphQL Playground feature is available only in a binary-debug zot build or when the zot registry was built with the debug extension label.

    The GraphQL Playground is an interactive graphical web interface for GraphQL hosted by the zot registry server.

    The GraphQL Playground is reachable by a browser at the following zot API:

    /v2/_zot/debug/graphql-playground#\n

    For example, if your zot server is located at http://localhost:8080, the GraphQL Playground can be accessed by your browser at this URL:

    http://localhost:8080/v2/_zot/debug/graphql-playground#\n

    In the GraphQL Playground, you can construct and submit a query structure and you can view the query response in a graphical environment in the browser. You can also inspect the schema.

    "},{"location":"articles/graphql/#what-graphql-queries-are-supported","title":"What GraphQL queries are supported","text":"Supported queries graphQL query Input Output Description Search images by digest ImageListForDigest digest image list Searches all repositories in the registry and returns list of images that matches given digest (manifest, config or layers) Search images affected by a given CVE id CVEListForImage CVE id image list Searches the entire registry and returns list of images affected by given CVE List CVEs for a given image CVEListForImage image CVE list Scans given image and returns list of CVEs affecting the image List images not affected by a given CVE id ImagesListWithCVEFixed repository, CVE id image list Scans all images in a given repository and returns list of latest (by date) images not affected by the given CVE Latest image from all repos RepoListWithNewestImage none repo summary list Returns the latest image from all the repos in the registry List all images with expanded information for a given repository ExpandedRepoInfo repository repo info List expanded repo information for all images in repo, alongside a repo summary All images in repo ImageList repository image list Returns all images in the specified repo Global search GlobalSearch query image summary / repo summary / layer summary Will return what's requested in the query argument Derived image list DerivedImageList image image list Returns a list of images that depend on the image specified in the argument Base image list BaseImageList image image list Returns a list of images that the specified image depends on Get details of a specific image Image image image summary Returns details about a specific image Get referrers of a specific image Referrers repo, digest, type artifact manifests Returns a list of artifacts of given type referring to a specific repo and digests"},{"location":"articles/graphql/#examples-of-zot-searches-using-graphql","title":"Examples of zot searches using GraphQL","text":"

    These examples show only the GraphQL query without details on how to send them to a server. See How to use GraphQL for search queries.

    The query structures shown in these examples request all fields allowed by the schema for the particular query type. The schema allows you to request a subset of the data, if desired, omitting any fields that you don't need.

    "},{"location":"articles/graphql/#list-cves-of-given-image","title":"List CVEs of given image","text":"

    Sample request

    {\n  CVEListForImage(\n    image: \"alpine:3.17\"\n    requestedPage: {limit: 1, offset:1, sortBy: SEVERITY}\n  ) {\n    Tag\n    Page {\n      TotalCount\n      ItemCount\n    }\n    CVEList {\n      Id\n      Title\n      Description\n      Severity\n      PackageList {\n        Name\n        InstalledVersion\n        FixedVersion\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"CVEListForImage\": {\n      \"Tag\": \"3.17\",\n      \"Page\": {\n        \"TotalCount\": 9,\n        \"ItemCount\": 1\n      },\n      \"CVEList\": [\n        {\n          \"Id\": \"CVE-2023-5363\",\n          \"Title\": \"openssl: Incorrect cipher key and IV length processing\",\n          \"Description\": \"Issue summary: A bug has been identified in the processing of key and\\ninitialisation vector (IV) lengths.  This can lead to potential truncation\\nor overruns during the initialisation of some symmetric ciphers.\\n\\nImpact summary: A truncation in the IV can result in non-uniqueness,\\nwhich could result in loss of confidentiality for some cipher modes.\\n\\nWhen calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or\\nEVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after\\nthe key and IV have been established.  Any alterations to the key length,\\nvia the \\\"keylen\\\" parameter or the IV length, via the \\\"ivlen\\\" parameter,\\nwithin the OSSL_PARAM array will not take effect as intended, potentially\\ncausing truncation or overreading of these values.  The following ciphers\\nand cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.\\n\\nFor the CCM, GCM and OCB cipher modes, truncation of the IV can result in\\nloss of confidentiality.  For example, when following NIST's SP 800-38D\\nsection 8.2.1 guidance for constructing a deterministic IV for AES in\\nGCM mode, truncation of the counter portion could lead to IV reuse.\\n\\nBoth truncations and overruns of the key and overruns of the IV will\\nproduce incorrect results and could, in some cases, trigger a memory\\nexception.  However, these issues are not currently assessed as security\\ncritical.\\n\\nChanging the key and/or IV lengths is not considered to be a common operation\\nand the vulnerable API was recently introduced. Furthermore it is likely that\\napplication developers will have spotted this problem during testing since\\ndecryption would fail unless both peers in the communication were similarly\\nvulnerable. For these reasons we expect the probability of an application being\\nvulnerable to this to be quite low. However if an application is vulnerable then\\nthis issue is considered very serious. For these reasons we have assessed this\\nissue as Moderate severity overall.\\n\\nThe OpenSSL SSL/TLS implementation is not affected by this issue.\\n\\nThe OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because\\nthe issue lies outside of the FIPS provider boundary.\\n\\nOpenSSL 3.1 and 3.0 are vulnerable to this issue.\",\n          \"Severity\": \"HIGH\",\n          \"PackageList\": [\n            {\n              \"Name\": \"libcrypto3\",\n              \"InstalledVersion\": \"3.0.8-r0\",\n              \"FixedVersion\": \"3.0.12-r0\"\n            },\n            {\n              \"Name\": \"libssl3\",\n              \"InstalledVersion\": \"3.0.8-r0\",\n              \"FixedVersion\": \"3.0.12-r0\"\n            }\n          ]\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#search-images-affected-by-a-given-cve-id","title":"Search images affected by a given CVE id","text":"

    Sample request

    {\n  ImageListForCVE(id: \"CVE-2023-0464\") {\n    Results{\n      RepoName\n      Tag\n      Digest\n      LastUpdated\n      IsSigned\n      Size\n      Vendor\n      DownloadCount\n      Licenses\n      Title\n      Manifests {\n        Digest\n        ConfigDigest\n        Platform {\n          Os\n          Arch\n        }\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"ImageListForCVE\": {\n      \"Results\": [\n        {\n          \"RepoName\": \"alpine\",\n          \"Tag\": \"3.17\",\n          \"Digest\": \"sha256:75bfe77c8d5a76b4421cfcebbd62a28ae70d10147578d0cda45820e99b0ef1d8\",\n          \"LastUpdated\": \"2023-02-11T04:46:42.558343068Z\",\n          \"IsSigned\": true,\n          \"Size\": \"3375436\",\n          \"Vendor\": \"\",\n          \"DownloadCount\": 0,\n          \"Licenses\": \"\",\n          \"Title\": \"\",\n          \"Manifests\": [\n            {\n              \"Digest\": \"sha256:75bfe77c8d5a76b4421cfcebbd62a28ae70d10147578d0cda45820e99b0ef1d8\",\n              \"ConfigDigest\": \"sha256:6a2bcc1c7b4c9207f791a4512d7f2fa8fc2daeae58dbc51cb2797b05415f082a\",\n              \"Platform\": {\n                \"Os\": \"linux\",\n                \"Arch\": \"amd64\"\n              }\n            }\n          ]\n        },\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#list-images-not-affected-by-a-given-cve-id","title":"List images not affected by a given CVE id","text":"

    Sample request

    {\n  ImageListWithCVEFixed(id: \"CVE-2023-0464\", image: \"ubuntu\") {\n    Results {\n      RepoName\n      Tag\n      Digest\n      LastUpdated\n      Manifests {\n        Digest\n        ConfigDigest\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"ImageListWithCVEFixed\": {\n      \"Results\": [\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"kinetic\",\n          \"Digest\": \"sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f\",\n          \"LastUpdated\": \"2022-10-14T15:28:55.0263968Z\",\n          \"Manifests\": [\n            {\n              \"Digest\": \"sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f\",\n              \"ConfigDigest\": \"sha256:824c0269745923afceb9765ae24f5b331bb6fcf2a82f7eba98b3cfd543afb41e\"\n            }\n          ]\n        },\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"kinetic-20220922\",\n          \"Digest\": \"sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff\",\n          \"LastUpdated\": \"2022-10-14T15:27:41.2144454Z\",\n          \"Manifests\": [\n            {\n              \"Digest\": \"sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff\",\n              \"ConfigDigest\": \"sha256:15c8dcf63970bb14ea36e41aa001b87d8d31e25a082bf6f659d12489d3e53d90\"\n            }\n          ]\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#search-images-by-digest","title":"Search images by digest","text":"

    Sample request

    {\n  ImageListForDigest(\n    id: \"79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff\"\n  ) {\n    Results{\n      RepoName\n      Tag\n      Title\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"ImageListForDigest\": {\n      \"Results\": [\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"kinetic-20220922\",\n          \"Title\": \"ubuntu\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#list-the-latest-image-across-every-repository","title":"List the latest image across every repository","text":"

    Sample request

    {\n  RepoListWithNewestImage(requestedPage: {limit: 2, offset:0, sortBy: ALPHABETIC_ASC}) {\n    Page {\n      TotalCount\n      ItemCount\n    }\n    Results {\n      Name\n      LastUpdated\n      Size\n      Platforms {\n        Os\n        Arch\n      }\n      NewestImage {\n        Digest\n        Tag\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"RepoListWithNewestImage\": {\n      \"Page\": {\n        \"TotalCount\": 30,\n        \"ItemCount\": 2\n      },\n      \"Results\": [\n        {\n          \"Name\": \"mariadb\",\n          \"LastUpdated\": \"2022-10-18T14:56:33.1993083+03:00\",\n          \"Size\": \"124116964\",\n          \"Platforms\": [\n            {\n              \"Os\": \"linux\",\n              \"Arch\": \"amd64\"\n            }\n          ],\n          \"NewestImage\": {\n            \"Digest\": \"sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0\",\n            \"Tag\": \"latest\"\n          }\n        },\n        {\n          \"Name\": \"tomcat\",\n          \"LastUpdated\": \"2022-10-18T14:55:13.8303866+03:00\",\n          \"Size\": \"311658063\",\n          \"Platforms\": [\n            {\n              \"Os\": \"linux\",\n              \"Arch\": \"amd64\"\n            }\n          ],\n          \"NewestImage\": {\n            \"Digest\": \"sha256:bbc5a3912b568fbfb5912beaf25054f1f407c32a53acae29f19ad97485731a78\",\n            \"Tag\": \"jre17\"\n          }\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#all-images-in-repo","title":"All images in repo","text":"

    Sample request

    {\n  ImageList (repo: \"ubuntu\") {\n    Results {\n      Tag\n      Digest\n      LastUpdated\n      Size\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"ImageList\": {\n      \"Results\": [\n        {\n          \"Tag\": \"jammy\",\n          \"Digest\": \"sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27\",\n          \"LastUpdated\": \"2022-10-14T15:29:18.0325322Z\",\n          \"Size\": \"30472739\"\n        },\n        {\n          \"Tag\": \"jammy-20221003\",\n          \"Digest\": \"sha256:86681debca1719dff33f426a0f5c41792ebc52496c5d78a93b655b8b48fb71b2\",\n          \"LastUpdated\": \"2022-10-14T15:29:07.0004587Z\",\n          \"Size\": \"30472748\"\n        },\n        {\n          \"Tag\": \"kinetic\",\n          \"Digest\": \"sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f\",\n          \"LastUpdated\": \"2022-10-14T15:28:55.0263968Z\",\n          \"Size\": \"27498890\"\n        },\n        {\n          \"Tag\": \"kinetic-20220922\",\n          \"Digest\": \"sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff\",\n          \"LastUpdated\": \"2022-10-14T15:27:41.2144454Z\",\n          \"Size\": \"27498899\"\n        },\n        {\n          \"Tag\": \"latest\",\n          \"Digest\": \"sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c\",\n          \"LastUpdated\": \"2022-10-14T15:26:59.6707939Z\",\n          \"Size\": \"30472740\"\n        },\n        {\n          \"Tag\": \"rolling\",\n          \"Digest\": \"sha256:72e75626c5068b9d9a462c4fc80a29787d0cf61c8abc81bfd5ea69f6248d56fc\",\n          \"LastUpdated\": \"2022-10-14T15:27:21.2441356Z\",\n          \"Size\": \"30472741\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#list-all-images-with-expanded-information-for-a-given-repository","title":"List all images with expanded information for a given repository","text":"

    Sample request

    {\n  ExpandedRepoInfo(repo: \"ubuntu\") {\n    Images {\n      Tag\n      Digest\n    }\n    Summary {\n      LastUpdated\n      Size\n      NewestImage {\n        Tag\n        LastUpdated\n        Digest\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"ExpandedRepoInfo\": {\n      \"Images\": [\n        {\n          \"Tag\": \"jammy\",\n          \"Digest\": \"sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27\"\n        },\n        {\n          \"Tag\": \"jammy-20221003\",\n          \"Digest\": \"sha256:86681debca1719dff33f426a0f5c41792ebc52496c5d78a93b655b8b48fb71b2\"\n        },\n        {\n          \"Tag\": \"kinetic\",\n          \"Digest\": \"sha256:1ac35e499e330f6520e80e91b29a55ff298077211f5ed66aff5cb357cca4a28f\"\n        },\n        {\n          \"Tag\": \"kinetic-20220922\",\n          \"Digest\": \"sha256:79eae04a0e32878fef3f8c5f901c32f6704c4a80b7f3fd9d89629e15867acfff\"\n        },\n        {\n          \"Tag\": \"rolling\",\n          \"Digest\": \"sha256:72e75626c5068b9d9a462c4fc80a29787d0cf61c8abc81bfd5ea69f6248d56fc\"\n        },\n        {\n          \"Tag\": \"latest\",\n          \"Digest\": \"sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c\"\n        }\n      ],\n      \"Summary\": {\n        \"LastUpdated\": \"2022-10-14T15:29:18.0325322Z\",\n        \"Size\": \"58146896\",\n        \"NewestImage\": {\n          \"Tag\": \"jammy\",\n          \"LastUpdated\": \"2022-10-14T15:29:18.0325322Z\",\n          \"Digest\": \"sha256:f96fcb040c7ee00c037c758cf0ab40638e6ee89b03a9d639178fcbd0e7f96d27\"\n        }\n      }\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#global-search","title":"Global search","text":"

    Sample request

    {\n  GlobalSearch(query: \"ubuntu:latest\") {\n    Page {\n      ItemCount\n      TotalCount\n    }\n    Images {\n      RepoName\n      Tag\n      LastUpdated\n      Manifests {\n        Digest\n        Layers {\n          Size\n          Digest\n        }\n      }\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"GlobalSearch\": {\n      \"Page\": {\n        \"ItemCount\": 1,\n        \"TotalCount\": 1\n      },\n      \"Images\": [\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"latest\",\n          \"LastUpdated\": \"2022-10-14T15:26:59.6707939Z\",\n          \"Manifests\": [\n            {\n              \"Digest\": \"sha256:9bc6d811431613bf2fd8bf3565b319af9998fc5c46304022b647c63e1165657c\",\n              \"Layers\": [\n                {\n                  \"Size\": \"30428928\",\n                  \"Digest\": \"sha256:cf92e523b49ea3d1fae59f5f082437a5f96c244fda6697995920142ff31d59cf\"\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  }\n}\n

    Sample request

    {\n  GlobalSearch(query: \"\") {\n    Repos {\n      Name\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"GlobalSearch\": {\n      \"Repos\": [\n        {\n          \"Name\": \"centos\"\n        },\n        {\n          \"Name\": \"ubuntu\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#search-derived-images","title":"Search derived images","text":"

    Sample query

    {\n  DerivedImageList(image: \"ubuntu:latest\", requestedPage: {offset: 0, limit: 10}) {\n    Page {\n      TotalCount\n      ItemCount\n    }\n    Results {\n      RepoName\n      Tag\n      LastUpdated\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"DerivedImageList\": {\n      \"Page\": {\n        \"TotalCount\": 9,\n        \"ItemCount\": 9\n      },\n      \"Results\": [\n        {\n          \"RepoName\": \"mariadb\",\n          \"Tag\": \"latest\",\n          \"LastUpdated\": \"2022-10-18T14:56:33.1993083+03:00\"\n        },\n        {\n          \"RepoName\": \"maven\",\n          \"Tag\": \"latest\",\n          \"LastUpdated\": \"2022-10-14T18:30:12.0929807+03:00\"\n        },\n        {\n          \"RepoName\": \"tomcat\",\n          \"Tag\": \"latest\",\n          \"LastUpdated\": \"2022-10-18T14:50:09.7229959+03:00\"\n        },\n        {\n          \"RepoName\": \"tomcat\",\n          \"Tag\": \"jre17\",\n          \"LastUpdated\": \"2022-10-18T14:55:13.8303866+03:00\"\n        },\n        {\n          \"RepoName\": \"tomcat\",\n          \"Tag\": \"jre17-temurin\",\n          \"LastUpdated\": \"2022-10-18T14:54:46.4133521+03:00\"\n        },\n        {\n          \"RepoName\": \"tomcat\",\n          \"Tag\": \"jre17-temurin-jammy\",\n          \"LastUpdated\": \"2022-10-18T14:51:12.235475+03:00\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#search-base-images","title":"Search base images","text":"

    Sample query

    {\n  BaseImageList(image: \"mariadb:latest\", requestedPage: {offset: 0, limit: 10}) {\n    Page {\n      TotalCount\n      ItemCount\n    }\n    Results {\n      RepoName\n      Tag\n      LastUpdated\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"BaseImageList\": {\n      \"Page\": {\n        \"TotalCount\": 4,\n        \"ItemCount\": 4\n      },\n      \"Results\": [\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"jammy\",\n          \"LastUpdated\": \"2022-10-14T18:29:18.0325322+03:00\"\n        },\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"jammy-20221003\",\n          \"LastUpdated\": \"2022-10-14T18:29:07.0004587+03:00\"\n        },\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"latest\",\n          \"LastUpdated\": \"2022-10-14T18:26:59.6707939+03:00\"\n        },\n        {\n          \"RepoName\": \"ubuntu\",\n          \"Tag\": \"rolling\",\n          \"LastUpdated\": \"2022-10-14T18:27:21.2441356+03:00\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#get-details-of-a-specific-image","title":"Get details of a specific image","text":"

    Sample query

    {\n  Image(image: \"mariadb:latest\") {\n    RepoName\n    Tag\n    LastUpdated\n    Digest\n    Description\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"Image\": {\n      \"RepoName\": \"mariadb\",\n      \"Tag\": \"latest\",\n      \"LastUpdated\": \"2022-10-18T14:56:33.1993083+03:00\",\n      \"Digest\": \"sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0\",\n      \"Description\": \"MariaDB Server is a high performing open source relational database, forked from MySQL.\"\n    }\n  }\n}\n
    "},{"location":"articles/graphql/#get-referrers-of-a-specific-image","title":"Get referrers of a specific image","text":"

    Sample query

    {\n  Referrers(\n    repo: \"golang\"\n    digest: \"sha256:fed08b0eaea00aab17f82ecbb78675919d216c72eea985581758191f694aeaf7\"\n    type: \"application/vnd.example.icecream.v1\"\n  ) {\n    MediaType\n    ArtifactType\n    Digest\n    Annotations {\n      Key\n      Value\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"Referrers\": [\n      {\n        \"MediaType\": \"application/vnd.oci.artifact.manifest.v1+json\",\n        \"ArtifactType\": \"application/vnd.example.icecream.v1\",\n        \"Digest\": \"sha256:be7a3d01c35a2cf53c502e9dc50cdf36b15d9361c81c63bf319f1d5cbe44ab7c\",\n        \"Annotations\": [\n          {\n            \"Key\": \"format\",\n            \"Value\": \"oci\"\n          },\n          {\n            \"Key\": \"demo\",\n            \"Value\": \"true\"\n          }\n        ]\n      },\n      {\n        \"MediaType\": \"application/vnd.oci.artifact.manifest.v1+json\",\n        \"ArtifactType\": \"application/vnd.example.icecream.v1\",\n        \"Digest\": \"sha256:d9ad22f41d9cb9797c134401416eee2a70446cee1a8eb76fc6b191f4320dade2\",\n        \"Annotations\": [\n          {\n            \"Key\": \"demo\",\n            \"Value\": \"true\"\n          },\n          {\n            \"Key\": \"format\",\n            \"Value\": \"oci\"\n          }\n        ]\n      }\n    ]\n  }\n}\n
    "},{"location":"articles/immutable-tags/","title":"Immutable Image Tags","text":"

    Immutable image tag support is achieved by leveraging authorization policies.

    It is considered best practice to avoid changing the content once a software version has been released. While zot does not have an explicit configuration flag to make image tags immutable, the same effect can be achieved with authorization as follows.

    "},{"location":"articles/immutable-tags/#immutable-for-all-users","title":"Immutable For All Users","text":"

    By setting the defaultPolicy to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled but further updates are rejected.

    {\n...\n  \"repositories\": {\n    \"**\": {\n      \"defaultPolicy\": [\"read\", \"create\"]\n    }\n  }\n...\n}\n
    "},{"location":"articles/immutable-tags/#immutable-with-overrides","title":"Immutable With Overrides","text":"

    As in the example above, with defaultPolicy set to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled, but further updates are rejected. Exceptions can be made for some users, and user-specific policies can be added to allow \"update\" operations as shown below.

    {\n...\n  \"repositories\": {\n    \"**\": {\n      \"policies\": [{\n        \"users\": [\"alice\", \"bob\"],\n        \"actions\": [\"read\", \"create\", \"update\"]\n      }],\n      \"defaultPolicy\": [\"read\", \"create\"]\n    }\n  }\n...\n}\n
    "},{"location":"articles/kind-deploy/","title":"Using kind for Deployment Testing","text":"

    Use kind to try out zot deployment with Kubernetes.

    This article describes how to create a kind cluster that includes a local zot registry.

    "},{"location":"articles/kind-deploy/#deploying-the-cluster-and-registry","title":"Deploying the cluster and registry","text":"

    The procedure described installs a kind cluster with a zot registry at localhost:5001 and then loads and runs a \"hello\" app to test the installation. Although the procedure is given as a series of steps, you can find a complete shell script to perform these steps at the end of this article.

    This article is based on Create A Cluster And Registry, which you can find on the kind website.

    "},{"location":"articles/kind-deploy/#step-1-prepare-the-environment","title":"Step 1: Prepare the environment","text":"

    The following packages must be installed:

    • docker
    • kubernetes
    • kind
    • containerd
    • skopeo

    Execute the following shell commands to set environment variables.

    set -o errexit\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n  echo \"Updating no_proxy environment variables\";\n  export no_proxy=${no_proxy},kind-registry;\n  export NO_PROXY=${no_proxy};\nfi\n
    "},{"location":"articles/kind-deploy/#step-2-create-a-registry-container","title":"Step 2: Create a registry container","text":"

    Create a kind-registry container, pulling a zot binary from the GitHub Container Registry (ghcr.io).

    This example pulls zot-minimal-linux-amd64:latest, a minimal (no extensions) zot image for an AMD-based linux server.

    Other available images are described at the zot releases page in GitHub. You can also specify a release by replacing latest with an available release number.

    # create registry container unless it already exists\nreg_name='kind-registry'\nreg_port='5001'\nif [ \"$(docker inspect -f '{{.State.Running}}' \"${reg_name}\" 2>/dev/null || true)\" != 'true' ]; then\n  docker run \\\n    -d --restart=always -p \"127.0.0.1:${reg_port}:5000\" --name \"${reg_name}\" \\\n    ghcr.io/project-zot/zot-minimal-linux-amd64:latest\nfi\n
    "},{"location":"articles/kind-deploy/#step-3-create-the-kind-cluster","title":"Step 3: Create the kind cluster","text":"

    Create a cluster with the local registry enabled.

    # enable the local registry in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n  [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n    endpoint = [\"http://${reg_name}:5000\"]\nEOF\n
    "},{"location":"articles/kind-deploy/#step-4-connect-the-registry-to-the-cluster-network","title":"Step 4: Connect the registry to the cluster network","text":"

    Connect the registry to the \"kind\" network so that it can communicate with other resources in the same network.

    # check whether already connected to the network\nif [ \"$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' \\\n\"${reg_name}\")\" = 'null' ]; then\n  docker network connect \"kind\" \"${reg_name}\"\nfi\n
    "},{"location":"articles/kind-deploy/#step-5-document-the-local-registry","title":"Step 5: Document the local registry","text":"

    Create a ConfigMap that specifies how to interact with the local registry. This ConfigMap follows the KEP-1755 Standard for communicating a local registry.

    cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: local-registry-hosting\n  namespace: kube-public\ndata:\n  localRegistryHosting.v1: |\n    host: \"localhost:${reg_port}\"\n    help: \"https://kind.sigs.k8s.io/docs/user/local-registry/\"\nEOF\n
    "},{"location":"articles/kind-deploy/#step-6-deploy-and-test","title":"Step 6: Deploy and test","text":"

    Use skopeo to copy (pull) a \"hello\" app from the Google Container Registry (gcr.io) into the new zot registry. Using kubectl, deploy the app from the new local zot registry as \"hello-server\" and monitor the deployment for initial availability.

    # copy an image\nskopeo copy --format=oci --dest-tls-verify=false \\\ndocker://gcr.io/google-samples/hello-app:1.0 \\\ndocker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server \\\n  --for condition=Available=True --timeout=90s\n
    "},{"location":"articles/kind-deploy/#clean-up","title":"Clean up","text":"

    To clean up after testing, run the following commands to delete the kind cluster and registry.

    kind delete cluster\ndocker stop kind-registry\ndocker rm kind-registry\n
    "},{"location":"articles/kind-deploy/#reference-a-complete-script","title":"Reference: A complete script","text":"

    The following script executes all of the preceding steps.

    Click here to view the entire script
    #!/bin/sh\nset -o errexit\n\n# Reference: https://kind.sigs.k8s.io/docs/user/local-registry/\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n  echo \"Updating no_proxy env var\";\n  export no_proxy=${no_proxy},kind-registry;\n  export NO_PROXY=${no_proxy};\nfi\n\n# create registry container unless it already exists\nreg_name='kind-registry'\nreg_port='5001'\nif [ \"$(docker inspect -f '{{.State.Running}}' \"${reg_name}\" 2>/dev/null || true)\" != 'true' ]; then\n  docker run \\\n    -d --restart=always -p \"127.0.0.1:${reg_port}:5000\" --name \"${reg_name}\" \\\n    ghcr.io/project-zot/zot-minimal-linux-amd64:latest\nfi\n\n# create a cluster with the local registry enabled in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n  [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n    endpoint = [\"http://${reg_name}:5000\"]\nEOF\n\n# connect the registry to the cluster network if not already connected\nif [ \"$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' \"${reg_name}\")\" = 'null' ]; then\n  docker network connect \"kind\" \"${reg_name}\"\nfi\n\n# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry\n#\n# document the local registry\ncat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: local-registry-hosting\n  namespace: kube-public\ndata:\n  localRegistryHosting.v1: |\n    host: \"localhost:${reg_port}\"\n    help: \"https://kind.sigs.k8s.io/docs/user/local-registry/\"\nEOF\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://gcr.io/google-samples/hello-app:1.0 docker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server --for condition=Available=True --timeout=90s\n\n# cleanup\necho \"Press a key to begin cleanup ...\"\nread KEYPRESS\nkind delete cluster\ndocker stop kind-registry\ndocker rm kind-registry\n
    "},{"location":"articles/mirroring/","title":"OCI Registry Mirroring With zot","text":"

    A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry (gcr.io).

    A key use case for zot is to act as a mirror for upstream registries. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Because synchronized images are stored in zot's local storage, registry mirroring allows for a fully distributed disconnected container image build pipeline. Container image operations terminate in local zot storage, which may reduce network latency and costs.

    Because zot is a OCI-only registry, any upstream image stored in the Docker image format is converted to OCI format when downloading to zot. In the conversion, some non-OCI attributes may be lost. Signatures, for example, are removed due to the incompatibility between formats.

    "},{"location":"articles/mirroring/#mirroring-modes","title":"Mirroring modes","text":"

    For mirroring an upstream registry, two common use cases are a fully mirrored or a pull through (on-demand) cache registry.

    As with git, wherein every clone is a full repository, you can configure your local zot instance to be a fully mirrored OCI registry. For this mode, configure zot for synchronization by periodic polling, not on-demand. Zot copies and caches a full copy of every image on the upstream registry, updating the cache whenever polling discovers a change in content or image version at the upstream registry.

    For a pull through cache mirrored registry, configure zot for on-demand synchronization. When an image is first requested from the local zot registry, the image is downloaded from the upstream registry and cached in local storage. Subsequent requests for the same image are served from zot's cache. Images that have not been requested are not downloaded. If a polling interval is also configured, zot periodically polls the upstream registry for changes, updating any cached images if changes are detected.

    Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only on-demand mirroring with Docker Hub.

    "},{"location":"articles/mirroring/#migrating-or-updating-a-registry-using-mirroring","title":"Migrating or updating a registry using mirroring","text":"

    Mirroring zot using the sync feature allows you to easily migrate a registry. In situations such as the following, zot mirroring provides an easy solution.

    • Migrating an existing zot or non-zot registry to a new location.

      Provided that the source registry is OCI-compliant for image pulls, you can mirror the registry to a new zot registry, delete the old registry, and reroute network traffic to the new registry.

    • Updating (or downgrading) a zot registry.

      To minimize downtime during an update, or to avoid any incompatibilities between zot releases that would preclude an in-place update, you can bring up a new zot registry with the desired release and then migrate from the existing registry.

    To ensure a complete migration of the registry contents, set a polling interval in the configuration of the new zot registry and set prefix to **, as shown in this example:

      {\n    \"urls\": [\n        \"https://registry1:5000\"\n    ],\n    \"pollInterval\": \"12h\",\n    \"onDemand\": true,\n    \"content\": [\n        {\n            \"prefix\": \"**\"\n        }\n    ]\n  }\n
    "},{"location":"articles/mirroring/#basic-configuration-for-mirroring-with-sync","title":"Basic configuration for mirroring with sync","text":"

    The sync feature of zot is an extension of the OCI-compliant registry implementation. You can configure the sync feature under the extensions section of the zot configuration file, as shown in this example:

      \"extensions\": {\n    \"sync\": {\n      \"credentialsFile\": \"./examples/sync-auth-filepath.json\",\n      \"registries\": [\n        {\n          \"urls\": [\n            \"https://registry1:5000\"\n          ],\n          \"onDemand\": false,\n          \"pollInterval\": \"6h\",\n          \"tlsVerify\": true,\n          \"certDir\": \"/home/user/certs\",\n          \"maxRetries\": 3,\n          \"retryDelay\": \"5m\", \n          \"onlySigned\": true,\n          \"content\": [\n            {\n              \"prefix\": \"/repo2/repo\",\n              \"tags\": {\n                \"regex\": \"4.*\",\n                \"semver\": true\n              }\n              \"destination\": \"/repo2\",\n              \"stripPrefix\": true\n            }\n          ]\n        }\n      ]\n    }\n  }\n

    The following table lists the configurable attributes for the sync feature:

    Attribute Description

    credentialsFile

    The location of a local file containing credentials for other registries, as in the following example:

    {\u2003\u2003\"127.0.0.1:8080\": {\u2003\u2003\u2003\u2003\"username\": \"user\",\u2003\u2003\u2003\u2003\"password\": \"pass\"\u2003\u2003},\u2003\u2003\u2003\u2003\"registry2:5000\": {\u2003\u2003\u2003\u2003\"username\": \"user2\",\u2003\u2003\u2003\u2003\"password\": \"pass2\"\u2003\u2003}}

    urls

    A list of one or more URLs to an upstream image registry. If the main URL fails, the sync process will try the next URLs in the listed order.

    onDemand

    • false: Pull all images not found in the local registry.

    • true: Pull any image not found in the local registry only when the image is requested by a user.

    pollInterval

    The period in seconds between polling of a remote registry. If no value is specified, no periodic polling will occur. If a value is set and the content attributes are configured, periodic synchronization is enabled and will run at the specified value.Note: Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only onDemand mirroring with Docker Hub.

    tlsVerify

    • false: TLS will not be verified.

    • true: (Default) The TLS connection to the destination registry will be verified.

    certDir

    If a path is specified, use certificates (*.crt, *.cert, *.key files) at this path when connecting to the destination registry or daemon. If no path is specified, use the default certificates directory.

    maxRetries

    The maximum number of retries if an error occurs during either an on-demand or periodic synchronization. If no value is specified, no retries will occur.

    retryDelay

    The interval in seconds between retries. This attribute is mandatory when maxRetries is configured.

    onlySigned

    • false: Synchronize signed or unsigned images.

    • true: Synchronize only signed images (either notary or cosign).

    content

    The included attributes in this section specify which content will be pulled. If this section is not populated, periodic polling will not occur. The included attributes can also filter which on-demand images are pulled.

    prefix

    On the remote registry, the path from which images will be pulled. This path can be a string that exactly matches the remote path, or it can be a glob pattern. For example, the path can include a wildcard (*) or a recursive wildcard (**).

    tags

    The included attributes in this optional section specify how remote images will be selected for synchronization based on image tags.

    tags.regex

    Specifies a regular expression for matching image tags. Images whose tags do not match the expression are not pulled.

    tags.semver

    Specifies whether image tags are to be filtered by semantic versioning (semver) compliance.

    • false: Do not filter by semantic versioning.

    • true: Filter by semantic versioning.

    destination

    Specifies the local path in which pulled images are to be stored.

    stripPrefix

    Specifies whether the prefix path from the remote registry will be retained or replaced when the image is stored in the zot registry.

    • false: Retain the source prefix, append it to the destination path.

    • true: Remove the source prefix.

      Note: If the source prefix was specified with meta-characters (such as **), only the prefix segments that precede the meta-characters are removed. Any remaining path segments are appended to the destination path.

    "},{"location":"articles/mirroring/#configuration-examples-for-mirroring","title":"Configuration examples for mirroring","text":""},{"location":"articles/mirroring/#example-multiple-repositories-with-polled-mirroring","title":"Example: Multiple repositories with polled mirroring","text":"

    The following is an example of sync configuration for mirroring multiple repositories with polled mirroring.

    \"sync\": {\n  \"enable\": true,\n  \"credentialsFile\": \"./examples/sync-auth-filepath.json\",\n  \"registries\": [\n    {\n      \"urls\": [\"https://registry1:5000\"],\n      \"onDemand\": false,\n      \"pollInterval\": \"6h\",\n      \"tlsVerify\": true,\n      \"certDir\": \"/home/user/certs\",\n      \"maxRetries\": 3,\n      \"retryDelay\": \"5m\",\n      \"onlySigned\": true,\n      \"content\": [\n        {\n          \"prefix\": \"/repo1/repo\",\n          \"tags\": {\n            \"regex\": \"4.*\",\n            \"semver\": true\n          }\n        },\n        {\n          \"prefix\": \"/repo2/repo\",\n          \"destination\": \"/repo2\",\n          \"stripPrefix\": true\n        },\n        {\n          \"prefix\": \"/repo3/repo\"\n        }\n      ]\n    }\n  }\n

    The configuration in this example will result in the following behavior:

    • Only signed images (notation and cosign) are synchronized.
    • The sync communication is secured using certificates in certDir.
    • This registry synchronizes with upstream registry every 6 hours.
    • On-demand mirroring is disabled.
    • Based on the content filtering options, this registry synchronizes these images:
      • From /repo1/repo, images with tags that begin with \"4.\" and are semver compliant. Files are stored locally in /repo1/repo on localhost.
      • From /repo2/repo, images with all tags. Because stripPrefix is enabled, files are stored locally in /repo2. For example, docker://upstream/repo2/repo:v1 is stored as docker://local/repo2:v1.
      • From /repo3/repo, images with all tags. Files are stored locally in /repo3/repo.
    "},{"location":"articles/mirroring/#example-multiple-registries-with-on-demand-mirroring","title":"Example: Multiple registries with on-demand mirroring","text":"

    The following is an example of sync configuration for mirroring multiple registries with on-demand mirroring.

    {\n  \"distSpecVersion\": \"1.0.1\",\n  \"storage\": {\n    \"rootDirectory\": \"/tmp/zot\",\n    \"gc\": true\n  },\n  \"http\": {\n    \"address\": \"0.0.0.0\",\n    \"port\": \"8080\"\n  },\n  \"log\": {\n    \"level\": \"debug\"\n  },\n  \"extensions\": {\n    \"sync\": {\n      \"enable\": true,\n      \"registries\": [\n        {\n          \"urls\": [\"https://k8s.gcr.io\"],\n          \"content\": [\n            {\n              \"prefix\": \"**\", \n              \"destination\": \"/k8s-images\"\n            }\n          ],\n          \"onDemand\": true,\n          \"tlsVerify\": true\n        },\n        {\n          \"urls\": [\"https://docker.io/library\"],\n          \"content\": [\n            {\n              \"prefix\": \"**\", \n              \"destination\": \"/docker-images\"\n            }\n          ],\n          \"onDemand\": true,\n          \"tlsVerify\": true\n        }\n      ]\n    }\n  }\n}\n

    With this zot configuration, the sync behavior is as follows:

    1. This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/docker-images/alpine <dest>causes zot to synchronize the content with the docker.io registry: docker.io/library/alpine:latestto the zot registry: localhost:8080/docker-images/alpine:latestbefore delivering the content to the requestor at <dest>.

    2. This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/k8s-images/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with the gcr.io registry: k8s.gcr.io/kube-proxy:v1.19.2 to the zot registry: localhost:8080/k8s-images/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.

    You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:

      {\n    \"repositories\":[\n      \"docker-images/alpine\",\n      \"k8s-images/kube-proxy\"\n    ]\n  }\n
    "},{"location":"articles/mirroring/#example-multiple-registries-with-mixed-mirroring-modes","title":"Example: Multiple registries with mixed mirroring modes","text":"

    The following is an example of a zot configuration file for mirroring multiple upstream registries.

    {\n  \"distSpecVersion\": \"1.1.0-dev\",\n  \"storage\": {\n    \"rootDirectory\": \"/tmp/zot\"\n  },\n  \"http\": {\n    \"address\": \"127.0.0.1\",\n    \"port\": \"8080\"\n  },\n  \"log\": {\n    \"level\": \"debug\"\n  },\n  \"extensions\": {\n    \"sync\": {\n      \"enable\": true,\n      \"credentialsFile\": \"./examples/sync-auth-filepath.json\",\n      \"registries\": [\n        {\n          \"urls\": [\n            \"https://registry1:5000\"\n          ],\n          \"onDemand\": false,\n          \"pollInterval\": \"6h\",\n          \"tlsVerify\": true,\n          \"certDir\": \"/home/user/certs\",\n          \"maxRetries\": 3,\n          \"retryDelay\": \"5m\",\n          \"onlySigned\": true,\n          \"content\": [\n            {\n              \"prefix\": \"/repo1/repo\",\n              \"tags\": {\n                \"regex\": \"4.*\",\n                \"semver\": true\n              }\n            },\n            {\n              \"prefix\": \"/repo1/repo\",\n              \"destination\": \"/repo\",\n              \"stripPrefix\": true\n            },\n            {\n              \"prefix\": \"/repo2/repo\"\n            }\n          ]\n        },\n        {\n          \"urls\": [\n            \"https://registry2:5000\",\n            \"https://registry3:5000\"\n          ],\n          \"pollInterval\": \"12h\",\n          \"tlsVerify\": false,\n          \"onDemand\": false,\n          \"content\": [\n            {\n              \"prefix\": \"/repo2\",\n              \"tags\": {\n                \"semver\": true\n              }\n            }\n          ]\n        },\n        {\n          \"urls\": [\n            \"https://docker.io/library\"\n          ],\n          \"onDemand\": true,\n          \"tlsVerify\": true,\n          \"maxRetries\": 6,\n          \"retryDelay\": \"5m\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/mirroring/#example-support-for-subpaths-in-local-storage","title":"Example: Support for subpaths in local storage","text":"

    {\n  \"distSpecVersion\": \"1.0.1\",\n  \"storage\": {\n    \"subPaths\":{\n      \"/kube-proxy\":{\n        \"rootDirectory\": \"/tmp/kube-proxy\",\n        \"dedupe\": true,\n        \"gc\": true\n       }\n     },\n    \"rootDirectory\": \"/tmp/zot\",\n    \"gc\": true\n  },\n  \"http\": {\n    \"address\": \"0.0.0.0\",\n    \"port\": \"8080\"\n  },\n  \"log\": {\n    \"level\": \"debug\"\n  },\n  \"extensions\": {\n    \"sync\": {\n      \"enable\": true,\n      \"registries\": [\n        {\n          \"urls\": [\"https://k8s.gcr.io\"],\n          \"content\": [\n            {\n              \"destination\": \"/kube-proxy\", \n              \"prefix\": \"**\"\n            }\n          ],\n          \"onDemand\": true,\n          \"tlsVerify\": true,\n          \"maxRetries\": 2,\n          \"retryDelay\": \"5m\"\n        }\n      ]\n    }\n  }\n}\n
    With this zot configuration, the sync behavior is as follows:

    • This user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/kube-proxy/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with this remote registry: k8s.gcr.io/kube-proxy:v1.19.2to the zot registry: localhost:8080/kube-proxy/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.

    You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:

      {\n    \"repositories\":[\n      \"docker-images/alpine\",\n      \"k8s-images/kube-proxy\",\n      \"kube-proxy/kube-proxy\"\n    ]\n  }\n

    In zot storage, the requested content is located here: /tmp/zot/kube-proxy/kube-proxy/kube-proxy/This subpath is created from the following path components:

    • /tmp/zot is the rootDirectory of the zot registry
    • kube-proxy is the rootDirectory of the storage subpath
    • kube-proxy is the sync destination parameter
    • kube-proxy is the repository name
    "},{"location":"articles/monitoring/","title":"Monitoring the registry","text":"

    zot supports a range of monitoring tools including logging, metrics, and benchmarking.

    The following sections describe how to configure logging and monitoring with zot. You can use zot's benchmarking tool to test your configuration and deployment, as described in Benchmarking zot with zb.

    "},{"location":"articles/monitoring/#logging","title":"Logging","text":"

    Logging for zot operations is configured with the log attribute in the configuration file, as shown in the following example.

    \"log\":{\n  \"level\":\"debug\",\n  \"output\":\"/tmp/zot.log\",\n  \"audit\": \"/tmp/zot-audit.log\"\n}\n

    The following table lists the configurable attributes.

    Attribute Description

    level

    The minimum level for logged events. The levels are: panic, fatal, error, warn, info, debug, and trace.

    output

    The filesystem path for the log output file. The default is stdout.

    audit

    (Optional) If a filesystem path is specified for audit logging, an audit log is enabled and will be stored at the specified path.

    "},{"location":"articles/monitoring/#metrics","title":"Metrics","text":"

    The available methods for collecting metrics varies depending on whether your zot installation is a minimal (distribution-spec-only) image or a full image including extensions.

    "},{"location":"articles/monitoring/#enabling-metrics-for-a-full-zot-image-with-extensions","title":"Enabling metrics for a full zot image with extensions","text":"

    Add the metrics attribute under extensions in the configuration file to enable and configure metrics, as shown in the following example.

    \"extensions\": {\n    \"metrics\": {\n        \"enable\": true,\n        \"prometheus\": {\n            \"path\": \"/metrics\"\n        }\n    }\n}\n

    The following table lists the configurable attributes for metrics collection.

    Attribute Description enable If this attribute is missing, metrics collection is enabled by default. Metrics collection can be disabled by setting this attribute to false. prometheus Attributes under prometheus contain configuration settings for the Prometheus node exporter. path The server path on which metrics will be exposed."},{"location":"articles/monitoring/#collecting-metrics-from-a-minimal-zot-image-using-a-node-exporter","title":"Collecting metrics from a minimal zot image using a node exporter","text":"

    Although a minimal zot image does not contain a node exporter, it exposes internal metrics in a Prometheus format for collection by a separate node exporter tool such as zxp. The zot companion binary zxp is a node exporter that can be deployed with a minimal zot image in order to scrape metrics from the zot server.

    Metrics are automatically enabled in the zot server upon first scrape from the node exporter and the metrics are automatically disabled when the node exporter has not performed any scraping for some period. No extra zot configuration is needed for this behavior.

    You can download the zxp executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.

    The binary image is named using the target platform and architecture. For example, the binary for an Intel-based MacOS server is zxp-darwin-amd64. To configure the zxp example image, run this command:

    zxp-darwin-amd64 config zxp-config-file

    For convenience, you can rename the binary image file to simply zxp.

    A sample Dockerfile for zxp is available at Dockerfile-zxp.

    The configuration file of zxp contains connection details for the zot server from which it will scrape metrics. The following JSON structure is an example of the zxp-config-file contents:

    {\n    \"Server\": {\n        \"protocol\": \"http\",\n        \"host\": \"127.0.0.1\",\n        \"port\": \"8080\"\n    },\n    \"Exporter\": {\n        \"port\": \"8081\",\n        \"log\": {\n            \"level\": \"debug\"\n        }\n    }\n}\n

    The zxp module does not have Prometheus integration.

    The zxp module is not needed with a full zot image.

    "},{"location":"articles/pprofiling/","title":"Performance Profiling in zot","text":"

    Use zot's built-in profiling tools to collect and analyze runtime performance.

    The profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

    If authentication is enabled, only a zot admin user can access the APIs for profiling.

    All examples in this article assume that the zot registry is running at localhost:8080.

    "},{"location":"articles/pprofiling/#what-data-is-available","title":"What data is available?","text":"

    The zot source code incorporates golang's pprof package of runtime analysis tools to collect data for the following performance-related profiles:

    Profile Description allocs A sampling of all past memory allocations. block Stack traces that led to blocking on synchronization primitives. cmdline The command line invocation of the current program. goroutine Stack traces of all current goroutines. Use debug=2 as a URL query parameter to export in the same format as an unrecovered panic. heap A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. mutex Stack traces of holders of contended mutexes. profile CPU usage profile. You can specify the duration in the seconds URL query parameter. After receiving the profile file, use the go tool pprof command to investigate the profile. threadcreate Stack traces that led to the creation of new OS threads. trace A trace of execution of the current program. You can specify the duration in the seconds URL query parameter. After you get the trace file, use the go tool trace command to investigate the trace.

    To return a current HTML-format profile list along with a count of currently available records for each profile, use the following API command:

    /v2/_zot/pprof/\n

    If authentication is enabled, only an admin user can access this API.

    "},{"location":"articles/pprofiling/#how-do-i-export-profile-data","title":"How do I export profile data?","text":"

    To collect and export any available profile, use the following API command format:

    /v2/_zot/pprof/<profile-type>[?<query-parameters>]\n

    The following example shows an API request for the CPU usage profile named profile using a collection window of 30 seconds:

    $ curl -s http://localhost:8080/v2/_zot/pprof/profile?seconds=30 > cpu.prof\n

    This command example creates an output data file named \"cpu.prof\".

    • The query parameter ?seconds=<number> specifies the number of seconds to gather the profile data. If this parameter is not specified, the default is 30 seconds.
    • In this example, the raw output data is redirected to a file named \"cpu.prof\". Alternatively, you can use curl -O to create a file with the default profile name (in this case, \"profile\"). If no output file is specified by either a cURL flag or an output redirection, the cURL command fails with \"Failure writing output to destination\".
    • The command output file is in a machine-readable format that can be interpreted by performance analyzers.
    "},{"location":"articles/pprofiling/#analyzing-the-cpu-usage-profile-using-go-tool-pprof","title":"Analyzing the CPU usage profile using go tool pprof","text":"

    Go's pprof package provides a variety of presentation formats for analyzing runtime performance.

    For detailed information, see the pprof documentation.

    "},{"location":"articles/pprofiling/#generating-a-pprof-web-presentation","title":"Generating a pprof web presentation","text":"

    When an HTTP port is specified as a command flag, the go tool pprof command installs and opens a local web server that provides a web interface for viewing and analyzing the profile data. This example opens a localhost page at port 9090 for viewing the CPU usage data captured in the profile file named \"cpu.prof\".

    $ go tool pprof -http=:9090 cpu.prof\nServing web UI on http://localhost:9090\n

    The pprof web view offers several options for viewing and interpreting the collected performance data. Select VIEW to see the available options:

    A Flame Graph can be very useful for analyzing CPU usage:

    "},{"location":"articles/pprofiling/#generating-a-graphic-image","title":"Generating a graphic image","text":"

    The pprof package can generate graphic representations of profile data in many formats. This example generates a PNG file representing the CPU usage in the \"cpu.prof\" file.

    $ go tool pprof -png cpu.prof\nGenerating report in profile001.png\n
    "},{"location":"articles/pprofiling/#opening-a-pprof-interactive-session","title":"Opening a pprof interactive session","text":"

    This example opens an interactive session with pprof and executes the pprof top command, which displays the top ten modules by CPU usage during the profiling capture window.

    $ go tool pprof cpu.prof\nType: cpu\nTime: Sep 26, 2023 at 10:01am (PDT)\nDuration: 30s, Total samples = 10ms (  0.1%)\nEntering interactive mode (type \"help\" for commands, \"o\" for options)\n(pprof) top\nShowing nodes accounting for 10ms, 100% of 10ms total\n    flat  flat%   sum%        cum   cum%\n    10ms   100%   100%       10ms   100%  runtime.pthread_cond_signal\n        0     0%   100%       10ms   100%  runtime.findRunnable\n        0     0%   100%       10ms   100%  runtime.mcall\n        0     0%   100%       10ms   100%  runtime.notewakeup\n        0     0%   100%       10ms   100%  runtime.park_m\n        0     0%   100%       10ms   100%  runtime.runSafePointFn\n        0     0%   100%       10ms   100%  runtime.schedule\n        0     0%   100%       10ms   100%  runtime.semawakeup\n(pprof)\n
    "},{"location":"articles/pprofiling/#analyzing-the-trace-profile-using-go-tool-trace","title":"Analyzing the trace profile using go tool trace","text":"

    You can collect trace data with the trace profile, as in this example:

      $ curl -s -v http://localhost:8080/v2/_zot/pprof/trace?seconds=30 > trace.prof\n

    Using the go tool trace package, you can analyze the trace data captured in the \"trace.prof\" example file:

    $ go tool trace trace.prof\n2023/09/21 16:58:58 Parsing trace...\n2023/09/21 16:58:58 Splitting trace...\n2023/09/21 16:58:58 Opening browser. Trace viewer is listening on http://127.0.0.1:62606\n

    The go tool trace command installs and opens a local web server that provides a web interface for viewing and analyzing the trace data.

    As an alternative, you can generate a pprof-like profile from the trace file using the following command:

    $ go tool trace -pprof=[net|sync|syscall|sched] <filename>\n

    For example:

    $ go tool trace -pprof=net trace.prof\n
    "},{"location":"articles/retention/","title":"Configuring zot Tag Retention Policies","text":"

    To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.

    Tag retention policies in zot can specify how many tags of a given repository to retain or how long to retain certain tags.

    You can define tag retention policies that apply one or more of the following rules:

    • Top <n> tags most recently pushed
    • Top <n> tags most recently pulled
    • Tags pushed in the past <n> hours
    • Tags pulled in the past <n> hours
    • Tags matching a regular expression (regex) pattern
    "},{"location":"articles/retention/#configuring-retention-policies","title":"Configuring retention policies","text":"

    Retention policies are configured in the storage section of the zot configuration file under the retention attribute. One or more policies can be grouped under the policies attribute.

    By default, if no retention policies are defined, all tags are retained.

    If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed. To avoid unintended removals, we recommend defining a default policy, as described in Configuration notes.

    "},{"location":"articles/retention/#configuration-example","title":"Configuration example","text":"

    The following example is a simple retention configuration with two policies:

    • The first includes all available configuration attributes.
    • The second acts as a default policy.

    simple policy example

      \"storage\": {\n    \"retention\": {\n      \"dryRun\": false,\n      \"delay\": \"24h\",\n      \"policies\": [\n        {\n          \"repoNames\": [\"infra/*\", \"tmp/**\"],\n          \"deleteReferrers\": false,\n          \"deleteUntagged\": true,\n          \"KeepTags\": [{\n            \"patterns\": [\"v2.*\", \".*-prod\"],\n            \"mostRecentlyPushedCount\": 10,\n            \"mostRecentlyPulledCount\": 10,\n            \"pulledWithin\": \"720h\",\n            \"pushedWithin\": \"720h\"\n          }]  \n        },\n        {\n          \"keepTags\": [{\n            \"patterns\": [\".*\"]\n          }]\n        }\n      ]\n    }\n  }\n
    "},{"location":"articles/retention/#configurable-attributes","title":"Configurable attributes","text":"

    The following table lists the attributes available in the retention policy configuration.

    Attribute Value Description dryRun boolean If true, will log a removal action without actually removing the image. Default is false. delay time Remove untagged and referrers only if they are older than the specified <time> hours, such as 24h. policies list A list of policies. repositories list A list of glob patterns to match repositories. deleteReferrers boolean If true, delete manifests with a missing Subject. Default is false. deleteUntagged boolean If true, delete untagged manifests. Default is true. keepTags list Criteria for tags to retain always. mostRecentlyPushedCount count Retains the top <count> most recently pushed tags. mostRecentlyPulledCount count Retains the top <count> most recently pulled tags. pushedWithin time Retains the tags pushed during the last <time> hours, such as 24h. pulledWithin time Retains the tags pulled during the last <time> hours, such as 24h. patterns regex See Notes."},{"location":"articles/retention/#configuration-notes","title":"Configuration notes","text":"
    • A repository will apply the first policy it matches.
    • If a repository matches no policy, the repository and all its tags are retained.
    • If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed.
    • If keepTags is present but empty, all tags are retained.
    • When multiple rules are configured, a tag is retained if it meets at least one rule.
    • When you specify a regex pattern combined with one or more rules, the rules are applied only to those tags matching the regex.
    • When you specify a regex pattern with no rules other than the default, all tags matching the pattern are retained.
    • In the repositories list, a single asterisk (/*) matches all first-level items in the repository. A double asterisk (/**) matches all recursively.

    We recommend defining a default keepTags policy, such as the following example, as the last policy in the policy list. All tags that don't match the preceding policies will be retained by this default policy:

    default policy example

      {\n    \"keepTags\": [{                               \n        \"patterns\": [\".*\"]\n      }]\n  }\n
    "},{"location":"articles/retention/#complete-configuration-file-example","title":"Complete configuration file example","text":"

    The following example shows the configuration of multiple retention policies in the context of a complete configuration file.

    {\n  \"distSpecVersion\": \"1.1.0-dev\",\n  \"storage\": {\n    \"rootDirectory\": \"/tmp/zot\",\n    \"gc\": true,\n    \"gcDelay\": \"2h\",\n    \"gcInterval\": \"1h\",\n    \"retention\": {\n      \"dryRun\": false,\n      \"delay\": \"24h\",\n      \"policies\": [\n        {\n          \"repositories\": [\"infra/*\", \"prod/*\"],\n          \"deleteReferrers\": false,\n          \"keepTags\": [{\n            \"patterns\": [\"v2.*\", \".*-prod\"]\n          },\n          {\n            \"patterns\": [\"v3.*\", \".*-prod\"],\n            \"pulledWithin\": \"168h\"\n          }]\n        },\n        {\n          \"repositories\": [\"tmp/**\"],\n          \"deleteReferrers\": true,\n          \"deleteUntagged\": true,\n          \"keepTags\": [{\n            \"patterns\": [\"v1.*\"],\n            \"pulledWithin\": \"168h\",\n            \"pushedWithin\": \"168h\"\n          }]\n        },\n        {\n          \"repositories\": [\"**\"],\n          \"deleteReferrers\": true,\n          \"deleteUntagged\": true,\n          \"keepTags\": [{\n            \"mostRecentlyPushedCount\": 10,\n            \"mostRecentlyPulledCount\": 10,\n            \"pulledWithin\": \"720h\",\n            \"pushedWithin\": \"720h\"\n          }]\n        }\n      ]\n    },\n    \"subPaths\": {\n      \"/a\": {\n        \"rootDirectory\": \"/tmp/zot1\",\n        \"dedupe\": true,\n        \"retention\": {\n          \"policies\": [\n            {\n              \"repositories\": [\"infra/*\", \"prod/*\"],\n              \"deleteReferrers\": false\n            }\n          ]\n        }\n      }\n    }\n  },\n  \"http\": {\n    \"address\": \"127.0.0.1\",\n    \"port\": \"8080\"\n  },\n  \"log\": {\n    \"level\": \"debug\"\n  }\n}\n
    "},{"location":"articles/security-posture/","title":"zot Security Posture","text":"

    An overview of zot build-time and runtime security hardening features, including:

    • Build-time hardening such as PIE-mode builds
    • Minimal-build option for smaller attack surface
    • Open Source Security Foundation best practices for CI/CD
    • Non-root deployment
    • Robust authentication/authorization options

    The zot project takes a defense-in-depth approach to security, applying industry-standard best practices at various stages. Recognizing that security hardening and product features are sometimes in conflict with each other, we also provide flexibility both at build and deployment time.

    "},{"location":"articles/security-posture/#build-time-hardening","title":"Build-time hardening","text":"

    The following are the steps taken during build-time.

    "},{"location":"articles/security-posture/#pie-build-mode","title":"PIE build-mode","text":"

    The zot binary is built with PIE build-mode enabled to take advantage of ASLR support in modern operating systems such as Linux ASLR. While zot is intended to be a long-running service (without frequent restarts), it prevents attackers from developing a generic attack that depends on predictable memory addresses across multiple zot deployments.

    "},{"location":"articles/security-posture/#conditional-builds","title":"Conditional builds","text":"

    Functionality in zot is broadly organized as a core Distribution Specification implementation and additional features as extensions. The rationale behind this approach is to minimize or control library dependencies that get included in the binary and consequently the attack surface.

    We currently build and release two image flavors:

    • minimal, which is a minimal Distribution Specification conformant registry, and

    • full, which incorporates the minimal build and all extensions

    The minimal flavor is for the security-minded and minimizes the number of dependencies and libraries. The full flavor is for the functionality-minded with the caveat that the attack surface of the binary is potentially broader. However by no means are these the only options. Our build (via the Makefile) provides the flexibility to pick and choose extensions in order to build a binary between minimal and full. For example,

    make EXTENSIONS=search binary

    produces a zot binary with only the search feature enabled.

    "},{"location":"articles/security-posture/#cicd-pipeline","title":"CI/CD pipeline","text":"

    zot CI/CD process attempts to align with the Open Source Security Foundation (OSSF) best practices guidelines to achieve high code quality.

    "},{"location":"articles/security-posture/#code-reviews","title":"Code reviews","text":"

    zot is an open source project and all code submissions are open and transparent. Every pull request (PR) submitted to the project repository must be reviewed by the code owners. We have additional CI/CD workflows monitoring for unreviewed commits.

    "},{"location":"articles/security-posture/#cicd-checks","title":"CI/CD checks","text":"

    All PRs must pass the full CI/CD pipeline checks including unit, functional, and integration tests, code quality and style checks, and performance regressions. In addition, all binaries produced are subjected to further security scans to detect any known vulnerabilities.

    "},{"location":"articles/security-posture/#runtime-hardening","title":"Runtime hardening","text":"

    The following steps can be taken to harden a zot deployment.

    "},{"location":"articles/security-posture/#unprivileged-runtime-process","title":"Unprivileged runtime process","text":"

    Running zot doesn\u2019t require root privileges. In fact, the recommended approach is to create a separate user/group ID for the zot process.

    "},{"location":"articles/security-posture/#authentication","title":"Authentication","text":"

    All interactions with zot are over HTTP APIs, and htpasswd-based local authentication, LDAP, mutual TLS, and token-based authentication mechanisms are supported. We strongly recommend enabling a suitable mechanism for your deployment use case in order to prevent unauthorized access. See the provided authentication examples.

    "},{"location":"articles/security-posture/#access-control","title":"Access control","text":"

    Following authentication, it is further possible to allow or deny actions by a user on a particular repository stored on the zot registry. See the provided access control examples.

    "},{"location":"articles/security-posture/#vulnerability-scans","title":"Vulnerability scans","text":"

    Apart from hardening the deployment itself, zot also supports security scanning of stored container images.

    "},{"location":"articles/security-posture/#reporting-security-issues","title":"Reporting security issues","text":"

    We understand that no software is perfect and in spite of our best efforts, security bugs may be found. Refer to our security policy for taking a responsible course of action when reporting security bugs.

    "},{"location":"articles/storage/","title":"Storage Planning with zot","text":"

    zot supports the following features to provide OCI standards-based, vendor-agnostic image storage:

    • Local and remote file storage
    • Inline deduplication and garbage collection
    • Data scrubbing in background
    "},{"location":"articles/storage/#storage-model","title":"Storage model","text":"

    Data handling in zot revolves around two main principles: that data and APIs on the wire conform to the OCI Distribution Specification and that data on the disk conforms to the OCI Image Layout Specification. As a result, any client that is compliant with the Distribution Specification can read from or write to a zot registry. Furthermore, the actual storage is simply an OCI Image Layout. With only these two specification documents in hand, the entire data flow inside can be easily understood.

    zot does not implement, support, or require any vendor-specific protocols, including that of Docker.

    "},{"location":"articles/storage/#hosting-an-oci-image-layout","title":"Hosting an OCI image layout","text":"

    Because zot supports the OCI image layout, it can readily host and serve any directories holding a valid OCI image layout even when those directories have been created elsewhere. This property of zot is suitable for use cases in which container images are independently built, stored, and transferred, but later need to be served over the network.

    "},{"location":"articles/storage/#storage-features","title":"Storage features","text":"

    Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.

    "},{"location":"articles/storage/#commit","title":"Commit","text":"

    Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.

    "},{"location":"articles/storage/#deduplication","title":"Deduplication","text":"

    Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.

    Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.

    "},{"location":"articles/storage/#garbage-collection","title":"Garbage collection","text":"

    After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. See Configuring garbage collection for details.

    "},{"location":"articles/storage/#scrub","title":"Scrub","text":"

    The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.

    "},{"location":"articles/storage/#storage-backends","title":"Storage backends","text":"

    The following types of storage backends are supported.

    "},{"location":"articles/storage/#local-filesystem","title":"Local filesystem","text":"

    zot can store and serve files from one or more local directories. A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.

    Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.

    "},{"location":"articles/storage/#remote-filesystem","title":"Remote filesystem","text":"

    zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS s3 storage service.

    "},{"location":"articles/storage/#example-configuration-for-remote-s3-storage","title":"Example: configuration for remote (s3) storage","text":"Click here to view a sample zot configuration for remote storage.
    {\n    \"distSpecVersion\": \"1.0.1-dev\",\n    \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\",\n        \"dedupe\": true,\n        \"storageDriver\": {\n            \"name\": \"s3\",\n            \"rootdirectory\": \"/zot\",\n            \"region\": \"us-east-2\",\n            \"bucket\": \"zot-storage\",\n            \"secure\": true,\n            \"skipverify\": false\n        },\n        \"cacheDriver\": {\n            \"name\": \"dynamodb\",\n            \"endpoint\": \"http://localhost:4566\",\n            \"region\": \"us-east-2\",\n            \"tableName\": \"MainTable\"\n        },\n    },\n    \"http\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": \"8080\"\n    },\n    \"log\": {\n        \"level\": \"debug\"\n    }\n}\n
    "},{"location":"articles/storage/#configuring-zot-storage","title":"Configuring zot storage","text":"

    Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following example.

        \"storage\":{\n        \"rootDirectory\":\"/tmp/zot\",\n        \"commit\": true,\n        \"dedupe\": true,\n        \"gc\": true,\n        \"gcDelay\": \"1h\",\n        \"gcInterval\": \"24h\"\n    }\n
    "},{"location":"articles/storage/#configurable-attributes","title":"Configurable attributes","text":"

    The following table lists the attributes of the storage configuration.

    Attribute Description

    rootDirectory

    Location of the images stored in the server file system.

    commit

    For faster performance, data written by zot is retained in memory before being periodically committed to disk by the operating system. To eliminate this retention time and cause data to be written to disk immediately, set to true. This prevents data loss but reduces performance.

    dedupe

    If the server filesystem supports hard links, you can optimize storage space by enabling inline deduplication of layers and blobs that are shared among multiple container images. Deduplication is enabled by default. Set to false to disable deduplication.

    gc

    When an image is deleted, either by tag or by reference, orphaned blobs can lead to wasted storage. Garbage collection (gc) is enabled by default to reclaim this space. Set to false to disable garbage collection.

    gcDelay

    (Optional) If garbage collection is enabled, causes it to run once after the specified delay time. The default is 1 hour. Requires the gc attribute to be true.

    gcInterval

    (Optional) If garbage collection is enabled, causes periodic collection at the specified interval. Must be set based on use cases and user workloads. If no value is specified, there is no periodic collection. Requires the gc attribute to be true.

    subpaths

    You can store and serve images from multiple filesystems, each with their own repository paths and settings. The following example shows three subpaths.

    \"storage\":{\n  \"subPaths\": {\n    \"/a\": {\n      \"rootDirectory\": \"/tmp/zot1\",\n      \"dedupe\": true,\n      \"gc\": true\n    },\n    \"/b\": {\n      \"rootDirectory\": \"/tmp/zot2\",\n      \"dedupe\": true\n    },\n    \"/c\": {\n      \"rootDirectory\": \"/tmp/zot3\",\n      \"dedupe\": false\n    }\n  }\n}

    storageDriver

    (Remote storage only) Contains settings for a remote storage service. See Configuring remote storage with s3 for details.

    cacheDriver

    Specifies which database is used to store duplicate blobs when deduplication is enabled. See Cache drivers for details.

    "},{"location":"articles/storage/#configuring-garbage-collection","title":"Configuring garbage collection","text":"

    The zot configuration model allows for enabling and disabling garbage collection (gc) and specifying a periodic interval (gcInterval) for collection.

    gc gcInterval Result false n/a GC disabled omitted n/a GC enabled with 1 hour interval (default) true omitted GC enabled with 1 hour interval true 0 GC runs only once true >0 GC enabled with specified interval

    The configuration model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs. The gcDelay attribute causes collection to run once after the specified delay time. This attribute has a default value of one hour (1h).

    "},{"location":"articles/storage/#configuring-remote-storage-with-s3","title":"Configuring remote storage with s3","text":"

    To configure an Amazon Simple Storage Service (s3) bucket for zot, use the storageDriver attribute in the zot configuration file, as shown in the following example:

        \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\",\n        \"storageDriver\": {\n            \"name\": \"s3\",\n            \"region\": \"us-east-2\",\n            \"bucket\": \"zot-storage\",\n            \"secure\": true,\n            \"skipverify\": false,\n            \"accesskey\": \"<YOUR_ACCESS_KEY_ID>\",\n            \"secretkey\": \"<YOUR_SECRET_ACCESS_KEY>\"\n        }\n    }\n

    For descriptions of the configurable attributes for storageDriver, see the s3 storage driver project in GitHub.

    "},{"location":"articles/storage/#s3-credentials","title":"s3 Credentials","text":"

    In the s3 configuration file example, the s3 credentials were configured with the attributes accesskey and secretkey. As an alternative, you can omit these attributes from the configuration file and you can configure them using environment variables or a credential file.

    • Environment variables

      zot looks for credentials in the following environment variables:

      AWS_ACCESS_KEY_ID\nAWS_SECRET_ACCESS_KEY\nAWS_SESSION_TOKEN (optional)\n
    • Credential file

      A credential file is a plaintext file that contains your access keys, as shown in the following example.

      [default]\naws_access_key_id = <YOUR_DEFAULT_ACCESS_KEY_ID>\naws_secret_access_key = <YOUR_DEFAULT_SECRET_ACCESS_KEY>\n\n[test-account]\naws_access_key_id = <YOUR_TEST_ACCESS_KEY_ID>\naws_secret_access_key = <YOUR_TEST_SECRET_ACCESS_KEY>\n\n[prod-account]\n; work profile\naws_access_key_id = <YOUR_PROD_ACCESS_KEY_ID>\naws_secret_access_key = <YOUR_PROD_SECRET_ACCESS_KEY>\n

      The [default] heading defines credentials for the default profile, which zot will use unless you configure it to use another profile. You can specify a profile using the AWS_PROFILE environment variable as in this example:

      AWS_PROFILE=test-account\n

      The credential file must be named credentials. The file must be located in the .aws/ subdirectory in the home directory of the same server that is running your zot application.

    For more details about specifying s3 credentials, see the AWS documentation.

    "},{"location":"articles/storage/#s3-permissions-scopes","title":"S3 permissions scopes","text":"

    The following AWS policy is required by zot for push and pull.

    Replace S3_BUCKET_NAME with the name of your s3 bucket.

    [AWS CONFIGURATION]\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:ListBucket\",\n        \"s3:GetBucketLocation\",\n        \"s3:ListBucketMultipartUploads\"\n      ],\n      \"Resource\": \"arn:aws:s3:::<S3_BUCKET_NAME>\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:PutObject\",\n        \"s3:GetObject\",\n        \"s3:DeleteObject\",\n        \"s3:ListMultipartUploadParts\",\n        \"s3:AbortMultipartUpload\"\n      ],\n      \"Resource\": \"arn:aws:s3:::<S3_BUCKET_NAME>/*\"\n    }\n  ]\n}\n

    For more details about configuring AWS policies, see the AWS documentation.

    "},{"location":"articles/storage/#cache-drivers","title":"Cache drivers","text":"

    A cache driver is used to store duplicate blobs when dedupe is enabled. zot supports database caching using BoltDB as the cache driver for local filesystems and DynamoDB for remote filesystems.

    "},{"location":"articles/storage/#boltdb","title":"BoltDB","text":"

    If you don't specify a cache driver, zot defaults to BoltDB. BoltDB is stored either in zot's root directory or in the subpath root directory.

        \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\",\n        \"dedupe\": true\n    }\n

    In this example, BoltDB can be found at /tmp/zot/cache.db.

    "},{"location":"articles/storage/#dynamodb","title":"DynamoDB","text":"

    To use DynamoDB as the cache driver, the following storage configuration must be present:

    • dedupe is enabled
    • remoteCache is enabled
    • cacheDriver attribute is configured as in the following example:
        \"storage\": {\n        \"rootDirectory\": \"/tmp/zot\",\n        \"dedupe\": true,\n        \"remoteCache\": true,\n        \"cacheDriver\": {\n            \"name\": \"dynamodb\",                  // driver name\n            \"endpoint\": \"http://localhost:4566\", // aws endpoint\n            \"region\": \"us-east-2\"                // aws region\n            \"cacheTablename\": \"ZotBlobTable\"     // table to store deduped blobs\n        }\n    },\n

    The AWS GO SDK loads additional configuration and credentials values from your environment variables, shared credentials, and shared configuration files.

    If the search extension is enabled, additional parameters are required:

            \"cacheDriver\": {\n            \"name\": \"dynamodb\",\n            \"endpoint\": \"http://localhost:4566\",\n            \"region\": \"us-east-2\",\n            \"cacheTablename\": \"ZotBlobTable\",\n            // used by search extensions\n            \"repoMetaTablename\": \"ZotRepoMetadataTable\",\n            \"manifestDataTablename\": \"ZotManifestDataTable\",\n            \"versionTablename\": \"ZotVersion\"\n        }\n
    "},{"location":"articles/storage/#dynamodb-permission-scopes","title":"DynamoDB permission scopes","text":"

    The following AWS policy is required by zot for caching blobs.

    Replace DYNAMODB_TABLE with the name of your table, which should be the value of cacheTablename in the zot configuration.

    In this case, the AWS Resource value would be arn:aws:dynamodb:*:*:table/ZotBlobTable

    [AWS CONFIGURATION]\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"dynamodb:CreateTable\",\n        \"dynamodb:GetItem\",\n        \"dynamodb:UpdateItem\",\n        \"dynamodb:DeleteItem\"\n      ],\n      \"Resource\": \"arn:aws:dynamodb:*:*:table/<DYNAMODB_TABLE>\"\n    }\n  ]\n}\n

    For more details about configuring AWS DynamoDB, see the AWS documentation.

    "},{"location":"articles/storage/#remote-storage-subpaths","title":"Remote storage subpaths","text":"

    As in the case with local filesystem storage, you can use multiple remote storage locations using the subpath attribute, as in the following example.

    \"subPaths\": {\n    \"/a\": {\n        \"rootDirectory\": \"/zot-a\",\n        \"storageDriver\": {\n            \"name\": \"s3\",\n            \"region\": \"us-east-2\",\n            \"bucket\": \"zot-storage\",\n            \"secure\": true,\n            \"skipverify\": false\n        }\n    },\n    \"/b\": {\n       .\n       .\n       .\n    }\n}\n

    The subPaths feature ties together several separate storage filesystems and backends behind the same HTTP API interface. In the example above, both repository paths \"/a\" and \"/b\" are exposed to clients. Content on these two paths can be hosted completely separately by different storage services, locations, or filesystems, with no difference to the user interface and no perceptible difference to the user experience. This is useful if one wants to serve existing OCI images from different backends or if storage can be expanded only by using different backing stores.

    zot also supports different storage drivers for each subpath.

    "},{"location":"articles/verifying-signatures/","title":"Verifying image signatures","text":"

    Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user.

    To verify image signatures, zot supports the following tools:

    • cosign
    • notation
    "},{"location":"articles/verifying-signatures/#enabling-image-signature-verification","title":"Enabling image signature verification","text":"

    To enable image signature verification, add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:

    \"extensions\": {\n  \"trust\": {\n    \"enable\": true,\n    \"cosign\": true,\n    \"notation\": true\n  }\n}\n

    The following table lists the configurable attributes of the trust extension.

    Attribute Description enable If this attribute is missing, signature verification is disabled by default. Signature verification is enabled by including this attribute and setting it to true. You must also enable at least one of the verification tools. cosign Set to true to enable signature verification using the cosign tool. notation Set to true to enable signature verification using the notation tool."},{"location":"articles/verifying-signatures/#what-is-needed-for-verifying-signatures","title":"What is needed for verifying signatures","text":"

    To verify the validity of a signature for an image, zot makes use of two types of files:

    • A public key file that pairs with the private key used to sign an image with cosign

    • A certificate file that is used to sign an image with notation

    Upload these files using an extension of the zot API, as shown in the following examples:

    • To upload a public key for cosign:

      API path

      /v2/_zot/ext/cosign\"\n
      Example request
      curl --data-binary @file.pub -X POST \"http://localhost:8080/v2/_zot/ext/cosign\"\n
      Result

      The uploaded file is stored in the _cosign directory under the rootDir specified in the zot configuration file or in the Secrets Manager.

    • To upload a certificate for notation:

      API path

      /v2/_zot/ext/notation?truststoreType=ca\n

      When uploading a certificate, you should specify the truststoreType. If the truststore is a certificate authority, the value is ca. This is the default if this attribute is omitted.

      Example request

      curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
      Result

      The uploaded file is stored in the _notation/truststore/x509/{truststoreType}/default directory under the rootDir specified in the zot configuration file or in the Secrets Manager.

    "},{"location":"articles/verifying-signatures/#where-needed-files-are-stored","title":"Where needed files are stored","text":"

    Uploaded public keys and certificates are stored in the local filesystem, in specific directories named _cosign and _notation under $rootDir, or in the Secrets Manager.

    • The _cosign directory contains uploaded public key files in the following structure:

      _cosign\n\u251c\u2500\u2500 $publicKey1\n\u2514\u2500\u2500 $publicKey2\n
    • The _notation directory contains a set of files in the following structure:

      _notation\n\u251c\u2500\u2500 trustpolicy.json\n\u2514\u2500\u2500 truststore\n    \u2514\u2500\u2500 x509\n        \u2514\u2500\u2500 $truststoreType\n            \u2514\u2500\u2500 default\n                \u2514\u2500\u2500 $certificate\n

      In this directory, the trustpolicy.json file contains content that is updated automatically whenever a new certificate is added to a new truststore. This content cannot be changed by the user. An example of the trustpolicy.json file content is shown below:

      {\n \"version\": \"1.0\",\n  \"trustPolicies\": [\n    {\n      \"name\": \"default-config\",\n      \"registryScopes\": [ \"*\" ],\n      \"signatureVerification\": {\n        \"level\" : \"strict\" \n      },\n      \"trustStores\": [\"ca:default\",\"signingAuthority:default\"],\n      \"trustedIdentities\": [\n        \"*\"\n      ]\n    }\n  ]\n}\n
      • By default, the trustpolicy.json file sets the signatureVerification.level property to strict, which enforces all validations. For example, a signature is not trusted if its certificate has expired, even if the certificate verifies the signature.

      • The trustpolicy.json file contains two default truststores, ca:default and signingAuthority:default. This list of truststores is not updated when a new certificate is uploaded.

      • The content of the trustStores field will match the content of the _notation/truststore directory.

    "},{"location":"articles/verifying-signatures/#how-signature-verification-works","title":"How signature verification works","text":"

    Based on the uploaded files and the information about images stored in zot's database, signature verification is performed for all signed images. The verification result for each signed image is stored in the database and is visible from GraphQL. The stored information about a signature includes:

    • The tool that was used to generate the signature, such as cosign or notation
    • The trustworthiness of the signature, such as whether a certificate or public key exists that can successfully verify the signature
    • The author of the signature, which can be either:

      • The public key, for signatures generated using cosign
      • The subject of the certificate, for signatures generated using notation
    "},{"location":"articles/verifying-signatures/#example-of-graphql-output","title":"Example of GraphQL output","text":"

    Sample request

    {\n  Image(image: \"busybox:latest\") {\n    Digest\n    IsSigned\n    Tag\n    SignatureInfo {\n        Tool\n        IsTrusted\n        Author\n    }\n  }\n}\n

    Sample response

    {\n  \"data\": {\n    \"Image\": {\n      \"Digest\":\"sha256:6c19fba547b87bde9a45df2f8563e0c61826d098dd30192a2c8b86da1e1a6360\",\n      \"IsSigned\": true,\n      \"Tag\": \"latest\",\n      \"SignatureInfo\":[\n        {\n          \"Tool\":\"cosign\",\n          \"IsTrusted\":false,\n          \"Author\":\"\"\n        },\n        {\n          \"Tool\":\"cosign\",\n          \"IsTrusted\":false,\n          \"Author\":\"\"\n        },\n        {\n          \"Tool\":\"cosign\",\n          \"IsTrusted\": true,\n          \"Author\":\"-----BEGIN PUBLIC KEY-----\\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9pN+/hGcFlh4YYaNvZxNvuh8Qyhl\\npURz77qScOHe3DqdmiWiuqIseyhEdjEDwpL6fHRwu3a2Nd9wbKqm0la76w==\\n-----END PUBLIC KEY-----\\n\"\n        },\n        {\n          \"Tool\":\"notation\",\n          \"IsTrusted\": false,\n          \"Author\":\"CN=v4-test,O=Notary,L=Seattle,ST=WA,C=US\"\n        },\n        {\n          \"Tool\":\"notation\",\n          \"IsTrusted\": true,\n          \"Author\":\"CN=multipleSig,O=Notary,L=Seattle,ST=WA,C=US\"\n        }\n      ]\n    }\n  }\n}\n
    "},{"location":"articles/workflow/","title":"Software Provenance Workflow Using OCI Artifacts","text":"

    This article demonstrates an end-to-end workflow for installing a zot registry, then pushing and signing an image and a related artifact, such as an SBOM.

    "},{"location":"articles/workflow/#workflow","title":"Workflow","text":"

    The following sections describe the step-by-step workflow. To view the steps combined into a single script, see Reference: Full workflow script.

    For the workflow examples, the zot registry is assumed to be installed and running at localhost:8080.

    "},{"location":"articles/workflow/#step-1-download-the-client-tools","title":"Step 1: Download the client tools","text":"

    This workflow uses the regctl registry client and the cosign image signing tool. As a first step, we download binaries for these tools in a tools directory.

    TEST_TMPDIR=$(mktemp -d \"${PWD}/artifact-test-${1:+-$1}.XXXXXX\")\n\nTOOLSDIR=$(pwd)/hack/tools\nmkdir -p ${TOOLSDIR}/bin\n\nREGCLIENT=${TOOLSDIR}/bin/regctl\nREGCLIENT_VERSION=v0.5.1\ncurl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64\nchmod +x ${REGCLIENT}\n\nCOSIGN=${TOOLSDIR}/bin/cosign\nCOSIGN_VERSION=2.1.1\ncurl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 \nchmod +x ${COSIGN}\n
    "},{"location":"articles/workflow/#step-2-deploy-an-oci-registry-with-referrers-support-zot","title":"Step 2: Deploy an OCI registry with referrers support (zot)","text":"

    Next, we execute the following tasks to deploy an OCI registry:

    • Copy a zot executable binary to the server.
    • Create a basic configuration file for the zot server, specifying the local root directory, the network location, and the port number.
    • Launch zot with the newly-created configuration file.
    • Looping with a periodic cURL query, detect when zot is up and running.
    ZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\n# function to start zot and test for readiness\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n  \"distSpecVersion\": \"1.1.0-dev\",\n  \"storage\": {\n      \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n  },\n  \"http\": {\n      \"address\": \"$ZOT_HOST\",\n      \"port\": \"$ZOT_PORT\"\n  },\n  \"log\": {\n      \"level\": \"error\"\n  }\n}\nEOF\n  # start zot as a background task\n  ${ZOT} serve $TEST_TMPDIR/zot-config.json &\n  pid=$!\n        # wait until service is up\n  count=5\n  up=0\n  while [[ $count -gt 0 ]]; do\n    if [ ! -d /proc/$pid ]; then\n      echo \"zot failed to start or died\"\n      exit 1\n    fi\n    up=1\n    curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n    if [ $up -eq 1 ]; then break; fi\n    sleep 1\n    count=$((count - 1))\n  done\n  if [ $up -eq 0 ]; then\n    echo \"Timed out waiting for zot\"\n    exit 1\n  fi\n  # setup an OCI client\n  ${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# call the function to start zot\nzot_setup\n
    "},{"location":"articles/workflow/#step-3-copy-an-image-to-the-oci-registry","title":"Step 3: Copy an image to the OCI registry","text":"

    This step copies a busybox container image into the registry.

    skopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n
    "},{"location":"articles/workflow/#step-4-copy-a-related-artifact-to-the-oci-registry","title":"Step 4: Copy a related artifact to the OCI registry","text":"

    This step creates a simple artifact file and associates it with the busybox image in the registry.

    cat > ${TEST_TMPDIR}/artifact.yaml << EOF\nkey:\n  val: artifact\nEOF\n${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n

    The --subject command flag associates the artifact file with the specified subject (in this case, the busybox image). If no subject is specified by the command, the artifact is considered independent and not associated with any existing image.

    "},{"location":"articles/workflow/#step-5-display-the-artifact-tree","title":"Step 5: Display the artifact tree","text":"

    This step prints the artifact tree of the busybox image. The tree includes the artifact yaml file, showing the association of the artifact to the busybox image.

    These script commands define REF0 as the artifact that was uploaded referring to the first container image.

    REF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n

    The following example shows the command and its output:

    $ regctl artifact tree localhost:8080/busybox:latest\n\nRef: localhost:8080/busybox:latest  \nDigest: sha256:9172c5f692f2c65e4f773448503b21dba2de6454bd159905c4bf6d83176e4ea3\nReferrers:  \n   - sha256:9c0655368b10ca4b2ffe39e4dd261fb89df25a46ae92d6eb4e6e1792a451883e: application/yaml\n

    The displayed artifact tree shows that the original image (localhost:8080/busybox:latest) has one direct referrer (sha256:9c06...883e: application/yaml), the artifact yaml file.

    "},{"location":"articles/workflow/#step-6-sign-the-image-and-artifact","title":"Step 6: Sign the image and artifact","text":"

    This step creates a key pair for cosign in a separate directory, then uses cosign to sign both the image and the artifact file. Both signatures, like the artifact file itself, are associated with the busybox image.

    # create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n
    "},{"location":"articles/workflow/#step-7-display-the-artifact-tree","title":"Step 7: Display the artifact tree","text":"

    This step again prints the artifact tree, which should now show the artifact and the two signatures, all associated to the busybox image.

    ${REGCLIENT} artifact tree localhost:8080/busybox:latest\n

    The following example shows the command and its output:

    $ regctl artifact tree localhost:8080/busybox:latest\n\nRef: localhost:8080/busybox:latest\nDigest: sha256:9172c5f692f2c65e4f773448503b21dba2de6454bd159905c4bf6d83176e4ea3\nReferrers:\n  - sha256:9c0655368b10ca4b2ffe39e4dd261fb89df25a46ae92d6eb4e6e1792a451883e: application/yaml\n    Referrers:\n      - sha256:06792b209137486442a2b804b2225c0014e3e238d363cdbea088bbd73207fb34: application/vnd.dev.cosign.artifact.sig.v1+json\n  - sha256:995b6a78bf04a7a9676dac76b4598ccb645c17e30b02f294de9fdfa2f28eb7b2: application/vnd.dev.cosign.artifact.sig.v1+json\n

    The displayed artifact tree shows that the original image now has two direct referrers \u2014 the artifact and the cosign signature of the original image. In addition, there is a second-level referrer \u2014 the cosign signature of the artifact, which is a referrer of the artifact file.

    "},{"location":"articles/workflow/#step-8-end-of-demonstration","title":"Step 8: End of demonstration","text":"

    This step halts the zot registry server, ending the workflow demonstration.

    # function for stopping zot after demonstration\nfunction zot_teardown() {\n  killall zot\n}\n\n# stop zot\nzot_teardown\n
    "},{"location":"articles/workflow/#reference-full-workflow-script","title":"Reference: Full workflow script","text":"

    Expand the text box below to view the entire workflow as a single executable shell script.

    To copy the script to the clipboard, click the copy icon that appears in the upper right corner of the expanded text box.

    Click here to view the all-in-one script
    #!/bin/bash -xe\n\nTEST_TMPDIR=$(mktemp -d \"${PWD}/artifact-test-${1:+-$1}.XXXXXX\")\n\nTOOLSDIR=$(pwd)/hack/tools\nmkdir -p ${TOOLSDIR}/bin\n\nREGCLIENT=${TOOLSDIR}/bin/regctl\nREGCLIENT_VERSION=v0.5.1\ncurl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64\nchmod +x ${REGCLIENT}\n\nCOSIGN=${TOOLSDIR}/bin/cosign\nCOSIGN_VERSION=2.1.1\ncurl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 \nchmod +x ${COSIGN}\n\n# OCI registry\nZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n  \"distSpecVersion\": \"1.1.0-dev\",\n  \"storage\": {\n      \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n  },\n  \"http\": {\n      \"address\": \"$ZOT_HOST\",\n      \"port\": \"$ZOT_PORT\"\n  },\n  \"log\": {\n      \"level\": \"error\"\n  }\n}\nEOF\n# start as a background task\n${ZOT} serve $TEST_TMPDIR/zot-config.json &\npid=$!\n        # wait until service is up\ncount=5\nup=0\nwhile [[ $count -gt 0 ]]; do\n    if [ ! -d /proc/$pid ]; then\n    echo \"zot failed to start or died\"\n    exit 1\n    fi\n    up=1\n    curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n    if [ $up -eq 1 ]; then break; fi\n    sleep 1\n    count=$((count - 1))\ndone\nif [ $up -eq 0 ]; then\n    echo \"Timed out waiting for zot\"\n    exit 1\nfi\n# setup a OCI client\n${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# function for stopping zot after demonstration\nfunction zot_teardown() {\nkillall zot\n}\n\n# call the function to start zot\nzot_setup\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n\n# copy an artifact referring to the above image\ncat > ${TEST_TMPDIR}/artifact.yaml << EOF\nkey:\nval: artifact\nEOF\n${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\nREF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n\n# create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n\n# list the reference tree\n${REGCLIENT} artifact tree localhost:8080/busybox:latest\n\n# stop zot\nzot_teardown\n
    "},{"location":"developer-guide/api-reference/","title":"zot API Command Reference","text":"

    This article describes the zot REST API commands, parameters, and responses.

    The information presented here is adapted from the interactive OpenAPI (formerly swagger) JSON file in the zot Github project.

    For instructions and examples of how to use the zot API, see Using the zot API.

    "},{"location":"developer-guide/api-reference/#zotauthapikey","title":"/zot/auth/apikey","text":""},{"location":"developer-guide/api-reference/#delete-zotauthapikey","title":"DELETE /zot/auth/apikey","text":"

    Revokes one current user API key based on given key ID

    Parameters

    Name In Type Required Description id query string true api token id (UUID)

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#get-zotauthapikey","title":"GET /zot/auth/apikey","text":"

    Get list of all API keys for a logged in user

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#post-zotauthapikey","title":"POST /zot/auth/apikey","text":"

    Can create an api key for a logged in user, based on the provided label and scopes.

    Body parameter

    {\n  \"expirationDate\": \"string\",\n  \"label\": \"string\",\n  \"scopes\": [\n    \"string\"\n  ]\n}\n

    Parameters

    Name In Type Required Description body body api.APIKeyPayload true api token id (UUID)

    Example responses

    201 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#zotauthlogout","title":"/zot/auth/logout","text":""},{"location":"developer-guide/api-reference/#post-zotauthlogout","title":"POST /zot/auth/logout","text":"

    Logout by removing current session

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok\". string 500 Internal Server Error internal server error\". string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#orasartifactsv1namemanifestsdigestreferrers","title":"/oras/artifacts/v1/{name}/manifests/{digest}/referrers","text":""},{"location":"developer-guide/api-reference/#get-orasartifactsv1namemanifestsdigestreferrers","title":"GET /oras/artifacts/v1/{name}/manifests/{digest}/referrers","text":"

    Get references for an image given a digest and artifact type

    Parameters

    Name In Type Required Description name path string true repository name digest path string true image digest artifactType query string true artifact type

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2","title":"/v2/","text":""},{"location":"developer-guide/api-reference/#get-v2","title":"GET /v2/","text":"

    Check if this API version is supported

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok\". string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_catalog","title":"/v2/_catalog","text":""},{"location":"developer-guide/api-reference/#get-v2_catalog","title":"GET /v2/_catalog","text":"

    List all image repositories

    Example responses

    200 Response

    {\n  \"repositories\": [\n    \"string\"\n  ]\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK api.RepositoryList 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_ociextdiscover","title":"/v2/_oci/ext/discover","text":""},{"location":"developer-guide/api-reference/#get-v2_ociextdiscover","title":"GET /v2/_oci/ext/discover","text":"

    List all extensions present on registry

    Example responses

    200 Response

    {\n  \"extensions\": [\n    {\n      \"description\": \"string\",\n      \"endpoints\": [\n        \"string\"\n      ],\n      \"name\": \"string\",\n      \"url\": \"string\"\n    }\n  ]\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK api.ExtensionList

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_zotextcosign","title":"/v2/_zot/ext/cosign","text":""},{"location":"developer-guide/api-reference/#post-v2_zotextcosign","title":"POST /v2/_zot/ext/cosign","text":"

    Upload cosign public keys for verifying signatures

    Body parameter

    string\n

    Parameters

    Name In Type Required Description body body string true Public key content

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request\". string 500 Internal Server Error internal server error\". string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_zotextmgmt","title":"/v2/_zot/ext/mgmt","text":""},{"location":"developer-guide/api-reference/#get-v2_zotextmgmt","title":"GET /v2/_zot/ext/mgmt","text":"

    Get current server configuration

    Parameters

    Name In Type Required Description resource query string false specify resource

    Enumerated Values

    Parameter Value resource config

    Example responses

    200 Response

    {\n  \"binaryType\": \"string\",\n  \"distSpecVersion\": \"string\",\n  \"http\": {\n    \"auth\": {\n      \"bearer\": {\n        \"realm\": \"string\",\n        \"service\": \"string\"\n      },\n      \"htpasswd\": {\n        \"path\": \"string\"\n      },\n      \"ldap\": {\n        \"address\": \"string\"\n      },\n      \"openid\": {\n        \"providers\": {\n          \"property1\": {\n            \"name\": \"string\"\n          },\n          \"property2\": {\n            \"name\": \"string\"\n          }\n        }\n      }\n    }\n  }\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK extensions.StrippedConfig 500 Internal Server Error internal server error\". string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_zotextnotation","title":"/v2/_zot/ext/notation","text":""},{"location":"developer-guide/api-reference/#post-v2_zotextnotation","title":"POST /v2/_zot/ext/notation","text":"

    Upload notation certificates for verifying signatures

    Body parameter

    string\n

    Parameters

    Name In Type Required Description truststoreType query string false truststore type body body string true Certificate content

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request\". string 500 Internal Server Error internal server error\". string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2_zotextuserprefs","title":"/v2/_zot/ext/userprefs","text":""},{"location":"developer-guide/api-reference/#put-v2_zotextuserprefs","title":"PUT /v2/_zot/ext/userprefs","text":"

    Add bookmarks/stars info

    Parameters

    Name In Type Required Description action query string true specify action repo query string true repository name

    Enumerated Values

    Parameter Value action toggleBookmark action toggleStar

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request\". string 403 Forbidden forbidden string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2nameblobsdigest","title":"/v2/{name}/blobs/{digest}","text":""},{"location":"developer-guide/api-reference/#delete-v2nameblobsdigest","title":"DELETE /v2/{name}/blobs/{digest}","text":"

    Delete an image's blob/layer given a digest

    Parameters

    Name In Type Required Description name path string true repository name digest path string true blob/layer digest

    Example responses

    202 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 202 Accepted accepted string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#get-v2nameblobsdigest","title":"GET /v2/{name}/blobs/{digest}","text":"

    Get an image's blob/layer given a digest

    Parameters

    Name In Type Required Description name path string true repository name digest path string true blob/layer digest

    Example responses

    200 Response

    Responses

    Status Meaning Description Schema 200 OK OK api.ImageManifest

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#head-v2nameblobsdigest","title":"HEAD /v2/{name}/blobs/{digest}","text":"

    Check an image's blob/layer given a digest

    Parameters

    Name In Type Required Description name path string true repository name digest path string true blob/layer digest

    Example responses

    200 Response

    {\n  \"annotations\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"artifactType\": \"string\",\n  \"config\": {\n    \"annotations\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"artifactType\": \"string\",\n    \"data\": [\n      0\n    ],\n    \"digest\": \"string\",\n    \"mediaType\": \"string\",\n    \"platform\": {\n      \"architecture\": \"string\",\n      \"os\": \"string\",\n      \"os.features\": [\n        \"string\"\n      ],\n      \"os.version\": \"string\",\n      \"variant\": \"string\"\n    },\n    \"size\": 0,\n    \"urls\": [\n      \"string\"\n    ]\n  },\n  \"layers\": [\n    {\n      \"annotations\": {\n        \"property1\": \"string\",\n        \"property2\": \"string\"\n      },\n      \"artifactType\": \"string\",\n      \"data\": [\n        0\n      ],\n      \"digest\": \"string\",\n      \"mediaType\": \"string\",\n      \"platform\": {\n        \"architecture\": \"string\",\n        \"os\": \"string\",\n        \"os.features\": [\n          \"string\"\n        ],\n        \"os.version\": \"string\",\n        \"variant\": \"string\"\n      },\n      \"size\": 0,\n      \"urls\": [\n        \"string\"\n      ]\n    }\n  ],\n  \"mediaType\": \"string\",\n  \"schemaVersion\": 0,\n  \"subject\": {\n    \"annotations\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"artifactType\": \"string\",\n    \"data\": [\n      0\n    ],\n    \"digest\": \"string\",\n    \"mediaType\": \"string\",\n    \"platform\": {\n      \"architecture\": \"string\",\n      \"os\": \"string\",\n      \"os.features\": [\n        \"string\"\n      ],\n      \"os.version\": \"string\",\n      \"variant\": \"string\"\n    },\n    \"size\": 0,\n    \"urls\": [\n      \"string\"\n    ]\n  }\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK api.ImageManifest

    Response Headers

    Status Header Type Format Description 200 constants.DistContentDigestKey object none

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2nameblobsuploads","title":"/v2/{name}/blobs/uploads","text":""},{"location":"developer-guide/api-reference/#post-v2nameblobsuploads","title":"POST /v2/{name}/blobs/uploads","text":"

    Create a new image blob/layer upload

    Parameters

    Name In Type Required Description name path string true repository name

    Example responses

    202 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 202 Accepted accepted string 401 Unauthorized unauthorized string 404 Not Found not found string 500 Internal Server Error internal server error string

    Response Headers

    Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-0

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2nameblobsuploadssession_id","title":"/v2/{name}/blobs/uploads/{session_id}","text":""},{"location":"developer-guide/api-reference/#delete-v2nameblobsuploadssession_id","title":"DELETE /v2/{name}/blobs/uploads/{session_id}","text":"

    Delete an image's blob/layer given a digest

    Parameters

    Name In Type Required Description name path string true repository name session_id path string true upload session_id

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#get-v2nameblobsuploadssession_id","title":"GET /v2/{name}/blobs/uploads/{session_id}","text":"

    *Get an image's blob/layer upload given a session_id

    Parameters

    Name In Type Required Description name path string true repository name session_id path string true upload session_id

    Example responses

    204 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 204 No Content no content string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#patch-v2nameblobsuploadssession_id","title":"PATCH /v2/{name}/blobs/uploads/{session_id}","text":"

    Resume an image's blob/layer upload given an session_id

    Parameters

    Name In Type Required Description name path string true repository name session_id path string true upload session_id

    Example responses

    202 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 202 Accepted accepted string 400 Bad Request bad request string 404 Not Found not found string 416 Range Not Satisfiable range not satisfiable string 500 Internal Server Error internal server error string

    Response Headers

    Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-128

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#put-v2nameblobsuploadssession_id","title":"PUT /v2/{name}/blobs/uploads/{session_id}","text":"

    Update and finish an image's blob/layer upload given a digest

    Parameters

    Name In Type Required Description name path string true repository name session_id path string true upload session_id digest query string true blob/layer digest

    Example responses

    201 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 201 Created created string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2namemanifestsreference","title":"/v2/{name}/manifests/{reference}","text":""},{"location":"developer-guide/api-reference/#delete-v2namemanifestsreference","title":"DELETE /v2/{name}/manifests/{reference}","text":"

    Delete an image's manifest given a reference or a digest

    Parameters

    Name In Type Required Description name path string true repository name reference path string true image reference or digest

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#get-v2namemanifestsreference","title":"GET /v2/{name}/manifests/{reference}","text":"

    Get an image's manifest given a reference or a digest

    Parameters

    Name In Type Required Description name path string true repository name reference path string true image reference or digest

    Example responses

    200 Response

    {\n  \"annotations\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"artifactType\": \"string\",\n  \"config\": {\n    \"annotations\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"artifactType\": \"string\",\n    \"data\": [\n      0\n    ],\n    \"digest\": \"string\",\n    \"mediaType\": \"string\",\n    \"platform\": {\n      \"architecture\": \"string\",\n      \"os\": \"string\",\n      \"os.features\": [\n        \"string\"\n      ],\n      \"os.version\": \"string\",\n      \"variant\": \"string\"\n    },\n    \"size\": 0,\n    \"urls\": [\n      \"string\"\n    ]\n  },\n  \"layers\": [\n    {\n      \"annotations\": {\n        \"property1\": \"string\",\n        \"property2\": \"string\"\n      },\n      \"artifactType\": \"string\",\n      \"data\": [\n        0\n      ],\n      \"digest\": \"string\",\n      \"mediaType\": \"string\",\n      \"platform\": {\n        \"architecture\": \"string\",\n        \"os\": \"string\",\n        \"os.features\": [\n          \"string\"\n        ],\n        \"os.version\": \"string\",\n        \"variant\": \"string\"\n      },\n      \"size\": 0,\n      \"urls\": [\n        \"string\"\n      ]\n    }\n  ],\n  \"mediaType\": \"string\",\n  \"schemaVersion\": 0,\n  \"subject\": {\n    \"annotations\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"artifactType\": \"string\",\n    \"data\": [\n      0\n    ],\n    \"digest\": \"string\",\n    \"mediaType\": \"string\",\n    \"platform\": {\n      \"architecture\": \"string\",\n      \"os\": \"string\",\n      \"os.features\": [\n        \"string\"\n      ],\n      \"os.version\": \"string\",\n      \"variant\": \"string\"\n    },\n    \"size20\": 0,\n    \"urls\": [\n      \"string\"\n    ]\n  }\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK api.ImageManifest 404 Not Found not found string 500 Internal Server Error internal server error string

    Response Headers

    Status Header Type Format Description 200 constants.DistContentDigestKey object none

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#head-v2namemanifestsreference","title":"HEAD /v2/{name}/manifests/{reference}","text":"

    Check an image's manifest given a reference or a digest

    Parameters

    Name In Type Required Description name path string true repository name reference path string true image reference or digest

    Example responses

    200 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 200 OK ok string 404 Not Found not found string 500 Internal Server Error internal server error\". string

    Response Headers

    Status Header Type Format Description 200 constants.DistContentDigestKey object none

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#put-v2namemanifestsreference","title":"PUT /v2/{name}/manifests/{reference}","text":"

    Update an image's manifest given a reference or a digest

    Parameters

    Name In Type Required Description name path string true repository name reference path string true image reference or digest

    Example responses

    201 Response

    \"string\"\n

    Responses

    Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2namereferrersdigest","title":"/v2/{name}/referrers/{digest}","text":""},{"location":"developer-guide/api-reference/#get-v2namereferrersdigest","title":"GET /v2/{name}/referrers/{digest}","text":"

    Get referrers given a digest

    Parameters

    Name In Type Required Description name path string true repository name digest path string true digest artifactType query string false artifact type

    Example responses

    200 Response

    {\n  \"annotations\": {\n    \"property1\": \"string\",\n    \"property2\": \"string\"\n  },\n  \"artifactType\": \"string\",\n  \"manifests\": [\n    {\n      \"annotations\": {\n        \"property1\": \"string\",\n        \"property2\": \"string\"\n      },\n      \"artifactType\": \"string\",\n      \"data\": [\n        0\n      ],\n      \"digest\": \"string\",\n      \"mediaType\": \"string\",\n      \"platform\": {\n        \"architecture\": \"string\",\n        \"os\": \"string\",\n        \"os.features\": [\n          \"string\"\n        ],\n        \"os.version\": \"string\",\n        \"variant\": \"string\"\n      },\n      \"size\": 0,\n      \"urls\": [\n        \"string\"\n      ]\n    }\n  ],\n  \"mediaType\": \"string\",\n  \"schemaVersion\": 0,\n  \"subject\": {\n    \"annotations\": {\n      \"property1\": \"string\",\n      \"property2\": \"string\"\n    },\n    \"artifactType\": \"string\",\n    \"data\": [\n      0\n    ],\n    \"digest\": \"string\",\n    \"mediaType\": \"string\",\n    \"platform\": {\n      \"architecture\": \"string\",\n      \"os\": \"string\",\n      \"os.features\": [\n        \"string\"\n      ],\n      \"os.version\": \"string\",\n      \"variant\": \"string\"\n    },\n    \"size\": 0,\n    \"urls\": [\n      \"string\"\n    ]\n  }\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK api.ImageIndex 404 Not Found not found string 500 Internal Server Error internal server error string

    This operation does not require authentication

    "},{"location":"developer-guide/api-reference/#v2nametagslist","title":"/v2/{name}/tags/list","text":""},{"location":"developer-guide/api-reference/#get-v2nametagslist","title":"GET /v2/{name}/tags/list","text":"

    List all image tags in a repository

    Parameters

    Name In Type Required Description name path string true repository name n query integer true limit entries for pagination last query string true last tag value for pagination

    Example responses

    200 Response

    {\n  \"name\": \"string\",\n  \"tags\": [\n    \"string\"\n  ]\n}\n

    Responses

    Status Meaning Description Schema 200 OK OK common.ImageTags 400 Bad Request bad request\". string 404 Not Found not found string

    This operation does not require authentication

    "},{"location":"developer-guide/api-user-guide/","title":"Using the zot API","text":"

    This document describes how to use the zot REST API and provides a number of examples.

    For comprehensive details of all zot API commands, see Viewing the complete zot API reference.

    The zot API implements the OCI Distribution endpoints along with additional endpoints for supported extensions. You can access the REST API at the same URL and port number used by the GUI and by datapath tools.

    The examples in this article assume that the zot registry is located at localhost:8080.

    "},{"location":"developer-guide/api-user-guide/#supported-api-endpoints","title":"Supported API endpoints","text":"

    The following is a list of zot API endpoints along with the conditions under which each endpoint is available.

    Some API endpoints are available only when a specific extension is enabled in the zot configuration file, or when an extension build label is specified in the make command (for example, make binary EXTENSIONS=ui), or both.

    For comprehensive details of the API endpoints, see Viewing the complete zot API reference.

    "},{"location":"developer-guide/api-user-guide/#oci-endpoints","title":"OCI endpoints","text":"Endpoint Actions Description /v2/ GET OCI specification endpoints /v2/_catalog GET Lists repositories in a registry. /v2/_oci/ext/discover GET Discover extensions per the OCI specification /v2/{repo}/blobs/{digest} DELETE, GET, HEAD Lists or deletes an image's blob/layer given a digest /v2/{repo}/blobs/uploads POST Creates an image blob/layer upload /v2/{repo}/blobs/uploads/{session_id} DELETE, GET, PATCH, PUT Creates, lists, or deletes an image's blob/layer upload given a session_id /v2/{repo}/manifests/{reference} DELETE, GET, HEAD, PUT Creates, lists, or deletes references for an image /v2/{repo}/referrers/{digest} GET Lists referrers given a digest /v2/{repo}/tags/list GET List all image tags in a repository"},{"location":"developer-guide/api-user-guide/#zot-oci-extension-endpoints","title":"zot OCI extension endpoints","text":"Endpoint Actions Description Availability /v2/_zot/ext/mgmt GET Mgmt extension endpoints Enabled by using the mgmt build label and enabling the search extension in the configuration file. /v2/_zot/ext/notation POST With query parameters, uploads certificates for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the notation option enabled. /v2/_zot/ext/search Enhanced search Enabled by using the search build label and enabling the search extension in the configuration file. /v2/_zot/ext/cosign POST Uploads keys for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the cosign option enabled. /v2/_zot/ext/userprefs PUT User preferences endpoints Enabled by using the userprefs build label and enabling both the search and the ui extensions in the configuration file."},{"location":"developer-guide/api-user-guide/#zot-auth-endpoints","title":"zot auth endpoints","text":"Endpoint Actions Description Availability /zot/auth/apikey DELETE, GET, POST Creates, lists, or deletes API keys Available when API key authentication is enabled in the configuration file (\"apikey\": true). /zot/auth/login POST Opens an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/logout POST Ends an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/callback/\\<provider> POST Specifies a social authentication service provider for redirecting logins, such as Google or dex. Enabled when an OpenID authentication service provider is specified in the configuration file."},{"location":"developer-guide/api-user-guide/#other-zot-endpoints","title":"other zot endpoints","text":"Endpoint Actions Description Availability /v2/_zot/pprof/ GET Returns a current HTML-format profile list along with a count of currently available records for each profile. See Performance Profiling in zot for usage details. Always enabled. /v2/_zot/debug/graphql-playground# See Using GraphQL for details. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#oras-endpoints","title":"ORAS endpoints","text":"Endpoint Actions Description Availability /oras/artifacts/v1/{repo}/ manifests/{digest}/referrers GET OCI Registry As Storage (ORAS) endpoints Always enabled."},{"location":"developer-guide/api-user-guide/#prometheus-endpoint","title":"prometheus endpoint","text":"Endpoint Actions Description Availability /metrics GET Returns extended metrics for monitoring by prometheus Enabled when the metrics extension is enabled in the configuration file."},{"location":"developer-guide/api-user-guide/#openapi-swagger-endpoints","title":"OpenAPI (swagger) endpoints","text":"

    This endpoint is accessed with a browser.

    Endpoint Action Description Availability /swagger/v2/ (browser) Displays an interactive OpenAPI (swagger) API reference. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#api-authentication","title":"API authentication","text":"

    If zot authentication is not configured, any user can access the zot API.

    When pushing and pulling images using API calls, your identity can be authenticated by either a password or an API key.

    With a valid password, you can specify your credentials in a cURL request as shown in this example:

    curl -u <user>:<password> -X GET http://<server>/<endpoint>\n

    An API key has advantages in situations where the primary zot authentication does not use the command line, such as a GUI login or social login. Also, you can reduce your security exposure by using an API key instead of your broader credentials, such as an LDAP username and password.

    "},{"location":"developer-guide/api-user-guide/#using-api-keys","title":"Using API keys","text":""},{"location":"developer-guide/api-user-guide/#enabling-api-keys","title":"Enabling API keys","text":"

    To enable the use of API keys, you must set the apikey attribute to true in the zot configuration file, as shown in the following example:

      \"http\": {\n    \"auth\": {\n      \"apikey\": true\n    }\n  }\n
    "},{"location":"developer-guide/api-user-guide/#creating-your-api-key","title":"Creating your API key","text":"

    Before you can create or revoke an API key, you must first log in using a different authentication mechanism, such as logging in through the zot GUI. When you are logged in, you can create an API key for your identity using the following API command:

    POST /zot/auth/apikey\n

    cURL command example:

    curl -u user:password -X POST http://localhost:8080/zot/auth/apikey -d '{\"label\": \"myAPIKEY\", \"scopes\": [\"repo1\", \"repo2\"], \"expirationDate\": \"2023-08-28T17:10:05+03:00\"}'\n

    The scopes and expiration date in this example are optional. By default, an API key has the same permissions as the user who created it.

    Command output:

    {\n  \"createdAt\":\"2023-08-28T17:09:59.2603515+03:00\",\n  \"expirationDate\":\"2023-08-28T17:10:05+03:00\",\n  \"isExpired\":false,\n  \"creatorUa\":\"curl/7.68.0\",\n  \"generatedBy\":\"manual\",\n  \"lastUsed\":\"0001-01-01T00:00:00Z\",\n  \"label\":\"myAPIKEY\",\n  \"scopes\": [\n    \"repo1\",\n    \"repo2\"\n  ],\n  \"uuid\":\"c931e635-a80d-4b52-b035-6b57be5f6e74\",\n  \"apiKey\":\"zak_ac55a8693d6b4370a2003fa9e10b3682\"\n}\n

    The API key (apiKey) is shown to the user only in the command output when the key is created. It cannot be later retrieved from zot with any other command.

    "},{"location":"developer-guide/api-user-guide/#using-your-api-key-in-an-api-command","title":"Using your API key in an API command","text":"

    The API key replaces a password in the API command, as shown in the following cURL example:

    curl -u user:zak_e77bcb9e9f634f1581756abbf9ecd269 http://localhost:8080/v2/_catalog\n
    "},{"location":"developer-guide/api-user-guide/#removing-your-api-key","title":"Removing your API key","text":"

    When logged in, you can revoke your own API key with the following API command:

    DELETE /zot/auth/apikey?id=$uuid\n

    cURL command example:

    curl -u user:password -X DELETE http://localhost:8080/v2/zot/auth/apikey?id=46a45ce7-5d92-498a-a9cb-9654b1da3da1\n
    "},{"location":"developer-guide/api-user-guide/#listing-your-current-api-keys","title":"Listing your current API keys","text":"

    When logged in, you can display a list of your API keys with the following API command:

    GET /zot/auth/apikey\n

    cURL command example:

    curl -u user:password -X GET http://localhost:8080/zot/auth/apikey\n

    Command output:

    {\n  \"apiKeys\": [\n    {\n      \"createdAt\": \"2023-05-05T15:39:28.420926+03:00\",\n      \"expirationDate\": \"0001-01-01T00:00:00Z\",\n      \"isExpired\": true,\n      \"creatorUa\": \"curl/7.68.0\",\n      \"generatedBy\": \"manual\",\n      \"lastUsed\": \"0001-01-01T00:00:00Z\",\n      \"label\": \"git\",\n      \"scopes\": [\n        \"repo1\",\n        \"repo2\"\n      ],\n      \"uuid\": \"46a45ce7-5d92-498a-a9cb-9654b1da3da1\"\n    },\n    {\n      \"createdAt\": \"2023-08-11T14:43:00.6459729+03:00\",\n      \"expirationDate\": \"2023-08-17T18:24:05+03:00\",\n      \"isExpired\": false,\n      \"creatorUa\": \"curl/7.68.0\",\n      \"generatedBy\": \"manual\",\n      \"lastUsed\": \"2023-08-11T14:43:47.5559998+03:00\",\n      \"label\": \"myAPIKEY\",\n      \"scopes\": null,\n      \"uuid\": \"294abf69-b62f-4e58-b214-dad2aec0bc52\"\n    }\n  ]\n}\n

    This command output example shows an expired key and a current key for this user.

    The actual API key (apiKey) is not shown. The key is shown to the user only when it is created.

    "},{"location":"developer-guide/api-user-guide/#api-examples","title":"API examples","text":"

    The following examples assume that the zot registry is located at localhost:8080.

    "},{"location":"developer-guide/api-user-guide/#listing-repositories","title":"Listing repositories","text":"

    To get a list of all image repositories in the registry, use the following API endpoint:

    GET /v2/_catalog\n

    cURL command example:

    curl -X GET http://localhost:8080/v2/_catalog\n

    Command output:

    {\n    \"repositories\": [\"alpine\", \"busybox\"]\n}\n
    "},{"location":"developer-guide/api-user-guide/#discovering-extension-endpoints","title":"Discovering extension endpoints","text":"

    To list the installed and enabled zot extensions that can be accessed through the API, use the following OCI API endpoint:

    GET /v2/_oci/ext/discover\n

    cURL command example:

    curl -X GET http://localhost:8080/v2/_oci/ext/discover\n

    Command output:

    {\n  \"extensions\": [\n  {\n    \"name\": \"_zot\",\n    \"url\": \"https://github.com/project-zot/zot/blob//pkg/extensions/_zot.md\",\n    \"description\": \"zot registry extensions\",\n    \"endpoints\": [\"/v2/_zot/ext/search\", \"/v2/_zot/ext/userprefs\", \"/v2/_zot/ext/mgmt\"]\n  }]\n}\n
    "},{"location":"developer-guide/api-user-guide/#uploading-a-certificate-for-notation","title":"Uploading a certificate for Notation","text":"

    To upload a certificate for notation, use the following endpoint:

    POST /v2/_zot/ext/notation\n

    cURL command example:

    curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
    "},{"location":"developer-guide/api-user-guide/#viewing-the-complete-zot-api-reference","title":"Viewing the complete zot API reference","text":"

    You can find comprehensive details of all zot API commands in either of the following locations:

    • As text descriptions in the zot API Command Reference in the zot documentation.

    • As an interactive OpenAPI (swagger) JSON file in the zot Github project.

    There are many ways to view a swagger file as an interactive document. If you have the npm package installed, for example, you can execute the following command:

      $ npx open-swagger-ui swagger.json\n

    This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.

    "},{"location":"developer-guide/contributing/","title":"Contributing to zot Development","text":"

    The zot project is built for developers by developers. The zot project welcomes the participation of the open source community in extending and improving zot.

    "},{"location":"developer-guide/contributing/#submission-requirements","title":"Submission Requirements","text":"

    Summary: All contributions must meet these requirements:

    • Adhere to the Apache license
    • Be submitted by a pull request (PR) from your fork
    • Commits must have a
    "},{"location":"developer-guide/contributing/#license","title":"License","text":"

    zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.

    "},{"location":"developer-guide/contributing/#submitting-a-pull-request-pr","title":"Submitting a Pull Request (PR)","text":"

    First, fork the zot project on GitHub and submit a commit to your fork. Then open a new pull request (PR) to the zot project. All pull requests must meet these requirements:

    • License statement

    Either the commit message or the PR description must contain the following statement:

    \"By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.\"

    • Developer Certificate of Origin (DCO) and sign-off

    All commits require a Developer Certificate of Origin via the \"Signed-off-by:\" commit message and commit signatures using GPG keys. Include the -s flag in your git commit command.

    • Commit message format

    The commit message must follow the Convention Commits format. The message must begin with a keyword that categorizes the commit, followed by a colon. Validation of a commit message is determined by this expression:

    \"^((build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\(.+\\))?(!)?(: (.*\\s*)*))\"

    An example of a valid commit message is \"docs: Fixes a typo in module.md.\"

    In addition, any new PR requires a brief form to be completed by the submitter with details about the PR. Appropriate code owners are automatically identified and will be notified of the new PR.

    "},{"location":"developer-guide/contributing/#cicd-checks","title":"CI/CD Checks","text":"

    We take code quality very seriously. All PRs must pass various CI/CD checks that enforce code quality such as code coverage, security scanning, performance regressions, distribution spec conformance, ecosystem client tool compatibility, etc.

    "},{"location":"developer-guide/contributing/#reporting-issues","title":"Reporting Issues","text":"

    Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.

    "},{"location":"developer-guide/contributing/#filing-a-functional-issue","title":"Filing a Functional Issue","text":"

    No software is perfect, and we expect users to find issues with the zot code base. First, check whether your issue has already been filed by someone else by performing an issue search. If the issue is not found, file a new issue by clicking the New issue button on the zot/issues page and answering the questions. The more information that you can provide, the easier it becomes to triage the issue.

    "},{"location":"developer-guide/contributing/#filing-a-security-issue","title":"Filing a Security Issue","text":"

    Security issues are best filed by sending an email to security@zotregistry.dev. After 45 days, we will make the issue public and give credit to the original filer of the issue.

    "},{"location":"developer-guide/contributing/#code-of-conduct","title":"Code of Conduct","text":"

    The zot project follows the CNCF Code of Conduct.

    "},{"location":"developer-guide/contributing/#reporting-conduct-incidents","title":"Reporting Conduct Incidents","text":"

    To report a conduct-related incident occurring on the zot project, contact the zot project conduct committee by sending an email to conduct@zotregistry.dev. You can expect a response within three business days.

    "},{"location":"developer-guide/extensions-dev/","title":"Developing New Extensions","text":"

    You can add new functionality to the zot registry by developing extensions for integration into zot.

    The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.

    When planning the development of a new extension, be sure to familiarize yourself with the OCI documentation and guidelines for extensions.

    "},{"location":"developer-guide/extensions-dev/#current-extensions","title":"Current extensions","text":"

    The following extensions are currently available in the zot project:

    • metrics
    • sync
    • search
    • scrub
    • lint

    You can examine the implementation of these extensions in the zot project extensions section. The operation and configuration of the current extensions is described in Configuring zot.

    "},{"location":"developer-guide/extensions-dev/#guidelines-for-developing-new-extensions","title":"Guidelines for developing new extensions","text":"
    • Each file to be included in the binary for only a specific extension must contain the following syntax at the beginning of the file. For example, a file to be included in the build for extension foo must begin with the following lines:
      //go:build foo\n  // +build foo\n\n  package foo\n\n  ...\n
    - The first line (`//go:build foo`) is added automatically by the linter if not already present.\n\n- The second line and the third (blank) line are mandatory.\n
    • For each file that contains functions specific to the extension, create a corresponding \"no-op\" file that contains exactly the same function names. In this file:

      • Each function is a \"no-op,\" performing no action other than to return a \"success\" value if expected.
      • We recommend naming this \"no-op\" file by appending -disabled to the name of the original file. For example, if the extension is implemented by extension-foo.go, the corresponding \"no-op\" file could be named extension-foo-disabled.go.
      • The first two lines declare an \"anti-tag\" (for example, !foo). In the foo extension example, the \"no-op\" file will be included in binaries that don't implement the foo extension, but won't be included in binaries that implement the foo extension. The foo example \"no-op\" file begins with the following lines:

        //go:build !foo\n    // +build !foo\n\n    package foo\n\n    ...\n
    See extension lint-disabled.go in the zot project for an example of a \"no-op\" file.

    • When developing a new extension, you should create a blackbox test in which a binary containing the new extension can be tested in a usage scenario. See the test/blackbox folder in the zot project for examples of extension tests.

      • Create targets in Makefile for newly added blackbox tests. You should also add them as GitHub Workflows in .github/workflows/ecosystem-tools.yaml in the zot project.
    • When configuring multiple extensions in the extensions section of the zot configuration file, list new extensions after the current extensions in the recommended order, such as:

      metrics, sync, search, scrub, lint, new_extension_1, new_extension_2, ...

    "},{"location":"developer-guide/extensions-dev/#building-zot-with-extensions","title":"Building zot with extensions","text":"

    When you build the full zot image (for example, make binary), all extensions listed in the EXTENSIONS variable in Makefile are included in the build. When you've created a new extension, you must modify the EXTENSIONS variable in Makefile by adding the new extension.

    To build an image with only selected extensions, you can specify the desired extensions by declaring them in the build command:

    make binary EXTENSIONS=extension1,extension2,extension3...\n

    For example, to build with only sync and scrub, the command would be:

    make binary EXTENSIONS=sync,scrub\n
    "},{"location":"developer-guide/onboarding/","title":"Onboarding zot for Development","text":"

    zot is a production-ready, open-source, extensible OCI-native image registry, built for developers by developers.

    "},{"location":"developer-guide/onboarding/#getting-started","title":"Getting Started","text":""},{"location":"developer-guide/onboarding/#supported-developer-platforms","title":"Supported Developer Platforms","text":"

    Development is officially supported on Linux and Apple MacOS platforms. However, development should be possible on any platform that supports the golang toolchain.

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1)

    Supported platforms and architectures

    "},{"location":"developer-guide/onboarding/#prerequisites","title":"Prerequisites","text":""},{"location":"developer-guide/onboarding/#install-golang","title":"Install golang","text":"

    Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.

    You must use a golang version of at least the minimum specified in go.mod or the build will fail.

    "},{"location":"developer-guide/onboarding/#cloning-zot","title":"Cloning zot","text":"

    The zot registry code base is hosted on GitHub at https://github.com/project-zot/zot.

    To clone the zot project, use this command:

    $ git clone https://github.com/project-zot/zot.git\n
    "},{"location":"developer-guide/onboarding/#building-zot","title":"Building zot","text":"

    To build zot, execute the make command in the zot directory using the following general syntax:

    $ make OS=os ARCH=architecture {binary | binary-minimal}

    • The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.

    • The binary option builds the full zot binary image with all extensions.

    • The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.

    For example, to build a zot image with extensions for an Intel-based linux server, use the following command:

    make OS=linux ARCH=amd64 binary\n

    The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-minimal-linux-amd64.

    Click here to view an example of the getting started process.

    "},{"location":"developer-guide/onboarding/#running-zot","title":"Running zot","text":"

    The behavior of zot is controlled via configuration only. To launch the zot server, execute the following command:

    $  bin/zot-linux-amd64 serve examples/config-minimal.json\n
    "},{"location":"developer-guide/onboarding/#debugging-zot","title":"Debugging zot","text":"

    To produce a zot binary that includes extensive debugging information, build zot with the binary-debug option, as shown in this example:

    make OS=linux ARCH=amd64 binary-debug\n

    You can then attach and run a debugging tool such as Delve to the running zot process.

    Delve is a powerful open-source debugger for the Go programming language. Downloads and documentation for Delve are available on GitHub at https://github.com/go-delve/delve.

    "},{"location":"developer-guide/onboarding/#performance-profiling","title":"Performance profiling","text":"

    Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.

    For detailed information about performance profiling, see Performance Profiling in zot.

    "},{"location":"developer-guide/onboarding/#code-organization","title":"Code Organization","text":"

    The zot project codebase is organized as follows:

    /\n- pkg/              # Source code for all libraries\n  - api/            # Source code for HTTP APIs\n    - config/       # Global configuration model\n  - storage/        # Source code for storage backends\n  - cli/            # Source code for command line interface (cli)\n  - common/         # Source code for common utility routines\n  - compliance/     # Source code for dist-spec conformance tests\n  - log/            # Source code for logging framework\n  - test/           # Internal test scripts/data\n  - extensions/     # Source code for all extensions\n    - config/\n    - sync/\n    - monitoring/\n    - sync/\n  - exporter/       # Source code for metrics exporter\n- cmd/              # Source code for binary main()s\n  - zot/            # Source code for zot binary\n  - zli/            # Source code for zot cli\n  - zb/             # Source code for zb, the dist-spec benchmarking tool\n- errors/           # Source code for error codes\n- examples/         # Configuration examples\n- swagger/          # Swagger integration\n- docs/             # Documentation\n
    "},{"location":"developer-guide/onboarding/#additional-state-in-zot","title":"Additional state in zot","text":"

    In addition to the storage of repository images, zot stores data for various processes in local and remote storage and databases. The following table shows the storage locations for different processes and types of data.

    Data or Process Storage Location Description images local andAWS S3 Image blobs repository synchronization local/<repo_name>/.sync The sync operation temporarily copies the upstream blobs to: /<repo_name>/.sync/${UUID}/<repo_name>, then copies to /<repo_name> and deletes the temporary directory ${UUID} deduplication local/cache.db Cache for deduplication of files stored locally AWS DynamoDB Cache for deduplication of files stored in AWS CVE local/_trivy Database of Common Vulnerabilities and Exposures (CVE) information and scan results user sessions local/_sessions zot user session authentication (for zui) PKI authentication documents local/_cosign Private keys for signature verification using cosign local/_notation Certificates for signature verification using notation metadata local/repo.db Local storage of manifests, configurations, download counters, signature verification results AWS DynamoDB Cloud storage of manifests, configurations, download counters, signature verification results"},{"location":"general/architecture/","title":"Architecture","text":"

    zot is an OCI-native container image registry. This document discusses the design goals, the overall architecture, and the design choices made in the implementation of the design goals.

    "},{"location":"general/architecture/#design-goals","title":"Design Goals","text":""},{"location":"general/architecture/#oci-first","title":"OCI-first","text":"
    • HTTP APIs strictly conforms to the OCI Distribution Specification

      zot intends to be a production reference implementation for the OCI Distribution Specification. In fact, zot does not support any other vendor protocol or specification.

    • Storage layout follows the OCI Image Specification

      The default and only supported storage layout is the OCI Image Layout. The implications of this choice are that any OCI image layout can be served by zot and conversely, zot converts data on-the-wire into an OCI image layout.

    "},{"location":"general/architecture/#single-binary-model","title":"Single binary model","text":"

    zot is a single binary image with all features included so that deployment is extremely simple in various environments, including bare-metal, cloud, and embedded devices. Behavior is controlled by a single configuration file.

    "},{"location":"general/architecture/#enable-only-what-you-need","title":"Enable Only What You Need","text":"

    A clear separation exists between (1) the core OCI-compliant HTTP APIs and storage functionality, and (2) other add-on features modeled as extensions. The extension features can be selectively enabled both at build-time and run-time.

    For more information, see \"Conditional Builds\" in zot's security posture document.

    "},{"location":"general/architecture/#overall-architecture","title":"Overall Architecture","text":"

    As shown in the following figure, the architecture of zot is organized as:

    zot-full = zot-minimal + extensions

    The minimal build is the core OCI-compliant registry functionality as described by the OCI Distribution Specification.

    The full build adds features that are not a part of the Distribution Specification, but are allowed to be added as Extensions.

    "},{"location":"general/architecture/#external-interaction","title":"External Interaction","text":"

    External interaction with zot consists of the following two types:

    • Client-initiated data or meta-data queries

    • Admin-initiated configuration

    All client-side interaction occurs over HTTP APIs. The core data path queries are governed by the OCI Distribution Specification. All additional meta-data queries are handled based on the setting of the search extension:

    • If the search extension is enabled, enhanced registry searching and filtering is supported, using graphQL. A database is maintained by zot to efficiently answer complex queries on data stored in the database.

    • If the search extension is not enabled, basic queries are supported using the core APIs. These queries are less efficient and search actual storage, which is limited in content.

    "},{"location":"general/architecture/#configuration","title":"Configuration","text":"

    A single configuration file governs zot instance behavior. An exception can be made for security concerns, wherein configuration items containing sensitive credentials can be stored in separate files referenced by the main configuration file. Using separate files allows stricter permissions to be enforced on those files if stored locally. Also, modeling as external files allows for storing Kubernetes Secrets.

    The configuration file is divided into sections for http, storage, log, and extension, governing the behavior of the respective components.

    "},{"location":"general/architecture/#authentication-and-authorization","title":"Authentication and Authorization","text":"

    A robust set of authentication and authorization options are supported natively in zot. These controls are enforced before access is allowed into the storage layer.

    For more information, see User Authentication and Authorization with zot.

    "},{"location":"general/architecture/#storage-driver-support","title":"Storage Driver Support","text":"

    zot supports any modern local filesystem. Remote filesystems, such as AWS S3 or any AWS S3-compatible storage system, are supported. Additional driver support is planned in the roadmap.

    Deduplication is supported for both local and remote filesystems, but deduplication requires a filesystem with hard-link support.

    For more information, see Storage Planning with zot.

    "},{"location":"general/architecture/#security-scanning","title":"Security Scanning","text":"

    zot integrates with the trivy security scanner to scan container images for vulnerabilities. The database is kept current by periodically downloading any vulnerability database updates at a configurable interval. The user remains agnostic of the actual scanner implementation, which may change over time.

    "},{"location":"general/architecture/#extensions","title":"Extensions","text":"

    Additional registry features that are not a part of the Distribution Specification are added as Extensions.

    Extension features of zot are available only with a full zot image. They are not supported in a minimal zot image.

    For more information about zot's extensions, see Extensions.

    "},{"location":"general/architecture/#background-tasks","title":"Background Tasks","text":"

    Several periodic tasks occur in the registry, such as garbage collection, sync mirroring, and scrubbing. A task scheduler handles these tasks in the background, taking care not to degrade or interrupt foreground tasks running in the context of HTTP APIs.

    "},{"location":"general/concepts/","title":"Concepts","text":""},{"location":"general/concepts/#what-is-zot","title":"What is zot?","text":"

    zot is a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.

    Two broad trends are changing how we build, distribute, and consume software. The first trend is the increasing adoption of container technologies. The second trend is that software solutions are being composed by combining elements from various sources rather than being built entirely from scratch. The latter trend raises the importance of software provenance and supply chain security. In both trends, zot intends to play an important role by providing a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.

    "},{"location":"general/concepts/#what-is-an-oci-image-registry","title":"What is an OCI image registry?","text":"

    An OCI image registry is a server-based application that allows you to store, manage, and share container images. A developer uploads (pushes) an image to the registry for distribution. Users can then download (pull) the image to run on their systems. The OCI Distribution Specification, published by the Open Container Initiative (OCI), defines a standard API protocol for these and other image registry operations.

    An image registry can be a part of your continuous integration and continuous deployment (CI/CD) pipeline when you host zot on your public or private server. In its minimal form, you can also embed a zot registry in a product. In either case, zot provides a secure software supply chain for container images.

    "},{"location":"general/concepts/#why-zot","title":"Why zot?","text":"

    zot = OCI Distribution Specification + OCI Image Format

    At its heart, zot is a production-ready, vendor-neutral OCI image registry with images stored in the OCI image format and with the OCI distribution specification on-the-wire. zot is built for developers by developers, offering features such as minimal deployment using a single binary image, built-in authentication and authorization, and inline garbage collection and storage deduplication.

    Some of the principal advantages of zot are:

    • Open source

    • OCI standards-only both on-the-wire and on-disk

    • Clear separation between core distribution spec and zot-specific extensions

    • Software supply chain security, including support for cosign and notation

    • Security hardening

    • Single binary with many features built-in

    • Suitable for deployments in cloud, bare-metal, and embedded devices

    zot fully conforms to the OCI Distribution Specification.

    The following table lists additional advantages of zot:

    Distribution Spec conformance yes CNCF project accepted as a Sandbox Project License Apache 2.0 On-premises deployment yes OCI conformance* yes Single binary image* yes Minimal build* yes Storage Layout OCI v1 Image Layout Authentication built-in Authorization built-in Garbage collection inline Storage deduplication inline Cloud storage support yes Delete by tag yes Vulnerability scanning built-in Command line interface (cli) yes UI yes External contributions beta available Image signatures built-in

    * The minimal build feature is the ability to build a minimal Distribution Spec compliant registry in order to reduce library dependencies and the possible attack surface.

    "},{"location":"general/extensions/","title":"Extensions","text":"

    Extensions provide additional registry features that are not a part of the Distribution Specification.

    The following extensions are currently available with zot:

    • Search (enhanced)
    • Sync
    • Lint
    • Scrub
    • Trust
    • Metrics
    • Graphical user interface
    • User preferences

    For detailed information about configuring zot extensions, see Configuring zot.

    "},{"location":"general/extensions/#about-extensions","title":"About extensions","text":"

    The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.

    Wherever applicable, extensions can be dynamically discovered using the extensions support of the OCI Distribution Specification.

    Extension features of zot are available only with a full zot image. They are excluded from the minimal zot image.

    "},{"location":"general/extensions/#extensions-implemented-in-zot","title":"Extensions implemented in zot","text":"

    The extensions implemented in zot include administrator-configured functionality and end-user features.

    Currently, search, trust, and userprefs are the only zot extensions operable by end users. Only these extensions are accessible through HTTP APIs and are discoverable using the OCI extensions mechanism.

    The following extensions are currently supported by zot:

    "},{"location":"general/extensions/#search","title":"Search","text":"

    One of the key functions of a container image registry (which is essentially a graph of blobs) is the ability to perform interesting image and graph traversal queries. The user interacts with the search extension via a graphQL endpoint. The schema is published with every release.

    Examples of queries are:

    • \"Does an image exist?\"
    • \"What is its size?\"
    • \"Does an image depend on this image via its layers?\"
    • \"What vulnerabilities exist in an image or its dependent images?\"
    "},{"location":"general/extensions/#sync","title":"Sync","text":"

    You can deploy a local mirror pointing to an upstream zot instance with various container image download policies, including on-demand and periodic downloads. The sync function is useful to avoid overwhelming the upstream instance, or if the upstream instance has rate-limited access.

    docker.io is supported as an upstream mirror.

    "},{"location":"general/extensions/#lint","title":"Lint","text":"

    The lint extension helps to avoid image compliance issues by enforcing certain policies about the image or the image metadata. Currently, lint can check an uploaded image to enforce the presence of required annotations such as the author or the license.

    "},{"location":"general/extensions/#scrub","title":"Scrub","text":"

    Although container images are content-addressable with their SHA256 checksums, and validations are performed during storage and retrieval, it is possible that bit-rot sets in when not in use. The scrub extension actively scans container images in the background to proactively detect errors.

    "},{"location":"general/extensions/#trust","title":"Trust","text":"

    Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user through the zot API. The trust extension enables and configures this function.

    "},{"location":"general/extensions/#metrics","title":"Metrics","text":"

    The metrics extension adds a node exporter, which is not present in the minimal build.

    "},{"location":"general/extensions/#graphical-user-interface","title":"Graphical user interface","text":"

    Using the zot graphical user interface (GUI), you can browse a zot registry for container images and artifacts. From the web interface, you can copy the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.

    "},{"location":"general/extensions/#user-preferences","title":"User preferences","text":"

    The userprefs extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.

    The functions currently implemented by this extension include:

    • Toggling the star (favorites) icon for a repository.
    • Toggling the bookmark icon for a repository.

    For information about configuring zot extensions, see Configuring zot.

    "},{"location":"general/features/","title":"Summary of Key Features","text":"
    • Conforms to OCI distribution spec APIs
    • Uses OCI image layout for image storage
      • Can serve any OCI image layout as a registry
    • Single binary for all the features
    • Doesn't require root privileges
    • Clear separation between core dist-spec and zot-specific extensions
    • Supports container image signatures - cosign and notation
    • Supports helm charts
    • Behavior controlled via configuration
    • Binaries released for multiple operating systems and architectures
    • Supports advanced image queries using search extension
    • Supports image deletion by tag
    • Currently suitable for on-premises deployments (e.g. colocated with Kubernetes)
    • Compatible with ecosystem tools such as skopeo and cri-o
    • Vulnerability scanning of images
    • TLS support Authentication via:
      • TLS mutual authentication
      • HTTP Basic (local htpasswd and LDAP)
      • HTTP Bearer token
    • Supports Identity-Based Access Control
    • Supports live modifications on the configuration file while zot is running (Authorization configuration only)
    • Inline storage optimizations:
      • Automatic garbage collection of orphaned blobs
      • Layer deduplication using hard links when content is identical
      • Data scrubbing
    • Serve multiple storage paths (and backends) using a single zot server
    • Pull and synchronize from other dist-spec conformant registries
    • Supports rate limiting including per HTTP method
    • Metrics with Prometheus
      • Using a node exporter in case of minimal zot
    • Swagger based documentation
    • zli: command-line client support
    • zb: a benchmarking tool for dist-spec conformant registries
    • Released under Apache 2.0 License
    "},{"location":"general/glossary/","title":"Glossary","text":""},{"location":"general/glossary/#documentation-icons","title":"Documentation Icons","text":"Icon Description Note \u2014 A point of emphasis or caution. Tip \u2014 A helpful suggestion or a reference to additional material not covered in this document. Warning \u2014 A suggestion or advisory intended to avoid a loss of service or data."},{"location":"general/glossary/#definitions","title":"Definitions","text":"Term Description artifact A file of any kind produced during a container build process or associated with the operation of a container. For example, a Helm chart is an artifact that might be stored along with a container. CNCF As part of the Linux Foundation, the Cloud Native Computing Foundation provides support, oversight, and direction for open-source, cloud native projects. cosign cosign is a tool that performs container signing, verification, and storage in an OCI registry. cosigned cosigned is an image admission controller that validates container images before deploying them. cri-o cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes. deduplication A storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. digest A hashed checksum, such as SHA-256, for verifying the integrity of the downloaded image. Distribution Specification The OCI Distribution Specification project defines an API protocol to facilitate and standardize the distribution of content. extensions Additional registry features (APIs) that are not a part of the Distribution Specification can be added as Extensions. helm chart A helm chart is a package of files that orchestrate the deployment of Kubernetes resources into a Kubernetes cluster. manifest An image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system. node exporter A software component that collects hardware and operating system level metrics exposed by the kernel. OCI The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes. ORAS OCI Registry as Storage (ORAS) is a tool for distributing OCI artifacts across OCI registries. prometheus Prometheus is a node exporter that exposes a wide variety of hardware- and kernel-related metrics. referrer An image containing a non-nil subject field with a descriptor to the referred image. registry A service that stores and distributes container images and artifacts. repository A collection of images with the same name, differentiated by tags. skopeo skopeo is a command line utility that performs various operations on container images and image repositories. stacker stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout. tag A label applied to an image that distinguishes the image from other images in the same repository. A common example is a version tag. zb A benchmarking tool, available as a zot companion binary, for benchmarking a zot registry or any other container image registry that conforms to the OCI Distribution Specification. zli A zot companion binary that implements a set of command line commands for interacting with the zot registry server. zui A zot companion binary that implements a graphical user interface (GUI) for interacting with the zot registry server. zxp A node exporter, available as a zot companion binary, that can be deployed with a minimal zot image in order to scrape metrics from the zot server."},{"location":"general/project/","title":"About the zot Project","text":""},{"location":"general/project/#project-repository","title":"Project Repository","text":"

    The zot project is hosted on GitHub:

    project-zot/zot

    "},{"location":"general/project/#sponsors","title":"Sponsors","text":"

    Cisco Systems, Inc.

    "},{"location":"general/project/#adopters","title":"Adopters","text":"

    Cisco Systems, Inc.

    "},{"location":"general/project/#presentations","title":"Presentations","text":"

    OCI Weekly Discussion - Oct 2, 2019

    "},{"location":"general/releases/","title":"Released Images for zot","text":"

    This document describes the available zot images for the various supported hardware and software platforms, along with information about image variations, image locations, and image naming formats.

    "},{"location":"general/releases/#supported-platforms","title":"Supported platforms","text":"

    zot is supported on Linux and Apple MacOS platforms with Intel or ARM processors.

    Table: Supported platforms and architectures

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1) freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*

    **NOTE:* While binary images are available for FreeBSD, building container images is not supported at this time."},{"location":"general/releases/#full-and-minimal-binary-images","title":"Full and minimal binary images","text":"

    In addition to variations for specific platforms and architectures, binary images are also available in full and minimal flavors:

    • A full zot binary image is compiled with all extensions. Extensions include functions such as metrics, registry synchronization, search, and scrub.

    • A minimal distribution-spec conformant zot binary image is compiled with only a minimal set of code and libraries, reducing the attack surface. This option might be optimal for a registry embedded in a shipping product.

    "},{"location":"general/releases/#binary-image-file-naming","title":"Binary image file naming","text":"

    An executable binary image for zot is named using the target platform and architecture from the Supported platforms and architectures table. The general format of a binary image file name is one of these two:

    zot-<os>-<architecture>

    • A full zot binary image with all extensions has a filename of the form zot-<os>-<architecture>. For example, the full binary image for an Intel-based linux server is zot-linux-amd64.

    zot-<os>-<architecture>-minimal

    • A minimal distribution-spec conformant zot binary image has a filename of the form zot-<os>-<architecture>-minimal. For example, the minimal binary image for an Intel-based linux server is zot-linux-amd64-minimal.

    For convenience, you can rename the binary image file to simply zot after downloading.

    "},{"location":"general/releases/#where-to-get-zot","title":"Where to get zot","text":"

    You can download native executable binary images or container (Docker) images.

    "},{"location":"general/releases/#getting-binary-images","title":"Getting binary images","text":"

    The zot project is hosted on GitHub at project-zot.

    To download a binary image, go to the zot releases and select a release. Go to the Assets section of the release page and download the binary for your platform and architecture.

    You may need to use the chmod command to make the image executable.

    When downloading a binary image for MacOS, download the darwin image.

    "},{"location":"general/releases/#getting-container-images","title":"Getting container images","text":"

    You can download a container image from ghcr.io by forming a URL with the desired image name, such as:

    https://ghcr.io/project-zot/zot-<os>-<architecture>[-<build>]\n

    If <build> is not specified, the default is full. For example, to download the minimal binary image for an Intel-based linux server. The URL is:

    https://ghcr.io/project-zot/zot-linux-amd64-minimal\n

    When downloading a container image for MacOS, download the linux image, not the darwin image.

    "},{"location":"general/releases/#licensing","title":"Licensing","text":"

    zot is released under the Apache License 2.0.

    "},{"location":"general/whats-new/","title":"What's New","text":""},{"location":"general/whats-new/#v202","title":"v2.0.2","text":""},{"location":"general/whats-new/#cve-query-enhancements","title":"CVE Query Enhancements","text":"

    It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.

    "},{"location":"general/whats-new/#documentation-for-immutable-image-tags","title":"Documentation for \"Immutable Image Tags\"","text":"

    A new article has been added to document how image tags can be made immutable.

    "},{"location":"general/whats-new/#cross-repo-tag-search-in-ui","title":"Cross-repo tag search in UI","text":"

    You can now search for a tag across all repos by starting your query as ':' in the UI, which will return all images that have that tag."},{"location":"general/whats-new/#support-for-oras-artifacts-removed","title":"Support for ORAS Artifacts removed","text":"

    OCI distribution spec 1.1.0 has added support \"artifacts\" which is likely to gain wider adoption. ORAS artifacts are not widely used or supported.

    :warning:  Support is removed starting from this version.\n
    "},{"location":"general/whats-new/#v201","title":"v2.0.1","text":""},{"location":"general/whats-new/#support-for-hot-reloading-of-ldap-credentials-file","title":"Support for hot reloading of LDAP credentials file","text":"

    Since v2.0.0, LDAP credentials have been specified in a separate file. Starting with this version, the file is watched and changes applied without restarting zot.

    "},{"location":"general/whats-new/#bugfixes-and-performance-improvements","title":"Bugfixes and performance improvements","text":"

    Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.

    "},{"location":"general/whats-new/#v200","title":"v2.0.0","text":""},{"location":"general/whats-new/#updated-oci-support","title":"Updated OCI support","text":"
    • Support is added for OCI Distribution Spec v1.1.0-rc3 and OCI Image Spec v1.1.0-rc4. The OCI changes are summarized here. These specifications allow arbitrary artifact types and references so that software supply chain use cases can be supported (SBOMs, signatures, etc). Currently, oras and regclient support this spec.

    • For a demonstration of an end-to-end OCI artifacts workflow, see Software Provenance Workflow Using OCI Artifacts.

      Support is deprecated for earlier OCI release candidates.

    "},{"location":"general/whats-new/#built-in-ui-support","title":"Built-in UI support","text":"
    • Using the new zot GUI, you can browse a zot registry for container images and artifacts. The web interface provides the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
    "},{"location":"general/whats-new/#support-for-social-logins","title":"Support for social logins","text":"
    • Support is added for OpenID authentication with GitHub, Google, and dex.
    "},{"location":"general/whats-new/#group-policies-for-authorization","title":"Group policies for authorization","text":"
    • When creating authorization policies, you can assign multiple users to a named group. A group-specific authorization policy can then be defined, specifying allowed access and actions for the group.

      Configuration syntax change: In the previous release, authorization policies were defined directly under the accessControl key in the zot configuration file. With the new ability to create authorization groups, it becomes necessary to add a new repositories key below accessControl. Beginning with zot v2.0.0, the set of authorization policies are now defined under the repositories key.

    "},{"location":"general/whats-new/#signature-verification","title":"Signature verification","text":"
    • The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.
    "},{"location":"general/whats-new/#ldap-credentials-stored-separately-from-configuration","title":"LDAP credentials stored separately from configuration","text":"
    • The LDAP credentials are removed from zot's LDAP configuration and stored in a separate file. See zot's LDAP documentation.

      This LDAP configuration change is incompatible with previous zot releases. When upgrading, you must reconfigure your LDAP credentials if you use LDAP.

    "},{"location":"general/whats-new/#storage-deduplication-on-startup","title":"Storage deduplication on startup","text":"
    • Deduplication, a storage space saving feature, now runs or reverts at startup depending on whether the feature is enabled or disabled. You can trigger deduplication by enabling it and then restarting zot.
    "},{"location":"general/whats-new/#retention-policies","title":"Retention policies","text":"
    • To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.
    "},{"location":"general/whats-new/#cve-scanning-support-for-image-indexes","title":"CVE scanning support for image indexes","text":"
    • The trivy backend now supports vulnerability scanning of image indexes. Previously, only images were scanned.
    "},{"location":"general/whats-new/#bookmarks","title":"Bookmarks","text":"
    • In the zot GUI, you can bookmark an image so that it can be easily found later. Bookmarked images appear in search queries when the bookmarked option is enabled.
    "},{"location":"general/whats-new/#ability-to-delete-tags-from-the-ui","title":"Ability to delete tags from the UI","text":""},{"location":"general/whats-new/#command-line-search","title":"Command line search","text":"
    • The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.
    "},{"location":"general/whats-new/#search-by-digest","title":"Search by digest","text":"
    • You can perform a global search for a digest (SHA hash) using either the UI or the CLI. This function is useful when an issue is found in a layer that is used by multiple images. In the UI Search box, for example, begin typing sha256: followed by a partial or complete digest value to see a dropdown list of images that contain the layer with the digest value.
    "},{"location":"general/whats-new/#graphql-support-for-search","title":"GraphQL support for search","text":"
    • A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. In addition to supporting direct GraphQL queries through the API, zot hosts the GraphQL Playground, which provides an interactive graphical environment for GraphQL queries.
    "},{"location":"general/whats-new/#scheduling-of-background-tasks","title":"Scheduling of background tasks","text":"
    • You can adjust the background scheduler based on your deployment requirements for tasks that are handled in the background, such as garbage collection. See Configuring zot.
    "},{"location":"general/whats-new/#performance-profiling-for-troubleshooting","title":"Performance profiling for troubleshooting","text":"
    • You can use zot's built-in profiling tools to collect and analyze runtime performance data.
    "},{"location":"general/whats-new/#binaries-for-freebsd","title":"Binaries for FreeBSD","text":"
    • zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.

      \u00a0zot container images for FreeBSD will be available in a future release.

    "},{"location":"general/whats-new/#v143","title":"v1.4.3","text":""},{"location":"general/whats-new/#remote-only-storage-support","title":"Remote-only Storage Support","text":"
    • The two types of state (images and image metadata) can both now be on remote storage so that zot process lifecycle and its storage can be managed and scaled independently.
    "},{"location":"general/whats-new/#digest-collision-detection-during-image-deletion","title":"Digest Collision Detection During Image Deletion","text":"
    • When two or more image tags point to the same image digest and the image is deleted by digest causes data loss and dangling references. A new behavior-based policy called detectManifestCollision was added to prevent this.
    "},{"location":"install-guides/install-guide-k8s/","title":"Installing zot with Kubernetes and Helm","text":"

    Using Kubernetes with Helm charts for zot, you can easily deploy zot as an application in a Kubernetes cluster.

    "},{"location":"install-guides/install-guide-k8s/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-k8s/#prerequisites","title":"Prerequisites","text":"
    • kubectl must be installed and a Kubernetes cluster must be ready.

    • Helm must be installed.

    "},{"location":"install-guides/install-guide-k8s/#supported-platforms","title":"Supported platforms","text":"

    You can install zot on standard Linux platforms with Intel or ARM processors and with systemd installed.

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4

    Supported platforms and architectures

    "},{"location":"install-guides/install-guide-k8s/#about-binary-images","title":"About binary images","text":"

    Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

    "},{"location":"install-guides/install-guide-k8s/#installing-zot","title":"Installing zot","text":""},{"location":"install-guides/install-guide-k8s/#step-1-locate-the-helm-charts-in-a-remote-repository","title":"Step 1: Locate the Helm charts in a remote repository","text":"
    1. Specify a remote repository that contains the Helm charts for zot. Give the repo a local name, such as project-zot, as in this example:

      helm repo add project-zot http://zotregistry.dev/helm-charts

      \"project-zot\" has been added to your repositories\n

      The Helm charts for zot are currently hosted in these publicly-accessible repositories: - zotregistry.dev - artifacthub.io

    2. Search the repository to see the Helm charts for zot installation. Search using the keyword 'project-zot' or 'zot', as in this example:

      helm search repo project-zot

      NAME             CHART VERSION  APP VERSION  DESCRIPTION\nproject-zot/zot  <chart-version>          v2.0.2       A Helm chart for Kubernetes\n

      The APP VERSION is the version/tag of the zot image used for the deployment.

    3. Update to the latest information of available charts from the chart repository, as shown in this example:

      helm repo update project-zot

      Hang tight while we grab the latest from your chart repositories...\n...Successfully got an update from the \"project-zot\" chart repository\nUpdate Complete. \u2388Happy Helming!\u2388\n
    4. Display the default information of the Helm chart, as shown in this example:

    helm show all project-zot/zot

        apiVersion: v2\n    appVersion: v2.0.2\n    description: A Helm chart for Kubernetes\n    name: zot\n    type: application\n    version: <chart-version>\n\n    # Default values for zot.\n    # This is a YAML-formatted file.\n    # Declare variables to be passed into your templates.\n    replicaCount: 1\n    image:\n      repository: ghcr.io/project-zot/zot-linux-amd64\n      pullPolicy: IfNotPresent\n      tag: \"v2.0.2\"\n    serviceAccount:\n      create: true\n      annotations: {}\n      name: \"\"\n    service:\n      type: NodePort\n      port: 5000\n
    "},{"location":"install-guides/install-guide-k8s/#step-2-determine-any-needed-changes-from-the-helm-charts-defaults","title":"Step 2: Determine any needed changes from the Helm chart\u2019s defaults","text":"

    Inspect the default information of the Helm chart, as shown in the previous step. In many cases, the default chart values may be acceptable. If your installation requires any non-default settings, you may be able to specify them during the installation. Not all chart values are configurable, but you can display those that are configurable using the command in the following example:

    helm show values project-zot/zot

      # Default values for zot.\n  # This is a YAML-formatted file.\n  # Declare variables to be passed into your templates.\n  replicaCount: 1\n  image:\n    repository: ghcr.io/project-zot/zot-linux-amd64\n    pullPolicy: IfNotPresent\n    tag: \"v2.0.2\"\n  serviceAccount:\n    create: true\n    annotations: {}\n    name: \"\"\n  service:\n    type: NodePort\n    port: 5000\n

    The configurable settings in the chart are listed in the following table:

    parameter description

    replicaCount

    Desired number of replicas of the application

    image.repository

    Repository and image name for the application

    image.pullPolicy

    Whether to pull the image from the repository. If not specified, the policy depends on image.tag:

    • If tag is :latest or no tag: Always

    • If tag is other than :latest: IfNotPresent

    image.tag

    Identifies different versions the image. default is the chart appVersion.

    Examples: :latest (the default) or :v2.0.2

    serviceAccount.create

    Specifies whether a service account should be created

    serviceAccount.annotations

    Annotations to add to the service account

    serviceAccount.name

    Name of the service account to use. If name is not set and create is true, a name is generated using the fullname template.

    service.type

    ClusterIP (default), NodePort, LoadBalancer, ExternalName, or Headless

    service.port

    Port number for calling the service

    strategy.type

    Kubernetes deployment strategy type. [More Info](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy)

    "},{"location":"install-guides/install-guide-k8s/#customizing-the-helm-chart-using-set","title":"Customizing the Helm chart using 'set'","text":"

    To override the default values in the chart, you can pass your custom values by adding the --set flag in the helm install command.

    For example, if your servers use an ARM processor instead of Intel, you must change the image.repository name from zot-linux-amd64 to zot-linux-arm64:

    --set image.repository=ghcr.io/project-zot/zot-linux-arm64

    You can change multiple settings with one --set statement. For example, you might want your installation to have more replicas or a different port number:

    --set replicaCount=2,service.port=5050

    "},{"location":"install-guides/install-guide-k8s/#customizing-the-helm-chart-using-a-file","title":"Customizing the Helm chart using a file","text":"

    You can also create a YAML file with your overrides and then add the new file by adding the -f flag to the helm install command. For example, to override the replica count and port number, the contents of your YAML file (for example, \"myfile.yaml\") would be:

    replicaCount: 2\nservice:\n  port: 5050\n

    and the following flag would be added to the helm install command:

    -f myfile.yaml

    "},{"location":"install-guides/install-guide-k8s/#additional-information","title":"Additional information","text":"

    See the Helm documentation for further information about modifying the Helm chart.

    "},{"location":"install-guides/install-guide-k8s/#step-3-install-zot","title":"Step 3: Install zot","text":"

    Install zot using the helm install command. The first example shows how to perform a default installation. The additional examples show different ways to modify the helm install command to override default settings in the Helm chart:

    Example 1: use default chart parameters

    helm install zot project-zot/zot

    NAME: zot\nLAST DEPLOYED: Thu Aug 11 19:13:02 2022\nNAMESPACE: default\nSTATUS: deployed\nREVISION: 1\nNOTES:\n Get the application URL by running these commands:\n export NODE_PORT=$(kubectl get --namespace default -o jsonpath=\"{.spec.ports[0].nodePort}\" services zot)\n export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n echo http://$NODE_IP:$NODE_PORT\n

    Example 2: modify specific chart parameters with 'set'

    helm install --set replicaCount=2,service.port=5050 zot project-zot/zot

    Example 3: modify specific chart parameters with a file

    helm install -f myfile.yaml zot project-zot/zot

    Example 4: use a specific version of the Helm chart

    helm install zot project-zot/zot --version 0.1.0

    Example 5: link to a kubeconfig file

    helm install zot project-zot/zot --kubeconfig $HOME/.kube/config

    "},{"location":"install-guides/install-guide-k8s/#after-the-installation","title":"After the installation","text":""},{"location":"install-guides/install-guide-k8s/#verify-the-installation","title":"Verify the installation","text":"
    1. List all releases that are either deployed or failed.

      helm list

      NAME  NAMESPACE  REVISION  UPDATED    STATUS    CHART      APP VERSION\nzot   default    1         <datetime> deployed  <chart-version>  v2.0.2\n

      This response indicates that zot is deployed.

    2. After making sure that your pods are up and running, execute the following commands:

      $ export NODE_PORT=$(kubectl get --namespace default -o jsonpath=\"{.spec.ports[0].nodePort}\" services zot)\n$ export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n$ echo http://$NODE_IP:$NODE_PORT\n$ curl http://$NODE_IP:$NODE_PORT/v2/_catalog\n

      The response should display the current contents of your zot repository, which should be empty immediately after installation:

      {\"repositories\":[]}\n
    "},{"location":"install-guides/install-guide-k8s/#edit-the-zot-configuration-file","title":"Edit the zot configuration file","text":"

    The zot configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:

    • network

    • storage

    • authentication

    • authorization

    • logging

    • metrics

    • synchronization with other registries

    • clustering

    The Helm chart installs a minimal JSON configuration file as shown below:

    {\n    \"storage\":\n    {\n        \"rootDirectory\": \"/var/lib/registry\"\n    },\n    \"http\":\n    {\n        \"address\": \"0.0.0.0\",\n        \"port\": \"5000\"\n    },\n    \"log\":\n    {\n        \"level\": \"debug\"\n    }\n}\n

    The zot configuration file is located at /etc/zot/config.json.

    Refer to Configuring zot for complete information on configuring the zot server with the zot configuration file.

    "},{"location":"install-guides/install-guide-k8s/#uninstalling-zot","title":"Uninstalling zot","text":"

    Should you need to uninstall zot, use the helm uninstall command, as in this example:

    helm uninstall zot

    "},{"location":"install-guides/install-guide-linux/","title":"Installing zot on Bare Metal Linux","text":"

    Using an available executable zot image, you can easily deploy zot on a Linux server.

    "},{"location":"install-guides/install-guide-linux/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-linux/#about-binary-images","title":"About binary images","text":"

    Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.

    Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.

    "},{"location":"install-guides/install-guide-linux/#installation","title":"Installation","text":""},{"location":"install-guides/install-guide-linux/#step-1-get-zot","title":"Step 1: Get zot","text":"

    Using wget, download the appropriate zot binary image for your platform from the zot GitHub project. Download the image to the`/usr/bin/` directory and rename it to zot, as in this example:

    sudo wget -O /usr/bin/zot https://github.com/project-zot/zot/releases/download/v2.0.2/zot-linux-amd64\n

    Then fix permissions to it:

    sudo chmod +x /usr/bin/zot\nsudo chown root:root /usr/bin/zot\n
    "},{"location":"install-guides/install-guide-linux/#step-2-create-a-zot-configuration-file","title":"Step 2: Create a zot configuration file","text":"

    Create a zot configuration file as /etc/zot/config.json.

    See Configuration file options for an example file with options and recommendations. You can find other configuration file examples in the zot GitHub project and in Configuring zot.

    "},{"location":"install-guides/install-guide-linux/#step-3-configure-a-local-authentication-account","title":"Step 3: Configure a local authentication account","text":"

    If you want to use local authentication with zot, create a /etc/zot/htpasswd file with an initial account entry using the htpasswd command as in this example:

    htpasswd -bnB myUserName myPassword > /etc/zot/htpasswd\n

    To add additional local users, use the >> redirect as in this example:

    htpasswd -bnB myUserName2 myPassword2 >> /etc/zot/htpasswd\n
    "},{"location":"install-guides/install-guide-linux/#step-4-define-the-zot-service","title":"Step 4: Define the zot service","text":"

    Create a /etc/systemd/system/zot.service file to define the zot service in systemd. The following is an example service file for zot:

    [Unit]\nDescription=OCI Distribution Registry\nDocumentation=https://zotregistry.dev/\nAfter=network.target auditd.service local-fs.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/zot serve /etc/zot/config.json\nRestart=on-failure\nUser=zot\nGroup=zot\nLimitNOFILE=500000\nMemoryHigh=30G\nMemoryMax=32G\n\n[Install]\nWantedBy=multi-user.target\n

    Be sure to configure a dedicated non-root user ID as the User and Group in the zot service definition. The 'zot' user ID in this example is created in the next step.

    "},{"location":"install-guides/install-guide-linux/#step-5-create-a-user-id-to-own-the-zot-service","title":"Step 5: Create a user ID to own the zot service","text":"

    Create a non-root user ID to be the owner of the zot service and its resources.

    In this example, the user ID 'zot' is created with the adduser command, and resource ownership is assigned.

    sudo adduser --no-create-home --disabled-password --gecos --disabled-login zot\n\nsudo mkdir -p /data/zot\nsudo chown -R zot:zot /data/zot\n\nsudo mkdir -p /var/log/zot\nsudo chown -R zot:zot /var/log/zot\n\nsudo chown -R root:root /etc/zot/\n

    With the adduser options shown, the 'zot' user ID has no local directory. There is no ability to log into the zot user account, and the account has no finger information.

    "},{"location":"install-guides/install-guide-linux/#step-6-start-zot","title":"Step 6: Start zot","text":"

    Reload systemd config:

    sudo systemctl daemon-reload\n

    Enable and start the zot service with these commands:

    sudo systemctl enable zot\nsudo systemctl start zot\n

    Check if zot config is valid:

    sudo -u zot zot verify /etc/zot/config.json\n

    When the zot service has started, you can check its status with this command:

    sudo systemctl status zot\n
    "},{"location":"install-guides/install-guide-linux/#after-the-installation","title":"After the installation","text":"

    If your zot registry server is public facing, we recommend that you test your TLS configuration using a service such as the Qualys SSL Server Test.

    Refer to Configuring zot for further information about maintaining your zot registry server.

    "},{"location":"install-guides/install-guide-linux/#configuration-file-options-and-recommendations","title":"Configuration file options and recommendations","text":"

    The following zot configuration file (config.json) can be used as a template for your own installation. You can modify this file to suit your own environment.

    Click here to view the sample configuration file.
    {\n  \"distSpecVersion\":\"1.0.1\",\n  \"storage\":{\n    \"dedupe\": true,\n    \"gc\": true,\n    \"gcDelay\": \"1h\",\n    \"gcInterval\": \"6h\",\n    \"rootDirectory\":\"/data/zot/\"\n  },\n  \"http\": {\n    \"address\":\"0.0.0.0\",\n    \"port\":\"443\",\n    \"realm\":\"zot\",\n    \"tls\": {\n      \"cert\": \"/etc/letsencrypt/live/zothub.io/fullchain.pem\",\n      \"key\": \"/etc/letsencrypt/live/zothub.io/privkey.pem\"\n    },\n    \"auth\": {\n      \"htpasswd\": {\n        \"path\": \"/etc/zot/htpasswd\"\n      },\n      \"failDelay\": 5\n    },\n    \"allowReadAccess\": true\n  },\n  \"log\":{\n    \"level\":\"debug\",\n    \"output\":\"/var/log/zot/zot.log\",\n    \"audit\":\"/var/log/zot/zot-audit.log\"\n  },\n  \"extensions\": {\n    \"search\": {\n      \"enable\": true,\n      \"cve\": {\n        \"updateInterval\": \"24h\"\n      }\n    },\n    \"sync\": {\n      \"enable\": false,\n      \"registries\": [\n        {\n          \"urls\": [\"https://mirror.gcr.io/library\"],\n          \"onDemand\": true,\n          \"maxRetries\": 3,\n          \"retryDelay\": \"5m\",\n          \"pollInterval\": \"6h\"\n        },\n        {\n          \"urls\": [\"https://docker.io/library\"],\n          \"onDemand\": true\n        }\n      ]\n    },\n    \"scrub\": {\n      \"interval\": \"24h\"\n    }\n  }\n}\n

    Refer to Configuring zot for more details about configuration file options.

    "},{"location":"install-guides/install-guide-linux/#tls-encryption","title":"TLS encryption","text":"

    We recommend using a certificate authority such as Let\u2019s Encrypt that offers TLS encryption, as shown in this configuration example:

    \"tls\": {\n  \"cert\": \"/etc/letsencrypt/live/zothub.io/fullchain.pem\",\n  \"key\": \"/etc/letsencrypt/live/zothub.io/privkey.pem\"\n}\n
    "},{"location":"install-guides/install-guide-linux/#registry-synchronization","title":"Registry synchronization","text":"

    The example file enables registry synchronization with two other container registries. In the example, the zot server synchronizes with the Google and Docker container registries, as shown here:

    \"sync\": {\n  \"enable\": false,\n  \"registries\": [\n    {\n      \"urls\": [\"https://mirror.gcr.io/library\"],\n      \"onDemand\": true,\n      \"maxRetries\": 3,\n      \"retryDelay\": \"5m\",\n      \"pollInterval\": \"6h\"\n    },\n    {\n      \"urls\": [\"https://docker.io/library\"],\n      \"onDemand\": true\n    }\n  ]\n}\n
    "},{"location":"user-guides/user-guide-datapath/","title":"Push and Pull Image Content","text":"

    zot is an OCI image registry that allows you to store, manage, and share container images.

    A zot registry can store and serve a variety of content, but the type of content may dictate your choice of a client tool.

    For various content types, this document shows examples of using a third-party client tool that supports the content. The following table shows which content and client tools are demonstrated.

    Content Type Client OCI images skopeo OCI images regclient (regctl) OCI images crane OCI artifacts oras Helm charts helm

    zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.

    In the following examples, the zot registry is located at localhost, using port number 5000.

    "},{"location":"user-guides/user-guide-datapath/#common-tasks-using-skopeo-for-oci-images","title":"Common tasks using skopeo for OCI images","text":"

    skopeo is a command line client that performs various operations on OCI container images and image repositories.

    For detailed information about using skopeo, see the skopeo man page.

    "},{"location":"user-guides/user-guide-datapath/#push-an-oci-image","title":"Push an OCI image","text":"

    This example pushes the latest container image for the busybox application to a zot registry.

    $ skopeo --insecure-policy copy --dest-tls-verify=false --multi-arch=all \\\n   --format=oci docker://busybox:latest \\\n   docker://localhost:5000/busybox:latest\n
    "},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image","title":"Pull an OCI image","text":"

    This example pulls the latest container image for the busybox application and stores the image to a local OCI-layout directory (/oci/images).

    $ skopeo --insecure-policy copy --src-tls-verify=false --multi-arch=all \\\n   docker://localhost:5000/busybox:latest \\\n   oci:/oci/images:busybox:latest\n
    "},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image-to-a-private-docker-registry","title":"Pull an OCI image to a private docker registry","text":"

    This example pulls the latest container image for the busybox application and stores the image to a local private docker registry.

    $ skopeo --insecure-policy copy --src-tls-verify=false --multi-arch=all \\\n   docker://localhost:5000/busybox:latest \\\n   docker://localhost:5000/busybox:latest\n
    Click here to view an example of pushing and pulling an image using skopeo.

    "},{"location":"user-guides/user-guide-datapath/#authentication","title":"Authentication","text":"

    In these examples, authentication is disabled for the source and destination. You can enable authentication by changing the command line options as follows:

    --src-tls-verify=true\n--dest-tls-verify=true\n

    You can also add credentials for authenticating with a source or destination repository:

    --src-creds username:password\n--dest-creds username:password\n
    "},{"location":"user-guides/user-guide-datapath/#common-tasks-using-regclient-for-oci-images","title":"Common tasks using regclient for OCI images","text":"

    regclient is a client interface that performs various operations on OCI container images and image repositories. The command line interface for regclient is regctl.

    For detailed information about regctl commands, see the regctl Documentation.

    "},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_1","title":"Push an OCI image","text":"

    This example pushes version 1.20 of golang to a tools repository within the registry.

    $ regctl registry set --tls=disabled localhost:5000\n$ regctl image copy ocidir://path/to/golang:1.20 localhost:5000/tools\n
    "},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image_1","title":"Pull an OCI image","text":"

    This example pulls version 1.20 of golang to a local OCI-layout directory.

    $ regctl image copy localhost:5000/tools ocidir://path/to/golang:1.20\n
    "},{"location":"user-guides/user-guide-datapath/#list-all-repositories-in-registry","title":"List all repositories in registry","text":"

    This example list all repositories in the registry.

    $ regctl repo ls localhost:5000\n
    "},{"location":"user-guides/user-guide-datapath/#list-tags","title":"List tags","text":"

    This example lists all tags in the tools repository within the registry.

    $ regctl tag ls localhost:5000/tools\n
    "},{"location":"user-guides/user-guide-datapath/#pull-and-push-manifest","title":"Pull and push manifest","text":"

    This example pulls and pushes the manifest in the tools repository within the registry.

    $ regctl manifest get localhost:5000/tools --format=raw-body\n$ regctl manifest put localhost:5000/tools:1.0.0 \\\n--format oci --content-type application/vnd.oci.image.manifest.v1+json \\\n--format oci\n
    "},{"location":"user-guides/user-guide-datapath/#authentication_1","title":"Authentication","text":"

    In the preceding examples, TLS authentication with the zot registry was disabled by the following command:

    $ regctl registry set --tls=disabled localhost:5000\n

    This command allows regctl to accept an HTTP response from the zot server. If TLS authentication is enabled on the zot registry server, you can omit this command from your regctl session.

    "},{"location":"user-guides/user-guide-datapath/#common-tasks-using-oras-for-oci-artifacts","title":"Common tasks using oras for OCI artifacts","text":"

    ORAS (OCI Registry As Storage) is a command line client for storing OCI artifacts on OCI repositories.

    For detailed information about the oras commands in these examples, see the ORAS CLI documentation.

    "},{"location":"user-guides/user-guide-datapath/#push-an-artifact","title":"Push an artifact","text":"

    This example pushes version 2 of an artifact file named hello-artifact to a zot registry.

    $ oras push --plain-http localhost:5000/hello-artifact:v2 \\\n        --config config.json:application/vnd.acme.rocket.config.v1+json \\\n        artifact.txt:text/plain -d -v\n
    "},{"location":"user-guides/user-guide-datapath/#pull-an-artifact","title":"Pull an artifact","text":"

    This example pulls version 2 of an artifact file named hello-artifact from a zot registry.

    $ oras pull --plain-http localhost:5000/hello-artifact:v2 -d -v\n
    Click here to view an example of pushing and pulling an artifact using oras.

    "},{"location":"user-guides/user-guide-datapath/#attach-a-reference","title":"Attach a reference","text":"
    $ echo '{\"artifact\": \"localhost:5000/hello-artifact:v2\", \"signature\": \"pat hancock\"}' > signature.json\n\n$ oras push localhost:5000/hello-artifact \\\n  --artifact-type 'signature/example' \\\n  --subject localhost:5000/hello-artifact:v2 \\\n  ./signature.json:application/json\n\n$ oras discover -o tree localhost:5000/hello-artifact:v2\n
    "},{"location":"user-guides/user-guide-datapath/#authentication_2","title":"Authentication","text":"

    To authenticate with the zot server, log in at the start of your session using the following command:

    $ oras login -u myUsername -p myPassword localhost:5000\n

    You can also add credentials in the push or pull commands as in this example:

    $ oras pull -u myUsername -p myPassword localhost:5000/hello-artifact:v2 -d -v\n

    For additional authentication options, including interactive credential entry and disabling TLS, see the ORAS authentication documentation.

    "},{"location":"user-guides/user-guide-datapath/#common-tasks-using-helm-for-helm-charts","title":"Common tasks using helm for helm charts","text":"

    Helm is a package manager for Kubernetes. Among many other capabilities, helm can store and retrieve helm charts on OCI image repositories.

    For detailed information about the helm commands in these examples, see Commands for working with registries in the helm documentation.

    "},{"location":"user-guides/user-guide-datapath/#push-a-helm-chart","title":"Push a helm chart","text":"

    This example pushes version 1.2.3 of a zot helm chart to a zot-chart repository within the registry.

    $ helm package path/to/helm-charts/charts/zot\n$ helm push zot-1.2.3.tgz oci://localhost:5000/zot-chart\n
    "},{"location":"user-guides/user-guide-datapath/#pull-a-helm-chart","title":"Pull a helm chart","text":"

    This example pulls version 1.2.3 of a zot helm chart from a zot-chart repository within the registry.

    $ helm pull oci://localhost:5000/zot-chart/zot --version 1.2.3\n
    "},{"location":"user-guides/user-guide-datapath/#authentication_3","title":"Authentication","text":"

    To authenticate with the zot server, log in at the start of your session using the following command:

    $ helm registry login -u myUsername localhost:5000\n

    You will be prompted to manually enter a password.

    "},{"location":"user-guides/user-guide-datapath/#common-tasks-using-crane-for-oci-images","title":"Common tasks using crane for OCI images","text":"

    crane is an open-source project that provides a command-line interface (CLI) for interacting with container registries, such as Docker Hub and Google Container Registry.

    For detailed information about crane commands, see the crane Documentation.

    "},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_2","title":"Push an OCI image","text":"

    This example pushes the latest container image for the alpine application to a registry.

    $ crane --insecure push \\\n   oci/images/alpine:latest \\\n   localhost:5000/alpine:latest\n
    "},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image_2","title":"Pull an OCI image","text":"

    This example pulls the latest container image for the alpine application and stores the image to a local OCI-layout directory (/oci/images).

    $ crane --insecure pull \\\n   --format oci \\\n   localhost:5000/alpine:latest \\\n   oci/images/alpine:latest\n
    "},{"location":"user-guides/user-guide-datapath/#copy-an-oci-image-to-a-private-docker-registry","title":"Copy an OCI image to a private docker registry","text":"

    This example pulls the latest container image for the alpine application and stores the image to a local private docker registry.

    $ crane --insecure copy \\\n   alpine:latest \\\n   localhost:5000/alpine:latest\n
    "},{"location":"user-guides/user-guide-datapath/#list-tags_1","title":"List tags","text":"

    This example lists all tags in the alpine image within the registry.

    $ crane ls localhost:5000/alpine\n
    "},{"location":"user-guides/user-guide-datapath/#find-the-digest-of-an-image","title":"Find the digest of an image","text":"

    This example gets the digest of the alpine image within the registry.

    $ crane digest localhost:5000/alpine:latest\n
    "},{"location":"user-guides/user-guide-datapath/#authentication_4","title":"Authentication","text":"

    To authenticate with the registry server, log in at the start of your session using the following command:

    $ crane auth login -u myUsername localhost:5000\n
    "},{"location":"user-guides/user-guide-gui/","title":"Use the Web Interface to Find Images","text":"

    Using a browser, you can browse a zot repository for container images and artifacts. The web interface also provides the commands for downloading an image using popular third-party tools.

    If a zot registry is built with the optional zui package, the registry has a web interface.

    "},{"location":"user-guides/user-guide-gui/#access-the-registry","title":"Access the registry","text":"

    Depending on the security configuration of the zot registry, you might need to authenticate before being given access.

    The initial page of the registry displays a sampling of the most popular images and recently updated images. To view all available images in the registry, click the View all link in the upper right of the page to go to the /explore page.

    Wherever an image name appears, two icons follow the name, indicating the results of the vulnerability scan and the signature status. These icons are described in Icons and their meanings.

    "},{"location":"user-guides/user-guide-gui/#find-an-image","title":"Find an image","text":"

    To assist you in finding images specific to your requirements, the /explore page provides several sorting options along with faceted navigation in addition to a general search box.

    • Sorting criteria include relevance, most recently updated, alphabetical, and most downloaded.

    • Navigation facets include operating system, CPU architecture, and signature status.

    When you locate the desired image, click its tile.

    "},{"location":"user-guides/user-guide-gui/#inspect-the-image-properties","title":"Inspect the image properties","text":"

    The OVERVIEW tab of the initial image description page contains a brief description of the image along with several details, such as the repository URL, number of downloads, last published, size, and license type.

    Click the TAGS tab to view the available versions of the image.

    Click the tag link of the desired version of the image. In the resulting page, you can view detailed information about the image, including its digest hash, and you can obtain a command to pull the image from the repository.

    Tabs on this page provide the following information:

    Tab Description LAYERS The build command and the digest hash USES A list of images used by this image USED BY A list of images that use this image VULNERABILITIES A list of known vulnerabilities

    From the LAYERS tab, click Details to view an example of the image build command and the layer's digest hash.

    "},{"location":"user-guides/user-guide-gui/#pull-an-image","title":"Pull an image","text":"

    After opening the tag link of the desired image, click the Pull Image drop-down list to display the available pull commands. Docker, podman, and skopeo image management tools are supported.

    Select a tool and click the pages icon next to the command to copy the full command to your clipboard. An example of the pull command using podman is:

    podman pull zothub.io/c3/debian/base-amd64:bullseye

    Paste the pull command into your terminal to pull the image.

    For information about using image management tools to pull images, see Push and Pull Image Content.

    "},{"location":"user-guides/user-guide-gui/#adding-bookmarks","title":"Adding Bookmarks","text":"

    To mark an image so that it can be easily found later, click the bookmark icon on the image page. Bookmarked images appear in search queries when the Bookmarked option is enabled.

    The bookmark icon before selection:

    The bookmark icon after selection:

    "},{"location":"user-guides/user-guide-gui/#icons-and-their-meanings","title":"Icons and their meanings","text":"

    These icons appear next to the image name, indicating the results of the vulnerability scan and the signature status.

    Icon Description A vulnerability scan of the image found no vulnerabilities A vulnerability scan of the image failed(See severity icon in VULNERABILITIES tab) Critical severity High severity Medium severity Low severity The image signature is verified The image signature is not verified The image is not bookmarked by the user The image is bookmarked by the user"},{"location":"user-guides/zli/","title":"Using the command line interface (zli)","text":"

    zli: The command line tool for zot servers

    "},{"location":"user-guides/zli/#what-is-zli","title":"What is zli?","text":"

    zli is a binary that implements a set of command line commands for interacting with the zot registry server.

    We recommend installing zli when you install zot.

    "},{"location":"user-guides/zli/#how-to-get-zli","title":"How to get zli","text":"

    zli is hosted with zot on GitHub at project-zot. From GitHub, you can download the zli binary or you can build zli from the source.

    "},{"location":"user-guides/zli/#supported-platforms","title":"Supported platforms","text":"

    zli is supported for the following operating systems and platform architectures:

    OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"user-guides/zli/#downloading-zli-binaries","title":"Downloading zli binaries","text":"

    You can download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.

    The binary image is named using the OS and architecture from the Supported platforms table. For example, the binary for an Intel-based MacOS server is zli-darwin-amd64.

    "},{"location":"user-guides/zli/#building-zli-from-source","title":"Building zli from source","text":"

    To build the zli binary, copy or clone the zot project from GitHub and execute the make cli command in the zot directory. Use the same command options that you used to build zot, as shown:

    make OS=os ARCH=architecture cli

    For example, the following command builds zli for an Intel-based MacOS server:

    make OS=darwin ARCH=amd64 cli\n

    In this example, the resulting executable file is zli-darwin-amd64 in the zot/bin directory.

    "},{"location":"user-guides/zli/#common-tasks-using-zli","title":"Common tasks using zli","text":"

    This section includes examples of common zot server tasks using the zli command line interface. For a detailed listing of zli commands, see the zli Command Reference in this guide.

    The original filename of the zli executable file will reflect the build options, such as zli-linux-amd64. For convenience, you can rename the executable to simply zli. The instructions and examples in this guide use zli as the name of the executable file.

    "},{"location":"user-guides/zli/#adding-a-zot-server-url","title":"Adding a zot server URL","text":"

    You can modify the zot server configuration using the zli config add command. This example adds a zot server URL with an alias of remote-zot:

    $ bin/zli config add remote-zot https://server-example:8080\n

    Use the zli config command to list all configured URLs with their aliases:

    $ bin/zli config -l\n\nremote-zot   https://server-example:8080\nlocal        http://localhost:8080\n
    "},{"location":"user-guides/zli/#listing-images","title":"Listing images","text":"

    You can list all images hosted on a zot server using the zli image list command with the server\u2019s alias:

    $ bin/zli image list --config local\n\nREPOSITORY        TAG       OS/ARCH         DIGEST      SIGNED      SIZE        \nalpine            latest    linux/amd64     3fc10231    false       84MB        \nbusybox           latest    linux/amd64     9172c5f6    false       2.2MB\n

    You can also filter the image list to view a specific image by specifying the image name:

    $ bin/zli image name busybox:latest --config local\n\nREPOSITORY        TAG       OS/ARCH         DIGEST      SIGNED      SIZE              \nbusybox           latest    linux/amd64     9172c5f6    false       2.2MB\n
    "},{"location":"user-guides/zli/#scanning-images-for-known-vulnerabilities","title":"Scanning images for known vulnerabilities","text":"

    Using the zli cve list command, you can fetch the CVE (Common Vulnerabilities and Exposures) information for images hosted on the zot server. This example shows how to learn which images are affected by a specific CVE:

    $ bin/zli cve affected CVE-2017-9935 --config remote-zot\n\nIMAGE NAME        TAG               DIGEST    SIZE\nc3/openjdk-dev    commit-5be4d92    ac3762e2  335MB\n

    This example displays a list of all CVEs affecting a specific image:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot\n\nID                SEVERITY  TITLE\nCVE-2015-8540     LOW       libpng: underflow read in png_check_keyword()\nCVE-2017-16826    LOW       binutils: Invalid memory access in the coff_s...\n

    This example (--verbose) displays a list of all CVEs affecting a specific image with details:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot --verbose\nLOW 2, UNKNOWN 1, TOTAL 3\n\nCVE-2015-8540\n...\n

    Note that the details may display the package path in the image when the information is available.

    This example displays the detailed CVEs in JSON format:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot -f json\n{\n  \"Tag\": \"0.3.19\",\n  \"CVEList\": [\n    {\n      \"Id\": \"CVE-2019-17006\",\n      \"Severity\": \"MEDIUM\",\n      \"Title\": \"nss: Check length of inputs for cryptographic primitives\",\n      \"Description\": \"A vulnerability was discovered in nss where input text length was not checked when using certain cryptographic primitives. This could lead to a heap-buffer overflow resulting in a crash and data leak. The highest threat is to confidentiality and integrity of data as well as system availability.\",\n      \"PackageList\": [\n        {\n          \"Name\": \"nss\",\n          \"InstalledVersion\": \"3.44.0-7.el7_7\",\n          \"FixedVersion\": \"Not Specified\"\n        },\n        {\n          \"Name\": \"nss-sysinit\",\n          \"InstalledVersion\": \"3.44.0-7.el7_7\",\n          \"FixedVersion\": \"Not Specified\"\n        },\n        {\n          \"Name\": \"nss-tools\",\n          \"InstalledVersion\": \"3.44.0-7.el7_7\",\n          \"FixedVersion\": \"Not Specified\"\n        }]\n    }]\n}\n

    This example lists all images on a specific zot server that are affected by a specific CVE:

    $ bin/zli cve affected --config remote-zot CVE-2017-9935 --repo c3/openjdk-dev\n\nIMAGE NAME        TAG               DIGEST    SIZE\nc3/openjdk-dev    commit-2674e8a    71046748  338MB\nc3/openjdk-dev    commit-bd5cc94    0ab7fc76\n

    This example lists all images on a specific zot server where the CVE has been fixed:

    $ bin/zli cve fixed c3/openjdk-dev CVE-2017-9935 --config remote-zot\n\nIMAGE NAME        TAG                       DIGEST    SIZE\nc3/openjdk-dev    commit-2674e8a-squashfs   b545b8ba  321MB\nc3/openjdk-dev    commit-d5024ec-squashfs   cd45f8cf  321MB\n

    This example lists all CVEs that have been found in one image and not the other:

    $ bin/zli cve diff c3/openjdk-dev:1.0.0 c3/openjdk-dev:2.0.0 --config remote-zot\n\nID                SEVERITY  TITLE\nCVE-2015-8540     LOW       libpng: underflow read in png_check_keyword()\nCVE-2017-16826    LOW       binutils: Invalid memory access in the coff_s...\n

    For example, the above query lists all CVEs that have been found in c3/openjdk-dev:1.0.0 but not in c3/openjdk-dev:2.0.0

    "},{"location":"user-guides/zli/#listing-repositories","title":"Listing repositories","text":"

    You can list all repositories hosted on a zot server using the zli repo command with the server\u2019s alias:

    Searching... \ud83c\udf0d\n\nREPOSITORY NAME\nalpine\nbusybox\n
    "},{"location":"user-guides/zli/#searching-for-repositories-and-images","title":"Searching for repositories and images","text":"

    You can locate repositories and images hosted on a zot server using the zli search command.

    • To search for a repository, specify the full name with a colon or a partial name with no colon.
    • To search for an image, specify the full repository name followed by the tag or a prefix of the tag.

    This example searches the zot registry named 'local' for a repository whose name contains the substring 'ng':

    $ bin/zli search query ng --config local\n\nNAME            SIZE        LAST UPDATED                             DOWNLOADS   STARS\nnginx           794MB       2023-03-01 18:44:17.707690369 +0000 UTC  0           0\nmongo           232MB       2022-10-18 15:03:40.7646203 +0300 +0300  0           0\ngolang          1.1GB       2023-06-22 00:32:38.613354854 +0000 UTC  0           0\n

    This example searches the zot registry named 'local' for a repository named 'nginx'. Because the repository name is followed by a colon, the search results must match the name exactly.

    $ bin/zli search query nginx: --config local\n\nREPOSITORY  TAG          OS/ARCH         DIGEST      SIGNED      SIZE\nnginx       1.23.1       linux/amd64     d2ad9089    true        57MB\nnginx       latest       *               c724afdf    true        448MB\n                         linux/amd64     009c6fda    false       57MB\n                         linux/arm/v5    1d5d4f53    false       54MB\n                         linux/arm/v7    f809744c    false       50MB\n                         linux/arm64/v8  ebb807a9    false       56MB\n                         linux/386       19cf4b3c    false       59MB\n                         linux/mips64le  45ab60e6    false       55MB\n                         linux/ppc64le   89511bee    false       63MB\n                         linux/s390x     713b9329    false       55MB\nnginx       stable-perl  *               4383a0b8    true        534MB\n                         linux/amd64     308a37a0    false       68MB\n                         linux/arm/v5    0fb8fb71    false       64MB\n                         linux/arm/v7    6868f552    false       60MB\n                         linux/arm64/v8  aed72c86    false       66MB\n                         linux/386       5c7ed456    false       69MB\n                         linux/mips64le  546d2bae    false       65MB\n                         linux/ppc64le   7db02f5a    false       74MB\n                         linux/s390x     800fd86f    false       66MB\n
    "},{"location":"user-guides/zli/#sorting-the-output-of-a-zli-command","title":"Sorting the output of a zli command","text":"

    For a zli command that can result in a lengthy output list, you can use the command flag --sort-by <option> to cause the output to be sorted by a specified property of the output data. The available sorting criteria vary for different commands, but examples of sorting criteria options are described in the following table:

    flag option criteria alpha-asc alphabetical, ascending alpha-dsc alphabetical, descending relevance quality of match severity severity of condition update-time timestamp

    For a given command that results in an output list, you can see the available sorting criteria in the usage information returned by the --help flag. For example, bin/zli image name --help returns usage information containing the following line under \"Flags\":

    --sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")

    According to this information, the list of image names returned by the bin/zli image name command can be sorted in order of alphabetical ascending, alphabetical descending, or the timestamp of the latest update of the image. The default sorting method for this command, if no --sort-by flag is present, is alphabetical ascending.

    "},{"location":"user-guides/zli/#command-reference","title":"Command reference","text":"

    This section provides detailed usage information for basic first-level zli commands. Many zli commands also support subcommands, which are listed as \"Available Commands\" in each command description. For example, zli search can be extended with either the query or subject subcommand. To see the detailed usage for each subcommand, type the command with the subcommand and append --help, such as zli search query --help. The zli search description below includes the subcommand help as an example.

    "},{"location":"user-guides/zli/#zli","title":"zli","text":"
    $ bin/zli --help\n\nUsage:\n  zli [flags]\n  zli [command]\n\nAvailable Commands:\n  completion  Generate the autocompletion script for the specified shell\n  config      Configure zot registry parameters for CLI\n  cve         Lookup CVEs in images hosted on the zot registry\n  help        Help about any command\n  image       List images hosted on the zot registry\n  repo        List all repositories\n  search      Search images and their tags\n\nFlags:\n  -h, --help      help for zli\n  -v, --version   show the version and exit\n\nUse \"zli [command] --help\" for more information about a command.\n
    "},{"location":"user-guides/zli/#zli-completion","title":"zli completion","text":"

    This command generates the autocompletion script for zli for the specified shell. See each subcommand\u2019s help for details on how to use the generated script.

    $ bin/zli completion --help\n\nUsage:\n  zli completion [command]\n\nAvailable Commands:\n  bash        Generate the autocompletion script for bash\n  fish        Generate the autocompletion script for fish\n  powershell  Generate the autocompletion script for powershell\n  zsh         Generate the autocompletion script for zsh\n\nFlags:\n  -h, --help   help for completion\n\nUse \"zli completion [command] --help\" for more information about a command.\n
    "},{"location":"user-guides/zli/#zli-config","title":"zli config","text":"

    This command configures zot registry parameters for CLI.

    $ bin/zli config --help\n\nUsage:\n  zli config <config-name> [variable] [value] [flags]\n  zli config [command]\n\nExamples:\n  zli config add main https://zot-foo.com:8080\n  zli config --list\n  zli config main url\n  zli config main --list\n  zli config remove main\n\nAvailable Commands:\n  add         Add configuration for a zot registry\n  remove      Remove configuration for a zot registry\n\nFlags:\n  -h, --help    help for config\n  -l, --list    List configurations\n      --reset   Reset a variable value\n\nUse \"zli config [command] --help\" for more information about a command.\n\nUseful variables:\n  url       zot server URL\n  showspinner   show spinner while loading data [true/false]\n  verify-tls    enable TLS certificate verification of the server [default: true]\n
    "},{"location":"user-guides/zli/#zli-cve","title":"zli cve","text":"

    This command lists CVEs (Common Vulnerabilities and Exposures) of images hosted on the zot registry

    $ ./zli cve --help\n\nUsage:\n  zli cve [command]\n\nAvailable Commands:\n  affected    List images affected by a CVE\n  fixed       List tags where a CVE is fixedRetryWithContext\n  list        List CVEs by REPO:TAG or REPO@DIGEST\n\nFlags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -f, --format string   Specify output format [text/json/yaml]\n  -h, --help            help for cve\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n      --verbose         Show verbose output\n\nUse \"zli cve [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
    "},{"location":"user-guides/zli/#zli-image","title":"zli image","text":"

    This command lists images hosted on the zot registry.

    $ ./zli image --help\n\nUsage:\n  zli image [command]\n\nAvailable Commands:\n  base        List images that are base for the given image\n  cve         List all CVE's of the image\n  derived     List images that are derived from given image\n  digest      List images that contain a blob(manifest, config or layer) with the given digest\n  list        List all images\n  name        List image details by name\n\nFlags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -f, --format string   Specify output format [text/json/yaml]\n  -h, --help            help for image\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n      --verbose         Show verbose output\n\nUse \"zli image [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
    "},{"location":"user-guides/zli/#zli-repo","title":"zli repo","text":"

    This command lists all repositories in the zot registry.

    $ ./zli repo --help\n\nUsage:\n  zli repo [command]\n\nAvailable Commands:\n  list        List all repositories\n\nFlags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -h, --help            help for repo\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n\nUse \"zli repo [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
    "},{"location":"user-guides/zli/#zli-search","title":"zli search","text":"

    The search command allows smart searching for a repository by its name or for an image by its repo:tag.

    $ ./zli search --help\n\nSearch repos or images\n\nUsage:\n  zli search [command]\n\nAvailable Commands:\n  query       Fuzzy search for repos and their tags.\n  subject     List all referrers for this subject.\n\nFlags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -f, --format string   Specify output format [text/json/yaml]\n  -h, --help            help for search\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n      --verbose         Show verbose output\n\nUse \"zli search [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
    "},{"location":"user-guides/zli/#zli-search-query","title":"zli search query","text":"
    $ ./zli search query --help\n\nUsage:\n  zli search query [repo]|[repo:tag] [flags]\n\nExamples:\n# For repo search specify a substring of the repo name without the tag\n  zli search query \"test/repo\"\n\n# For image search specify the full repo name followed by the tag or a prefix of the tag.\n  zli search query \"test/repo:2.1.\"\n\nFlags:\n  -h, --help             help for query\n      --sort-by string   Options for sorting the output: [relevance, update-time, alpha-asc, alpha-dsc] (default \"relevance\")\n\nGlobal Flags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -f, --format string   Specify output format [text/json/yaml]\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n      --verbose         Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
    "},{"location":"user-guides/zli/#zli-search-subject","title":"zli search subject","text":"
    $ ./zli search subject --help\n\nList all referrers for this subject. The subject can be specified by tag(repo:tag) or by digest\" or (repo@digest)\n\nUsage:\n  zli search subject [repo:tag]|[repo@digest] [flags]\n\nExamples:\n# For referrers search specify the referred subject using it's full digest or tag:\n  zli search subject \"repo@sha256:f9a0981...\"\n  zli search subject \"repo:tag\"\n\nFlags:\n  -h, --help             help for subject\n      --sort-by string   Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")\n\nGlobal Flags:\n      --config string   Specify the registry configuration to use for connection\n      --debug           Show debug output\n  -f, --format string   Specify output format [text/json/yaml]\n      --url string      Specify zot server URL if config-name is not mentioned\n  -u, --user string     User Credentials of zot server in \"username:password\" format\n      --verbose         Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
    "}]} \ No newline at end of file diff --git a/v2.0.2/sitemap.xml b/v2.0.2/sitemap.xml new file mode 100644 index 0000000..6bc7811 --- /dev/null +++ b/v2.0.2/sitemap.xml @@ -0,0 +1,183 @@ + + + + https://zotregistry.dev/v2.0.2/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/admin-guide/admin-configuration/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/admin-guide/admin-getting-started/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/authn-authz/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/benchmarking-with-zb/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/building-ci-cd-pipeline/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/clustering/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/graphql/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/immutable-tags/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/kind-deploy/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/mirroring/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/monitoring/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/pprofiling/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/retention/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/security-posture/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/storage/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/verifying-signatures/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/articles/workflow/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/developer-guide/api-reference/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/developer-guide/api-user-guide/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/developer-guide/contributing/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/developer-guide/extensions-dev/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/developer-guide/onboarding/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/architecture/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/concepts/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/extensions/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/features/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/glossary/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/project/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/releases/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/general/whats-new/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/install-guides/install-guide-k8s/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/install-guides/install-guide-linux/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/user-guides/user-guide-datapath/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/user-guides/user-guide-gui/ + 2024-03-13 + daily + + + https://zotregistry.dev/v2.0.2/user-guides/zli/ + 2024-03-13 + daily + + \ No newline at end of file diff --git a/v2.0.2/sitemap.xml.gz b/v2.0.2/sitemap.xml.gz new file mode 100644 index 0000000..7725090 Binary files /dev/null and b/v2.0.2/sitemap.xml.gz differ diff --git a/v2.0.2/stylesheets/custom.css b/v2.0.2/stylesheets/custom.css new file mode 100644 index 0000000..1e94eac --- /dev/null +++ b/v2.0.2/stylesheets/custom.css @@ -0,0 +1,56 @@ +.default-bg { + background: none!important; + background-color:hsla(232,15%,21%,1)!important; +} + +.content-container-centered { + padding: 5.2rem 0; + margin: 0 0.8rem; +} + +.centered-content-grid { + margin-top: 2.4rem + +} + +.centered-content-grid ul.centered-content-grid__list { + display: flex; + flex-flow: row wrap; + gap: 1.6rem; + padding: 0; + margin: 0; +} + +.centered-content-grid ul.centered-content-grid__list > li.centered-content-grid__item{ + display: flex; + flex: 1 0 48%; + gap: 0.6rem; + margin: 0; +} + +.centered-content-grid ul.centered-content-grid__list > li.centered-content-grid__item div.item_content{ + color: var(--md-typeset-color)!important; +} + + +.centered-content-grid ul.centered-content-grid__list > li.centered-content-grid__item div.item_content h2.card_title{ + font-weight: 700; + margin-top: 0.175em; +} + +.centered-content-grid ul.centered-content-grid__list > li.centered-content-grid__item div.content_icon{ + fill: currentcolor; + background-color: var(--md-default-fg-color--lightest); + border-radius: 100%; + flex-shrink: 0; + height: 2.2rem; + padding: 0.55rem 0.4rem 0.4rem 0.4rem; + width: 2.2rem; +} + +[data-md-color-scheme="slate"] { + --md-hue: 210; + --md-primary-fg-color: #b37400; + --md-primary-fg-color--light: #ECB7B7; + --md-primary-fg-color--dark: #90030C; +} diff --git a/v2.0.2/user-guides/user-guide-datapath/index.html b/v2.0.2/user-guides/user-guide-datapath/index.html new file mode 100644 index 0000000..799acb3 --- /dev/null +++ b/v2.0.2/user-guides/user-guide-datapath/index.html @@ -0,0 +1,55 @@ + Push and Pull Image Content - zotregistry.dev

    Push and Pull Image Content

    👉 zot is an OCI image registry that allows you to store, manage, and share container images.

    A zot registry can store and serve a variety of content, but the type of content may dictate your choice of a client tool.

    For various content types, this document shows examples of using a third-party client tool that supports the content. The following table shows which content and client tools are demonstrated.

    Content Type Client
    OCI images skopeo
    OCI images regclient (regctl)
    OCI images crane
    OCI artifacts oras
    Helm charts helm

    ✏ zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.

    ✏ In the following examples, the zot registry is located at localhost, using port number 5000.

    Common tasks using skopeo for OCI images

    skopeo is a command line client that performs various operations on OCI container images and image repositories.

    ✏ For detailed information about using skopeo, see the skopeo man page.

    Push an OCI image

    This example pushes the latest container image for the busybox application to a zot registry.

    $ skopeo --insecure-policy copy --dest-tls-verify=false --multi-arch=all \
    +   --format=oci docker://busybox:latest \
    +   docker://localhost:5000/busybox:latest
    +

    Pull an OCI image

    This example pulls the latest container image for the busybox application and stores the image to a local OCI-layout directory (/oci/images).

    $ skopeo --insecure-policy copy --src-tls-verify=false --multi-arch=all \
    +   docker://localhost:5000/busybox:latest \
    +   oci:/oci/images:busybox:latest
    +

    Pull an OCI image to a private docker registry

    This example pulls the latest container image for the busybox application and stores the image to a local private docker registry.

    $ skopeo --insecure-policy copy --src-tls-verify=false --multi-arch=all \
    +   docker://localhost:5000/busybox:latest \
    +   docker://localhost:5000/busybox:latest
    +
    Click here to view an example of pushing and pulling an image using skopeo.

    Authentication

    In these examples, authentication is disabled for the source and destination. You can enable authentication by changing the command line options as follows:

    --src-tls-verify=true
    +--dest-tls-verify=true
    +

    You can also add credentials for authenticating with a source or destination repository:

    --src-creds username:password
    +--dest-creds username:password
    +

    Common tasks using regclient for OCI images

    regclient is a client interface that performs various operations on OCI container images and image repositories. The command line interface for regclient is regctl.

    ✏ For detailed information about regctl commands, see the regctl Documentation.

    Push an OCI image

    This example pushes version 1.20 of golang to a tools repository within the registry.

    $ regctl registry set --tls=disabled localhost:5000
    +$ regctl image copy ocidir://path/to/golang:1.20 localhost:5000/tools
    +

    Pull an OCI image

    This example pulls version 1.20 of golang to a local OCI-layout directory.

    $ regctl image copy localhost:5000/tools ocidir://path/to/golang:1.20
    +

    List all repositories in registry

    This example list all repositories in the registry.

    $ regctl repo ls localhost:5000
    +

    List tags

    This example lists all tags in the tools repository within the registry.

    $ regctl tag ls localhost:5000/tools
    +

    Pull and push manifest

    This example pulls and pushes the manifest in the tools repository within the registry.

    $ regctl manifest get localhost:5000/tools --format=raw-body
    +$ regctl manifest put localhost:5000/tools:1.0.0 \
    +--format oci --content-type application/vnd.oci.image.manifest.v1+json \
    +--format oci
    +

    Authentication

    In the preceding examples, TLS authentication with the zot registry was disabled by the following command:

    $ regctl registry set --tls=disabled localhost:5000
    +

    This command allows regctl to accept an HTTP response from the zot server. If TLS authentication is enabled on the zot registry server, you can omit this command from your regctl session.

    Common tasks using oras for OCI artifacts

    ORAS (OCI Registry As Storage) is a command line client for storing OCI artifacts on OCI repositories.

    ✏ For detailed information about the oras commands in these examples, see the ORAS CLI documentation.

    Push an artifact

    This example pushes version 2 of an artifact file named hello-artifact to a zot registry.

    $ oras push --plain-http localhost:5000/hello-artifact:v2 \
    +        --config config.json:application/vnd.acme.rocket.config.v1+json \
    +        artifact.txt:text/plain -d -v
    +

    Pull an artifact

    This example pulls version 2 of an artifact file named hello-artifact from a zot registry.

    $ oras pull --plain-http localhost:5000/hello-artifact:v2 -d -v
    +
    Click here to view an example of pushing and pulling an artifact using oras.

    Attach a reference

    $ echo '{"artifact": "localhost:5000/hello-artifact:v2", "signature": "pat hancock"}' > signature.json
    +
    +$ oras push localhost:5000/hello-artifact \
    +  --artifact-type 'signature/example' \
    +  --subject localhost:5000/hello-artifact:v2 \
    +  ./signature.json:application/json
    +
    +$ oras discover -o tree localhost:5000/hello-artifact:v2
    +

    Authentication

    To authenticate with the zot server, log in at the start of your session using the following command:

    $ oras login -u myUsername -p myPassword localhost:5000
    +

    You can also add credentials in the push or pull commands as in this example:

    $ oras pull -u myUsername -p myPassword localhost:5000/hello-artifact:v2 -d -v
    +

    ✏ For additional authentication options, including interactive credential entry and disabling TLS, see the ORAS authentication documentation.

    Common tasks using helm for helm charts

    Helm is a package manager for Kubernetes. Among many other capabilities, helm can store and retrieve helm charts on OCI image repositories.

    ✏ For detailed information about the helm commands in these examples, see Commands for working with registries in the helm documentation.

    Push a helm chart

    This example pushes version 1.2.3 of a zot helm chart to a zot-chart repository within the registry.

    $ helm package path/to/helm-charts/charts/zot
    +$ helm push zot-1.2.3.tgz oci://localhost:5000/zot-chart
    +

    Pull a helm chart

    This example pulls version 1.2.3 of a zot helm chart from a zot-chart repository within the registry.

    $ helm pull oci://localhost:5000/zot-chart/zot --version 1.2.3
    +

    Authentication

    To authenticate with the zot server, log in at the start of your session using the following command:

    $ helm registry login -u myUsername localhost:5000
    +

    You will be prompted to manually enter a password.

    Common tasks using crane for OCI images

    crane is an open-source project that provides a command-line interface (CLI) for interacting with container registries, such as Docker Hub and Google Container Registry.

    ✏ For detailed information about crane commands, see the crane Documentation.

    Push an OCI image

    This example pushes the latest container image for the alpine application to a registry.

    $ crane --insecure push \
    +   oci/images/alpine:latest \
    +   localhost:5000/alpine:latest
    +

    Pull an OCI image

    This example pulls the latest container image for the alpine application and stores the image to a local OCI-layout directory (/oci/images).

    $ crane --insecure pull \
    +   --format oci \
    +   localhost:5000/alpine:latest \
    +   oci/images/alpine:latest
    +

    Copy an OCI image to a private docker registry

    This example pulls the latest container image for the alpine application and stores the image to a local private docker registry.

    $ crane --insecure copy \
    +   alpine:latest \
    +   localhost:5000/alpine:latest
    +

    List tags

    This example lists all tags in the alpine image within the registry.

    $ crane ls localhost:5000/alpine
    +

    Find the digest of an image

    This example gets the digest of the alpine image within the registry.

    $ crane digest localhost:5000/alpine:latest
    +

    Authentication

    To authenticate with the registry server, log in at the start of your session using the following command:

    $ crane auth login -u myUsername localhost:5000
    +

    Last update: September 13, 2023
    \ No newline at end of file diff --git a/v2.0.2/user-guides/user-guide-gui/index.html b/v2.0.2/user-guides/user-guide-gui/index.html new file mode 100644 index 0000000..0756e90 --- /dev/null +++ b/v2.0.2/user-guides/user-guide-gui/index.html @@ -0,0 +1 @@ + Use the Web Interface to Find Images - zotregistry.dev

    Use the Web Interface to Find Images

    👉 Using a browser, you can browse a zot repository for container images and artifacts. The web interface also provides the commands for downloading an image using popular third-party tools.

    If a zot registry is built with the optional zui package, the registry has a web interface.

    Access the registry

    ✏ Depending on the security configuration of the zot registry, you might need to authenticate before being given access.

    The initial page of the registry displays a sampling of the most popular images and recently updated images. To view all available images in the registry, click the View all link in the upper right of the page to go to the /explore page.

    screen-initial

    💡 Wherever an image name appears, two icons follow the name, indicating the results of the vulnerability scan and the signature status. These icons are described in Icons and their meanings.

    Find an image

    To assist you in finding images specific to your requirements, the /explore page provides several sorting options along with faceted navigation in addition to a general search box.

    • Sorting criteria include relevance, most recently updated, alphabetical, and most downloaded.

    • Navigation facets include operating system, CPU architecture, and signature status.

    screen-initial

    When you locate the desired image, click its tile.

    tile

    Inspect the image properties

    The OVERVIEW tab of the initial image description page contains a brief description of the image along with several details, such as the repository URL, number of downloads, last published, size, and license type.

    Click the TAGS tab to view the available versions of the image.

    screen-tags

    Click the tag link of the desired version of the image. In the resulting page, you can view detailed information about the image, including its digest hash, and you can obtain a command to pull the image from the repository.

    screen-layers

    Tabs on this page provide the following information:

    Tab Description
    LAYERS The build command and the digest hash
    USES A list of images used by this image
    USED BY A list of images that use this image
    VULNERABILITIES A list of known vulnerabilities

    From the LAYERS tab, click Details to view an example of the image build command and the layer's digest hash.

    layers-details

    Pull an image

    After opening the tag link of the desired image, click the Pull Image drop-down list to display the available pull commands. Docker, podman, and skopeo image management tools are supported.

    pull-image

    Select a tool and click the pages icon next to the command to copy the full command to your clipboard. An example of the pull command using podman is:

    podman pull zothub.io/c3/debian/base-amd64:bullseye

    Paste the pull command into your terminal to pull the image.

    💡 For information about using image management tools to pull images, see Push and Pull Image Content.

    Adding Bookmarks

    To mark an image so that it can be easily found later, click the bookmark icon on the image page. Bookmarked images appear in search queries when the Bookmarked option is enabled.

    The bookmark icon before selection:

    The bookmark icon after selection:

    Icons and their meanings

    These icons appear next to the image name, indicating the results of the vulnerability scan and the signature status.

    Icon Description
    A vulnerability scan of the image found no vulnerabilities
    A vulnerability scan of the image failed
    (See severity icon in VULNERABILITIES tab)
          Critical severity
          High severity
          Medium severity
          Low severity
    The image signature is verified
    The image signature is not verified
    The image is not bookmarked by the user
    The image is bookmarked by the user

    Last update: August 4, 2023
    \ No newline at end of file diff --git a/v2.0.2/user-guides/zli/index.html b/v2.0.2/user-guides/zli/index.html new file mode 100644 index 0000000..902f5bc --- /dev/null +++ b/v2.0.2/user-guides/zli/index.html @@ -0,0 +1,306 @@ + Command Line (zli) - zotregistry.dev

    Using the command line interface (zli)

    👉 zli: The command line tool for zot servers

    What is zli?

    zli is a binary that implements a set of command line commands for interacting with the zot registry server.

    💡 We recommend installing zli when you install zot.

    How to get zli

    zli is hosted with zot on GitHub at project-zot. From GitHub, you can download the zli binary or you can build zli from the source.

    Supported platforms

    zli is supported for the following operating systems and platform architectures:

    OS ARCH Platform
    linux amd64 Intel-based Linux servers
    linux arm64 ARM-based servers and Raspberry Pi4
    darwin amd64 Intel-based MacOS
    darwin arm64 ARM-based MacOS

    Downloading zli binaries

    You can download the executable binary for your server platform and architecture under "Assets" on the GitHub zot releases page.

    The binary image is named using the OS and architecture from the Supported platforms table. For example, the binary for an Intel-based MacOS server is zli-darwin-amd64.

    Building zli from source

    To build the zli binary, copy or clone the zot project from GitHub and execute the make cli command in the zot directory. Use the same command options that you used to build zot, as shown:

    make OS=os ARCH=architecture cli

    For example, the following command builds zli for an Intel-based MacOS server:

    make OS=darwin ARCH=amd64 cli
    +

    In this example, the resulting executable file is zli-darwin-amd64 in the zot/bin directory.

    Common tasks using zli

    This section includes examples of common zot server tasks using the zli command line interface. For a detailed listing of zli commands, see the zli Command Reference in this guide.

    💡 The original filename of the zli executable file will reflect the build options, such as zli-linux-amd64. For convenience, you can rename the executable to simply zli. The instructions and examples in this guide use zli as the name of the executable file.

    Adding a zot server URL

    You can modify the zot server configuration using the zli config add command. This example adds a zot server URL with an alias of remote-zot:

    $ bin/zli config add remote-zot https://server-example:8080
    +

    Use the zli config command to list all configured URLs with their aliases:

    $ bin/zli config -l
    +
    +remote-zot   https://server-example:8080
    +local        http://localhost:8080
    +

    Listing images

    You can list all images hosted on a zot server using the zli image list command with the server’s alias:

    $ bin/zli image list --config local
    +
    +REPOSITORY        TAG       OS/ARCH         DIGEST      SIGNED      SIZE        
    +alpine            latest    linux/amd64     3fc10231    false       84MB        
    +busybox           latest    linux/amd64     9172c5f6    false       2.2MB
    +

    You can also filter the image list to view a specific image by specifying the image name:

    $ bin/zli image name busybox:latest --config local
    +
    +REPOSITORY        TAG       OS/ARCH         DIGEST      SIGNED      SIZE              
    +busybox           latest    linux/amd64     9172c5f6    false       2.2MB
    +

    Scanning images for known vulnerabilities

    Using the zli cve list command, you can fetch the CVE (Common Vulnerabilities and Exposures) information for images hosted on the zot server. This example shows how to learn which images are affected by a specific CVE:

    $ bin/zli cve affected CVE-2017-9935 --config remote-zot
    +
    +IMAGE NAME        TAG               DIGEST    SIZE
    +c3/openjdk-dev    commit-5be4d92    ac3762e2  335MB
    +

    This example displays a list of all CVEs affecting a specific image:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot
    +
    +ID                SEVERITY  TITLE
    +CVE-2015-8540     LOW       libpng: underflow read in png_check_keyword()
    +CVE-2017-16826    LOW       binutils: Invalid memory access in the coff_s...
    +

    This example (--verbose) displays a list of all CVEs affecting a specific image with details:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot --verbose
    +LOW 2, UNKNOWN 1, TOTAL 3
    +
    +CVE-2015-8540
    +...
    +

    Note that the details may display the package path in the image when the information is available.

    This example displays the detailed CVEs in JSON format:

    $ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot -f json
    +{
    +  "Tag": "0.3.19",
    +  "CVEList": [
    +    {
    +      "Id": "CVE-2019-17006",
    +      "Severity": "MEDIUM",
    +      "Title": "nss: Check length of inputs for cryptographic primitives",
    +      "Description": "A vulnerability was discovered in nss where input text length was not checked when using certain cryptographic primitives. This could lead to a heap-buffer overflow resulting in a crash and data leak. The highest threat is to confidentiality and integrity of data as well as system availability.",
    +      "PackageList": [
    +        {
    +          "Name": "nss",
    +          "InstalledVersion": "3.44.0-7.el7_7",
    +          "FixedVersion": "Not Specified"
    +        },
    +        {
    +          "Name": "nss-sysinit",
    +          "InstalledVersion": "3.44.0-7.el7_7",
    +          "FixedVersion": "Not Specified"
    +        },
    +        {
    +          "Name": "nss-tools",
    +          "InstalledVersion": "3.44.0-7.el7_7",
    +          "FixedVersion": "Not Specified"
    +        }]
    +    }]
    +}
    +

    This example lists all images on a specific zot server that are affected by a specific CVE:

    $ bin/zli cve affected --config remote-zot CVE-2017-9935 --repo c3/openjdk-dev
    +
    +IMAGE NAME        TAG               DIGEST    SIZE
    +c3/openjdk-dev    commit-2674e8a    71046748  338MB
    +c3/openjdk-dev    commit-bd5cc94    0ab7fc76
    +

    This example lists all images on a specific zot server where the CVE has been fixed:

    $ bin/zli cve fixed c3/openjdk-dev CVE-2017-9935 --config remote-zot
    +
    +IMAGE NAME        TAG                       DIGEST    SIZE
    +c3/openjdk-dev    commit-2674e8a-squashfs   b545b8ba  321MB
    +c3/openjdk-dev    commit-d5024ec-squashfs   cd45f8cf  321MB
    +

    This example lists all CVEs that have been found in one image and not the other:

    $ bin/zli cve diff c3/openjdk-dev:1.0.0 c3/openjdk-dev:2.0.0 --config remote-zot
    +
    +ID                SEVERITY  TITLE
    +CVE-2015-8540     LOW       libpng: underflow read in png_check_keyword()
    +CVE-2017-16826    LOW       binutils: Invalid memory access in the coff_s...
    +

    For example, the above query lists all CVEs that have been found in c3/openjdk-dev:1.0.0 but not in c3/openjdk-dev:2.0.0

    Listing repositories

    You can list all repositories hosted on a zot server using the zli repo command with the server’s alias:

    Searching... 🌍
    +
    +REPOSITORY NAME
    +alpine
    +busybox
    +

    Searching for repositories and images

    You can locate repositories and images hosted on a zot server using the zli search command.

    • To search for a repository, specify the full name with a colon or a partial name with no colon.
    • To search for an image, specify the full repository name followed by the tag or a prefix of the tag.

    This example searches the zot registry named 'local' for a repository whose name contains the substring 'ng':

    $ bin/zli search query ng --config local
    +
    +NAME            SIZE        LAST UPDATED                             DOWNLOADS   STARS
    +nginx           794MB       2023-03-01 18:44:17.707690369 +0000 UTC  0           0
    +mongo           232MB       2022-10-18 15:03:40.7646203 +0300 +0300  0           0
    +golang          1.1GB       2023-06-22 00:32:38.613354854 +0000 UTC  0           0
    +

    This example searches the zot registry named 'local' for a repository named 'nginx'. Because the repository name is followed by a colon, the search results must match the name exactly.

    $ bin/zli search query nginx: --config local
    +
    +REPOSITORY  TAG          OS/ARCH         DIGEST      SIGNED      SIZE
    +nginx       1.23.1       linux/amd64     d2ad9089    true        57MB
    +nginx       latest       *               c724afdf    true        448MB
    +                         linux/amd64     009c6fda    false       57MB
    +                         linux/arm/v5    1d5d4f53    false       54MB
    +                         linux/arm/v7    f809744c    false       50MB
    +                         linux/arm64/v8  ebb807a9    false       56MB
    +                         linux/386       19cf4b3c    false       59MB
    +                         linux/mips64le  45ab60e6    false       55MB
    +                         linux/ppc64le   89511bee    false       63MB
    +                         linux/s390x     713b9329    false       55MB
    +nginx       stable-perl  *               4383a0b8    true        534MB
    +                         linux/amd64     308a37a0    false       68MB
    +                         linux/arm/v5    0fb8fb71    false       64MB
    +                         linux/arm/v7    6868f552    false       60MB
    +                         linux/arm64/v8  aed72c86    false       66MB
    +                         linux/386       5c7ed456    false       69MB
    +                         linux/mips64le  546d2bae    false       65MB
    +                         linux/ppc64le   7db02f5a    false       74MB
    +                         linux/s390x     800fd86f    false       66MB
    +

    Sorting the output of a zli command

    For a zli command that can result in a lengthy output list, you can use the command flag --sort-by <option> to cause the output to be sorted by a specified property of the output data. The available sorting criteria vary for different commands, but examples of sorting criteria options are described in the following table:

    flag option criteria
    alpha-asc alphabetical, ascending
    alpha-dsc alphabetical, descending
    relevance quality of match
    severity severity of condition
    update-time timestamp

    For a given command that results in an output list, you can see the available sorting criteria in the usage information returned by the --help flag. For example, bin/zli image name --help returns usage information containing the following line under "Flags":

    --sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default "alpha-asc")

    According to this information, the list of image names returned by the bin/zli image name command can be sorted in order of alphabetical ascending, alphabetical descending, or the timestamp of the latest update of the image. The default sorting method for this command, if no --sort-by flag is present, is alphabetical ascending.

    Command reference

    This section provides detailed usage information for basic first-level zli commands. Many zli commands also support subcommands, which are listed as "Available Commands" in each command description. For example, zli search can be extended with either the query or subject subcommand. To see the detailed usage for each subcommand, type the command with the subcommand and append --help, such as zli search query --help. The zli search description below includes the subcommand help as an example.

    zli

    $ bin/zli --help
    +
    +Usage:
    +  zli [flags]
    +  zli [command]
    +
    +Available Commands:
    +  completion  Generate the autocompletion script for the specified shell
    +  config      Configure zot registry parameters for CLI
    +  cve         Lookup CVEs in images hosted on the zot registry
    +  help        Help about any command
    +  image       List images hosted on the zot registry
    +  repo        List all repositories
    +  search      Search images and their tags
    +
    +Flags:
    +  -h, --help      help for zli
    +  -v, --version   show the version and exit
    +
    +Use "zli [command] --help" for more information about a command.
    +

    zli completion

    This command generates the autocompletion script for zli for the specified shell. See each subcommand’s help for details on how to use the generated script.

    $ bin/zli completion --help
    +
    +Usage:
    +  zli completion [command]
    +
    +Available Commands:
    +  bash        Generate the autocompletion script for bash
    +  fish        Generate the autocompletion script for fish
    +  powershell  Generate the autocompletion script for powershell
    +  zsh         Generate the autocompletion script for zsh
    +
    +Flags:
    +  -h, --help   help for completion
    +
    +Use "zli completion [command] --help" for more information about a command.
    +

    zli config

    This command configures zot registry parameters for CLI.

    $ bin/zli config --help
    +
    +Usage:
    +  zli config <config-name> [variable] [value] [flags]
    +  zli config [command]
    +
    +Examples:
    +  zli config add main https://zot-foo.com:8080
    +  zli config --list
    +  zli config main url
    +  zli config main --list
    +  zli config remove main
    +
    +Available Commands:
    +  add         Add configuration for a zot registry
    +  remove      Remove configuration for a zot registry
    +
    +Flags:
    +  -h, --help    help for config
    +  -l, --list    List configurations
    +      --reset   Reset a variable value
    +
    +Use "zli config [command] --help" for more information about a command.
    +
    +Useful variables:
    +  url       zot server URL
    +  showspinner   show spinner while loading data [true/false]
    +  verify-tls    enable TLS certificate verification of the server [default: true]
    +

    zli cve

    This command lists CVEs (Common Vulnerabilities and Exposures) of images hosted on the zot registry

    $ ./zli cve --help
    +
    +Usage:
    +  zli cve [command]
    +
    +Available Commands:
    +  affected    List images affected by a CVE
    +  fixed       List tags where a CVE is fixedRetryWithContext
    +  list        List CVEs by REPO:TAG or REPO@DIGEST
    +
    +Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -f, --format string   Specify output format [text/json/yaml]
    +  -h, --help            help for cve
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +      --verbose         Show verbose output
    +
    +Use "zli cve [command] --help" for more information about a command.
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    zli image

    This command lists images hosted on the zot registry.

    $ ./zli image --help
    +
    +Usage:
    +  zli image [command]
    +
    +Available Commands:
    +  base        List images that are base for the given image
    +  cve         List all CVE's of the image
    +  derived     List images that are derived from given image
    +  digest      List images that contain a blob(manifest, config or layer) with the given digest
    +  list        List all images
    +  name        List image details by name
    +
    +Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -f, --format string   Specify output format [text/json/yaml]
    +  -h, --help            help for image
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +      --verbose         Show verbose output
    +
    +Use "zli image [command] --help" for more information about a command.
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    zli repo

    This command lists all repositories in the zot registry.

    $ ./zli repo --help
    +
    +Usage:
    +  zli repo [command]
    +
    +Available Commands:
    +  list        List all repositories
    +
    +Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -h, --help            help for repo
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +
    +Use "zli repo [command] --help" for more information about a command.
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    The search command allows smart searching for a repository by its name or for an image by its repo:tag.

    $ ./zli search --help
    +
    +Search repos or images
    +
    +Usage:
    +  zli search [command]
    +
    +Available Commands:
    +  query       Fuzzy search for repos and their tags.
    +  subject     List all referrers for this subject.
    +
    +Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -f, --format string   Specify output format [text/json/yaml]
    +  -h, --help            help for search
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +      --verbose         Show verbose output
    +
    +Use "zli search [command] --help" for more information about a command.
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    zli search query

    $ ./zli search query --help
    +
    +Usage:
    +  zli search query [repo]|[repo:tag] [flags]
    +
    +Examples:
    +# For repo search specify a substring of the repo name without the tag
    +  zli search query "test/repo"
    +
    +# For image search specify the full repo name followed by the tag or a prefix of the tag.
    +  zli search query "test/repo:2.1."
    +
    +Flags:
    +  -h, --help             help for query
    +      --sort-by string   Options for sorting the output: [relevance, update-time, alpha-asc, alpha-dsc] (default "relevance")
    +
    +Global Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -f, --format string   Specify output format [text/json/yaml]
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +      --verbose         Show verbose output
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    zli search subject

    $ ./zli search subject --help
    +
    +List all referrers for this subject. The subject can be specified by tag(repo:tag) or by digest" or (repo@digest)
    +
    +Usage:
    +  zli search subject [repo:tag]|[repo@digest] [flags]
    +
    +Examples:
    +# For referrers search specify the referred subject using it's full digest or tag:
    +  zli search subject "repo@sha256:f9a0981..."
    +  zli search subject "repo:tag"
    +
    +Flags:
    +  -h, --help             help for subject
    +      --sort-by string   Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default "alpha-asc")
    +
    +Global Flags:
    +      --config string   Specify the registry configuration to use for connection
    +      --debug           Show debug output
    +  -f, --format string   Specify output format [text/json/yaml]
    +      --url string      Specify zot server URL if config-name is not mentioned
    +  -u, --user string     User Credentials of zot server in "username:password" format
    +      --verbose         Show verbose output
    +
    +Run 'zli config -h' for details on [config-name] argument
    +

    Last update: March 13, 2024
    \ No newline at end of file diff --git a/versions.json b/versions.json index 8ed6485..b38a1a8 100644 --- a/versions.json +++ b/versions.json @@ -1 +1 @@ -[{"version": "v2.0.1", "title": "v2.0.1", "aliases": ["zot", "latest"]}, {"version": "v2.0.0", "title": "v2.0.0", "aliases": []}, {"version": "v1.4.3", "title": "v1.4.3", "aliases": []}] \ No newline at end of file +[{"version": "v2.0.2", "title": "v2.0.2", "aliases": ["zot", "latest"]}, {"version": "v2.0.1", "title": "v2.0.1", "aliases": []}, {"version": "v2.0.0", "title": "v2.0.0", "aliases": []}, {"version": "v1.4.3", "title": "v1.4.3", "aliases": []}] \ No newline at end of file diff --git a/zot/404.html b/zot/404.html index 0aea49c..3bc7e6c 100644 --- a/zot/404.html +++ b/zot/404.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../v2.0.1/404.html... + Redirecting to ../v2.0.2/404.html... \ No newline at end of file diff --git a/zot/admin-guide/admin-configuration/index.html b/zot/admin-guide/admin-configuration/index.html index 07d4263..9832a93 100644 --- a/zot/admin-guide/admin-configuration/index.html +++ b/zot/admin-guide/admin-configuration/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/admin-guide/admin-configuration/... + Redirecting to ../../../v2.0.2/admin-guide/admin-configuration/... \ No newline at end of file diff --git a/zot/admin-guide/admin-getting-started/index.html b/zot/admin-guide/admin-getting-started/index.html index dbf76ab..bcc323a 100644 --- a/zot/admin-guide/admin-getting-started/index.html +++ b/zot/admin-guide/admin-getting-started/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/admin-guide/admin-getting-started/... + Redirecting to ../../../v2.0.2/admin-guide/admin-getting-started/... \ No newline at end of file diff --git a/zot/articles/authn-authz/index.html b/zot/articles/authn-authz/index.html index e750771..004a67c 100644 --- a/zot/articles/authn-authz/index.html +++ b/zot/articles/authn-authz/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/authn-authz/... + Redirecting to ../../../v2.0.2/articles/authn-authz/... \ No newline at end of file diff --git a/zot/articles/benchmarking-with-zb/index.html b/zot/articles/benchmarking-with-zb/index.html index b3416b7..4053ba9 100644 --- a/zot/articles/benchmarking-with-zb/index.html +++ b/zot/articles/benchmarking-with-zb/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/benchmarking-with-zb/... + Redirecting to ../../../v2.0.2/articles/benchmarking-with-zb/... \ No newline at end of file diff --git a/zot/articles/building-ci-cd-pipeline/index.html b/zot/articles/building-ci-cd-pipeline/index.html index 93c2ddc..148ca9b 100644 --- a/zot/articles/building-ci-cd-pipeline/index.html +++ b/zot/articles/building-ci-cd-pipeline/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/building-ci-cd-pipeline/... + Redirecting to ../../../v2.0.2/articles/building-ci-cd-pipeline/... \ No newline at end of file diff --git a/zot/articles/clustering/index.html b/zot/articles/clustering/index.html index 9cfcc66..d0ca945 100644 --- a/zot/articles/clustering/index.html +++ b/zot/articles/clustering/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/clustering/... + Redirecting to ../../../v2.0.2/articles/clustering/... \ No newline at end of file diff --git a/zot/articles/graphql/index.html b/zot/articles/graphql/index.html index a403ca8..63e9092 100644 --- a/zot/articles/graphql/index.html +++ b/zot/articles/graphql/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/graphql/... + Redirecting to ../../../v2.0.2/articles/graphql/... \ No newline at end of file diff --git a/zot/articles/immutable-tags/index.html b/zot/articles/immutable-tags/index.html new file mode 100644 index 0000000..1f81012 --- /dev/null +++ b/zot/articles/immutable-tags/index.html @@ -0,0 +1,17 @@ + + + + + Redirecting + + + + + Redirecting to ../../../v2.0.2/articles/immutable-tags/... + + \ No newline at end of file diff --git a/zot/articles/kind-deploy/index.html b/zot/articles/kind-deploy/index.html index 3cb6e65..f67927f 100644 --- a/zot/articles/kind-deploy/index.html +++ b/zot/articles/kind-deploy/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/kind-deploy/... + Redirecting to ../../../v2.0.2/articles/kind-deploy/... \ No newline at end of file diff --git a/zot/articles/mirroring/index.html b/zot/articles/mirroring/index.html index 27f210f..15af30b 100644 --- a/zot/articles/mirroring/index.html +++ b/zot/articles/mirroring/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/mirroring/... + Redirecting to ../../../v2.0.2/articles/mirroring/... \ No newline at end of file diff --git a/zot/articles/monitoring/index.html b/zot/articles/monitoring/index.html index f06afc7..116248f 100644 --- a/zot/articles/monitoring/index.html +++ b/zot/articles/monitoring/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/monitoring/... + Redirecting to ../../../v2.0.2/articles/monitoring/... \ No newline at end of file diff --git a/zot/articles/pprofiling/index.html b/zot/articles/pprofiling/index.html index 1eb49f2..066784b 100644 --- a/zot/articles/pprofiling/index.html +++ b/zot/articles/pprofiling/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/pprofiling/... + Redirecting to ../../../v2.0.2/articles/pprofiling/... \ No newline at end of file diff --git a/zot/articles/retention/index.html b/zot/articles/retention/index.html index e70ba71..1abae58 100644 --- a/zot/articles/retention/index.html +++ b/zot/articles/retention/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/retention/... + Redirecting to ../../../v2.0.2/articles/retention/... \ No newline at end of file diff --git a/zot/articles/security-posture/index.html b/zot/articles/security-posture/index.html index 7a8fdef..fa02dfb 100644 --- a/zot/articles/security-posture/index.html +++ b/zot/articles/security-posture/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/security-posture/... + Redirecting to ../../../v2.0.2/articles/security-posture/... \ No newline at end of file diff --git a/zot/articles/storage/index.html b/zot/articles/storage/index.html index 5310b8f..7c629ed 100644 --- a/zot/articles/storage/index.html +++ b/zot/articles/storage/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/storage/... + Redirecting to ../../../v2.0.2/articles/storage/... \ No newline at end of file diff --git a/zot/articles/verifying-signatures/index.html b/zot/articles/verifying-signatures/index.html index ba89d02..09e06de 100644 --- a/zot/articles/verifying-signatures/index.html +++ b/zot/articles/verifying-signatures/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/verifying-signatures/... + Redirecting to ../../../v2.0.2/articles/verifying-signatures/... \ No newline at end of file diff --git a/zot/articles/workflow/index.html b/zot/articles/workflow/index.html index 53c5599..6ad0f1c 100644 --- a/zot/articles/workflow/index.html +++ b/zot/articles/workflow/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/articles/workflow/... + Redirecting to ../../../v2.0.2/articles/workflow/... \ No newline at end of file diff --git a/zot/developer-guide/api-reference/index.html b/zot/developer-guide/api-reference/index.html index 0fa1549..db98591 100644 --- a/zot/developer-guide/api-reference/index.html +++ b/zot/developer-guide/api-reference/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/api-reference/... + Redirecting to ../../../v2.0.2/developer-guide/api-reference/... \ No newline at end of file diff --git a/zot/developer-guide/api-user-guide/index.html b/zot/developer-guide/api-user-guide/index.html index 33fa4c6..2a77f4f 100644 --- a/zot/developer-guide/api-user-guide/index.html +++ b/zot/developer-guide/api-user-guide/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/api-user-guide/... + Redirecting to ../../../v2.0.2/developer-guide/api-user-guide/... \ No newline at end of file diff --git a/zot/developer-guide/contributing/index.html b/zot/developer-guide/contributing/index.html index 15c00b0..c3fa106 100644 --- a/zot/developer-guide/contributing/index.html +++ b/zot/developer-guide/contributing/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/contributing/... + Redirecting to ../../../v2.0.2/developer-guide/contributing/... \ No newline at end of file diff --git a/zot/developer-guide/extensions-dev/index.html b/zot/developer-guide/extensions-dev/index.html index 180f863..fe7c709 100644 --- a/zot/developer-guide/extensions-dev/index.html +++ b/zot/developer-guide/extensions-dev/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/extensions-dev/... + Redirecting to ../../../v2.0.2/developer-guide/extensions-dev/... \ No newline at end of file diff --git a/zot/developer-guide/onboarding/index.html b/zot/developer-guide/onboarding/index.html index 6f0d5fc..fd33037 100644 --- a/zot/developer-guide/onboarding/index.html +++ b/zot/developer-guide/onboarding/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/developer-guide/onboarding/... + Redirecting to ../../../v2.0.2/developer-guide/onboarding/... \ No newline at end of file diff --git a/zot/general/architecture/index.html b/zot/general/architecture/index.html index 4819a3d..1435238 100644 --- a/zot/general/architecture/index.html +++ b/zot/general/architecture/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/architecture/... + Redirecting to ../../../v2.0.2/general/architecture/... \ No newline at end of file diff --git a/zot/general/concepts/index.html b/zot/general/concepts/index.html index 4430e56..c6e00c2 100644 --- a/zot/general/concepts/index.html +++ b/zot/general/concepts/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/concepts/... + Redirecting to ../../../v2.0.2/general/concepts/... \ No newline at end of file diff --git a/zot/general/extensions/index.html b/zot/general/extensions/index.html index a994523..51a37cc 100644 --- a/zot/general/extensions/index.html +++ b/zot/general/extensions/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/extensions/... + Redirecting to ../../../v2.0.2/general/extensions/... \ No newline at end of file diff --git a/zot/general/features/index.html b/zot/general/features/index.html index 490b3f8..c26a00d 100644 --- a/zot/general/features/index.html +++ b/zot/general/features/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/features/... + Redirecting to ../../../v2.0.2/general/features/... \ No newline at end of file diff --git a/zot/general/glossary/index.html b/zot/general/glossary/index.html index 4b862be..919affd 100644 --- a/zot/general/glossary/index.html +++ b/zot/general/glossary/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/glossary/... + Redirecting to ../../../v2.0.2/general/glossary/... \ No newline at end of file diff --git a/zot/general/project/index.html b/zot/general/project/index.html index 21c9878..3dd2cdc 100644 --- a/zot/general/project/index.html +++ b/zot/general/project/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/project/... + Redirecting to ../../../v2.0.2/general/project/... \ No newline at end of file diff --git a/zot/general/releases/index.html b/zot/general/releases/index.html index 1b13a50..916673f 100644 --- a/zot/general/releases/index.html +++ b/zot/general/releases/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/releases/... + Redirecting to ../../../v2.0.2/general/releases/... \ No newline at end of file diff --git a/zot/general/whats-new/index.html b/zot/general/whats-new/index.html index 3a6f2a5..3b9665e 100644 --- a/zot/general/whats-new/index.html +++ b/zot/general/whats-new/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/general/whats-new/... + Redirecting to ../../../v2.0.2/general/whats-new/... \ No newline at end of file diff --git a/zot/index.html b/zot/index.html index c3657da..1959f8f 100644 --- a/zot/index.html +++ b/zot/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../v2.0.1/... + Redirecting to ../v2.0.2/... \ No newline at end of file diff --git a/zot/install-guides/install-guide-k8s/index.html b/zot/install-guides/install-guide-k8s/index.html index 7b3560f..fee5175 100644 --- a/zot/install-guides/install-guide-k8s/index.html +++ b/zot/install-guides/install-guide-k8s/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/install-guides/install-guide-k8s/... + Redirecting to ../../../v2.0.2/install-guides/install-guide-k8s/... \ No newline at end of file diff --git a/zot/install-guides/install-guide-linux/index.html b/zot/install-guides/install-guide-linux/index.html index eae4aca..9e121ec 100644 --- a/zot/install-guides/install-guide-linux/index.html +++ b/zot/install-guides/install-guide-linux/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/install-guides/install-guide-linux/... + Redirecting to ../../../v2.0.2/install-guides/install-guide-linux/... \ No newline at end of file diff --git a/zot/user-guides/user-guide-datapath/index.html b/zot/user-guides/user-guide-datapath/index.html index cbb58e1..58e66de 100644 --- a/zot/user-guides/user-guide-datapath/index.html +++ b/zot/user-guides/user-guide-datapath/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/user-guide-datapath/... + Redirecting to ../../../v2.0.2/user-guides/user-guide-datapath/... \ No newline at end of file diff --git a/zot/user-guides/user-guide-gui/index.html b/zot/user-guides/user-guide-gui/index.html index 90a80d0..6276cef 100644 --- a/zot/user-guides/user-guide-gui/index.html +++ b/zot/user-guides/user-guide-gui/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/user-guide-gui/... + Redirecting to ../../../v2.0.2/user-guides/user-guide-gui/... \ No newline at end of file diff --git a/zot/user-guides/zli/index.html b/zot/user-guides/zli/index.html index afc343f..c0d758b 100644 --- a/zot/user-guides/zli/index.html +++ b/zot/user-guides/zli/index.html @@ -5,13 +5,13 @@ Redirecting - Redirecting to ../../../v2.0.1/user-guides/zli/... + Redirecting to ../../../v2.0.2/user-guides/zli/... \ No newline at end of file